背景
因公司有服务被恶意请求攻击导致服务瘫痪,为此要接入腾讯云的waf 功能,为核心接口进行保护,防止恶意频繁的访问导致服务无法正常提供服务(心想,这不是应该团队自己实现的吗?不管了,一算一年也不到2k,反正是公司出钱,加就完事儿了)
reqeust流程
解释下现有公司服务流程,当然是简化版的,为了描述此次问题,实际架构还是听负载的。
正式修改
本地修改hosts 后,测了各个域名下,比较核心的接口,都能正常访问,约定了尽快切1/2的流量到CLB 服务上。因为运维周末加班,运维兄弟是真苦啊,同时试用期的我想表现下,在周日运维兄弟找到我要切流量的时候,信誓旦旦的回话说可以,并关注线上业务是否有问题。
出事儿了
周日晚上还在打lol的我,被反馈说,登录功能有问题,我慌了。手足无措,因为就是一个请求的路径上加了一台代理服务器转发请求而已,怎么能影响到业务呢?也没有及时停止解析,无法登录的问题还在继续,没办法,就先停了CLB的解析,好了,能登录了。我一定要知道到底是为啥不能登录。
从sls 上搜索到的无法登录的用户日志,返回的结果显示是session不正确。项目比较久远了,解释下登录流程;
分析问题
从表层的代码来看,session是没有做共享的,想着觉得可能是clb 服务器接入后导致请求没有打入到同一台机器,运维也提供nginx上设置了iphash能让同一个client ip的请求继续请求到同一台服务。接着搜了成功功登录的日志,发现同一个用户调用接口1 ,2,3 打到的服务并不是同一台,刚升起的希望之火又灭了。好好康康代码,代码中有一套业务实现的存储session的逻辑,可登录并没有用,很茫然。已经是半夜1点了,看到有说tomcat 配置可以进行session 共享的案例,就给运维同学留言看下配置,以为找到了答案暂时休息了。
第二天运维反馈服务是jar包部署,没有tomcat配置,我恍然spring boot项目,咋可能部署在tomcat里呢。运维同学又反馈说,因为服务是k8s的,导致nginx 的iphash是不生效的,服务端是有做session共享的。继续搜索session共享的案例,结果找到了spring session 这个成熟的框架,一看我们服务也确实在用,那这个session 失效就无法解释了啊。
发现华点
因为只有安卓设备如此,居家办公手边的华为摔坏了,无法进行抓包验证。捅咕了好半天虚拟机,后抓包发现,在配置了clb 解析的两次接口连续请求connection是变化的,如图
而不加clb解析成功登录的连续请求connection 则是不变的
这也就是说连续的两个请求不是使用的同一个connection 导致获取不到session 中的内容,导致请求中断了。
完美谢幕
运维又反馈,clb中配置的负载均衡规则是加权轮询,这导致同一个client 可能经过clb后被分发到不同的nginx ,后端服务自然不能保证第二个接口拿到上一次请求生成的session,找到腾讯云的客服咨询了下,看了官方文档,确实如此,在修改clb 的负载均衡规则后,本地测试登录功能已经ok,了了一桩心事。
总结
此次问题出现原因,一是对接入功能的掉以轻心,导致没有对完全的流程进行测试,不过项目接口实在过于多且功能不一,也无法一一走全。二就是经验还是稍有欠缺,对request从客户端到服务端的流程有欠缺。不过这次也学到了很多东西,负载均衡策略,session共享实现方案,尤其是srping session 加个注解就能实现共享,框架真是解放双手啊。
大家加油!!!!