java项目线上捉BUG经验记录

一 线上问题

昨晚上突然接到公司紧急来电电桩设备大面积离线,意味着某市的车无法充电......",细想这个平台很久都没有更新,最近出现问题是刚好在一个月前也是出现这种情况,再上一次就是几年前更新的。平台平时是稳定,开始找BUG ......

二 线上分析

1 查项目运行日记

整个充电桩平台两台线上云服务器十多个java项目服务开始排查,由于整个项目都是由本人设计并负责核心的开发所以很快就定位服务器和出问题的服务,查该服务日记,发现大量的报错如下图:

看到是MQ报的错,一堆事物未确认回滚的错误,马上想到队列存在积压问题,访问web管理平台查看队列情况,发现阻塞有几千设备发的消息。立马清除通道不保不延迟(设备要求不可以延迟),发现队列恢复正常。观察一几分种后又开始有堆积的现象,消费端出了问题,除了队列异常项目没有明显出错信息。

2 查服务器流量:

查流量,发现网络流量异常如下图:

波动如此大,基本确定与网络传送有关联。在查询端口报文数据分析也排除外网被攻击,很可能是报文实时分发环节出了问题,设备报文发送到另一家公司系统(业务要求桩设备上传的数据,实时上到另外一家公司,用于核查数据)。

3 查项目运行状态:

问题项目cpu每间隔一段时间占用很高如下图:

在升高的时候查看栈信息

bash 复制代码
jstack 22561 |grep 'pole'

说明: jstack 是查看java项目运行中的一些栈信息, grep 是过滤内容,不然输出信息太多看不了这么多,pole是本项目的相关代码内容,如果不了解项目代码也可以用Excption或Error代替。

找到相关代码(太急了没截到图),代码功能正是报文实时分发部分,也与上面流量分析相应证,为了再次确定,马上把分发代码注释,编译打包,重新发布项目后恢复正常。

4 优化代码,顺便解决历史安全问题

在协议处理实时分发关键代码(未修改前):

java 复制代码
 try {
         
            String time=TimeFormatUtils.getTimeStrBy_yyyyMMddHHmmss(now);
            String txtTime=org_hex.concat("$$").concat(time)        
          
            RedisTemplate sec= SecondRedisConnection.getSecondRedisTemplate();
            sec.opsForList().leftPush("PUSH_TO_DB",txtTime);

            return true;
        } catch (Exception e) {
            logger.error("分发报文错误", e);
            return false;
        }

在协议处理实时分发代码分离,不再实时处理(2秒以上延迟),交由专门的任务线程处理,代码修改后:

java 复制代码
      try {


            String txtTime = org_hex.concat("$$").concat(time);
            MemDataTable.HEX_PUSH_HEX.offer(txtTime);
            return true;
        } catch (Exception e) {
            logger.error("分发报文错误", e);
            return false;
        }
java 复制代码
  public final static ArrayBlockingQueue<String> HEX_PUSH_HEX =new ArrayBlockingQueue<String>(300000);

  public static boolean sendDbRedis = true;



 public static long sendErr = 0;
    /**
     * 每2秒执行一次
     */
    @Scheduled(cron = "*/2 * * * * *")
    public void scheduled() {



        if (MemDataTable.HEX_PUSH_HEX.size() > 0) {
            RedisTemplate sec = SecondRedisConnection.getSecondRedisTemplate();

            while (MemDataTable.HEX_PUSH_HEX.peek()!=null) {
                String hex=MemDataTable.HEX_PUSH_HEX.poll();
                if (sendDbRedis) {
                    try {
                        sec.opsForList().leftPush("PUSH_HEX", hex);
                        sendErr=0;
                    } catch (Exception e1) {
                        logger.error("分发报文错误", e1);
                        logger.error("分发报文异常 hex="+hex, e1);

                        if(sendErr>10){
                            sendDbRedis = false;
                            logger.error("分发报文终止 hex="+hex, e1);
                        }
                        sendErr++;
                    }

                }else{
                    logger.error("====================分发报文,放弃:"+MemDataTable.HEX_PUSH_HEX.size());
                    MemDataTable.HEX_PUSH_HEX.clear();
                }
            }

        }

    }

代码分隔后,可以保证第三方网络断开与网络速度慢时影响到平台充电。

另外在修改项目代码准备发布前,想起这个项目用的apacheMQ是2019年安装(当时没有漏洞)在2023年10月份时报出严重漏洞,那时想过修复,跟业务提过,但由于线上不能停机,当时临时处理只配置了防火墙安全策略关了外网访问这些问题端口。开始换MQ后,各服务配置修改重新发布上线,

小结

有些情况不能按业务说得算。不然迟早要爆雷。

相关推荐
AI 编程助手GPT3 小时前
GPT-5.6意外曝光、Claude安全检查全面公测、Grok 4.3搅局价格战——多模型混战的五月,开发者如何避坑?
人工智能·gpt·ai·chatgpt·bug·ai编程
Zxxxxxy_1 天前
测试入门:从 0 到 1 搞懂开发与 Bug
bug
专注VB编程开发20年3 天前
Windows API 所有老式结构体4字节对齐,但是64位VBA,Twinbasic弄成了8字节对齐,大BUG
windows·bug
IT枫斗者4 天前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
半天法师4 天前
Bug 记录:UE 结构体转 JSON 时 Key 字段大小写异常 (Editor 与打包后表现不一致)
ai·ue5·json·bug
张小俊_4 天前
WPF 跨线程 UI 更新与硬编码赋值引发的 Bug 排查
c#·bug·wpf
鸿儒5175 天前
记录一个C++ Windows程序移植到Linux系统的bug
开发语言·c++·bug
Python私教6 天前
HermesAgent 终端工具 Windows 兼容性修复实战:两个 Bug 的排查与解决
windows·bug
瀚高PG实验室6 天前
pgroonga全文检索插件的BUG
数据库·postgresql·bug·瀚高数据库
¥-oriented7 天前
记录使用C#编程中遇到的一个小bug
c#·bug