無服務器架構
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 APIclient = 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/
無服務器架構