Transcript
This transcript was autogenerated. To make changes, submit a PR.
Jamaica real
time feedback into the behavior of your distributed systems
and observing changes exceptions errors in
real time allows you to not only experiment with confidence,
but respond instantly to get things working again.
Close hi
there folks, thanks so much for taking your time today to join
me to talk about my favorite topic. That's serverless application development,
and I want to get into talking about what serverless development
is and how it is changing the world for you as a developer today.
Those that aren't aware my name is Gareth McCumskey. I am
a developer advocate and customer success engineer at Serverless Inc.
The creators of the serverless framework, and I've been
building serverless applications since around 2016 and joined serverless
back in 2019 to help the company assist
users and customers with building serverless applications.
So let's get into it, and we have quite a lot to discuss today,
so forgive me if I go a little bit quickly at times. Thankfully,
being in a video format, you can pause, rewind, slow it down, speed it
up, even if you prefer. And to get us started, I really wanted to take
a look at defining what serverless is because there are
a lot of people talking about what serverless is with different definitions and so
on. So I thought, let's start with that. Let's define what I mean
by serverless. So we're all kind of on the same page. And what
we find today is traditionally your application that you're building
ends up just being a collection of code, and it's this huge pile of code
that you've got that makes your application what it is. And what serverless
is, is about taking that existing application youll have and
breaking it up in a way to use the cloud serverless available to you
in services such as AWS, Google Cloud,
Azure and so on. And this is not just
about taking that nice big chunk of code you've
got running on now and just picking it up and dropping it into Lambda.
What this is is about architecting your application to
make the best use of the cloud services that are available to you. And this
is what is often referred to as being cloud native. We're building
our application to make use of the cloud services, as opposed to
building youll application and happen to be using cloud services to
make it run.
So you'd be building your app. Something like this is a very simple example,
obviously, but you've got your front end and your back end. Your back end is
often defined with exprs, where it's managing
the routing for you, and you've got your front end with your HTML JavaScript and
CSS, and it's all one big pile of code. You have a server somewhere that
you're going to put that machine on. You have a web server application
like an Nginx or an Apache that receives HTTP requests,
and that application software will then format the
incoming HTTP request in a way that exprs and other frameworks
can understand it. What serverless development
does is a bit different. So typically what you'll find in
serverless development is that youll have a separation between a front end and a backend.
This is also where Jamstack becomes really useful if you have
a static front end, but there are ways as well to do
dynamic back ends. So typically
in a serverless application what you'll find on the front end side is in AWS
for example. And I'll be talking about AWS specifically because it's this
cloud vendor that I'm the most familiar with, but you'll have a service like s
three. S three is a really great cloud service for storing files
including HTML, CSS and JavaScript, and your front end is
then expressed using those three technologies. JavaScript is then used to
help make your site dynamic and query. Youll backend and
in youll front end you'll probably want a can of some type. So AWS provides
cloudfront to act as your CDN across the globe,
and now you've got a front end making requests into a backend. So you need
a way to receive HTTP requests for your backend. And this is often
done in AWS with a service called API gateway.
Instead of having application software that is receiving incoming HTTP requests
and formatting it for your code, API gateway will
actually expose endpoints that can receive those incoming
requests. There's no server involved in that. And then using
the path thing that's provided, automatically route that to the correct chunk of code
for you. There's no code that you had to write to set
up that routing, and that's where lambda comes in. Lambda will be the code
that you then execute when it receives the HTTP
request formatted for the lambda function. Then lambda will obviously have
to talk to database of some type usually. And in the serverless world, especially in
AWS, this is often done using Dynamodb as a
database, just because it's a fully managed data store. This is the
sort of rough, very basic macro overview of what a serverless application can
look like. There's a lot more stuff that you can do and a bit nuanced,
but those are the basics. So looking at this,
there are a lot of advantages as well to building serverless applications, and I wanted
to cover them. If you've heard people talk about serverless,
you've probably heard them mention these specific advantages,
one of them being that there's no infrastructure management, especially if you're using services
like S three lambda API, gateway and so on that are fully
managed. There's no machines or cpus or RAM or
anything like that you need to worry about. But even if you add on
services like RDS, which is the relational database service,
or an elastic search type service,
while you still have to worry about the cluster sizes and so on, there is
still nothing for you to maintain as far as application software updates,
making sure about bugs and so on. This is really useful and
it can be very time saving. And this time saving
that you get from the production in infrastructure management
means that you can spend more time building features and getting
stuff done. Accelerated time to market means that your business
is putting stuff in front of users faster and earning revenue sooner, which is often
very important for a business. Another really great benefit is that
with serverless development, often you only pay for what you actually use.
Lambda doesn't cost you anything at 02:00 a.m. When there's no users
on your site, unlike a server that's sitting around waiting for traffic to happen,
you're still getting billed even when nothing is actually happening.
So really useful for that.
And traffic management is often built into these services as well.
If you suddenly have a spike of users, there's often capacity in services like API,
Gateway and Lambda and so on to manage these bursts of traffic
and in the ability to automatically scale and to handle larger
amounts of traffic as it starts coming in, which is really useful, something that you
don't have to worry about now. But there's also other advantages to serverless,
and that's really what my talk is going to be discussing in more detail today.
The not so usual things that change the way we as developers
build applications for the better, and pretty big deals as well.
This is the kind of stuff that we figured out after years of building serverless
applications, working with teams of customers,
working with these teams to figure out how to structure and build
their serverless applications, and ourselves, we've been building serverless applications
ourselves, as well as services and products to provide
to our customers. And frameworks are a
very integral part of building a serverless application. Now, what you're
seeing in front of you here is an example of a configuration file for the
serverless framework, where I am essentially creating an HTTP
endpoint. This could be the start of my rest API that I'm busy building.
And really what this does is with a single command,
a serverless deploy command. This will connect to my AWS account.
It will create an API gateway endpoint for me. It will upload my lambda function
that's in the file called handler js with a function called
hello. And that code will then get triggered when a HTTP
request is made on the endpoint that's generated from API gateway.
All of this is automatically set up for me, along with permissions, IAM policies
and so on. I don't need to worry about setting any of that up.
Anybody in my team can now take this configuration file and deploy it into their
AWS account, and we can both be working on the
same the synchronization of these tools is
maintained in the cloud. I don't need to worry about whether my application
is synchronized or not, and I can make changes to this configuration file,
run a serverless deploy command, and it'll just make the changes in the
cloud for me automatically. So if you are looking at
building serverless applications, you could go to your AWS console and create an
API gateway endpoint and upload your lambda function and then try to connect the
two manually. But that doesn't allow you to share things, doesn't allow you to easily
debug, and so on. So using a framework
of some type is almost absolutely required.
I know the serverless framework. It's what I know really well. There are many others
out there, so there's a lot of choice for you to have.
Let's start taking a look at these other advantages I was talking about that makes
serverless application development so awesome and can rapidly change what we do
as developers. And the first one is that ultimately we end
up being closer to production, which is really useful feature to
have. Additionally, we have to develop
and test locally. Youll are going to be writing your code on youll own machine,
and then you're going to have some kind of environment, might be very simple,
might be really complex to test the code that you've written
on your own machine before you do anything else, to make sure it does what
you needed to do accomplishes the feature that you're coding for.
And once you've done that, the whole team might get together and you've merged a
bunch of code changes together and you're planning a release. It might be at
the end of your two week sprint, you start compiling all this stuff together that
the team's been working on, then ultimately that has to get passed over to
DevOps. Maybe that's just somebody else on the team, maybe that's an entirely different team.
But your code then needs to go to production, and the
phrase is toss it over the wall to developers and then
the app breaks. For some reason there was a
feature that youll coded on your local machine that doesn't quite work that way in
production. There are too many differences between the two environments
for you to absolutely 100% guarantee that you're building things
that work across both. And what has
happened is that teams have started moving towards better release configurations
so that they can release more often, potentially, or a little
bit more cleanly, or have interim deployment environments, like a staging
environment. But ultimately you're still expecting something
that you've built on your local machine to work in production as is,
to a large degree, and it can be pretty inaccurate.
So what we find in the serverless world, what we tend to
recommend, is that local emulation is really, really hard to do,
because cloud services are very difficult to run
locally. Even getting
a replica of production in the traditional sense, using something like vagrant or docker,
can be a tricky thing to do to some level of accuracy. Now that
you're using cloud services, this becomes even more difficult. This isn't necessarily a
bad thing. What this does is make it more appropriate for
us to consider using the cloud directly. So a better development
model is to push the changes to the cloud and rather test
there. Now, for some, this may seem
like a, it might seem like you have a bit of a slow development
cycle. You first make the changes, then you push it to the cloud, and then
you test, and so on. But there are a lot of benefits to doing it
directly in production, instead of trying to test locally and then push into production
later. Ultimately, you can very easily and
quickly deployed into a replica of production that
is exactly the same as production. You are essentially
deploying into production when you develop and test directly in the cloud.
So there is no difference between production and
your local testing environment. Apart from configuration settings. There's no
cpu difference, there's no hard drive difference, there's no library
difference. Everything is pretty much exactly the same between
your testing environment and your production environment, which reduces
that difference massively. Not to
mention, even if you could set up a local testing environment
to some degree, there are a lot of things about the cloud that
are just obviously possible to actually test locally.
IAM is a service in AWS that manages permissions between services.
It's very difficult to emulate that locally. There are latencies
between services. IAM itself adds latency between services, and you can't
really test the impact that latencies between services will have on your application
if they're all running on your local machine, not to mention concurrency.
Issues of running multiple services in parallel altogether,
API validations and an absolute ton more. There's so much more that
you actually cannot test on a local machine. And in order
to do this, this is where the advantage of frameworks comes in,
is that the serverless framework, for example, provides a way for you to edit
your lambda function code and immediately deploy that into the cloud within
seconds using the serverless deploy function command. At that point you
can then tail the logs in the cloud. You can run
an invoke command to execute the code in the cloud,
or use your curl command or whatever it is
to actually execute the function. So you deploy within seconds,
test, read the logs, continue to iterate and change and
make changes directly in the cloud. No difference with production. Really, really powerful.
So I want to take one step back from that. One nice thing about
building stuff in the cloud is that lambda as
a way to execute code is really forgiving of bad code.
If you've been building stuff on servers in the traditional
sense, youll might have experienced the issue
where you've written maybe a really bad for or while loop
and that code isn't optimal, and it starts
having a massively negative impact on the performance of your application as a
whole. It affects the entire application stack, all your users are affected.
This is because there are shared resources between threads.
When you have a single execution,
a single user executing your code, and it hits a
bad for loop or any other type of code, it's going
to bottle up cpu, it's going to affect all the other users that happen to
be on that machine at the same time and really negatively impact your entire
application. And clustering as a solution helps somewhat,
but ultimately as more and more users come on board, start executing
the code that is not performant, and starts bottling up more and
more cpu, you're going to be spinning up more and more machines as a part
of your cluster if you have auto scaling, for example, and ultimately
they're all using to get swamped. So this can be really bad.
This is why we have so many developers spending so much time
and effort trying to make sure they write optimal, well performing code, because it can
have a really disastrous effect on your cluster of machines that you run.
Containerization as a way to help manage this helps to some degree,
but it can only help so much because ultimately even those containers
are running on an actual cpu. And the containerization
methods used in the traditional sense, like Docker, aren't specifically
designed to limit the impact on cpu
as much as tools like lambda are. So in the serverless
world, single lambda executes very much in its
own context, and is specifically designed this way. The firecracker
virtual machine technology built by AWS, for example, for lambda
is different to Docker in that it is specifically designed to help
constrain CPU and other resource usage within
the context of the lambda, very, very tightly controlled.
And there's been extensive
testing done on this impact.
Lambda also has built in timeout, so even if the code is
so bad that the execution continues,
it'll eventually reach a timeout. There is a timeout even if you don't set one
explicitly. There is a default timeout that lambda has that it
cannot execute beyond. So your code will stop executing at some point.
And as I mentioned, there have been lots of tests showing that
the noisy neighbor issues on lambda are minimal at best.
Researchers have actually executed code that locks up a lot of cpu
and then run parallel loads next to it to see what the impact is,
and they can barely detect a difference at all. And this is where the ephemeral
nature of lambda is a savior. The problem with having these big clusters
of servers is that often these machines are around for days, weeks at
a time, and having something execute there means that
the processing of non performant code
is going to be around for a long time. Lambda functions execute
and either idle, waiting for the next time to execute, or are
killed immediately anyway. So this is a really useful feature to
help make sure that even if you write bad code, it's not going to have
as much of an impact. Now that we're in a situation with lambda
functions where you're not going to completely give up an optimization,
but you don't need to focus on it quite as intently. It's not going to
have quite as bad an impact on your application as a whole. Which means that
you and the rest of the team can focus more on what pays the bills
for your company, more on the features that your customers are to pay for.
I've never met a single MD of a company
that is going to be happy to hear that you need to spend two to
four weeks on optimizing code. Instead, they want to
hear you talk about features that you can push, that you can help drive revenue.
Now, in the beginning of the talk, I mentioned
the idea that building serverless applications helps reduce the
amount of code you generate, because you are switching from describing
everything in code to using the cloud services to replace some of that code
for you. This has the knock on benefit that just by having less code,
you're ultimately going to produce less errors.
So if we have a web application in the traditional sense,
we need to perform all of the reprocessing of the HTTP request in code.
All of it happens in code. Even if that code is a framework that youll
might use, it's still code that we need to worry about. Manage and
maintain the routing in the past is
stuff that we need to write our own authentication. Even if it is,
even if it's a library that we happen to use, we still need to implement,
we still need to manage it, maintain its versioning,
we need to manage cause responses and general responses and a lot more.
There's a ton of stuff that we need to write as a part of our
application. All of this means that there's a lot more code
and a lot more code isn't necessarily a good thing.
Single largest causes of failures in platforms is code written by developers.
When you have a bug, it's usually not the framework
that you installed three weeks ago, it's the chunk of code that was released last
week. And this is the single biggest cause of failures.
And this is where it's no wonder then that low code
or no code solutions have been getting so popular recently,
like Lambda. So if we look at serverless,
the interesting thing here is that we can replace pathing,
for example, and HTTP request management with API
gateway. API gateway can kind of handle a lot of the stuff for us,
just take that completely out of our hands. There's no framework to manage,
there's no libraries to maintain, there's no configuration. Once you've
got the API gateway set up, that's it, it's done.
Everything else is being managed by the team at AWS for you.
DynamoDB simplifies database interactions because instead
of having this very large, complex relational database where you've designed
the schema upfront and now you need to write complexity,
sometimes hard to manage, and error prone SQL queries to DynamoDB
is completely managed for you and you design your database structure based
on the data that you need to retrieve. So the design of your database
is based on your query patterns, not your query patterns need to
be to design to the structure of the database, which makes things far less error
prone and means that everything is decided up front more.
And if you ever had to build a system that has to interact with the
file system, that's often an incredibly scary prospect because working
on a file system can potentially cause massive performance issues.
However, with the serverless world with S three. S three is essentially a replacement
for a file system. S three is specifically designed to be a highly performant
way to store files and retrieve files in the cloud,
and it absolutely excels at that job. So using S three
will take a lot of load off of you having to worry about these file
system interactions. You can just use the SDK provided by AWS
to send files to s three and retrieve files from s three, and it absolutely
kills it. That job and the serverless framework itself.
Unlike other frameworks that you might have used like can exprs and
so on, serverless framework doesn't actually add any additional code to your application.
The point of the serverless framework is to give you the ability to
configure a serverless application in a configuration file,
and when you run a deploy command, all it does is use that configuration file
to package everything, including your lambda function, in a way that can
be sent to AWS. To instruct AWS to create all of
these cloud resources for you doesn't actually add any additional code,
and that's also pretty killer. The serverless framework version
isn't as integral in managing the deployment to AWS.
Only if you want to use new features in AWS might you need to upgrade
the serverless framework, but it doesn't actually change the code that is
sent into the cloud. So what you write is what is in
Lambda now with all this together as well, now that we're
using a framework to deploy, now we are writing less code and
we have the ability to very easily make deployed. This means continuous delivery
suddenly becomes a lot easier to do. And this is a practice we found very
useful at serverless as well, in that we can constantly be pushing out
new features as soon as developers finish building them. And some of the team have
spent some time validating the work instead of waiting for Big Bang releases,
you can push a code out very very quickly. And this is what we did
in the good old days. We would put these releases together and toss it over
the wall at the developers team, and this creates that friction between the infrastructure teams
and the developers. Now I keep throwing code at the infrastructure team to put into
production, it keeps breaking. They fight with me, we fight with them.
It's not a great situation to be in and leads to
these Big Bang releases collected over two to
four weeks or even longer, that suddenly have enormous amounts of
changes to deploy, when a better approach would be to push changes as they're made
piece by piece at a time. And this is what's recently started
happening even in the more traditional development sense, where teams are trying
to structure themselves in a way where as teams finish features,
they try to deploy them immediately into production instead of waiting around for
these big release cadences to come. But it's a
little tricky to do in the traditional sense.
The infrastructure around these applications tends to be slow
and time consuming to update. So if you're making a change to a relational database
that often requires downtime, you're going to have to tell users
to stop using the system or turn it off so that you can update that
relational database. Even EC two instances changing the structure of
the way EC two instances work because of the code you're deploying have
massive impact on the uptime and downtime of your system. And it's not great
to keep taking your system down because developers want to push code
really quickly, so difficult to balance.
But in the serverless world,
infrastructure that is needed is actually a part of the service
itself. It's not something over there that the developer sends code
to, it's a part of the app itself. It's integral to the actual
service that you're building. What this means is that when you're
busy making changes, you can immediately push them to production with a single command.
Now you might go through a process of validation with a sort of staging
environment where some of the team can look at what you've done and run some
tests. But ultimately sending stuff to production is a case of running a
command, and those changes are immediately deployed. You can also merge
changes immediately to GitHub. You can create pull requests and merge this into a
GitHub repo for a CRCD tool.
And with the advent these days of microservices
being a preferred architectural pattern, in a lot of situations,
serverless as an architectural pattern is very well
suited to microservices, and this means that you can now build
a collection of small services for your entire application.
These small services decrease the surface area of each individual service that
you might run a deploy command on, which makes it even easier to do this
continuous deployment of changes over time. And if
these little deployments over time are so much easier to do,
automation with something like CRCD becomes incredibly simple. You really just
keep running a deployed command in your CRCD tool on the services
as changing are pushed into a repo, like GitHub for example.
Thanks so much. Those are the big ones that I wanted to talk about,
how serverless is improving things and changing
the world for developers massively I
am looking forward to answering the questions you might have. I'll be in the discord
to take a look and answer anything that I can find. Thank you so much.