当前位置: 首页 > news >正文

发布课程的网站模板seo论坛

发布课程的网站模板,seo论坛,杭州手机网站建设公司 网络服务,体育馆做网站公司说明#xff1a;本文记录一次偶然出现的空指针异常#xff0c;在微服务架构中#xff0c;一个服务在调用另一个服务时#xff0c;出现了空指针异常。 业务描述#xff1a;在做订单超时功能时#xff0c;大家都知道#xff0c;可以使用RabbitMQ延迟队列#xff0c;下单…说明本文记录一次偶然出现的空指针异常在微服务架构中一个服务在调用另一个服务时出现了空指针异常。 业务描述在做订单超时功能时大家都知道可以使用RabbitMQ延迟队列下单的同时给队列发送一个延迟消息消息的内容是订单号比如延迟10分钟。10分钟之后该消息被消费者监听到会根据该订单ID查询数据库看该订单的状态是否为已支付是则忽略否则取消该订单恢复商品库存等等其他操作然而此时出现了空指针异常消息未被消费被路由到死信队列中。 微服务调用报空指针异常 消息被路由到死信队列 如下图的第三步 分析 首先排除FeignClient的问题因为下单减少库存取消订单恢复库存我使用的是同一个接口只是修改了商品的正负数不可能出现下单时可以取消订单时再使用就报错。 controller层代码 /*** 根据ID更新商品库存* param id* param num*/PutMapping(/update/{id}/{num})public void updateStockById(PathVariable(id) Long id, PathVariable(num) Integer num){itemService.updateStockById(id,num);}service层代码 Overridepublic void updateStockById(Long id, Integer num) {if (!ObjectUtil.isAllNotEmpty(id, num)) {System.out.println(参数不能为空);}if (id 0 || num 0) {System.out.println(参数非法);}update().setSql(stock stock num).eq(id, id).update();}其次再思考会不会不是因为Feign的调用报错而是微服务之间有什业务产生的报错。于是我找到了拦截器。 为了保证用户登录后经过Gateway网关后信息可以被下游服务获取到我的代码中是使用MVC拦截器Feign拦截器实现的如下图 每个服务会有两个拦截器分别把服务接收到的请求发出的请求拦截到然后分别解析用户信息添加用户信息到请求头以此达到参数透传用户信息可在微服务之间流传。 MVC拦截器代码获取请求头中用户的ID存到ThreadLocal中 public class AuthorizationInterceptor implements HandlerInterceptor {/*** 收到请求会执行的方法* param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String id request.getHeader(authorization);if (id ! null id ! ){long l Long.parseLong(id);TokenThreadLocal.set(l);}else {responseHandler(response);return false;}// 放行return true;}…… }Feign拦截器将本服务中的ThreadLocal中的用户ID再设置到请求头上 /*** 发送请求拦截器*/ Slf4j public class AuthorizationRequestInterceptor implements RequestInterceptor {Overridepublic void apply(RequestTemplate requestTemplate) {requestTemplate.header(authorization,TokenThreadLocal.get().toString());} }排查 给这两个地方分别打上断点等订单超时后进入拦截器的代码排查一下 断点来到Feign拦截器选中这行代码一看原来是这里报了空指针异常 再一看原来是TokenThreadLocal.get().toString()这里是空的 然后恍然大悟MQ发送消息是异步请求ThreadLocal本地线程池对象自然为空 解决 很自然的想到一种很简单的解决方法发送消息的时候把ThreadLocal中的值用户ID也给发到延迟队列中然后在消费者监听的代码里面再使用ThreadLocal的set()方法把用户ID设置到线程池中 把订单ID、用户ID封装成一个Map转为json格式发送到延迟队列里 消费者代码这边使用ThreadLocal的set()方法把用户ID再设置进去 启动测试下单等待订单超时清理超时订单进入断点问题解决 总结 这是一个非常隐蔽的异常因为设置了死信队列未被成功消费的消息会被路由到死信队列中程序并不会报错并且因为订单表的内容大部分是在订单服务中此异常仅仅会影响订单被取消后调用商品服务恢复商品库存数量这一个很小的功能未能执行要排除出来是非常困难的。 而问题原因概括来说是因为ThreadLocal的值不能在RabbitMQ的消息中传递导致在使用拦截器获取ThreadLocal值的时候报了空指针异常。
http://www.huolong8.cn/news/368012/

相关文章:

  • 新手做网站最简单流程网站优化教程
  • 袜子的网站建设方案万网网站多少
  • 电子商务网站 功能数据库做网站
  • 制作个人网站素材中国建盏品牌形象设计大赛
  • php做网站视频播放下载功能设计开发流程图
  • 怎么做网站demo网站备案建设方案
  • 做电影网站 资源怎么存放图片链接在线生成器
  • ip地址做网站泰安网站建设课程报告
  • 咸阳网站推广如何自学编程
  • 户外用品网站建设项目背景宣传册设计与制作公司
  • 路由器怎么做网站建设免费网站制作
  • 怎么查看一个网站是不是伪静态淮安制作网站在那里
  • 美食网站开发流程云南网站建设运营
  • 电脑什么软件做短视频网站最好的模板网站
  • Spring做网站和什么网站前端设计与制作ppt
  • 小程序设计网站佛山建设小学网站
  • 学校建设服务网网站建设方案项目书wordpress找回密码邮件
  • 可做影视网站的服务器桐梓住房和城乡建设部网站
  • 自己做网站需要服务器吗口碑好的扬州网站建设
  • 南昌建设局网站三明企业网站建设
  • 购物网站开发文档男科医生免费咨询
  • 小说网站建设教程网站建设竞争对手分析
  • 长沙公司网站高端网站建设dede网站婚纱模板
  • 温州建设银行官方网站连云港市网站优化
  • 深圳自适应网站推广价格wordpress模板怎么改成织梦模板
  • 济宁正德网站建设电商平台搭建方案
  • 个人网站建立国家住房和城乡建设部官方网站
  • 免费建设淘客网站wordpress elementor
  • 杭州自助建站网站网站开发主要学什么
  • 怎样做元古建筑的网站结构图h5开发app