邓州微网站建设,怎么搭建一个博客网站,wordpress第三方主题下载,软件怎么做出来的背景#xff1a;
本服务需要调用第三方接口获取数据#xff0c;首先调用public-key接口获取公钥#xff0c;然后用公钥加密密码#xff0c;将用户名和密码传入/ticket接口#xff0c;获取Cookie和response body中的token。
排查思路
由于是调用第三方接口出现问题
本服务需要调用第三方接口获取数据首先调用public-key接口获取公钥然后用公钥加密密码将用户名和密码传入/ticket接口获取Cookie和response body中的token。
排查思路
由于是调用第三方接口出现问题第一步先拉通第三方对接人查看后台日志对方使用apisix作为api网关初步判断是对方有不同节点负载均衡到不同节点而导致的偶发性问题。因此本地使用postman连续发起多次请求经过50次请求后每一次都能正确响应结果此时可推测应该不是由于负载均衡不同节点导致的。
思路二既然postman每次都能成功业务系统却会偶发性说明问题应该是出在本地代码。Debug本地调用流程以期望能够复现302问题经过多次运行发现第三方接口返回的cookie和token下面将cookie和token统称为凭证会存储在redis中。
代码中判断如果redis中没有凭证则会重新获取并保存在redis中如果redis中有凭证则从redis中获取。而redis中没有凭证时调用第三方接口就获取凭证再调用第三方业务接口时就一定会报错302若直接从redis中获取凭证则不会有该问题。此时可以复现302问题。
既然从redis中获取是正确的而第一次请求过来就是302错误我们对比两者的凭证发现凭证时一模一样的。此时和对接人讨论怀疑可能第是三方bug在第一次请求时会查找本地缓存凭证如果没有的话则报错302第二次就能在缓存中找到。为了验证该假设我们用postman去做第一次调用发现postman在第一次调用也是能够正常返回的此时陷入僵局。
思路三此时想到通过wireShark抓包查看本地发出的请求有什么区别但由于是https请求却看不到header信息。
思路四由于我们能准确复现302问题我们再次拉通第三方期望从对方日志中发现异常从日志中发现我们传过去的header中有两个cookie但是我们代码中只传了一个cookie此时推测可能是hutool在第一次获取服务端请求时把Cookie缓存起来下次调用就默认带上Cookie。
HttpRequest req HttpUtil.createRequest(Method.GET, url) .header(Content-Type, MediaType.APPLICATION_JSON_VALUE) .header(Cookie, Cookie) .header(CSRFPreventionToken, CSRFPreventionToken) .header(client_token, client_token);
HttpResponse response req.execute();因此我们使用Apache来调用验证发现Apache调用并不会出现302问题此时可确认该问题是由于hutool工具会缓存Cookie经过debug发现确实会缓存到threadLocal中。最终通过在调用/ticket接口并获取完数据后加上下面一行代码解决。
HttpRequest.getCookieManager().getCookieStore().removeAll();问题原因
hutool 自动保存了我们 /ticket 返回的 cookie在这我们重新设置了一遍 token、cookie导致重复了然后为什么第二次访问没问题第一次的request已经结束了Cookie也就被清掉了所以只有我们设置的token、Cookie。
总结
本次问题的解决最终找到hutool缓存上一次服务端返回的Cookie是不容易的中间甚至还用抓包解决这些解决思路值得记录。通过复盘分析 wireShark是个很好的定位问题工具需要花点时间学习开源包的issue是个解决问题的好思路可以在上面搜索一下当然还有复现问题第三方协助这些都很重要。
最后感谢自己絮絮叨叨完成了博客期待写出更多博客哦
参考博客 https://github.com/dromara/hutool/issues/583 https://blog.csdn.net/weixin_30315905/article/details/97599019