双机房多活实战(一)

一、双中心设计

记录在公司主导完成的双中心改造

1)背景

公司的基础平台放在阿里云 供多个项目共享使用,万一 阿里云环境出问题,会直接影响到 全国2近200个业主的线上系统,无法登录。所以进行在腾讯云购买了几台服务器,进行 阿里云+ 腾讯云的同城双活改造。

2)要点

  1. 不停服。 原因:被近200 业主项目跨公网调用,场景:C 端用户登录。

    解决:用nginx+lua (openresty)灰度线上流量到 腾讯云的新版本应用。进行局部测试,观察log。

  2. 评估mysql同步方案、压力。

  3. 评估memcache/redis 同步方案、压力。

  4. 灾备方案预演。

1) 架构

微信双活_拓扑_测试阶段_1.png

2) 方案

2.1) 概要

微信基础平台双中心最终落地的方案主要有如下几点:

  1. 采用 dns域名解析分摊流量,以及故障时的流量转移。

  2. 双机房mysql同步,采用 otter。

  3. memcache同步(根据业务改造):

    1. 手工http同步缓存

    2. 业务改造去掉缓存使用。

  4. 灰度测试/流量矫正 。

  5. 灰度上线:

    针对ip白名单已经添加好的公众号(例如易惠科技服务号),把流量转发到腾讯云进行测试。

  6. ip白名单兼容:

    如果某些公众号由于无法添加腾讯云ip到白名单,那就把这部分流量转发会阿里云。

2.2)mysql同步

毫无疑问了,用阿里的otter ,支持双A写入。

2.3)缓存同步

dynomite+dyno方案最终废弃: 虽然来自Netflix,但是国内实践经验很少,怕踩坑。

根据本项目特点进行业务改造如下:

  1. (主要)场景1:url跳转通过state传参取缓存的业务数据(详见Corecontroller类)。 改造:通过url参数传递业务数据,避开缓存的使用(保留缓存以供兼容/降级)。

  2. (次要)场景2:分布式锁刷新各种token()。 改造:

    1. 改成由定时任务主动刷新,避开分布式锁。 (包括4种:accessToken,jkkAccessToken,jsApiToken详见ScheduleConfig类)

    2. 定时任务跨中心高可用。 (定时互相http ping,详见类CoreIdcController.idcHeartBeat。

  3. (少量)场景3:appid,secret,token等重要信息获取。

    改造:http接口同步、懒加载mysql(详见CoreServiceImpl,SyncCacheController)。

  4. (少量)场景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 解析修改来做机房故障的流量切换。

例如当阿里云故障时

  1. 登录到阿里云-域名管理-模块 修改 wx.ylzpay.com的解析权重,把阿里云clb的ip权重改为0。 此后几十分钟/小时内,流量会逐步转到腾讯云。 注意观察腾讯云的带宽资源。

  2. 检查定时任务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流量的双活。

注意:

  1. 公众号必须添加ip白名单。

  2. 小程序执行如下请求验证。

2.增量数据

微信基础平台日常申请的应用需要项目经理确保也添加了腾讯ip白名单。

下一篇,双机房实战,mysql同步otter(二)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容