wordpress 如何备份数据库,抖音seo排名系统,广东江门最新消息今天,成都网站开发环球中心记一次远程API调用失败
最近开发忙#xff0c;项目紧#xff0c;系统出现一些忽隐忽现的问题#xff0c;本地也不能复现#xff0c;当时也无法理解#xff0c;就先搁置了#xff0c;现在回想起来#xff0c;这里还是明智的。
这个bug很神奇 今天#xff0c;原本好好的…记一次远程API调用失败
最近开发忙项目紧系统出现一些忽隐忽现的问题本地也不能复现当时也无法理解就先搁置了现在回想起来这里还是明智的。
这个bug很神奇 今天原本好好的API突然抽风爆出数据转换异常看看异常信息指向一个远程调用API response json转换异常 2020-04-09 15:12:57.236 DEBUG 22236 --- [http-nio-9010-exec-2] c.l.framework.remote.crm.CrmRemoteApi : [CrmRemoteApi#getProviderType] --- POST http://micro-service-crm/remote/provider/type/list HTTP/1.1
2020-04-09 15:13:02.336 DEBUG 22236 --- [http-nio-9010-exec-5] c.l.framework.remote.crm.CrmRemoteApi : [CrmRemoteApi#getProviderType] --- HTTP/1.1 200 (5133ms)
2020-04-09 15:13:02.339 ERROR 22236 --- [http-nio-9010-exec-5] c.l.f.exception.GlobleExceptionHandler : Exception:Error while extracting response for type [java.util.Listcom.lansen.framework.dto.provider.CrmMaterialInfoPartnerEntity] and content type [application/json;charsetutf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT tokenat [Source: (PushbackInputStream); line: 1, column: 1]feign.codec.DecodeException: Error while extracting response for type [java.util.Listcom.lansen.framework.dto.provider.CrmMaterialInfoPartnerEntity] and content type [application/json;charsetutf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT tokenat [Source: (PushbackInputStream); line: 1, column: 1]at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:180)at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:140)at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)at com.sun.proxy.$Proxy213.getProviderType(Unknown Source)这个问题应该不难看了一下异常远程API Overridepublic ListMapString, String getProviderType(ListString materialNos) {return crmMaterialInfoPartnerService.getProviderType(materialNos);}看代码返回值不符合开发规范**开发规范返回值不能使用Map必须是具体实体类**找了一下负责这个模块功能的开发者“乐宝”乐宝是我们项目组的一位呆萌男孩是个态度和工作都很努力的大眼小伙儿遇到问题总是眼睛瞳孔放大眼神一片迷茫还伴随着不断点头总之非常可爱简单讲解了一下异常信息把这个问题交给“乐宝”解决。下午的时候找到乐宝问了一下修复情况乐宝还是一头雾水看我过来了试探问是不是我这个返回实体有包含自己的情况 public class CrmMaterialInfoPartnerEntity extends BaseEntity {TableField(exist false)ListCrmMaterialInfoPartnerEntity materialList;
}想到这点他赶紧删掉测了一圈问题还是一样由于时间紧这块儿自引用先按下不表叮嘱乐宝先尝试解决不行就换一种写法试试经过了几轮儿排查不知不觉已经是下午6点了乐宝说改好了代码提交开始发测试版本版本发完测试验证问题依然存在乐宝本地验证没问题不过他发现第一次是正常的清理了redis问题就出现了这问题奇怪了怎么会跟redis有关系呢顿时陷入了沉思中…
这个bug很调皮 乐宝说返回List集合的接口都有问题他已经修复了2个模块了测试后仍然报错找不到问题的原因先让乐宝保留本地修改的代码暂不提交。我开始盯着代码思考这个问题一般这种转换异常的问题要么是返回值映射有问题要么是传参映射有问题顺着这两个思路我打开了debug模式A服务远程调用B服务先检查B服务有没有接收到请求排查B服务收到了请求但是B服务还未响应请求A服务突然报错了what… 沉思中时老大哥也过来帮忙排查我俩简单同步问题信息后定位到gateway的feign调用超时问题开始修改配置把超时时间设置大些把redis超时时间也调大正在尝试测试时另一个项目组也模拟出一种偶现问题调用远程API时提示强制退出登录这是什么情况猜测两个问题应该来源一个出处为什么远程API会跟redis有关系呢于是过去看了一下强制退出登录的问题也没摸到头绪回来时老大哥模拟出来一种新思路服务刚启动时清空redis问题会出现这时候把远程服务重启再次清理redis发现问题没有了重新整理思路代码开始在脑子里浮现每一个服务都有一个权限认证拦截器只有这里使用到了redis难道是这里出现的问题废话不多说开始在这里debug一番排查后发现远程服务验证token时候出错了根据报错信息还是很难分辨出为什么异常老大哥提出我们在这里打一下token看一下调用时候token有什么问题 2020-04-09 18:53:33.913 DEBUG 15880 --- [http-nio-9002-exec-2] c.l.f.web.filter.BaseInterceptor : 当前访问URL:/remote/provider/type/list,
redis token: eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkMWMyNzExNC1mZmU2LTQ0MTktODMzNC1hNjQwNjQ5YTYwODQiLCJpc3MiOiJKV1QiLCJzdWIiOiJ7XCJ1c2VySWRcIjpcImQ3YzNlNmY0NGMwMmUxMmM2NTVjOGRmM2NhZDM3MDFkXCIsXCJ1c2VyTmFtZVwiOlwiYW5kZXJzXCIsXCJ0eXBlXCI6XCJhY2NvdW50XCIsXCJhcHBsaWNhdGlvbklkXCI6XCJiMmFlZmNhMmI4YjA0YzJiYTEyZGYwY2JlZTkwdDJjZVwiLFwidGltZVwiOjE1ODY0Mjk1NjgzMzB9IiwiaWF0IjoxNTg2NDI5NTY4LCJleHAiOjE1ODcwMzQzNjh9.uvWNCUZR9JucS5aBdKdNui8bPxXVlXW_-wD1-pbt4rI
remote token: eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjMjQ0MmZjYy1mM2QxLTRjMzEtOTc5Yi00NDlhNTg4ZTRmMjMiLCJpc3MiOiJKV1QiLCJzdWIiOiJ7XCJ1c2VySWRcIjpcImQ3YzNlNmY0NGMwMmUxMmM2NTVjOGRmM2NhZDM3MDFkXCIsXCJ1c2VyTmFtZVwiOlwiYW5kZXJzXCIsXCJ0eXBlXCI6XCJhY2NvdW50XCIsXCJhcHBsaWNhdGlvbklkXCI6XCJiMmFlZmNhMmI4YjA0YzJiYTEyZGYwY2JlZTkwdDJjZVwiLFwidGltZVwiOjE1ODY0MzA1NTI2MTh9IiwiaWF0IjoxNTg2NDMwNTUyLCJleHAiOjE1ODcwMzUzNTJ9.SdqEVuVfUn7oPOoYZmVTwugONbfg8Vy12W2ffpNqdnM两次token不一致why 只有远程API调用的时候token不一致检查了一遍认证拦截器没有发现异常问题突然想到了远程API的feign拦截器打开代码一看恍然大悟就是这里了 Overridepublic void apply(RequestTemplate requestTemplate) {FeignRequestContext feignRequestContext FeignRequestContextLocal.getInstance().get();if (Objects.nonNull(feignRequestContext)) {requestTemplate.headers(feignRequestContext.buildHeaders());}else if(Objects.nonNull(CommonUtils.getRequest())) {requestTemplate.headers(getHeads(CommonUtils.getRequest()));}}private MapString, CollectionString getHeads(HttpServletRequest request) {FeignRequestContext feignRequestContext new FeignRequestContext(request);FeignRequestContextLocal.getInstance().set(feignRequestContext);return feignRequestContext.buildHeaders();}由于有异步处理的业务场景这里使用了线程变量存储远程上下文参数这里没有考虑到清理去掉这里的线程变量程序运行舒畅了到此问题圆满解决了真是一场深刻的bug排查。