引言

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 等换成对应的域名。
  1. service:
  2. name: foo-backend
  3. custom:
  4. serverless-offline:
  5. port: 3000
  6. domains:
  7. prod: api.demo.com
  8. staging: staging-api.demo.com
  9. dev: dev-api.demo.com
  10. customDomain:
  11. domainName: ${self:custom.domains.${self:provider.environment.stage}}
  12. basePath: 'foo'
  13. stage: ${self:provider.environment.stage}
  14. createRoute53Record: true
  15. # Add the serverless-webpack plugin
  16. plugins:
  17. - serverless-domain-manager
  18. provider:
  19. name: aws
  20. runtime: nodejs12.x
  21. stage: dev
  22. apiGateway:
  23. minimumCompressionSize: 1024 # Enable gzip compression for responses > 1 KB
  24. memorySize: 256
  25. environment:
  26. stage: ${opt:stage, self:provider.stage}
  27. AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
  28. functions:
  29. test:
  30. handler: handler.test
  31. events:
  32. - http:
  33. method: get
  34. path: test
  35. 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 文件,写入如下内容: ```yaml

    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

```yaml
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。