服务器创建多个dhcp服务
by Charlee Li
通过李李
如何在15分钟内创建无服务器服务 (How to create a serverless service in 15 minutes)
The word “serverless” has been popular for quite a while. When Amazon released the AWS Lambda service in 2015, many tools emerged to help people build serverless services with just a few commands. Compared to traditional always-on services, serverless services are very easy to develop, deploy and maintain. They’re also extremely cost effective, especially for those simple services which do not have too much traffic.
“无服务器”一词已经流行了很长时间。 当亚马逊于2015年发布AWS Lambda服务时,出现了许多工具,可帮助人们仅需几个命令即可构建无服务器服务。 与传统的永远在线服务相比,无服务器服务非常易于开发,部署和维护。 它们也极具成本效益,特别是对于那些没有太多流量的简单服务。
那么什么是无服务器? (So what is serverless?)
As its name implies, “serverless” means that you run a service without a server. Well, technically, there is still a server running the service, but you, as the service owner, do not need to worry about that server.
顾名思义,“无服务器”意味着您无需服务器即可运行服务。 嗯,从技术上讲,仍然有一个服务器在运行该服务,但是作为服务所有者,您不必担心该服务器。
For example, AWS Lambda allows you to deploy a “function” to deal with the requests. AWS has a server to run all the functions when they are requested. But you don’t need to worry about how this server works or how to make your code work with this server. All you need to know is that you write a function then push it to the Lambda service.
例如,AWS Lambda允许您部署“功能”来处理请求。 AWS拥有一台服务器,可以在需要时运行所有功能。 但是您不必担心该服务器的工作方式或如何使代码与此服务器一起工作。 您需要知道的是编写一个函数,然后将其推送到Lambda服务。
And the sweetest part is that it’s very cheap. Amazon Lambda provides 1M free requests and 400,000 GB-seconds free compute time per month (which means your computation can use 1GB memory for 400,000 seconds), which is enough for most small services. Compared to EC2, where a nano instance would cost you $0.0058 per Hour (which is $0.14 per day), Lambda is way cheaper.
最甜蜜的部分是它非常便宜。 Amazon Lambda每月提供1M的免费请求和400,000 GB-秒的免费计算时间(这意味着您的计算可以使用1GB内存持续400,000秒),足以满足大多数小型服务的需求。 与EC2相比,纳米实例的价格为每小时0.0058美元(每天0.14美元),而Lambda便宜得多。
我们将在这里做什么 (What we’ll do here)
In this post, I will show you how to build a small serverless personal website using AWS. The website has the following characteristics:
在本文中,我将向您展示如何使用AWS构建小型无服务器个人网站。 该网站具有以下特点:
- Includes both front-end and back-end 包括前端和后端
- Mostly static, or front-end heavy 通常是静态的,或者前端很重
- API requests — these are rare but necessary API请求-很少但有必要
- Back-end does not require too much memory or CPU (for example, a simple web counter that only requires one DB access) 后端不需要太多的内存或CPU(例如,仅需要一个DB访问权限的简单Web计数器)
Our service will be deployed at the following domains (I used fake domains in this post):
我们的服务将部署在以下域中(我在这篇文章中使用了虚假域):
API Service:
https://myservice-api.example.com
API服务:
https://myservice-api.example.com
:https://myservice-api.example.com
Front End:
https://myfrontend.example.com
前端:
https://myfrontend.example.com
:https://myfrontend.example.com
A serverless solution is perfect both technically and from a cost point of view. We will use the following AWS services:
从技术和成本角度来看,无服务器解决方案都是完美的。 我们将使用以下AWS服务:
- Lambda + API Gateway + S3, for API server Lambda + API Gateway + S3,用于API服务器
- DynamoDB, for data storage DynamoDB,用于数据存储
- S3, for static web hosting S3,用于静态虚拟主机
- Cloudfront, for distributed CDN Cloudfront,用于分布式CDN
- AWS Certificate Manager (ACM), for generating certificates for our https website AWS Certificate Manager(ACM),用于为我们的https网站生成证书
For the API server, we will use a Python + Flask combination, and Zappa as the serverless toolkit.
对于API服务器,我们将使用Python + Flask组合以及Zappa作为无服务器工具箱。
设置AWS环境 (Setting up the AWS Environment)
First we need to set up the AWS environment so that we can access AWS from our code and zappa. This takes two steps:
首先,我们需要设置AWS环境,以便可以从代码和zappa访问AWS。 这需要两个步骤:
- We need to create an AWS user for programmatic access 我们需要创建一个AWS用户以进行编程访问
- We need to set up a local AWS environment to use for that user 我们需要设置一个本地AWS环境以供该用户使用
创建一个AWS用户 (Create an AWS User)
Log into AWS, and choose the “IAM” service to manage user credentials.
登录AWS,然后选择“ IAM”服务来管理用户凭证。
Create a user called “myservice-admin”(or any other username you would like to use), and don’t forget to check the “Programmatic access” option.
创建一个名为“ myservice-admin”(或您要使用的任何其他用户名)的用户,并且不要忘记选中“ Programmatic access ”选项。
In the next screen, click the “Attach existing policies directly” button, then add “AdministratorAccess” to the user.
在下一个屏幕中,单击“ 直接附加现有策略 ”按钮,然后向用户添加“ AdministratorAccess ”。
Note: From a security perspective this is not the best practice. But for demonstration purposes, this post will not cover the details of narrowing down permissions.
注意:从安全角度来看,这不是最佳实践。 但是出于演示目的,本文不会涵盖缩小权限的详细信息。
Click on the “next” button and then the “Create User” button, and the user myservice-admin
will be created. On the last screen, the Access Key ID and Secret access key are displayed. Make sure to copy and paste them into a local file. These are the API credentials we are going to use in the next step.
单击“下一步”按钮,然后单击“创建用户”按钮,将创建用户myservice-admin
。 在最后一个屏幕上,显示访问密钥ID和秘密访问密钥 。 确保将它们复制并粘贴到本地文件中。 这些是我们将在下一步中使用的API凭据。
Note: This is the only place you can view the secret access keys! If you fail to make a copy of them, you have to go to the user detail screen and generate a new pair of access keys and secret.
注意: 这是您可以查看秘密访问密钥的唯一位置 ! 如果您无法复制它们,则必须转到用户详细信息屏幕并生成一对新的访问密钥和密码。
设置您的本地AWS环境 (Setup your Local AWS Environment)
We need to create a local environment in order to use AWS locally.
我们需要创建一个本地环境才能在本地使用AWS。
First, let’s install the awscli
tool, which will help us configure the environment:
首先,让我们安装awscli
工具,它将帮助我们配置环境:
$ sudo apt install awscli
After installation, we will setup AWS by using the aws configure
command:
安装后,我们将使用aws configure
命令设置AWS:
$ aws configureAWS Access Key ID [None]: ******AWS Secret Access Key [None]: ******Default region name [None]: us-east-1Default output format [None]: json
Here we need to type in the Access Key ID and Secret Access Key we received from the last step. In terms of default region, I used us-east-1
. You can choose any region you like, but other regions may cause some trouble when setting up CloudFront.
在这里,我们需要输入从上一步收到的访问密钥ID和秘密访问密钥 。 在默认区域方面,我使用了us-east-1
。 您可以选择自己喜欢的任何区域,但是其他区域在设置CloudFront时可能会造成一些麻烦。
在DynamoDB中创建表 (Create a Table in DynamoDB)
In order to store the website visitor counter value in DynamoDB, we need a persistent store. So we need to create a table and populate an initial value within it.
为了将网站访问者计数器值存储在DynamoDB中,我们需要一个持久存储。 因此,我们需要创建一个表并在其中填充一个初始值。
Within the AWS console, choose DynamoDB service. Then click the “Create Table” button. In the “Create DynamoDB table” screen, fill the Table name with myservice-dev
and the Primary key field with id
, then click the Create Table button.
在AWS控制台中,选择DynamoDB服务。 然后点击“ 创建表格 ”按钮。 在“创建DynamoDB表”屏幕中,在表名称中填充myservice-dev
,在主键字段中填充id
,然后单击“ 创建表”按钮。
After a couple of seconds, the table should be created. Select the newly created table, choose the Items tab from the right pane, then click the Create item button, and create an item with id='counter'
and counter_value=0
.
几秒钟后,应该创建该表。 选择新创建的表,从右窗格中选择“ 项目”选项卡,然后单击“ 创建项目”按钮,然后创建一个id='counter'
和counter_value=0
。
Note: You need to click the plus sign on the left side to add the
counter_value
attribute, and don’t forget to set the type ofcounter_value
to Number.注意:您需要单击左侧的加号以添加
counter_value
属性,并且不要忘记将counter_value
的类型设置为Number 。
创建一个API服务 (Create an API Service)
Next, we’ll create the API service. For demonstration purposes, this API service will provide a counter API which will increase a counter value when clicked. The counter value will be stored in DynamoDB. The API endpoints are:
接下来,我们将创建API服务。 出于演示目的,此API服务将提供一个计数器API,当单击该计数器API时会增加计数器值。 计数器值将存储在DynamoDB中。 API端点是:
POST /counter/increase
increases the counter and returns the counter valuePOST /counter/increase
增加计数器并返回计数器值GET /counter
returns the current counter valueGET /counter
返回当前计数器值
用Python和Flask编码API服务 (Coding the API Service with Python and Flask)
We will start with creating a Python virtual environment and install the necessary packages:
我们将从创建Python虚拟环境开始并安装必要的软件包:
$ mkdir myservice && cd myservice$ python3 -m venv .env$ source .env/bin/activate(.env)$ pip install flask boto3 simplejson
flask
is the web framework and the boto3
package is required for accessing DynamoDB. simplejson
can help us deal with some JSON conversion issues. Let’s create the service by creating a file myservice.py
with the content below:
flask
是Web框架,访问DynamoDB需要boto3
软件包。 simplejson
可以帮助我们处理一些JSON转换问题。 让我们通过创建文件myservice.py
来创建服务,其内容如下:
import boto3from flask import Flask, jsonify
app = Flask(__name__)
# Initialize dynamodb accessdynamodb = boto3.resource('dynamodb')db = dynamodb.Table('myservice-dev')
@app.route('/counter', methods=['GET'])def counter_get(): res = db.get_item(Key={'id': 'counter'}) return jsonify({'counter': res['Item']['counter_value']})
@app.route('/counter/increase', methods=['POST'])def counter_increase(): res = db.get_item(Key={'id': 'counter'}) value = res['Item']['counter_value'] + 1 res = db.update_item( Key={'id': 'counter'}, UpdateExpression='set counter_value=:value', ExpressionAttributeValues={':value': value}, ) return jsonify({'counter': value})
Create a run.py
file to test this API service locally:
创建一个run.py
文件以在本地测试此API服务:
from myservice import appif __name__ == '__main__': app.run(debug=True, host='127.0.0.1', port=8000)
Now run the service:
现在运行服务:
(.env)$ python run.py
And we can test this service with the following commands (open another terminal to type these commands):
我们可以使用以下命令测试该服务(打开另一个终端以键入这些命令):
$ curl localhost:8000/counter{ "counter": 0}$ curl -X POST localhost:8000/counter/increase{ "counter": 1}$ curl -X POST localhost:8000/counter/increase{ "counter": 2}$ curl localhost:8000/counter{ "counter": 2}
We can see that our code is working and it is successfully increasing the counter!
我们可以看到我们的代码正在运行,并且正在成功增加计数器!
使用Zappa将我们的代码部署到Lambda (Deploying our code to Lambda with Zappa)
Deploying our API to Lambda is extremely easy with zappa. First, we need to install zappa:
使用zappa,将我们的API部署到Lambda非常容易。 首先,我们需要安装zappa:
(.env)$ pip install zappa
Then initialize the zappa environment with zappa init
. It will ask you some questions, but generally you can use default answers for all the questions:
然后使用zappa init
初始化zappa环境。 它会问您一些问题,但是通常您可以对所有问题使用默认答案:
(.env)$ zappa init...What do you want to call this environment (default 'dev'): ...What do you want to call your bucket? (default 'zappa-ab7dd70x5'):
It looks like this is a Flask application.What's the modular path to your app's function?This will likely be something like 'your_module.app'.We discovered: myservice.appWhere is your app's function? (default 'myservice.app'): ...
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]:
Okay, here's your zappa_settings.json:
{ "dev": { "app_function": "myservice.app", "aws_region": "us-east-1", "profile_name": "default", "project_name": "myservice", "runtime": "python3.6", "s3_bucket": "zappa-ab7dd70x5" }}
Does this look okay? (default 'y') [y/n]: ...
After initialization, we can see the generated zappa_settings.json
file. Then we can start to deploy our service:
初始化之后,我们可以看到生成的zappa_settings.json
文件。 然后,我们可以开始部署我们的服务:
(.env)$ zappa deploy devCalling deploy for stage dev.....Deployment complete!: https://2ks1n5nrxh.execute-api.us-east-1.amazonaws.com/dev
Great! Our service is online. You can test this service with curl as well:
大! 我们的服务在线。 您还可以使用curl测试此服务:
(.env)$ curl https://2ks1n5nrxh.execute-api.us-east-1.amazonaws.com/dev/counter{"counter":2}(.env)$ curl -X POST https://2ks1n5nrxh.execute-api.us-east-1.amazonaws.com/dev/counter/increase{"counter":3}(.env)$ curl https://2ks1n5nrxh.execute-api.us-east-1.amazonaws.com/dev/counter{"counter":3}
设置API服务的自定义域 (Setup a Custom Domain for API Service)
However, there is one issue with the API service. The auto generated API endpoint 2ks1n5nrxh.execute-api.us-east-1.amazonaws.com
is very difficult to read or use for human consumption. Fortunately, we can bind a custom domain name to this API endpoint.
但是,API服务存在一个问题。 自动生成的API端点2ks1n5nrxh.execute-api.us-east-1.amazonaws.com
很难阅读或用于人类消费。 幸运的是,我们可以将自定义域名绑定到该API端点。
We will use the custom domain https://myservice-api.example.com
for this API service. Since we want to serve it with https, we need to get a certificate first. AWS provides a free certificate with the “Certificate Manager” service, and it is very easy to use.
我们将针对此API服务使用自定义域https://myservice-api.example.com
。 由于我们希望通过https进行提供,因此我们需要首先获得证书。 AWS通过“证书管理器”服务提供了免费证书,并且非常易于使用。
After the certificate is generated, we can use it to setup a custom domain for our service in the AWS API Gateway service.
生成证书后,我们可以使用它为AWS API Gateway服务中的服务设置自定义域。
申请证书 (Apply for a Certificate)
Switch to ACM service in the AWS management console (the service is actually called Certificate Manager, but you can type “ACM” to search for it). Click Request a certificate button, then choose Request a public certificate option in the next screen. The certificate is free as long as you choose a public certificate here.
在AWS管理控制台中切换到ACM服务(该服务实际上称为证书管理器,但是您可以键入“ ACM”进行搜索)。 单击请求证书按钮,然后在下一个屏幕中选择请求公共证书选项。 该证书是免费的,只要您在此处选择公共证书即可。
In the next screen, enter the domain name you want to apply the certificate for, then click Next. Here I applied for *.example.com
which means the certificate can be used by all the sub-domains under example.com
. In this way, we can use the same certificate for our front end at myfrontend.example.com
without having to apply for a new one.
在下一个屏幕中,输入要为其应用证书的域名,然后单击“ 下一步” 。 我在这里申请了*.example.com
,这意味着证书可以被example.com
下的所有子域使用。 这样,我们可以在myfrontend.example.com
为前端使用相同的证书,而无需申请新证书。
In the next step, we need to prove that we own this domain name. Since I applied for this domain name from Google Domains, I will choose DNS validation. Click the Review button then click Confirm and Request.
下一步,我们需要证明我们拥有此域名。 由于我是从Google Domains申请此域名的,因此我将选择DNS验证 。 单击“ 审阅”按钮,然后单击“ 确认并请求” 。
The certificate request will be created, and a validation screen will be displayed. The instructions show how to validate this domain name:
将创建证书申请,并显示验证屏幕。 说明说明如何验证此域名:
Based on the instructions, we need to add a CNAME
record and assign it the given value. In my case, I will open Google Domains, find my domain name example.com
, and add the specified CNAME record:
根据说明,我们需要添加一个CNAME
记录并为其指定值。 就我而言,我将打开Google Domains,找到我的域名example.com
,并添加指定的CNAME记录:
Note: I only added the random string _2adee19a0967c7dd5014b81110387d11
in the Name field, without typing the .example.com
part. This is to avoid the suffix .example.com
part getting duplicated.
注意:我只在“名称”字段中添加了随机字符串_2adee19a0967c7dd5014b81110387d11
,而没有键入.example.com
部分。 这是为了避免后缀.example.com
部分重复。
Now, we need to wait for about 10 minutes until AWS Certificate Manager validates this domain name. Once validated, the “Status” column in the certificate will display “Issued” in green.
现在,我们需要等待大约10分钟,直到AWS Certificate Manager验证该域名。 验证后,证书中的“状态”列将以绿色显示“已发行”。
Now that we have the certificate ready, we can start binding our custom domain name to our API.
现在我们已经准备好证书,我们可以开始将自定义域名绑定到我们的API。
为我们的API服务设置自定义域 (Setuping up a Custom Domain for our API Service)
Go to the “API Gateway” service. From the “APIs” in the left pane, we can see that our API myservice-dev
has already been created by zappa.
转到“ API网关”服务。 从左窗格中的“ API”,我们可以看到zappa已经创建了我们的API myservice-dev
。
Click on “Custom Domain Names” from the left pane, then click the Create Custom Domain Name button on the right pane and fill in the necessary fields.
在左窗格中单击“ 自定义域名 ”,然后在右窗格中单击“ 创建自定义域名”按钮,并填写必填字段。
Here I want my API service to be exposed via CloudFront so that it can be accessed with optimal speed all around the world. So I chose Edge Optimized in this configuration. You can choose Regional if you don’t need CloudFront.
在这里,我希望通过CloudFront公开我的API服务,以便可以在全球范围内以最佳速度对其进行访问。 因此,我在此配置中选择“ 边缘优化” 。 如果不需要CloudFront,则可以选择“ 区域” 。
Click the “Add mapping” link below, then select our API myservice-dev
as the Destination, and choose dev for the right most box. In this way, our API will not expose the environment name dev
in the URL. Leave the Path field empty.
单击下面的“ 添加映射 ”链接,然后选择我们的API myservice-dev
作为Destination ,然后在最右边的框中选择dev 。 这样,我们的API将不会在URL中公开环境名称dev
。 将“ 路径”字段保留为空。
After clicking the Save button, our custom domain binding will be created. The actual domain binding requires up to 40 minutes to initialize, but we can configure the DNS settings now.
单击“ 保存”按钮后,将创建我们的自定义域绑定。 实际的域绑定最多需要40分钟来初始化,但是我们现在可以配置DNS设置。
From the above screenshot, we can see that the actual domain name is dgt9opldriaup.cloudfront.net
. We need to setup a CNAME
in our DNS, pointing myservice-api.example.com
to the CloudFront subdomain dgt9opldriaup.cloudfront.net
.
从上面的屏幕截图中,我们可以看到实际的域名是dgt9opldriaup.cloudfront.net
。 我们需要在DNS中设置一个CNAME
,将myservice-api.example.com
指向CloudFront子域dgt9opldriaup.cloudfront.net
。
Go to Google Domains and add the CNAME to the DNS settings:
转到Google域,然后将CNAME添加到DNS设置中:
After this step, wait for about 40 minutes until the “Initializing…” in the API Gateway service disappears.
完成此步骤后,等待约40分钟,直到API Gateway服务中的“正在初始化...”消失。
Now try our new API service!
现在尝试我们的新API服务!
(.env)$ curl https://myservice-api.example.com/counter{"counter":3}(.env)$ curl -X POST https://myservice-api.example.com/counter/increase{"counter":4}(.env)$ curl https://myservice-api.example.com/counter{"counter":4}
前端静态网站 (Static Website for Front end)
For the next task, we will be creating a front end for our brand new API service. For demonstration purposes, we will create a simple page with a button that triggers the /counter/increase
API call.
对于下一个任务,我们将为我们全新的API服务创建一个前端。 出于演示目的,我们将创建一个带有触发/counter/increase
API调用的按钮的简单页面。
编码前端 (Coding the front end)
Let’s create a new directory called myfrontend
:
让我们创建一个名为myfrontend
的新目录:
$ mkdir myfrontend && cd myfrontend
Then make a simple HTML file index.html
:
然后制作一个简单HTML文件index.html
:
<html><body> <h1>Welcome to my homepage!</h1> <p>Counter: <span id="counter"></span></p> <button id="increase">Increase Counter</button> <script> const setCounter = (counter_value) => { document.querySelector('#counter').innerHTML = counter_value; };
const api = 'https://myservice-api.example.com'; fetch(api + '/counter') .then(res => res.json()) .then(result => setCounter(result.counter));
document.querySelector('#increase') .addEventListener('click', () => { fetch(api + '/counter/increase', { method: 'POST' }) .then(res => res.json()) .then(result => setCounter(result.counter)); } ); </script></body></html>
将前端发布到AWS S3 (Publish the Front end to AWS S3)
To create a static web site with S3, we need to create a bucket with the same name as our domain name.
要使用S3创建静态网站,我们需要创建一个与域名同名的存储桶。
Note: If you’ve been following along with this tutorial, the bucket name myfrontend.example.com may not be available, as bucket names are globally unique. Also, you’ll need to create a bucket name based on your public domain. For example,
myfrontend.[yourdomain].com
注意:如果您一直按照本教程进行操作,则存储桶名称myfrontend.example.com可能不可用,因为存储桶名称是全局唯一的。 另外,您需要根据您的公共域创建存储桶名称。 例如,
myfrontend. [yourdomain] .com
myfrontend. [yourdomain] .com
Switch to the S3 service in the AWS management console. Since we want to host the static website on myfrontend.example.com
, we will create a bucket with that name. Click the Create Bucket button, and fill in the bucket name, then keep clicking Next until the bucket is created.
切换到AWS管理控制台中的S3服务。 由于我们要在myfrontend.example.com
上托管静态网站, myfrontend.example.com
我们将使用该名称创建一个存储桶。 单击创建存储桶按钮,并填写存储桶名称,然后继续单击下一步,直到创建存储桶。
Next, we need to enable static web hosting from this bucket. Open this bucket, then choose the Properties tab, and choose Static Web Hosting. In the dialog, select Use this bucket to host a website, then type index.html
in the “Index document” field. Click Save when finished.
接下来,我们需要从此存储桶中启用静态Web托管。 打开此存储桶,然后选择“ 属性”选项卡,然后选择“ 静态虚拟主机” 。 在对话框中,选择“ 使用此存储桶托管网站” ,然后在“索引文档”字段中键入index.html
。 完成后单击“ 保存” 。
Note: The “Endpoint” link shown in the dialog above. We will test our static website with this URL later.
注意:上方对话框中显示的“端点”链接。 我们稍后将使用此URL测试我们的静态网站。
The last thing we need to do is to enable public access on the bucket. This can be done by adding a bucket policy. Open this bucket and choose the Permissions tab, then click the Bucket Policy button.
我们需要做的最后一件事是在存储桶上启用公共访问。 这可以通过添加存储桶策略来完成。 打开此存储桶,然后选择“ 权限”选项卡,然后单击“ 存储桶策略”按钮。
Type in the following content as the policy, then click the Save button (don’t forget to replace myservice.example.com
with your domain name).
输入以下内容作为策略,然后单击“ 保存”按钮(不要忘记用您的域名替换myservice.example.com
)。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::myfrontend.example.com/*" } ]}
After saving, we should be able to see an orange “public” sign on the Bucket Policy button and the Permissions tab, which indicates that our bucket is publicly accessible.
保存后,我们应该能够在“ 存储桶策略”按钮和“ 权限”选项卡上看到一个橙色的“公共”符号,这表明我们的存储桶可以公开访问。
Now the bucket is created but it is still empty. We need to upload our front end code files to this bucket. Make sure we are in the newly created myfrontend
directory and type the following command:
现在创建了存储桶,但它仍然是空的。 我们需要将前端代码文件上传到此存储桶。 确保我们位于新创建的myfrontend
目录中,然后键入以下命令:
# Make sure you are in the `myfrontend` directory...$ aws s3 sync . s3://myfrontend.example.com
The above command copies all files fromt he current .
directory to S3.
上面的命令从当前复制所有文件.
目录到S3。
All done! Now we can test this static web site with the URL displayed earlier. Open that URL with any browser (in my case, http://myfrontend.example.com.s3-website-us-east-1.amazonaws.com/) and see the result!
全做完了! 现在,我们可以使用前面显示的URL测试此静态网站。 使用任何浏览器(在我的情况下为http://myfrontend.example.com.s3-website-us-east-1.amazonaws.com/)打开该URL,然后查看结果!
Oops! The counter is not displayed at all. ?
糟糕! 计数器完全不显示。 ?
And it looks like we got some JavaScript error. We can see the following error in the console:
看来我们遇到了一些JavaScript错误。 我们可以在控制台中看到以下错误:
Failed to load https://myservice-api.example.com/counter: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://myfrontend.example.com.s3-website-us-east-1.amazonaws.com' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Apparently we need to set the CORS header in order to make this script work, since the backend API is located on another domain. But since we’re going to set up a custom domain for the frontend, the URL will change, so we will worry about CORS later.
显然,我们需要设置CORS标头以使此脚本起作用,因为后端API位于另一个域上。 但是,由于我们将为前端设置自定义域,因此URL将会更改,因此我们稍后会担心CORS。
为我们的静态网站设置CloudFront (Setting up CloudFront for our Static Web site)
The last step is to setup CloudFront for our front end. Since we have already created a certificate for *.example.com
, this step will be very easy.
最后一步是为我们的前端设置CloudFront。 由于我们已经为*.example.com
创建了证书,因此此步骤将非常容易。
Switch to CloudFront service in the AWS management console. Click Create Distribution button, then click the Start button in the “Web” section.
在AWS管理控制台中切换到CloudFront服务。 单击创建分发按钮,然后单击“ Web”部分中的开始按钮。
In the “Create Distribution” screen, we need to make five changes:
在“创建分发”屏幕中,我们需要进行五项更改:
Click the Origin domain name input box and select our S3 bucket
myfrontend.example.com.s3.amazonaws.com
.点击原始域名输入框,然后选择我们的S3存储桶
myfrontend.example.com.s3.amazonaws.com
。Then change the Viewer Protocol Policy to “Redirect HTTP to HTTPS” in order to force https access.
然后将查看器协议策略更改为“将HTTP重定向到HTTPS”,以强制进行https访问。
In the Alternate Domain Names box, type in our custom domain. In this case we type in
myfrontend.example.com
.在“ 备用域名”框中,键入我们的自定义域。 在这种情况下,我们输入
myfrontend.example.com
。Scroll down to the SSL Certificate section, choose “Custom SSL Certificate”, then select our
*.example.com
certificate.向下滚动到SSL证书部分,选择“自定义SSL证书”,然后选择我们的
*.example.com
证书。Change Default Root Object to
index.html
.将默认根对象更改为
index.html
。
After the distribution is created, we can see the CloudFront domain in the distribution list.
创建分配后,我们可以在分配列表中看到CloudFront域。
Although the status is still “In Progress”, we can setup our DNS record now. Go to Google Domains and add a CNAME for this domain:
尽管状态仍为“进行中”,但我们现在可以设置DNS记录。 转到Google域,并为此域添加一个CNAME:
Then wait until the distribution status change to “Deployed”. Now open your browser and try to access myfrontend.example.com
. We can see the exact same static web site!
然后等待,直到分发状态更改为“已部署”。 现在打开浏览器,尝试访问myfrontend.example.com
。 我们可以看到完全相同的静态网站!
解决CORS问题 (Fix the CORS issue)
Now the only issue left is CORS. Since we are using a different domain name on the backend and frontend, we need to add CORS support.
现在剩下的唯一问题是CORS。 由于我们在后端和前端使用了不同的域名,因此我们需要添加CORS支持。
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served. — Wikipedia
跨域资源共享(CORS)是一种机制,它允许从提供第一资源的域之外的另一个域请求网页上的受限资源(例如,字体)。 — 维基百科
Go back to our API directory (myservice
) and activate the Python environment. Then install the flask_cors
package.
返回我们的API目录( myservice
)并激活Python环境。 然后安装flask_cors
软件包。
$ cd myservice$ source .env/bin/activate(.env)$ pip install flask_cors
Then edit myservice.py
and add the following lines (in bold):
然后编辑myservice.py
并添加以下几行(粗体):
import boto3from flask import Flask, jsonifyfrom flask_cors import CORS
app = Flask(__name__)CORS(app, origins=['https://myfrontend.example.com'])
Push the updated service to AWS Lambda:
将更新的服务推送到AWS Lambda:
(.env)$ zappa update dev
Now try to refresh our browser. We can see the counter is displayed correctly. Clicking the “Increase Counter” button can increase the counter as well.
现在尝试刷新我们的浏览器。 我们可以看到计数器显示正确。 单击“增加计数器”按钮也可以增加计数器。
结论 (Conclusion)
In this post we explored various AWS services required to create a simple serverless service. You may feel there are too many AWS services if you are not familiar with AWS, but most AWS services we used here are for one-time use. Once they are setup, we don’t need to touch them at all in further development. All you need to do is to run zappa update
and aws s3 sync
.
在本文中,我们探讨了创建简单的无服务器服务所需的各种AWS服务。 如果您不熟悉AWS,您可能会觉得AWS服务太多,但是我们在这里使用的大多数AWS服务都是一次性的。 设置好之后,我们就无需再进一步开发了。 您所需要做的就是运行zappa update
和aws s3 sync
。
Besides, this is way easier than setting up a private VPS, installing web servers, and writing a Jenkins job for continuous deployment.
此外,这比设置私有VPS,安装Web服务器以及编写Jenkins作业进行连续部署要容易得多。
As a summary, here are the key takeaways from this post:
总结一下,这是这篇文章的主要内容:
- Lambda can run a simple service. This service can be exposed by API Gateway. Lambda可以运行简单的服务。 可以通过API网关公开此服务。
- zappa is a great tool if you want to write serverless services in Python. 如果您想用Python编写无服务器服务,那么zappa是一个很棒的工具。
- S3 bucket can be used for static hosting. S3存储桶可用于静态托管。
- Apply for a certificate from AWS ACM if you want to use https. 如果要使用https,请从AWS ACM申请证书。
- API Gateway and CloudFront both support custom domain names. API Gateway和CloudFront都支持自定义域名。
Hope you like this post and don’t hesitate to clap ? for me if you did! Follow me if you want to read more about web development.
希望您喜欢这篇文章,不要犹豫拍手吗? 对我来说,如果你做到了! 如果您想了解有关Web开发的更多信息,请关注我。
翻译自: https://www.freecodecamp.org/news/how-to-create-a-serverless-service-in-15-minutes-b63af8c892e5/
服务器创建多个dhcp服务