最近遇到的一个生产环境参数丢失的诡异问题,现将整个过程记录下来供参考。
其实问题在元旦之前就有厂商在反馈了,但是因为该厂商还是在联调测试阶段,又加上并没有收到线上其他用户的反馈,所以简单的认为是厂商因为某种原因漏传了参数。
元旦后问题依然存在,双方都摸不到头脑才开始决定认真分析看看。
问题表现
厂商反馈的问题共有两个,一个是证书更新接口请求出现SSL异常,通过追加日志输出发现原本HTTP的请求被强制重定向到了HTTPS(该接口需要HTTP)。
第二个问题为业务验证错误,从日志来看是缺少了必需的参数。
复现测试
HTTP强制跳转
开始在本地测试期望能复现,但是一直没有任何问题。通过与厂商环境对比,发现厂商使用的为移动网络,而自己手机为电信网络,公司为联通网络。使用移动网络进行测试后,首先复现了HTTP跳转问题。因为关系到不同运营商有不同的表现,自然考虑到公司负载均衡VIP的问题。在沟通后确认,公司近期的升级中增加了特定域名强制跳转到HTTPS的规则。在针对当前特定域名取消规则后,问题得到解决。
参数丢失
开始对第二个问题进行分析测试。
首先通过测试APP在不同运营商网络下测试,确认依然是移动网络存在问题。然后通过POSTMAN直接对接口请求,发现仍然存在问题,排除了客户端出问题的可能。
新的发现-下划线参数
继续分析日志发现,在一起传的参数中,丢失的参数仅仅为请求Header中一个带下划线的参数,考虑到参数的特殊性搜索发现,nginx存在配置默认情况下会过滤下划线参数。检查应用服务端nginx的配置后,确认当前已经配置了允许下划线参数。配置项:underscores_in_headers on
;
进一步在应用服务端nginx增加日志输出,看该参数是否被正确透传过来发现一直没有收到该参数。
在与LB同事沟通后,了解到最近正进行HA到HTTP2模式的升级,部分升级的HTTP2没有开启对下划线参数的透传导致出现该问题。最终确定解决方案为全部VIP均切换到HTTP2模式。
验证切换-不管用
在下午进行VIP切换后通过POSTMAN进行验证,确认下划线参数已经可以正常传递过去了。但在全部切换后通过测试APP验证却发现所有的网络均出现了问题,问题并没有解决。
为避免影响线上用户只能暂时进行了回滚,切换到一个可正常使用的HA负载均衡上。
抓包对比
现在问题更诡异了,因为通过请求工具参数可以正常传递,但是测试APP通过代码请求却不行。只能进行抓包对比。
首先使用Fidller对POSTMAN请求和APP请求均进行了抓包,然后进行对比。在将参数完全调整到一致后却发现仍然是一种可以一种不可以。
参数顺序
继续对比HTTP请求报文,现在唯一的不同只有Header中参数的顺序。开始一点点调整参数位置进行对比测试。最终发现:
当Header中带下划线参数在Host参数之前时,该参数会出现丢失而在Host参数之后却而已正常透传。问题最终有了突破。再次与LB同事沟通并后,最终确认了问题所在:
在负载均衡集群的nginx配置中,针对下划线参数的配置underscores_in_headers on,没有配置到default server中导致。配置修复后问题得到解决。
问题总结
不要因为问题小而不在意或者忽略,需要确认到根本的原因。
当没有其他分析思路和办法时,排除法和对比法都会适用。