文档章节

dubbo服务中的hessian序列化工厂使用hashmap加锁在高并发场景下的问题

杨武兵
 杨武兵
发布于 2015/06/12 17:30
字数 696
阅读 629
收藏 5

1.问题描述

我们在对5个dubbo接口并发进行测试,总共线程数是64个,不停的调用这些接口。观察到的异常显现是TPS波动较大,时高时低。

我们观察线程的运行状况是这样的:

上图红色部分是线程阻塞的情况。

我们查看线程栈的信息发现有20多个用户线程处于Blocked状态,blocked状态的代码如下:

"DubboServerHandler-192.168.183.17:20880-thread-200" daemon prio=10 tid=0x00007fc0e802b800 nid=0x6a8f waiting for monitor entry [0x00007fbf25bda000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.jd.com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:164)
    - locked <0x00000000c35af008> (a java.util.HashMap)
    at com.alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:406)
    at com. alibaba.com.caucho.hessian.io.CollectionSerializer.writeObject(CollectionSerializer.java:102)
    at com. alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:408)
    at com. alibaba.com.caucho.hessian.io.JavaSerializer$FieldSerializer.serialize(JavaSerializer.java:313)
   

 

这说明如果该服务在该并发下还是会出现用户线程阻塞在代码

at com.alibaba.com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:164)处的情况,对于服务的稳定性和TPS都会造成一定的影响。

2.问题分析

根据上述日志的分析,我们定位到了线程锁部分的代码,我们打开该代码如下所示:

if (_cachedSerializerMap != null) {
    synchronized (_cachedSerializerMap) {
  serializer = (Serializer) _cachedSerializerMap.get(cl);
    }

可以看到此处使用了HashMap,在并发读写map的代码的地方都添加了synchronized 关键字。而本问题也就是在该处BLOCKED了。如果并发较大的时候,线程释放锁的速度赶不上线程争夺资源的速度就会导致用户线程的锁定。

3.优化方案

在高并发的场景下,Hashmap+synchronized的锁的粒度太大,直接锁定了整个HashMap对象,那么我们可以用 ConcurrentHashMap来降低锁的粒度,这样并发处理能力就能够增强。

我在搜索类SerializerFactory的时候,也正好搜索到了hessian-4.0.7.jar中也有这个类,应该是dubbo从hessian里移植过来的另一个类。在这个版本里它就将HashMap替换为ConcurrentHashMap,

它替换之后的代码是这样的:

private ConcurrentHashMap _cachedSerializerMap;
private ConcurrentHashMap _cachedDeserializerMap;
 
  Serializer serializer;
  if (_cachedSerializerMap != null) {
    serializer = (Serializer) _cachedSerializerMap.get(cl);
    if (serializer != null)
      return serializer;
  }

它的区别就是使用ConcurrentHashMap ,去除了synchronized 关键字。

接下来我们也做这样的修改,替换jar包之后,再对服务进行一次压测,结果如下:

1.线程中无Blocked状态的用户线程。

2.TPS更加稳定。

TPS变得更加稳定,没有较大的波动。

从测试来看这种优化之后是有实际效果的,dubbo服务的并发能力明显增强了许多。

 

总结:

对于并发较高的dubbo服务,若希望提高并发处理能力,则应该做这样的优化。

© 著作权归作者所有

共有 人打赏支持
杨武兵

杨武兵

粉丝 255
博文 61
码字总数 123254
作品 1
昌平
架构师
私信 提问
加载中

评论(2)

小小小七
小小小七
非常好的文章,解除了我心中的疑惑。
279217639
279217639
备战一线互联网公司Java工程师面试题 (2)

JVM 1、请介绍一下JVM内存模型??用过什么垃圾回收器都说说呗 2、线上发送频繁full gc如何处理? CPU 使用率过高怎么办? 如何定位问题?如何解决说一下解决思路和处理方法 3、知道字节码吗?字节...

j4love
2018/04/14
0
0
dubbo典型协议、传输组件、序列化方式组合性能对比测试

前言 Dubbo作为一个扩展能力极强的分布式服务框架,在实现rpc特性的时候,给传输协议、传输框架和序列化方式提供了多种扩展实现,供开发者根据实际场景进行选择。 1、支持常见的传输协议:R...

杨武兵
2016/06/13
2.6K
6
Dubbo使用

入门 (+) (#) 背景 (#) 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。 单...

村长大神
2016/09/18
2.1K
1
阿里优酷面试经历——学无止境

最近几周与阿里的面试官聊了聊,趁着我还有记忆先写下来。本人近5年工作的JAVA程序员,技术不精。大伙不必太过吐槽。哈哈。我曾两次时间投过简历。 》2013年 第一次是在2013年的时候,当时工...

风铃无声江舟听雨
2017/11/07
0
0
hessian隐式传参

背景 web应用的项目:分表现层portal端和业务服务层service端,使用dubbo框架,rpc使用hessian。dubbo里的dubbo协议因为是socket长连接可以attachment隐式带参数,hessian协议则不能attachm...

v1-alpha
2016/03/07
29
0

没有更多内容

加载失败,请刷新页面

加载更多

zookeeper和HBASE总结

zookeeper快速上手 zookeeper的基本功能和应用场景 zookeeper的整体运行机制 zookeeper的数据存储机制 数据存储形式 zookeeper中对用户的数据采用kv形式存储 只是zk有点特别: key:是以路径...

瑞查德-Jack
47分钟前
1
0
Oracle 查询时间在当天的数据

要实现这个功能需要用到trunc这个函数对时间的操作select trunc(sysdate) from dual --2014-12-27 今天的日期为2014-12-27select trunc(sysdate, 'mm') from dual --2014-12-1 ......

覃光林
48分钟前
1
0
阿里技术专家详解 Dubbo 实践,演进及未来规划

作者:曹胜利 链接:https://www.infoq.cn/article/IwZCAp3jo_H5fJFbWOZu?utm_source=tuicool&utm_medium=referral Dubbo 整体介绍 Dubbo 是一款高性能,轻量级的 Java RPC 框架。虽然它是以...

Java干货分享
52分钟前
1
0
深入解读阿里云数据库POLARDB核心功能物理复制技术

日志是数据库的重要组成部份,按顺序以增量的方式记录了数据库上所有的操作,日志模块的设计对于数据库的可靠性、稳定性和性能都非常重要。 可靠性方面,在有一个数据文件的基础全量备份后,...

阿里云官方博客
55分钟前
1
0
Python数据科学环境:Anaconda 了解一下

几乎所有的 Python 学习者都遇到过“安装”方面的问题。这些安装问题包括 Python 自身环境的安装、第三方模块的安装、不同版本的切换,以及不同平台、版本间的兼容问题等。当你因为这些问题而...

crossin
56分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部