记一次生产事故排查

背景:刚接手一个新工程,是一个给国内top级医院开发的老项目,因为历史原因,代码质量略低,测试难度略高。

上线很久的功能,最近一直频繁的爆发各种问题,经排查发现都是因为在业务过程中im聊天账号绑定异常所致。

修复方案一:

因为im工程比较老,日志打印不完善,因此从日志看初步分析业务dubbo接口未调用到im服务因此导致了绑定失败,此时我开始在工程里设置dubbo接口该方法的重试机制,retries设置为2,timeout设置为3000,由于本身既有的一次rpc调用,因此实际在调用失败的情况下业务会对im接口进行3次rpc的调用。

鉴于项目的各种难度和稳定性要求,另在业务代码侧再次进行了三次递归重试(客户端超时30s,正常情况不会因为重试而超时,慢是肯定的)。

同时因为服务此时并没有打印traceId进行链路跟踪机制的拓展,因此另开发traceId写入MDC并通过log4j2打印到cosole并通过钉钉表达式进行采集汇总输出,针对dubbo接口也通过扩展spi进行了traceId的透传。

服务消费者端代码如下:

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;import javax.servlet.FilterChain;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** MDC属性设置  日志用* 方法屏蔽actuator接口*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter(urlPatterns = {"/*"})
public class MDCFilter extends OncePerRequestFilter {private  Logger LOGGER = LoggerFactory.getLogger(MDCFilter.class);@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {if(request.getRequestURI().contains("/actuator/health")){return;}try {String traceId = request.getHeader("traceId");if(StringUtils.isNotBlank(traceId)) {TraceIdUtil.create(traceId);} else {TraceIdUtil.create();}TraceContext.addAttachment("traceId",MDC.get("traceId"));chain.doFilter(new ContentCachingRequestWrapper(request), response);} catch (Exception exception) {LOGGER.error("Web端traceId处理异常", exception);} finally {TraceContext.clear();TraceIdUtil.clear();}}}
import java.util.UUID;
import org.slf4j.MDC;public class TraceIdUtil {public static final String TRACE_ID = "traceId";public TraceIdUtil() {}public static void create() {create(UUID.randomUUID().toString().replace("-", ""));}public static void create(String traceId) {MDC.put("traceId", traceId);}public static String get() {return MDC.get("traceId");}public static void clear() {MDC.clear();}
}
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;@Activate(group = {"consumer"})
public class DubboTraceFilter implements Filter {@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {RpcContext rpcContext = RpcContext.getContext();if (rpcContext.isConsumerSide()) {rpcContext.setAttachment("traceId", TraceContext.getTraceId());}return invoker.invoke(invocation);}
}
public class TraceContext {private static ThreadLocal<Map<String,Object>> threadLocal = new ThreadLocal<Map<String, Object>>(){@Overrideprotected Map<String, Object> initialValue() {return new LinkedHashMap<String, Object>();}};public static void addAttachment(String key, Object value){threadLocal.get().put(key,value);}public static void addAttachments(Map<String, Object> map){threadLocal.get().putAll(map);}public static Map<String, Object> getAttachments(){return threadLocal.get();}public static  void clear(){threadLocal.remove();}public static String getTraceId(){return String.valueOf(threadLocal.get().get("traceId"));}}

启动类添加注解:@ServletComponentScan

resource目录新建文件com.alibaba.dubbo.rpc.Filter

文件内容

dubboTraceFilter=com.xxx.filter.DubboTraceFilter(文件路径)

文件结构如下

服务提供者端代码如下:

import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;@Activate(group = {"provider","consumer"})
public class TraceIdFilter implements Filter {private static final Logger LOGGER = LoggerFactory.getLogger(TraceIdFilter.class);@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {try{String traceId = RpcContext.getContext().getAttachment("traceId");if ( !StringUtils.isEmpty(traceId) ) {// *) 从RpcContext里获取traceId并保存MDC.put("traceId", traceId);} else {// *) 交互前重新设置traceId, 避免信息丢失TraceIdUtil.create();RpcContext.getContext().setAttachment("traceId", MDC.get("traceId"));}// *) 实际的rpc调用return invoker.invoke(invocation);}catch (Exception e){LOGGER.error("rpcContext get traceId exception:",e);return null;}finally {TraceIdUtil.clear();}}
}

提供者端SPI扩展相同

此外:1、Log4j2需要解析自定义的traceId标签,可以用%X{traceId}打印

           2、resources目录下文件路径注意com.alibaba还是apache dubbo,请与依赖保持一致

 至此,问题修复完成。

代码上线后,发现问题依然存在。(上述方案仅可在一定程度上避免,并不能完全修复)

修复方案二:

再次排查发现,原来是im接口有另一个实现也在提供服务,此时找到了问题的元凶,摘除该无用实现问题解决。(也可考虑group隔离,因为另一实现无用,因此摘除)

经验总结:im的另一实现是前几天上线一新功能随之发布的,因为dubbo接口默认路由的随机性及测试账号的历史原因,导致该问题在测试过程未被发现。实际上当我们上线任何新功能,都应该全面进行评估上线代码是否会对老功能造成影响,而不应该只局限在眼前的需求,从而造成更大的损失。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/343925.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AOT-GAN-for-Inpainting项目解读|使用AOT-GAN进行图像修复

项目地址&#xff1a; https://github.com/researchmm/AOT-GAN-for-Inpainting 基于pytorch实现 论文地址&#xff1a; https://arxiv.org/abs/2104.01431 开源时间&#xff1a; 2021年 项目简介&#xff1a; AOT-GAN-for-Inpainting是一个开源的图像修复项目&#xff0c;其对 …

计算机毕业设计----Springboot超市订单管理系统

项目介绍 该超市订单管理毕业设计基于jdk8版本开发&#xff0c;在部署时需要使用jdk8以上的版本。使用了目前流行的框架组合springbootmybatis的框架技术&#xff0c; 实现了供应商管理对供应商实现增删改查、订单管理对超市订单实现增删改查、用户管理等功能&#xff0c;适用…

二十三、关于vite项目中无法使用minio的解决方案

问题背景 项目需要上传大文件,既然是大文件,如果一次性进行读取发送、接收都是不可取的,很容易导致内存问题。所以对于大文件上传,就一定要实现切片上传、断点续传。如果自己实现相对比较麻烦,但好消息是我们的文件服务使用了开源的minio作为对象存储服务,并且minio也提…

如何使用CentOS系统中的Apache服务器提供静态HTTP服务

在CentOS系统中&#xff0c;Apache服务器是一个常用的Web服务器软件&#xff0c;它可以高效地提供静态HTTP服务。以下是在CentOS中使用Apache提供静态HTTP服务的步骤&#xff1a; 1. 安装Apache服务器 首先&#xff0c;您需要确保已安装Apache服务器。可以使用以下命令安装Ap…

Linux第29步_虚拟机连接(与主机断开连接)U盘选项为灰色解决方法

在WIN11中&#xff0c;虚拟机“连接(与主机断开连接)U盘”选项为灰色&#xff0c;解决方法如下&#xff1a; 1、关闭虚拟机电源&#xff0c;得到下面的界面&#xff1a; 2、根据上述提示&#xff0c;找到虚拟机所在磁盘 3、配置文件属性见下图&#xff1a; 4、使用记事本打开…

Tomcat性能优化学习

Tomcat 服务器是一个开源的轻量级Web应用服务器&#xff0c;在中小型系统和并发量小的场合下被普遍使用&#xff0c;是开发和调试Servlet、JSP 程序的首选。相信大家对于 Tomcat 已经是非常熟悉了&#xff0c;本篇将介绍tomcat的常见优化。那么为什么要对tomcat进行优化呢。因为…

Qt QGraphicsItem获取鼠标位置对应图像坐标

本次使用了QGraphicsView来加载图像&#xff0c;然后给其设置了一个QGraphicsScene场景&#xff0c;再给场景添加了一个自定义的QGraphicsItem&#xff0c;在其中重写了paint事件&#xff0c;用来重绘图像。 正常情况时&#xff0c;QGraphicsItem上图像的有效区域QRect大小和QG…

【DotNetGuide】C#/.NET/.NET Core学习、工作、面试指南

&#x1f431;‍&#x1f680;C#/.NET/.NET Core学习、工作、面试指南 “ 让现在的自己不再迷茫✨✨✨。 GitHub开源地址&#xff1a;https://github.com/YSGStudyHards/DotNetGuide &#x1f4da;DotNetGuide简介 现如今网上关于Java、前端、Android、Golang...等相关技术的…

ssm基于Javaweb的网上奶茶店系统的设计与实现论文

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

Tomcat基础升华学习

01 What is Tomcat 1.1 Tomcat官网 官网 &#xff1a;https://tomcat.apache.org 1.2 Understand 为什么说Tomcat是Servlet之类技术的实现&#xff1f; 在我们的理解中&#xff0c;Tomcat可以称为Web容器或者Servlet容器 不妨通过手写一个Tomcat来推导一下 1.2.1 创建Tomc…

AI智能分析网关V4:太阳能+4G智慧水库远程可视化智能监管方案

一、背景需求分析 由于水库位置分散的原因&#xff0c;水库视频监控建设在立杆、布线等方面都存在一定的难度&#xff0c;且需要人力、物力的前期投入和后期维护。目前水库的监管存在一定的问题&#xff0c;管理人员工作强度大但管理质量并不高&#xff0c;人为巡检无法实时发…

Maven_下载_安装_配置

文章参考&#xff1a;https://zhuanlan.zhihu.com/p/615382243 Maven简介 Maven 是 Apache 软件基金会的一个开源项目,是一个优秀的项目构建工具,它用来帮助开发者管理项目中的 jar,以及 jar 之间的依赖关系、完成项目的编译、测试、打包和发布等工作。 maven优点&#xff1a;…