您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

Dubbo线程池调优

时间:2021-05-18 12:05:07  来源:知否网  作者:

1. Dubbo简介及线程池策略

Apache Dubbo 是一款高性能、轻量级的开源 JAVA 服务框架。提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。Dubbo之前是阿里开发,并得到广泛的应用,后来贡献给了Apache开源组织。

​ Dubbo默认的底层网络通讯使用的是Netty,服务提供方NettyServer使用两级线程池,其中 EventLoopGroup(boss) 主要用来接受客户端的链接请求,并把接受的请求分发给 EventLoopGroup(worker) 来处理,boss和worker线程组我们称之为IO线程。

​ 如果服务提供方的逻辑能迅速完成,并且不会发起新的IO请求,那么直接在IO线程上处理会更快,因为这减少了线程池调度。但如果处理逻辑很慢,或者需要发起新的IO请求,比如需要查询数据库,则IO线程必须派发请求到新的线程池进行处理,否则IO线程会阻塞,将导致不能接收其它请求。

2. 线程池报警

​ 生产环境,该服务大约QPS在1万左右,总共10个节点。最近该服务在高峰期,频繁触发流控和降级。查看dubbo日志,大量线程池耗尽的警告日志:

WARN  2021-05-11 **:**:** WARN AbortPolicyWithReport:65 -  [DUBBO] Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-**.**.**.**:**, Pool Size: 500 (active: 500, core: 500, max: 500, largest: 500), Task: 1285578 (completed: 1285135), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false)

​ 该服务线程池最大500,通过日志可以看到active线程已经达到500了,线程池耗尽了,这样势必造成请求的积压,触发流控和降级。

3. 问题排查

​ Dubbo可以通过配置,当线程池满时,会dump出JStack日志出来,便于分析排查问题。一般配置如下:

<dubbo:Application name="${server.name}" >
  <dubbo:parameter key="dump.directory"  value="${account.dubbo.dump.directory:/home/dubbo_dump/}${server.name}${server.id}" />
    </dubbo:application>  

​ 默认会输出到/home/java这个目录下。

​ 通过排查日志发现,大量线程是BLOCKED状态的,日志如下:

"DubboServerHandler-ip:port-thread-449" Id=633 BLOCKED on java.util.Collections$SynchronizedMap@2d796a15 owned by "DubboServerHandler-ip:port-thread-203" Id=325
    at java.util.Collections$SynchronizedMap.get(Collections.java:2584)
    -  blocked on java.util.Collections$SynchronizedMap@2d796a15
    at com.google.gson.Gson.getAdapter(Gson.java:332)
    at com.google.gson.Gson.fromJson(Gson.java:802)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    ...

​ 通过查看日志发现,最后问题出现在Gson做json反序列化时造成的。再来查看下Gson的源码发现:

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
    TypeAdapter<?> cached = typeTokenCache.get(type);
    if (cached != null) {
      return (TypeAdapter<T>) cached;
    }
    ...
  }

​ Gson这里是获取适配器,Gson是通过适配器设计模式,问题就出现在获取适配器这里。再来看下typeTokenCache的定义:

  private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache
      = Collections.synchronizedMap(new HashMap<TypeToken<?>, TypeAdapter<?>>());

​ 在早期的JDK版本中,使用线程安全的Map一般都是通过synchronizedMap这种方式,其实底层就是通过synchronized锁实现的。synchronized是互斥锁,也是重量级锁,虽然目前得到很多优化,但是当高并发下,线程获取不到锁,会立马进入BLOCKED状态,这就是Dubbo线程池满的原因。

​ 解决方式如下:

​ 在早期由于没有提供JUI包,也就是ConcurrentHashMap,所以使用synchronizedMap这种方式实现高并发。从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树。相信新的Gson版本肯定会做相应的升级,于是查看Gson的2.8.5版本的源码,果然升级了,源码如下:

private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();

​ 升级Gson到2.8.5版本后,问题解决。

​ 总结,线程池调优,主要关注线程的如下几种状态:

  • 死锁, Deadlock(重点排查)
  • 执行中,Runnable
  • 等待资源, Waiting on condition(重点排查)
  • 等待获取监视器, Waiting on monitor entry(重点排查)
  • 暂停,Suspended
  • 对象等待中,Object.wait() 或 TIMED_WAITING
  • 阻塞, Blocked(重点排查)
  • 停止,Parked


Tags:Dubbo线程池   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1. Dubbo简介及线程池策略Apache Dubbo 是一款高性能、轻量级的开源 Java 服务框架。提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现...【详细内容】
2021-05-18  Tags: Dubbo线程池  点击:(202)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(26)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(55)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条