引言
Serverless应用一般都是微服务架构,项目会比较多,域名管理比较复杂。
本文提出了一种便捷的Serverless应用域名管理方案。
此方案基于 AWS 平台,使用 Serverless 框架及其周边生态实现。使用其它平台或框架的读者请酌情参考。
方案概述
- 前后端分离
每个前端项目占用一个独立的子域名
- foo 项目前端工程会使用 foo.demo.com
- bar 项目前端工程会使用 bar.demo.com
后端项目共用一个公共子域名,如 api。再通过子路径区分不同的业务(以及公共服务)。
- foo 项目后端工程会使用 api.demo.com/foo
- bar 项目后端工程会使用 api.demo.com/bar
- 将域名委托在对应的Serverless云服务商(如 AWS Route53),方便使用程序添加、删除记录。
- 使用工具进行域名管理。
示意图
实现方式
Serverless 中主要有两种方式管理域名,分别是基于 Serverless Components 的 Domain 和基于原生 Serverless 的 serverless-domain-manager。
它们的主要区别有两个:
- 应用领域不同,Serverless Components 和 原生 Serverless 的写法差异比较大。
- 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管理后端应用,共用同一个域名的示例:
- 创建serverless.yml,如下所示,将其中的 *.demo.com,foo 等换成对应的域名。
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
安装相关依赖: serverless、serverless-domain-manager 等包
npm i -D serverless serverless-domain-manager
执行命令创建对应的域名
npx serverless create_domain --stage dev
这里的 dev 根据需要换成对应的 stage名。上面的 serverless.yml 中定义了三种stage(dev、staging、prod)分别对应三个不同的子域名。
如果此域名已经在别处创建过,此步骤可忽略执行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的自定义域名使用极为简单:
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。