服务器创建多个dhcp服务_如何在15分钟内创建无服务器服务

服务器创建多个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.comhttps://myservice-api.example.com

  • Front End: https://myfrontend.example.com

    前端: https://myfrontend.example.comhttps://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。 这需要两个步骤:

  1. We need to create an AWS user for programmatic access

    我们需要创建一个AWS用户以进行编程访问
  2. 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 configurecommand:

安装后,我们将使用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 of counter_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 value

    POST /counter/increase增加计数器并返回计数器值

  • GET /counter returns the current counter value

    GET /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记录并为其指定值。 就我而言,我将打开Goog​​le 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 updateaws 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服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php snoopy视频教程,php的Snoopy类

用了两天这个类&#xff0c;发现很好用。获取请求网页里面的所有链接&#xff0c;直接使用fetchlinks就可以&#xff0c;获取所有文本信息使用fetchtext(其内部还是使用正则表达式在进行处理)&#xff0c;还有其它较多的功能&#xff0c;如模拟提交表单等。使用方法&#xff1a…

网页解析 css

网页解析 css转载于:https://www.cnblogs.com/guozepingboke/p/10792298.html

如何看pg数据库版本号_查看pg数据库版本

PostgreSQL 基本命令链接&#xff1a;http://blog.itpub.net/28602568/viewspace-1841163/标题&#xff1a;PostgreSQL 基本命令作者&#xff1a;&#xff4c;ōττ&#xff52;&#xff59;©版权所有[文章允许转载,但必须以链接方式注明源地址,否则追究法律责任.]安装步…

leetcode1091. 二进制矩阵中的最短路径(bfs)

在一个 N N 的方形网格中&#xff0c;每个单元格有两种状态&#xff1a;空&#xff08;0&#xff09;或者阻塞&#xff08;1&#xff09;。一条从左上角到右下角、长度为 k 的畅通路径&#xff0c;由满足下述条件的单元格 C_1, C_2, ..., C_k 组成&#xff1a;相邻单元格 C_i …

lock和synchronized的同步区别与选择

区别如下&#xff1a; 1. lock是一个接口&#xff0c;而synchronized是java的一个关键字&#xff0c;synchronized是内置的语言实现&#xff1b;&#xff08;具体实现上的区别在《Java虚拟机》中有讲解底层的CAS不同&#xff0c;以前有读过现在又遗忘了。&#xff09; 2. syn…

首页显示登陆用户名php,首页登录后怎么在首页显示用户名以及隐藏登录框?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼index.php&#xff1a;登录页面用户名&#xff1a;密码&#xff1a;没有账号&#xff1f;立即注册——————————————————————————doaction.php&#xff1a;header("Content-type:text/html;charsetutf…

react中使用构建缓存_通过在React中构建Tic Tac Toe来学习ReasonML

react中使用构建缓存3. 7. 2018: UPDATED to ReasonReact v0.4.23. 7. 2018&#xff1a;更新为ReasonReact v0.4.2 You may have heard of Reason before. It’s a syntax on top of OCaml that compiles to both readable JavaScript code and to native and bytecode as well…

echart vue 图表大小_vue里echarts自适应窗口大小改变

echarts的图表提供了一个resize方法可以自适应屏幕窗口改变&#xff0c;而重新渲染图表大小的功能。因此我们只要监听浏览器的窗口改变的resize事件&#xff0c;再结合echarts的图表&#xff0c;就可以实现我们想要的功能了。如果是单个图表的情况的话用window.onresize myCha…

用js检测文本框中输入的是否符合条件并有错误和正确提醒

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>捕获异常</title></head><script type"text/javascript">function my_func(){try{xdocument.getElementById("input_id").value;ale…

leetcode784. 字母大小写全排列(回溯)

给定一个字符串S&#xff0c;通过将字符串S中的每个字母转变大小写&#xff0c;我们可以获得一个新的字符串。返回所有可能得到的字符串集合。 示例: 输入: S “a1b2” 输出: [“a1b2”, “a1B2”, “A1b2”, “A1B2”] 输入: S “3z4” 输出: [“3z4”, “3Z4”] 输入: S…

Petapoco使用SQLite的异常问题

在DbProviderFactory 初始化时&#xff0c;报一个"System.Data.SQLite.SQLiteFactory”的类型初始值设定项引发异常。 解决&#xff1a;不光要引用System.Data.SQLite。还要把SQLite.Interop.dll添加到运行目录下。转载于:https://www.cnblogs.com/crazy29/p/7595552.html…

CPP函数调用的方法

相比于C语言中函数可以直接调用&#xff0c;CPP的函数由于命名存在隐式添加&#xff0c;因此需要通过一套流程才能调用&#xff1a; 1. 编码中&#xff0c;使用extern "C" 定义一个C函数&#xff0c;返回获取对象的指针&#xff1b;执行该函数时&#xff0c;获得一个…

php 算法 二进制文件,关于PHP二进制流 逐bit的低位在前算法(详解)_PHP教程

复制代码 代码如下:/******************************************************* 逐bit的低位在前算法* param $x* return int*/function reverse($x){$result 0;for($i 0; $i < 8; $i){$result ($result <> $i));}return $result & 0xff;}调用展示&#xff1a;…

顶尖科技棋牌游戏开发_如何接受顶尖科技公司的采访

顶尖科技棋牌游戏开发If you’ve ever wondered how to land an interview with top tech companies or know someone who’s been struggling to get an interview with one, then this article is for you.如果您曾经想过如何与顶尖高科技公司进行面谈&#xff0c;或者想知道…

城轨列控系统

关于列控系统想问的问题 1&#xff09;列控系统的组成&#xff1f; 2&#xff09;城轨列控系统和列控系统有哪些区别&#xff1f; 3&#xff09;列控系统的设备图片&#xff1f; 4&#xff09;列控系统的作用&#xff1f; 1、地铁的供电部分&#xff1a; 参考&#xff1a;http:…

Thinkphp 发送邮件

TP框架实现发送邮件&#xff0c;亲测可用1.在模块的配置文件config中加入下里面代码THINK_EMAIL > array(SMTP_HOST > smtp.qq.com, //SMTP服务器SMTP_PORT > 465, //SMTP服务器端口SMTP_USER > 邮箱qq.com, //SMTP服务器用户名SMTP_PASS > 密码, //SMTP服务器密…

leetcode40. 组合总和 II(回溯)

给定一个数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 说明&#xff1a; 所有数字&#xff08;包括目标数&#xff09;都是正整数。 解集不能包含重复的组合…

python 面部识别_一文教你在Python中打造你自己专属的面部识别系统

原标题&#xff1a;一文教你在Python中打造你自己专属的面部识别系统人脸识别是用户身份验证的最新趋势。苹果推出的新一代iPhone X使用面部识别技术来验证用户身份。百度也在使“刷脸”的方式允许员工进入办公室。对于很多人来说&#xff0c;这些应用程序有一种魔力。但在这篇…

Computer Vision Review Incompletely

机器视觉牛人及其相关领域分类科普转载于:https://www.cnblogs.com/casperwin/p/6380484.html

php获取特殊标签,thinkphp特殊标签使用

特殊标签1、比较标签eq或者 equal 等于neq 或者notequal 不等于gt 大于egt 大于等于lt 小于elt 小于等于heq 恒等于nheq 不恒等于2.范围标签in(in namen value9,10,11,12)在这些数字里面(else/)不在这些数字的范围内(/in)(notin namen value9,10,11,12)在这些数字里面(else/)不…