公司内某开放平台集群服务出现了些许用户投诉,起初我们不以为意,直到看到了一个很有意思的用户反馈。
开放平台会给根据用户的行为不同推送消息,本来按照正常逻辑,A消息推送永远都会在B消息之前的。 但是用户反馈先收到的B消息,大约十分钟之后收到的A消息,这就有问题了。
我们的消息都是走的kafka,看了下日志的确发生了B消息先推送,A消息后推送的情况,这就不科学了。
首先想到的就是kafka消息积压了,因为A,B两种消息不在一个topic
看了下集群里的机器都会陆续出现CPU暴涨的情况,而且居高不下,一个个接着出现这种情况,
马上看zabbix,找到CPU暴涨的时间段的机器查看它的jstack日志
发现了那台机器有166个RUNNABEL的一样的堆栈信息,别的时间段CPU暴涨的机器的jstack日志也有一模一样的这样的日志,平均都是160+左右。
"pool-5-thread-95881" #174383 prio=5 os_prio=0 tid=0x00007 nid=0xce runnable [0x0000010] java.lang.Thread.State: RUNNABLE at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at com.thoughtworks.xstream.XStream.registerConverterDynamically(XStream.java:929) at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:898) at com.thoughtworks.xstream.XStream.(XStream.java:574) at com.thoughtworks.xstream.XStream. (XStream.java:496) at com.thoughtworks.xstream.XStream. (XStream.java:465) at com.thoughtworks.xstream.XStream. (XStream.java:411) at com.thoughtworks.xstream.XStream. (XStream.java:350) at com.xx.xxx.xxxx.util.XmlUtil.xml2Object(XmlUtil.java:13) ......
马上找到这个 XmlUtil
的代码。
......XStream xstream = new XStream();......return xstream.fromXML(inputXml);
XStream是线程安全的,不需要重复初始化xstream对象,每一种类型实例化一个对象即可,而正是由于开发人员错误地在每次处理时都实例化一个新的xstream对象,才导致了该问题
只需要将它写成一个单例就好了。
XStream xstream = XStreamUtil.getInstance();
至于 getInstance()
单例怎么写,在这里就不叙述了。