无服务器架构
Traditionally, when you wanted to build a web app or API, you’d usually have to spend significant time and effort managing servers and ensuring your app scales up to handle large request volumes. Serverless is a cloud computing model which lets you run applications without having to worry about managing and scaling servers.
传统上,当您要构建Web应用程序或API时,通常必须花费大量时间和精力来管理服务器,并确保您的应用程序可以扩展以处理大量请求。 无服务器是一种云计算模型,它使您可以运行应用程序而不必担心管理和扩展服务器。
All you need to do is to upload your code to a cloud provider’s service, and they automatically provision an ephemeral environment. Unlike traditional architectures, it can scale up to handle thousands of requests in an instant, and you only pay for the duration during which your code executes.
您需要做的就是将代码上传到云提供商的服务,然后他们会自动设置临时环境。 与传统体系结构不同,它可以扩展以立即处理数千个请求,而您只需要为代码执行的时间付费。
In this article, we’ll build a simple contact form powered by AWS’s (Amazon Web Services) serverless offering, Lambda. However, serverless is suitable for applications of any complexity or size. As an example, we built myCompiler — a programming playground that supports 20 languages — and it is largely powered by serverless.
在本文中,我们将构建一个简单的联系表单,该表单由AWS的(Amazon Web Services)无服务器产品Lambda提供支持。 但是,无服务器适用于任何复杂性或规模的应用程序。 例如,我们构建了myCompiler (一个支持20种语言的编程场所),它主要由无服务器驱动。
Before we get started, we’ll take a closer look at how serverless and Lambda work, and the architecture that we’re going to set up for our contact form. Also, towards the end of this article, we’ll look at some tools which are meant to help with building and deploying large serverless applications.
在开始之前,我们将仔细研究无服务器和Lambda的工作方式以及将为联系表单设置的体系结构。 另外,在本文结尾处,我们将介绍一些工具,这些工具可帮助构建和部署大型无服务器应用程序。
You’ll need an AWS account to follow along this guide, and you can register here. Our AWS usage for this guide will be entirely covered by the free tier.
您需要一个AWS账户才能遵循本指南,并且可以在此处注册 。 免费使用此指南将完全涵盖本指南的AWS使用情况。
AWS Lambda如何工作? (How does AWS Lambda work?)
In this section, we'll understand the workflow with Lambda and a brief understanding of how it works. However, these concepts apply to most other cloud providers’ serverless offerings as well.
在本节中,我们将了解Lambda的工作流程,并简要了解其工作方式。 但是,这些概念也适用于大多数其他云提供商的无服务器产品。
With Lambda, you upload your code to AWS, which is usually a script written in Python, Node.js or Ruby. In the case of a language such as Go, Java or C#, it is a Linux executable or a package in the language’s format (such as jar files for Java).
使用Lambda,您可以将代码上传到AWS,AWS通常是用Python,Node.js或Ruby编写的脚本。 对于Go,Java或C#之类的语言,它是Linux可执行文件或该语言格式的软件包(例如Java的jar文件)。
After uploading your code, you can then"invoke" it manually or use another AWS service for this purpose (we'll look at this in detail in a moment). When you invoke your code, Lambda creates a secure, ephemeral Linux environment called a"container" on one of their servers, and any data that you passed as part of the invocation is fed to your function.
上传代码后,您可以手动“调用”它或为此目的使用另一个AWS服务(我们将在稍后详细介绍)。 调用代码时,Lambda在其服务器之一上创建一个安全的临时Linux环境,称为“容器”,并且在调用过程中传递的任何数据都将馈送到您的函数中。
Once the function completes execution, the Lambda service returns the results of the code to its caller. The container can then be reused to serve another execution, or if the function hasn't been invoked for a long time, the container is destroyed.
函数完成执行后,Lambda服务会将代码结果返回给其调用方。 然后可以重用该容器以服务于另一个执行,或者如果很长时间没有调用该函数,则该容器将被销毁。
When you make parallel invocations, Lambda creates a container to serve each invocation. Because each invocation is dedicated to a single container, each invocation gets ample resources for execution. You can assign anywhere from 128 MB to 3 GB of memory to each invocation, along with CPUs that increase with memory. Combine this with the fact that it can serve up to a 1000 parallel invocations (this can be increased by contacting AWS), you can handle heavy workloads without having to worry about scaling.
进行并行调用时,Lambda将创建一个容器来服务每个调用。 因为每个调用专用于单个容器,所以每个调用都获得了足够的执行资源。 您可以为每次调用分配128 MB至3 GB的内存,以及随内存增加的CPU。 结合它可以处理多达1000个并行调用这一事实(可以通过联系AWS来增加),您可以处理繁重的工作负载而不必担心扩展。
So, with scaling concerns out of the way, what does AWS Lambda cost us to run? Lambda usage is measured using the following parameters: the number of requests, the memory allocated to it, and the number of milliseconds your functions take to run.
因此,随着问题的扩展,AWS Lambda的运行成本是多少? 使用以下参数来衡量Lambda的使用情况:请求数,分配给它的内存以及函数运行所花费的毫秒数。
If you choose the smallest memory size (128 MB), and your functions take 1 second to run when you invoke it, you can invoke your function up to a million times for free. After that, every 1 million invocations can cost up to $2.30. A memory size of 128 MB might seem tiny, but it is certainly enough to handle many kinds of workloads.
如果您选择最小的内存大小(128 MB),并且调用函数需要1秒钟才能运行,那么您最多可以免费调用一百万次函数。 之后,每100万次调用最多可花费$ 2.30。 128 MB的内存大小似乎很小,但足以应付多种工作负载。
API网关—使用Lambda服务HTTP请求 (API gateway — Serving HTTP requests with Lambda)
As we mentioned previously, once you upload your code, you have to invoke it manually. To build a web app, you'd need to have a server that listens for HTTP requests, invokes your function with the details of the request, and translates the data returned from your function as a HTTP response.
如前所述,一旦上传代码,就必须手动调用它。 要构建Web应用,您需要有一台服务器来侦听HTTP请求,使用请求的详细信息调用函数,并将从函数返回的数据转换为HTTP响应。
AWS has another service which allows you to do just that — API gateway. Just like Lambda, it is another AWS managed service which can automatically scale up to handle extremely high request volumes.
AWS提供了另一项服务,即API网关。 就像Lambda一样,它是另一项AWS托管服务,可以自动扩展以处理极高的请求量。
Once you create an API gateway, you'll get a base URL which looks something like this:https://abcdefgh.execute-api.us-east-1.amazonaws.com/
创建API网关后,您将获得基本URL,该URL类似于以下内容: https://abcdefgh.execute-api.us-east-1.amazonaws.com/
: https://abcdefgh.execute-api.us-east-1.amazonaws.com/
Under this base URL, you can map paths and request methods (such as GET or POST) to your functions. You also have the option of creating your custom domain if you’d like to use something else other than the default, but we won’t go through that in this guide.
在此基本URL下,您可以将路径和请求方法(例如GET或POST)映射到您的函数。 如果您想使用默认值以外的其他选项,也可以选择创建自定义域,但是本指南不会对此进行介绍。
Also, just like Lambda, API gateway’s pricing is great too — you can serve up to a million requests for free, and after that every 1 million requests costs you $1.
而且,就像Lambda一样,API网关的价格也很高-您可以免费提供多达一百万个请求,此后每100万个请求将花费您$ 1。
建立联络表格 (Building a contact form)
We’ll build a simple contact form that sends us an email containing the details that our user fills in. This is how we’ll build out the various parts of the contact form:
我们将构建一个简单的联系表单,向我们发送一封电子邮件,其中包含用户填写的详细信息。这就是我们构建联系表单各部分的方式:
- First, we’ll set up SES (Simple Email Service), AWS’s email offering. This is to help us send emails for the contact form. 首先,我们将设置AWS的电子邮件产品SES(简单电子邮件服务)。 这是为了帮助我们发送联系表的电子邮件。
- Next, we’ll set up a “role” for Lambda, and then create a Lambda function that receives the HTTP request and sends us an email. 接下来,我们将为Lambda设置一个“角色”,然后创建一个Lambda函数来接收HTTP请求并向我们发送电子邮件。
- We’ll set up API gateway and map it to the function that we created in step 2. 我们将设置API网关并将其映射到我们在步骤2中创建的功能。
- We’ll then set up a web page that interacts with the API gateway endpoint and submits details filled in by the user. 然后,我们将建立一个与API网关端点进行交互的网页,并提交用户填写的详细信息。
At the end of this guide, you’ll set up something that works like this:
在本指南的最后,您将设置如下所示的内容:
To get started, visit the AWS management console (or simply, the“console”) and log in with the details that you used to sign up. Once you’ve logged in, you can use the “Services” dropdown in the navigation bar to switch between various services that we’re going to use.
首先,请访问AWS管理控制台 (或简称为“控制台”),并使用您以前注册的详细信息登录。 登录后,您可以使用导航栏中的“服务”下拉菜单在我们要使用的各种服务之间进行切换。
设置SES发送电子邮件 (Setting up SES for sending emails)
Begin by visiting the SES (Simple Email Service) section of the console through the “Services” dropdown, or by using this direct link. Then, click on the “Email Addresses” section on the left. You’ll be greeted with this page:
首先通过“服务”下拉菜单或使用此直接链接访问控制台的SES(简单电子邮件服务)部分。 然后,单击左侧的“电子邮件地址”部分。 您会看到以下页面:
Click on the “Verify a New Email Address” button and then enter your email address, and click “Verify This Email Address”. You’ll receive an email with a verification link. Open it to verify the address, and then refresh the SES console page. You’ll see that the email address has been verified:
单击“验证新电子邮件地址”按钮,然后输入您的电子邮件地址,然后单击“验证此电子邮件地址”。 您会收到一封包含验证链接的电子邮件。 打开它以验证地址,然后刷新SES控制台页面。 您会看到该电子邮件地址已通过验证:
At this point, you’ll be able to send emails for your email address using SES.
此时,您将能够使用SES为您的电子邮件地址发送电子邮件。
设置Lambda函数的角色 (Setting up a role for the Lambda function)
In AWS, most things start out with no permissions at all to interact with other resources or services in your AWS account, unless you give it explicit permissions to do so.
在AWS中,大多数事情一开始根本没有与AWS账户中的其他资源或服务进行交互的权限,除非您明确授予这样做的权限。
This means that our Lambda function won’t be able to talk to services such as SES to send emails. Lambda uses something called a “role” to define the level of access it has to other services. So, in this section, we’ll set up a role for our function with access to SES and CloudWatch. CloudWatch is a service that stores logs and metrics, and Lambda uses it to store errors and execution logs for your functions.
这意味着我们的Lambda函数将无法与SES等服务进行通讯来发送电子邮件。 Lambda使用一种称为“角色”的东西来定义其对其他服务的访问级别。 因此,在本部分中,我们将通过访问SES和CloudWatch为我们的功能设置角色。 CloudWatch是一项存储日志和指标的服务,Lambda使用它来存储函数的错误和执行日志。
To set up the role, go to the IAM (Identity and Access Management) section of the console, or use this direct link, and click on“Roles” from the left. You’ll see a page like the one below:
要设置角色,请转到控制台的IAM(身份和访问管理)部分,或使用此直接链接 ,然后单击左侧的“角色”。 您会看到类似以下页面的页面:
We’ll need to create a new role, so click on “Create role”. You’ll see a page with a list of AWS services. Since we’re setting this up for Lambda, select “Lambda” and click on the “Next: Permissions” button.
我们需要创建一个新角色,所以单击“创建角色”。 您将看到一个包含AWS服务列表的页面。 由于我们为Lambda进行了设置,因此请选择“ Lambda”,然后单击“下一步:权限”按钮。
Now, on the Permissions page, you’ll get an option to attach policies. First, we’ll grant “SES” permissions — and you can do this by searching for “SES” and selecting the “AmazonSESFullAccess” policy.
现在,在“权限”页面上,您将获得一个附加策略的选项。 首先,我们将授予“ SES”权限-您可以通过搜索“ SES”并选择“ AmazonSESFullAccess”策略来做到这一点。
Similarly, you can grant CloudWatch access by searching for “CloudWatchFullAccess” and then selecting the policy that comes up:
同样,您可以通过搜索“ CloudWatchFullAccess”并选择出现的策略来授予CloudWatch访问权限:
After selecting these policies, click on “Next: Tags” and then the “Next: Review” button. In the “Role name” text box, enter a role name of your choice, such as “ContactFormRole”. Then, click the “Create Role” button.
选择这些策略后,单击“下一步:标签”,然后单击“下一步:复查”按钮。 在“角色名称”文本框中,输入您选择的角色名称,例如“ ContactFormRole”。 然后,单击“创建角色”按钮。
Now, we have a role ready to use with our Lambda function.
现在,我们已经准备好与Lambda函数一起使用。
创建Lambda函数 (Creating the Lambda function)
At this point, we can create the Lambda function that receives the details from API gateway, and sends us an email.
此时,我们可以创建Lambda函数,该函数从API网关接收详细信息,并向我们发送电子邮件。
To create the function over to the Lambda section of the console, or use this direct link. Click on “Functions” from the left side. On this page, click the “Create function” button.
要将功能创建到控制台的Lambda部分,或使用此直接链接 。 单击左侧的“功能”。 在此页面上,单击“创建功能”按钮。
On the create function page, you’ll be asked for the function’s name and the language that you want to use. We’ll name our function “ContactFormFunction”, and we’ll use Python 3.8 as the language.
在“创建函数”页面上,将询问您函数的名称和要使用的语言。 我们将函数命名为“ ContactFormFunction”,并将使用Python 3.8作为语言。
Next, we’ll attach the role that we created in the previous section. Click on the “Choose or create an execution role” below the “Permissions" section, and select “Use an existing role” and then select the role that we created earlier, “ContactFormRole”. Once you’ve entered the details, click on the “Create function” button.
接下来,我们将附加在上一节中创建的角色。 单击“权限”部分下方的“选择或创建执行角色”,然后选择“使用现有角色”,然后选择我们之前创建的角色“ ContactFormRole”。输入详细信息后,请点击“创建功能”按钮。
This will take you to a page showing details about your function. Scroll down a bit so that you can see the code editor, which looks like this:
这将带您到一个页面,显示有关您的功能的详细信息。 向下滚动一点,以便您可以看到代码编辑器,如下所示:
In the right pane, paste the following code and change your_email_address_here
with your email address.
在右窗格中,粘贴以下代码, your_email_address_here
使用您的电子邮件地址更改your_email_address_here
。
import boto3
from base64 import b64decode
from urllib.parse import parse_qs
# Replace your email address here
send_to = 'your_email_address_here'
def lambda_handler(event, context):
# We receive our data through POST requests. API gateway
# sends the POST data as a Base64 encoded string in
# event['body'], so we must decode it.
data = parse_qs(b64decode(event['body']).decode())
subject = 'You got a message from %s' % data['email'][0]
text = '\n'.join([
'Name: %s' % data['name'][0],
'Email: %s' % data['email'][0],
'Message %s' % data['message'][0]
])
# Send an email through SES with the SendEmail API
client = boto3.client('ses', region_name='us-east-1')
client.send_email(
Source=send_to,
Destination={'ToAddresses': [send_to]},
Message={
'Subject': {'Data': subject},
'Body': {'Text': {'Data': text}}
},
ReplyToAddresses=[data['email'][0]]
)
# This is the response that'll be sent out through the
# API gateway to the browser.
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*'
},
'body': '"Success"' # jquery expects a JSON response
}
Then, click on the “Save” button on the top right to save your code. With that out of the way, we’ll create an API gateway and map it with the Lambda function.
然后,单击右上角的“保存”按钮以保存您的代码。 有了这些,我们将创建一个API网关,并使用Lambda函数对其进行映射。
使用API网关处理HTTP请求 (Handling HTTP requests with API gateway)
To add an API gateway and map it to your function, scroll up in the Lambda function page till you see the “Designer” section, and click on the “Add Trigger” button as shown below:
要添加API网关并将其映射到您的函数,请在Lambda函数页面上向上滚动,直到看到“ Designer”部分,然后单击“ Add Trigger”按钮,如下所示:
This will open the “Trigger” configuration page. Triggers are something that can invoke your Lambda function, and since we need an API gateway, choose it from the dropdown:
这将打开“触发器”配置页面。 触发器可以调用Lambda函数,并且由于我们需要API网关,因此请从下拉列表中进行选择:
This will bring up various options for setting up the API gateway. Ensure that you’ve set up “API” to “Create a new API” and “Choose a template” to “HTTP API”:
这将显示用于设置API网关的各种选项。 确保已将“ API”设置为“创建新API”,并将“选择模板”设置为“ HTTP API”:
Scroll down below and click the “Add” function to set up the API gateway. This takes a few seconds to complete, and once it’s done, you’ll be taken to the designer view. Click on the “API gateway” button on the left to see the URL through which you can trigger the Lambda function:
向下滚动并单击“添加”功能以设置API网关。 这需要几秒钟才能完成,完成后,您将进入设计器视图。 单击左侧的“ API网关”按钮以查看可触发Lambda函数的URL:
Now, before we build the contact form page, we’ll test that our setup so far works correctly. If you’re on MacOS, Linux, or a recent version of Windows 10, you can copy the API gateway URL shown above and run the following command in your terminal. Make sure to replace your_api_gateway_url
with the actual URL!
现在,在构建联系表单页面之前,我们将测试到目前为止的设置是否可以正常运行。 如果您使用的是MacOS,Linux或Windows 10的最新版本,则可以复制上面显示的API网关URL,并在终端中运行以下命令。 确保使用实际网址替换your_api_gateway_url
!
curl -i your_api_gateway_url --data-urlencode "name=John" --data-urlencode "email=john@example.com" --data-urlencode "message=hi there"
If all went well, you can see a 200 OK response with a “Success” message, like so:
如果一切顺利,您会看到200 OK响应,并显示“成功”消息,如下所示:
You should also receive an email in your inbox titled “You got a message from john@example.com” with the details that were entered in the form.
您还将在收件箱中收到一封电子邮件,标题为“您从john@example.com收到了一封邮件”,其中包含在表格中输入的详细信息。
However, this can sometimes be finicky. The email might get delivered in your spam folder, or sometimes even get rejected without you ever seeing that email. This is because providers such as Gmail and Yahoo block third parties (such as SES) from sending emails using their domain name.
但是,这有时可能很挑剔。 该电子邮件可能会发送到您的垃圾邮件文件夹中,或者有时甚至在您没有看到该电子邮件的情况下被拒绝。 这是因为Gmail和Yahoo之类的提供商阻止了第三方(例如SES)使用其域名发送电子邮件。
If you have your own domain name, you can work around this by setting up a SPF record. However, we won’t discuss that in this guide, as we want you to be able to follow even without a domain.
如果您拥有自己的域名,则可以通过设置SPF记录来解决此问题。 但是,由于我们希望您即使没有领域也能继续学习,因此我们不会在本指南中进行讨论。
Next, we’ll complete this guide by building the contact form page.
接下来,我们将通过构建联系表单页面来完成本指南。
建立联系表格 (Building the contact form)
Open your favorite text editor and save the following code as a HTML file. Remember to replace your_api_gateway_url
with the full URL that you obtained previously.
打开您喜欢的文本编辑器,然后将以下代码另存为HTML文件。 请记住用您之前获得的完整URL替换your_api_gateway_url
。
<!DOCTYPE html>
<html>
<head>
<title>Contact form</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<style>
body {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h2>Contact form</h2>
<hr>
<form id="form">
<div class="form-group">
<label for="name">Your name</label>
<input type="text" class="form-control" id="name" placeholder="Your name">
</div>
<div class="form-group">
<label for="email">Your email address</label>
<input type="email" class="form-control" id="email" placeholder="Your email address">
</div>
<div class="form-group">
<label for="message">Your message</label>
<textarea class="form-control" id="message" rows="3"></textarea>
</div>
<div id="alert" class="alert d-none">
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
function showMessage(msg, type) {
$('#alert').attr('class', `alert alert-${type}`).text(msg)
}
function hideMessage(msg) {
$('#alert').attr('class', 'd-none')
}
$('#form').submit(event => {
event.preventDefault()
hideMessage()
let name = $('#name').val().trim()
let email = $('#email').val().trim()
let message = $('#message').val().trim()
if (!(name && email && message)) {
showMessage('You must fill in all the fields before submitting the form', 'danger')
return
}
$.post('your_api_gateway_url', {name, email, message}).done(_ => {
showMessage("Thanks for contacting us. We'll be in touch shortly.", 'success')
}).fail(_ => {
showMessage('Something went wrong when submiting the message', 'danger')
})
})
</script>
</body>
</html>
Once you’ve saved the file, open it in your browser, fill in the details and click “Submit”. You’ll be able to see a success message, like so:
保存文件后,在浏览器中打开文件,填写详细信息,然后单击“提交”。 您将能够看到成功消息,如下所示:
Clicking the button submits the details as a POST request to the API gateway, which then triggers the Lambda function, which in turn sends us an email over SES. However, as we discussed in the previous section (“Handling HTTP requests with API gateway”), you might not end up receiving an email in certain circumstances.
单击该按钮会将详细信息作为POST请求提交给API网关,API网关随后触发Lambda函数,该函数又通过SES向我们发送电子邮件。 但是,正如我们在上一节(“使用API网关处理HTTP请求”)中讨论的那样,在某些情况下,您可能最终不会收到电子邮件。
Now that we have a contact form that moves most of its logic over to serverless, you have this static web page that you need to host somewhere.
现在,我们有了一个联系表,可以将其大部分逻辑转移到无服务器上,您便拥有了一个静态网页,需要将其托管在某个地方。
So, do you need a server to host this page? Not at all! AWS offers a storage service named S3 (Simple Storage Service), and you can use it to host static websites. This does require a domain name, so if you own one, you can use this article to host the web page.
因此,您需要服务器来托管此页面吗? 一点也不! AWS提供了一个名为S3(简单存储服务)的存储服务,您可以使用它来托管静态网站。 这确实需要一个域名,因此,如果您拥有一个域名,则可以使用本文来托管网页。
接下来要去哪里? (Where to go next?)
Now that we’ve built a simple contact form using serverless, how do you build large applications? Clicking around various options in the console is a good way to learn AWS and serverless, but it’s not an option when you’re trying to build something big with lots of moving parts.
既然我们已经使用无服务器构建了一个简单的联系表单,那么如何构建大型应用程序? 在控制台中单击各种选项是学习AWS和无服务器的好方法,但是当您尝试使用大量活动部件构建大型组件时,则不是一种选择。
Fortunately, there are various tools that can help you build and deploy serverless apps on AWS, such as the Serverless framework or AWS Chalice. CloudFormation, a free AWS service, can also help you build apps by automating the deployment process through templates written in JSON or YAML, though it’s a bit difficult to use than the other options.
幸运的是,有多种工具可以帮助您在AWS上构建和部署无服务器应用程序,例如无服务器框架或AWS Chalice 。 CloudFormation (一项免费的AWS服务)还可以通过使用JSON或YAML编写的模板来自动化部署过程,从而帮助您构建应用程序,尽管它比其他选项难用。
翻译自: https://www.freecodecamp.org/news/how-to-get-started-with-serverless-architecture/
无服务器架构