所有的应用都在本地机房部署
有大概应用在20个左右,其中微服务应用各种组件和服务在8个左右,其他的都是老系统留下来的应用
服务类型 |
阿里云ECS规格 |
内存 |
CPU |
机械硬盘 |
固态硬盘 |
外网IP和带宽 |
数量 |
nginx代理转发 |
计算网络增强型 sn1ne |
8G |
4核 |
300G |
无 |
带宽10M(根据实际使用情况调整) |
1 |
tomcat类后端服务器 |
通用型g6 |
8G |
2核 |
300G |
无 |
无 |
10 |
redis缓存队列 |
通用型g6 |
8G |
2核 |
300G |
100G |
无 |
3 |
redis(可选配置) |
内存网络增强型 se1ne |
16G |
2核 |
300G |
100G |
无 |
|
redis(可选配置) |
内存型(原独享)se1 |
16G |
2核 |
300G |
100G |
无 |
|
数据库 |
通用型g6 |
16G |
4核 |
500G |
300G |
无 |
4 |
数据库(可选配置) |
内存型(原独享)se1 |
32G |
4核 |
500G |
300G |
无 |
|
数据库(可选配置) |
内存网络增强型 se1ne |
32G |
4核 |
500G |
300G |
无 |
|
我们的运维小哥哥从6月2号开始进行部署和迁移,三天之后也就是6月5号的时候完成整体的迁移工作,因为我们还在进行项目的迭代工作,所以我们的测试周期啦的比较长。到6月18号左右才完成测试工作。
6月20号,全员休息,对我们来说是一个好日子,奋斗开始了我和我们的运维小哥哥,测试小哥哥一大早开始来到公司,挂起维护页面。然后就开始干起来了:
第一步:数据同步,这是一个漫长的等待时间,当然这个主要是运维小哥哥在操作。
第二步:配置更新,对于微服务来说比较轻松,更改nacos上的配置文件就好了。
预期规划如下:
数据库 | redis | |
微服务应用 | 一主多从 | 哨兵模式 |
老应用 | 多写分离加多数据源 | 哨兵模式 |
对于的老的应用来说,用git做的配置中心,脚本拉取替换(WAR包,JAR包就别想了)的方式,其实更改起来也比较OK。所以配置更新也是相当顺利
第三步:更新所有的应用到最新的版本,这个就是jenkins上操作即可,无问题。
问题1:与第三方应用通讯需要外网的问题。
解决方式:弹性公网IP
问题2:文件共享问题
解决方式:因为本地机房应用是没有专门的文件服务器的,所以采用的软连等相关操作,阿里云上采用的共享和挂载操作
问题3:第三方推送地址更换问题
解决方式:联系第三方更改推送地址
问题4:访问白名单问题
解决方式:针对443端口开放所有的访问权限。
其他相关功能没有什么问题,基本上到这来说理论上这次迁移是很成功的,虽然忙活了一天但是还是心满意足的下班了。
第二天,怀着很忐忑的心情,早早的就起来坐到电脑旁边了。8点开始没什么问题,貌似很稳定的情况,8点50左右,我的同事们都开始上班上系统干活了,这个时候悲剧开始了。
第一个炸弹:大量的同事都是第一次通过外网的域名访问系统,所以大量的并发导致需要拉取大量的静态资源。瞬间带宽超了。这个其实好理解,只是瞬时的,而且后面访问基本趋于平稳状态,10M的带宽基本上能满足需求。OK,这个可以过了。
第二个炸弹:所有的同事都说卡,访问系统超级慢。然后就是整个钉钉群,微信群就炸了。
开始排查:
排查一:redis毫无压力,是不是redis没起作用?
因为redis没有开放外网端口,登录服务器查看。
./redis-cli -a 'pwd'
使用命令查看所有的key
keys *
redis正常缓存数据,没有问题。那么这个时候考虑是不是老系统不兼容哨兵配置,改回单机模式。并没有任何效果,redis正常读写没问题。排除
排查二:数据库,是否是数据库压力过大。
查看主库:没问题,兼职就是毫无压力
查看从库:压力爆满,CPU完成超超负荷运行。那么问题来了,为什么会出现这种情况?
解决方案1:分压,既然主库没有任何压力,那么先在某些应用的节点更改主库为从库,也就是主从一致。
效果:瞬间主库压力上来,从库反而没有任何压力了。卡顿现象并没有解决。
解决方案2:查看系统日志,发现某些节点的日志输出频率较慢。是不是因为某些服务器的配置的问题,重启相关服务器和从库。
效果:依然没有解决我们的问题。
此时时间已经走到了10点多了。但是经过这几轮的折腾,运维小哥哥突然记起来了,老的应用为了保持会话,是做了IP HASH的问题。以前使用的是内网环境,所以每一个的IP地址都不一样,现在用的外网环境,而公司统一的是专线固定IP,这样就变成了访问系统的IP变成了全一样的了。所以就全路由的一个服务节点上去了,其他的服务节点完全就没起作用了。
解决方案3:去掉IP HASH策略。
效果:去掉IP HASH会造成系统整个功能失常,所以基本上这个方案不可取。瞬间感觉好像走到死胡同了,连饭都不想吃了。
解决方案4:运维小哥哥在拿外卖的时候突然告诉我,我们可以根据IP手动指定路由节点。虽然我们的出网带宽固定了,但是还是有区域划分的,每个区域的IP还是不一样的。
效果:这个貌似解决了服务节点单一路由的问题。但是还是存在某些节点负载过大的情况,但是相比之前的情况,已经是好很多了。当然问题到这里只是万里长征走了第一步,完全没有实际的解决现在的系统的问题。
随着一天的上班结束,查询系统数据的人越来越多,查询量增大。这里就得说一下我们的老系统的报表相关的功能了,全是大的SQL汇总起来,有时候一个SQL包含了各种计算,函数,汇总,分组统计等功能。基本上我这么一个程序员老司机都不愿意看这些SQL。
解决方案5:增加数据库从库的CPU能力,升级数据库配置。
效果:这个时候已经是第二天了,毕竟花钱还是有流程的,当然领导很给力,直接给特事特办了。升级数据库配置,在增加1个从库,这个效果是立竿见影的,速度马上就上来。这个过程本来是个很轻松的过程,但是由于挂载问题,nginx所在的服务器居然重启失败,导致外网IP失效。最后还是联系阿里云的售后解决的。
这个时候基本上系统访问不存在的问题了,但是各位不要忘记了,IPHASH的问题我们还没有解决。
这个时候我一直在想nginx的IP hash的这个事情,其实所谓的IP hash不就是通过客户的IP来计算hash值,来确认他的路由保持,那么我在想我们是不是可以找一个替代IP的东西来解决这个会话保持的问题呢。
在我们的系统里面正好有这么一个东西对于客户来说是唯一的,那就是请求TOKEN,而且这个请求Token就在请求头里面。
解决方案6:自定义HASH策略
开启请求头检测
underscores_in_headers on;
定义2个路由规则:为什么是两个呢?因为我们有的请求是不需要登录就能获取的也就是没有token的,我们也希望随机轮询。
upstream https_prod {
hash $token;
server 172.17.150.127:8080 ;
server 172.17.150.128:8080 ;
server 172.17.150.129:10080 ;
}
upstream https_prods {
server 172.17.150.127:8080 ;
server 172.17.150.128:8080 ;
server 172.17.150.129:10080 ;
}
获取TOKEN,这里比较特殊的就是,websocket的连接的token我们放在的是Sec-WebSocket-Protocol上,这里注意了,在nginx配置文件中获取的时候,需要吧-换成_
set $token $http_Sec_WebSocket_Protocol;
if ($http_Authorization != '') {
set $token $http_Authorization;
}
定义自动的路由规则
set $group https_prod;
set $groups https_prods;
location ^~ /api/ {
if ($token != '') {
proxy_pass http://$group;
}
if ($token = '') {
proxy_pass http://$groups;
}
#proxy_pass http://$group;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
#WebScoket Support
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
到这里,自定义路由规则就完成,重启nginx加载策略。
效果:比较完美的解决了IP HASH的问题,理论上比IP HASH更加完美。这个时候系统访问速度的问题已经完全解决了
第三个炸弹:老系统的导出功能是,先在服务器上生产一个Excel文件,在吧连接返回给前端,前端通过a连打开下载的。因为a连请求是没有Token的,所以无法保持会话,所以有可能找不到这个文件。
解决方法:临时,运维小哥哥做了一个共享。
最终:文件下载改成流式下载。
三天已经过去,说实话,心里是贼几把累的,按一个正常程序员的心里,估计已经把前任骂的的飞起,但是其实我反而觉得这次的事情我自己应该有很多值得反思的事情。
借阿里的事故的一句话:敬畏每一行代码!在成长的过程中壮大自己!