鱼肚的博客

发布于: 2019-12-25作者: 鱼肚最后更新: 2020-11-30

引言

Serverless应用一般都是微服务架构,项目会比较多,域名管理比较复杂。

本文提出了一种便捷的Serverless应用域名管理方案。

此方案基于 AWS 平台,使用 Serverless 框架及其周边生态实现。使用其它平台或框架的读者请酌情参考。

方案概述

  1. 前后端分离
  2. 每个前端项目占用一个独立的子域名
    1. foo 项目前端工程会使用 foo.demo.com
    2. bar 项目前端工程会使用 bar.demo.com
  3. 后端项目共用一个公共子域名,如 api。再通过子路径区分不同的业务(以及公共服务)。
    1. foo 项目后端工程会使用 api.demo.com/foo
    2. bar 项目后端工程会使用 api.demo.com/bar
  4. 将域名委托在对应的Serverless云服务商(如 AWS Route53),方便使用程序添加、删除记录。
  5. 使用工具进行域名管理。

示意图

实现方式

Serverless 中主要有两种方式管理域名,分别是基于 Serverless Components 的 Domain 和基于原生 Serverless 的 serverless-domain-manager

它们的主要区别有两个:

  1. 应用领域不同,Serverless Components 和 原生 Serverless 的写法差异比较大。
  2. serverless-domain-manager支持子路径,而 Domain 暂时还不支持。

本方案中使用 serverless-domain-manager 管理后端域名,使多个工程即使不在同一个Git仓库中,也可以共用同一个域名(api.demo.com)。

至于前端项目域名就比较灵活了,具体看前端项目采用的是 Serverless Components 方式还是原生 Serverless 方式而定。

两种方式都需要先将域名的DNS服务改到Route53下,具体方法请参阅官方文档。

https://aws.amazon.com/cn/route53/

示例代码

基于serverless-domain-manager管理后端域名

基于serverless-domain-manager管理后端应用,共用同一个域名的示例:

  1. 创建serverless.yml,如下所示,将其中的 *.demo.com,foo 等换成对应的域名。
1service:
2  name: foo-backend
3
4custom:
5  serverless-offline:
6    port: 3000
7  domains:
8    prod: api.demo.com
9    staging: staging-api.demo.com
10    dev: dev-api.demo.com
11
12  customDomain:
13    domainName: ${self:custom.domains.${self:provider.environment.stage}}
14    basePath: 'foo'
15    stage: ${self:provider.environment.stage}
16    createRoute53Record: true
17
18# Add the serverless-webpack plugin
19plugins:
20  - serverless-domain-manager
21
22provider:
23  name: aws
24  runtime: nodejs12.x
25  stage: dev
26  apiGateway:
27    minimumCompressionSize: 1024 # Enable gzip compression for responses > 1 KB
28  memorySize: 256
29  environment:
30    stage: ${opt:stage, self:provider.stage}
31    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
32
33functions:
34  test:
35    handler: handler.test
36    events:
37      - http:
38          method: get
39          path: test
40          cors: true
  1. 安装相关依赖: serverless、serverless-domain-manager 等包

    npm i -D serverless serverless-domain-manager

  2. 执行命令创建对应的域名

    npx serverless create_domain --stage dev

    这里的 dev 根据需要换成对应的 stage名。上面的 serverless.yml 中定义了三种stage(dev、staging、prod)分别对应三个不同的子域名。

    如果此域名已经在别处创建过,此步骤可忽略

  3. 执行deploy

    npx serverless deploy --stage dev

基于serverless-domain-manager管理前端域名

与上面的方案基本相同,去除 basePath: 'foo' 即可。

基于 Serverless Components Domain 管理前端域名

Serverless Components环环相扣,所以有可能您并不需要直接使用 Serverless Components Domain。

如果您在使用 Next.js 做前端应用,可考虑使用 serverless-nextjs-component

serverless-nextjs-component的自定义域名使用极为简单:

  1. 创建 serverless.yml 文件,写入如下内容:

    1# serverless.yml
    2
    3myNextApplication:
    4  component: serverless-next.js
    5  inputs:
    6    domain: "example.com" # sub-domain defaults to www
  2. 运行 serverless ,自动执行部署及域名创建。(注意不是 serverless deploy)。

如果直接使用 serverless components domain,则可使用如下的 serverless.yml

1domain:
2  component: '@serverless/domain'
3  inputs:
4    privateZone: false
5    domain: mywebsite.com
6    subdomains:
7      www: ${websiteComponentInstance}
8      api: ${backendComponentInstance}
9      admin: ${anotherWebsiteComponentInstance}

HTTPS 证书

AWS Route53 会负责证书的自动创建和更新,如果是通过上述的两种serverless方案创建的域名,不需要关心证书问题。

总结

本文提出了一种简便的Serverless应用域名管理方案。

它将前端域名和后端域名独立开,规避了前端项目和后端项目处于同一子域名下带来的制约。

使得前端工程可以和后端工程互相独立。前端工程也可以不采用Serverless架构,直接做CNAME映射到其它静态托管服务,如 Github pages或netlify。



0条评论