Serverless域名管理方案

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

引言

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. 使用工具进行域名管理。

示意图

graph LR root(demo.com) foo-front(foo.demo.com) bar-front(bar.demo.com) subgraph backend api(api.demo.com) foo-backend(api.demo.com/foo) bar-backend(api.demo.com/bar) common-backend(api.demo.com/common) end root --> foo-front; root --> bar-front; root --> api; api --> foo-backend; api --> bar-backend; api --> common-backend;

实现方式

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 等换成对应的域名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
service:
  name: foo-backend

custom:
  serverless-offline:
    port: 3000
  domains:
    prod: api.demo.com
    staging: staging-api.demo.com
    dev: dev-api.demo.com

  customDomain:
    domainName: ${self:custom.domains.${self:provider.environment.stage}}
    basePath: 'foo'
    stage: ${self:provider.environment.stage}
    createRoute53Record: true

# Add the serverless-webpack plugin
plugins:
  - serverless-domain-manager

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  apiGateway:
    minimumCompressionSize: 1024 # Enable gzip compression for responses > 1 KB
  memorySize: 256
  environment:
    stage: ${opt:stage, self:provider.stage}
    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1

functions:
  test:
    handler: handler.test
    events:
      - http:
          method: get
          path: test
          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
    2
    3
    4
    5
    6
    # serverless.yml
    
    myNextApplication:
      component: serverless-next.js
      inputs:
        domain: "example.com" # sub-domain defaults to www
  2. 运行 serverless ,自动执行部署及域名创建。(注意不是 serverless deploy)。

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

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

HTTPS 证书

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

总结

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

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

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


0条评论