1 概述
为避免地域级别的故障,需要将单机房架构变成双地域架构(两个机房物理距离越远,网络延时越大,网延时是业务研发首先关注的)。单边写的多机房架构,是落地性比较大的一个方案,相对于单元化架构。并且,通过域名作为中间层来屏蔽故障切换时的数据库IP变化,业务研发就不需要修改应用配置了,只需要平台组工程师在DNS服务器上进行DNS记录的变更即可,省去故障切换时应用配置的变更。
2 架构
3 环境
3.1 广州地域:
ELB的公网地址是:139.xx.xx.xxx
数据库内网地址是:10.0.29.52
数据库公网地址是:113.xx.xx.xx
数据库域名是:mysql.example.com
数据库的database是:demo
数据库的用户是:demo
3.2 上海地域:
ELB的公网地址是:122.xx.xx.xxx
数据库内网地址是:192.168.14.185
数据库公网地址是:116.xx.xx.xx
数据库域名是:mysql.example.com
数据库的database是:demo
数据库的用户是:demo
3.3 数据库同步
使用华为云DRS服务的实时灾备任务作为数据同步工具:
3.4 应用公网域名:
demo-mall.xxxxx.com
3.5 应用部署
环境变量DATA_CENTER,表示该用于属于哪个地域。
环境变量MYSQL_HOST,表示数据库的地址。
环境变量MYSQL_USER,表示数据库的账号。
环境变量MYSQL_PASSWORD:表示数据库的密码。
应用会自动初始化数据库记录。
应用对外暴露的接口:
curl http://127.0.0.1:8080/productscurl -XPOST http://127.0.0.1:8080/products -d '{"name": "Product-21", "price": 1088.29}'
广州应用的kubernetes yaml,环境变量DATA_CENTER设置为GZ,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: gorm-demoname: gorm-demo
spec:selector:matchLabels:app: gorm-demotemplate:metadata:labels:app: gorm-demospec:containers:- image: swr.cn-south-1.myhuaweicloud.com/migrator/gorm-demo:latestname: gorm-demoimagePullPolicy: Alwaysports:- containerPort: 8080protocol: TCPenv:- name: DATA_CENTERvalue: "GZ"- name: MYSQL_HOSTvalue: mysql.example.com- name: MYSQL_PASSWORDvalue: *****************your_password*****************- name: MYSQL_USERvalue: demoresources:limits:cpu: 500mmemory: 500Mirequests:cpu: 100mmemory: 128MilivenessProbe:failureThreshold: 30httpGet:path: /productsport: 8080scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 3readinessProbe:failureThreshold: 3httpGet:path: /productsport: 8080scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 3
---
apiVersion: v1
kind: Service
metadata:name: gorm-demo
spec:ports:- name: gorm-demoport: 80protocol: TCPtargetPort: 8080selector:app: gorm-demotype: ClusterIP
上海应用的kubernetes yaml,环境变量DATA_CENTER设置为SH,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: gorm-demoname: gorm-demo
spec:selector:matchLabels:app: gorm-demotemplate:metadata:labels:app: gorm-demospec:containers:- image: swr.cn-south-1.myhuaweicloud.com/migrator/gorm-demo:latestname: gorm-demoimagePullPolicy: Alwaysports:- containerPort: 8080protocol: TCPenv:- name: DATA_CENTERvalue: "SH"- name: MYSQL_HOSTvalue: mysql.example.com- name: MYSQL_PASSWORDvalue: *****************your_password*****************- name: MYSQL_USERvalue: demoresources:limits:cpu: 500mmemory: 500Mirequests:cpu: 100mmemory: 128MilivenessProbe:failureThreshold: 30httpGet:path: /productsport: 8080scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 3readinessProbe:failureThreshold: 3httpGet:path: /productsport: 8080scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 3
---
apiVersion: v1
kind: Service
metadata:name: gorm-demo
spec:ports:- name: gorm-demoport: 80protocol: TCPtargetPort: 8080selector:app: gorm-demotype: ClusterIP
3.6 公网访问效果
4 模拟源端数据故障
直接在web控制台,停止广州数据库实例:
会发现,应用的pod的状态变成非就绪,因为探针接口会访问数据库,数据库不可用则探针失败:
很显然,此时如果访问公网域名,ELB会返回如下响应,因为它对后端pod的健康检查失败:
此时,关闭DRS的容灾任务,让上海数据库实例变成正常状态:
接着,不修改广州应用的环境变量配置,只需要将广州地域的数据库域名修改成上海数据库的公网地址:
发现广州的pod又重新就绪了:
接着,不修改上海应用的环境变量配置,只需要将上海地域的数据库域名修改成上海数据库的内网地址:
发现上海的pod又重新就绪了:
此时,重新访问外部域名,服务又正常了:
现在系统的架构变成这样了:
5 小结
单边写的应用双活,是落地性比较大的一种双活架构。加之通过域名来屏蔽数据库IP的变化,进一步减少了故障转移时的应用配置的变化,应用配置变化越少,RTO则越短。