java项目线上捉BUG经验记录

一 线上问题

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

二 线上分析

1 查项目运行日记

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

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

2 查服务器流量:

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

 

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

3 查项目运行状态:

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

在升高的时候查看栈信息

jstack 22561 |grep 'pole'

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

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

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

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

 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秒以上延迟),交由专门的任务线程处理,代码修改后:

      try {String txtTime = org_hex.concat("$$").concat(time);MemDataTable.HEX_PUSH_HEX.offer(txtTime);return true;} catch (Exception e) {logger.error("分发报文错误", e);return false;}
  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后,各服务配置修改重新发布上线,

小结

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

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

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

相关文章

获取C语言语句对应的汇编码和机器指令

借助IDE的调试功能 以CodeBlocks为例&#xff0c;先设置断点&#xff0c;然后点击红色三角形调试。 然后选择Debug➡ Debugging Windows➡Disassembly 就可以看到了 使用命令行 在工程文件中&#xff0c;一般可以找到一个.o文件。如果没有&#xff0c;可以先在program.c的目录下…

c++提高部分

c++提高部分 这部分主要涉及泛型编程和STL技术 1. 模版 1.1 模版的概念 模版就是通用的模具,大大提高复用性,但需要根据需求改动一些东西 1.2 函数模版 c++另一种编程思想为泛型编程,主要利用的技术就是模版c++提供两种模版机制:函数模板和类模板1.2.1 函数模板语法 …

NFT Insider #122:OpenSea与科切拉音乐节合作推出NFT系列,Flowty联合创始人购入勒布朗・詹姆斯NFT

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members (https://twitter.com/WHALEMembers)、BeepCrypto (https://twitter.com/beep_crypto) 联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据&a…

【Spring云原生系列】Spring RabbitMQ:异步处理机制的基础--消息队列 原理讲解+使用教程

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…

代码随想录第52天| ● 392.判断子序列 ● 115.不同的子序列

文章目录 ● 392.判断子序列思路代码&#xff1a; ● 115.不同的子序列思路&#xff1a;代码&#xff1a; ● 392.判断子序列 思路 递推顺序&#xff1a;从上到下 从左到右 代码&#xff1a; class Solution {public boolean isSubsequence(String s, String t) {int[][]dpn…

js【详解】event loop(事件循环/事件轮询)

event loop 是异步回调的实现原理 js 代码的执行过程 从前到后&#xff0c;一行一行执行如果某一行执行报错&#xff0c;则停止下面代码的执行先把同步代码执行完&#xff0c;再执行异步 event loop 图解 以下方代码为例&#xff1a; 第1步 将第 1 行代码放入调用栈 将要执行第…

若依前后端分离版实现excel导入功能

一、引言 本文将根据若依官方文档介绍实现excel表格导入功能,已excel表格批量导入用户为功能点。 若依导入excel文档 二、Vue代码 2.1 用户模块的index.vue中导入getToken方法: import {getToken } from "@/utils/auth";2.2 用户导入参数 // 用户导入参数

模拟实现strlen函数

一、逐个计数法 #include<assert.h> #include<stdio.h>size_t my_strlen(const char* p) {int count 0;assert(p);//断言while (*p ! \0){p;count;}return count; }int main() {char str[] "hello world";size_t len my_strlen(str);printf("%d…

finishConnect(..) failed: Connection refused,服务本地正常服务器网关报400,nacos服务实例不能下线

①application里固定ip # Spring spring:cloud:inetutils:preferred-networks: 127.0.0.1 ②找到nacos服务下的protocol&#xff0c;删除下面所有&#xff0c;/nacos-server/data/protocol&#xff0c;删了不会有问题&#xff0c;而且这东西越用越大&#xff0c;删了好爽 ③重…

05-调用API

上一篇&#xff1a; 04-JNI函数 调用 API 允许软件供应商将 Java VM 加载到任意本地应用程序中。供应商可以提供支持 Java 的应用程序&#xff0c;而无需链接 Java VM 源代码。 5.1 概述 下面的代码示例说明了如何使用调用 API 中的函数。在这个示例中&#xff0c;C 代码创建了…

想开发苹果群控软件?先了解这些代码!

随着智能设备的普及&#xff0c;群控软件的需求日益增加&#xff0c;特别是针对苹果设备的群控软件&#xff0c;因其出色的性能和广泛的用户基础&#xff0c;受到了开发者们的青睐。 然而&#xff0c;开发一款功能强大的苹果群控软件并非易事&#xff0c;需要深入了解苹果的开…

配电网数字化转型全面推进:《关于新形势下配电网高质量发展的指导意见》

近日&#xff0c;国家发展改革委、国家能源局印发了《关于新形势下配电网高质量发展的指导意见》&#xff08;以下简称《意见》&#xff09;&#xff0c;到2030年&#xff0c;基本完成配电网柔性化、智能化、数字化转型&#xff0c;实现主配微网多级协同、海量资源聚合互动、多…