一、双中心设计
记录在公司主导完成的双中心改造
1)背景
公司的基础平台放在阿里云 供多个项目共享使用,万一 阿里云环境出问题,会直接影响到 全国2近200个业主的线上系统,无法登录。所以进行在腾讯云购买了几台服务器,进行 阿里云+ 腾讯云的同城双活改造。
2)要点
-
不停服。 原因:被近200 业主项目跨公网调用,场景:C 端用户登录。
解决:用nginx+lua (openresty)灰度线上流量到 腾讯云的新版本应用。进行局部测试,观察log。
评估mysql同步方案、压力。
评估memcache/redis 同步方案、压力。
灾备方案预演。
1) 架构
2) 方案
2.1) 概要
微信基础平台双中心最终落地的方案主要有如下几点:
采用 dns域名解析分摊流量,以及故障时的流量转移。
双机房mysql同步,采用 otter。
-
memcache同步(根据业务改造):
手工http同步缓存
业务改造去掉缓存使用。
灰度测试/流量矫正 。
-
灰度上线:
针对ip白名单已经添加好的公众号(例如易惠科技服务号),把流量转发到腾讯云进行测试。
-
ip白名单兼容:
如果某些公众号由于无法添加腾讯云ip到白名单,那就把这部分流量转发会阿里云。
2.2)mysql同步
毫无疑问了,用阿里的otter ,支持双A写入。
2.3)缓存同步
dynomite+dyno方案最终废弃: 虽然来自Netflix,但是国内实践经验很少,怕踩坑。
根据本项目特点进行业务改造如下:
(主要)场景1:url跳转通过state传参取缓存的业务数据(详见Corecontroller类)。 改造:通过url参数传递业务数据,避开缓存的使用(保留缓存以供兼容/降级)。
-
(次要)场景2:分布式锁刷新各种token()。 改造:
改成由定时任务主动刷新,避开分布式锁。 (包括4种:accessToken,jkkAccessToken,jsApiToken详见ScheduleConfig类)
定时任务跨中心高可用。 (定时互相http ping,详见类CoreIdcController.idcHeartBeat。
-
(少量)场景3:appid,secret,token等重要信息获取。
改造:http接口同步、懒加载mysql(详见CoreServiceImpl,SyncCacheController)。
(少量)场景4: 后台使用以及其他不重要的。
3)代码分支
备注 | ||
---|---|---|
最新双活分支 | https://svn.xxxx.com/svn/YiKaTong/yktWechat/trunk/yktWechat | revision:87503开始双活任务 |
旧分支-备份 | https://svn.xxxx.com/svn/YiKaTong/yktWechat/trunk/yktWechat_bak | 双活改造前备份 |
双活-废弃方案 | https://svn.xxxx.com/svn/YiKaTong/yktWechat/trunk/yktWechat1.3.0 | dynomite+dyno |
4)部署/运维
1.机器编号
列举阿里,腾讯两个机房的机器,定义编号,便于本文档中描述。
机器编号 | 系统 | 云 | 公网IP | 描述 | |
---|---|---|---|---|---|
node1 | centos | 阿里 | 47.112.xxx.xxx | 微信基础平台,及其他组件 | |
node2 | centos | 阿里 | 119.23.xxx.xxx | 微信基础平台,及其他组件 | |
node3 | centos | 阿里 | 120.79.xxx.xxx | 微信基础平台,及其他组件 | |
node4 | centos | 腾讯 | 1.13.xxx.xxx | 微信基础平台,及其他组件 | |
node5 | centos | 腾讯 | 1.13.xxx.xxx | 微信基础平台,及其他组件 | |
node6 | win | 阿里 | 120.79.xxx.xxx | Navicat、RDM、Chrome等 |
2.角色规划
应用/机器 | NODE1 | NODE2 | NODE3 | NODE4 | NODE5 | NDOE6 |
---|---|---|---|---|---|---|
tomcat8-1407 | 1 | 1 | 1 | 1 | 1 | |
ngx | 1 | 1 | 1 | |||
otterNode | 1 | 1 | 1 | 1 | ||
otterWeb | 1 | |||||
zk | 1 | |||||
memcached | 1 | 1 | ||||
winTools | 1 |
3.网络
由运维同事负责 处理好阿里,腾讯双机房的网络访问互通。
主要是阿里云 和腾讯云的 组策略互相放行,建议规则为 指定机房ip+通配端口。
4.应用部署路径
双机房各个应用部署路径一致,只有otter node部署的路径有差异
以下表格包含node1~node5安装的应用路径说明
应用 | 路径 | 描述 |
---|---|---|
微信基础-旧 | /app/AllServer/tomcat8-1307 | 旧版微信基础平台(废弃) |
微信基础-新 | /app/AllServer/tomcat8-1407 | 微信基础 双中心新版 |
http证书 | /app/AllServer/data/cert/onepay/ | tomcat https证书 |
otter manager | /app/AllServer/manager | mysql同步工具 otter的webUI |
otter node_阿里 | /app/AllServer/node | otter的工作进程 |
otter node_腾讯 | /platform/node | otter的工作进程 |
zk | /app/AllServer/zookeeper-3.4.6 | otter依赖的zk |
aria | /app/AllServer/aria2-1.19.0 | otter依赖的传输提速工具 |
nginx | /app/AllServer/openrestyDemo | openresty用来灰度测试腾讯云 |
https证书 | /app/AllServer/openrestyDemo/conf/cert | nginx https证书 |
5)双中心-灰度测试
背景
因为 微信基础平台被很多线上项目使用,测试要谨慎,出事故影响很大,很广,
所以在腾讯云环境搭建初期用nginx转发部分项目的流量到腾讯云进行测试,
测试通过以后,灰度的转发流量就可以去掉(图中红色虚线部分),直接转到tomcat。
前提:1.腾讯云环境node4,node5部署好tomcat,调整好相关的配置文件。
2.腾讯云mysql 用otter搭建好跟 阿里云rds实例的双向同步。
具体操:阿里云 CLB实例 逐步调大80/443 转到 node2:1407/1408的权重,观察 log。
目前已经灰度易惠科技服务号(gh_43axxxxxxx)的流量到腾讯云,目前正常,验证方法如下:
#1 灰度验证:有转发流量
#.node2上看openrestyDemo的log验证流量有转发到腾讯云
#隔一会儿执行下如下统计,能看到灰度成功的请求数的变化
cd /app/AllServer/openrestyDemo/logs
[root@iZwz981qbhfk42pemfnqw9Z logs]# grep -ain '灰度成功:gh_43axxxxxxx' error_8443.log|wc -l
6268
#2.业务验证:转发到腾讯云后业务正常
#到node4查看业务log,分别统计业务成功数和失败数
cd /app/AllServer/logs/wechat-manager1407
[root@VM-16-14-centos wechat-manager1407]# grep -in 'oauth2授权类型3' yktWechat_debug.2023-02-20*|wc -l
7173
[root@VM-16-14-centos wechat-manager1407]# grep -in 'auth2获取微信openid失败' yktWechat_debug.2023-02-20*|wc -l
0</pre>
6)双中心-流量矫正
背景:
因为 微信接口需要ip白名单,只有配过ip白名单的项目(小程序可选,公众号必须配ip)的流量才可以落到腾讯云的tomcat。
所以
本着双中心优先保证高频/核心业务功能的部分接口可用的原则,
在腾讯云 两台服务器都部署了nginx,针对几个ip敏感,且高频率使用的项目登录相关的接口,解析出参数里的accountid,如果是已经配过ip白名单的,proxypass到本机房的tomcat,否则转发到阿里云。
核心代码解析:
conf/nginx.conf
#阿里云机器
upstream remotewx {
server 119.23.敏感数据:2407;
server 120.79.敏感数据:1407;
server 47.112.敏感数据:1407;
}
upstream remotewxssl {
server 119.23.敏感数据:2408;
server 120.79.敏感数据:1408;
server 47.112.敏感数据:1408;
}
#腾讯云 本地
upstream localwxssl {
server 127.0.0.1:1408;
server 10.206.敏感数据:1408;
}
upstream localwx {
server 127.0.0.1:1407;
server 10.206.敏感数据:1407;
}
#关键接口
location /coreController/oauth2 {
set_by_lua_file $cur_ups lua/oauth2_router.lua;
proxy_pass $scheme://$cur_ups;
}
location /coreController/jsapiTicket {
set $cur_ups '';
rewrite_by_lua_file lua/jsapiticket_router.lua;
proxy_pass $scheme://$cur_ups;
}
location /miniProgram/getOpenid {
set $cur_ups '';
rewrite_by_lua_file lua/get_openid_router.lua;
proxy_pass $scheme://$cur_ups;
}
location / {
proxy_pass $scheme://remotewxssl;
}
lua/switch.lua
处理好ip白名单的公众号,或者小程序(确认没开ip白名单),配到如下table里,value设置为true,即可把流量转发到腾讯云,实现双机房高可用。
local _M = {}
local accountidSwitch = {
gh_43a553dbff68=true,
gh_de8a8f2030e0=false};
function _M.check(accountid)
local status = accountidSwitch[""..accountid];
-- ngx.log(ngx.DEBUG,"status of accountid ",accountid..": "..tostring(status));
if not status then
return false;
end
return status;
end
return _M;
然后重载nginx.(node4,node5 都要操作一遍)
[root@VM-16-14-centos openrestyDemo]# pwd
/app/AllServer/openrestyDemo
[root@VM-16-14-centos openrestyDemo]# ./reload.sh
#还有启动和停止的脚本 ./start.sh, ./stop.sh</pre>
二、故障预案
1) 机房故障
主要修改通过dns 解析修改来做机房故障的流量切换。
例如当阿里云故障时
登录到阿里云-域名管理-模块 修改 wx.ylzpay.com的解析权重,把阿里云clb的ip权重改为0。 此后几十分钟/小时内,流量会逐步转到腾讯云。 注意观察腾讯云的带宽资源。
-
检查定时任务master是否转移到腾讯云。 postman/curl GET http://1.13.敏感数据:1407/coreController/idc/selfstatus.htm
如下返回信息: remoteIdcAlive: false 或者接口不通, 代表阿里云的定时任务已经没执行,腾讯云的机器会自动接管定时任务,继续定时执行。
{
"data": {
"twoIdcTestRun": true,
"mainIDC": false,
"twoIdcOnline": true,
"remoteIdcDomain": "http://120.79.敏感数据:1407",
"remoteIdcAlive": true
},
"status": "OK"
}
如果remoteIdcAlive还是 true, 可以手工改配置来切换定时任务的master机房:
# 1.阿里云node2
cd /app/AllServer/tomcat8-1407/webapps/ROOT/WEB-INF/classes
vi global_names.properties
mainIDC=false
#重启tomcat
# 2.腾讯云 node4
cd /app/AllServer/tomcat8-1407/webapps/ROOT/WEB-INF/classes
vi global_names.properties
mainIDC=true
#重启tomcat</pre>
2) mysql同步故障
同步故障时,建议先按 机房故障,把流量收回到阿里云,然后处理好otter同步故障,再重新分流量到腾讯云。
ps: 因为微信基础平台并没有重要的业务数据如金额等,
所以为了优先保证otter的可用性,已经配置了忽略几种常见的异常,从而降低otter故障的概率。
如果有网络抖动之类的偶发问题,重启下channel任务即可。
otter WebUI默认密码admin/admin,目前只能通过内网winServer访问。
三、持续处理项目
1.存量数据。
腾讯表格(敏感数据)记录了存量公众号/小程序 添加 腾讯ip白名单的进度。
每处理一批ip白名单,就可以把原始id 加到(node4、node5)lua/switch.lua 中,实现该原始id流量的双活。
注意:
公众号必须添加ip白名单。
小程序执行如下请求验证。
2.增量数据
微信基础平台日常申请的应用需要项目经理确保也添加了腾讯ip白名单。
下一篇,双机房实战,mysql同步otter(二)