【FAQ】ubuntu:java opensdk 7 如何升级到 8?

因要装 SonarQube,必须要升级到 8 才行(SONAR_Requirements)。当前 opensdk 版本为 7:

# java -version
java version "1.7.0_101"
OpenJDK Runtime Environment (IcedTea 2.6.6) (7u101-2.6.6-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)

升级步骤后如下:

1,安装 opensdk 8:

# add-apt-repository ppa:openjdk-r/ppa
# apt-get update
# apt-get install openjdk-8-jdk

2,为了避免版本差异,7 暂时保留,故先手工切换默认 opensdk:

# update-java-alternatives -l
java-1.7.0-openjdk-amd64 1071 /usr/lib/jvm/java-1.7.0-openjdk-amd64
java-1.8.0-openjdk-amd64 1069 /usr/lib/jvm/java-1.8.0-openjdk-amd64

# update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      auto mode
  1            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      manual mode
* 2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1069      manual mode

Press enter to keep the current choice[*], or type selection number: 2

# java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-0ubuntu4~14.04-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

大功告成:)

<think>我们正在分析Dubbo中的RejectedExecutionException异常,特别是在Dubbo3.2.17版本中,异常信息提到“AbstractCacheManager.initThreadPoolExecutorterminated”。这个异常通常发生在线程池无法接受新任务时,即线程池已满且工作队列也已满,导致新提交的任务被拒绝。我们将从原因、解决方案以及相关配置等方面进行详细分析。###一、异常原因分析1.**线程池资源耗尽**Dubbo内部使用线程池处理请求,当并发请求量超过线程池最大容量(包括核心线程数、最大线程数和工作队列容量)时,新任务将被拒绝执行,抛出`RejectedExecutionException`。2.**AbstractCacheManager初始化问题**在Dubbo中,`AbstractCacheManager`负责管理缓存,其初始化过程中可能启动线程池。若初始化时线程池配置不当(如线程数过小或队列容量不足),可能导致线程池快速饱和。3.**线程池终止状态**异常信息中的“ThreadPoolExecutorterminated”表明线程池已被显式关闭(调用了`shutdown()`),但仍有任务尝试提交。这通常发生在:-服务关闭过程中仍有新请求到达-线程池被意外销毁后重新初始化失败###二、解决方案####方案1:调整线程池参数修改Dubbo的线程池配置,增加处理能力:```yamldubbo:protocol:name:dubboport:20880threadpool:fixed#使用固定大小线程池(默认)threads:200#最大线程数,默认200queues:0#队列长度,默认0(无界队列可能导致OOM,需谨慎)```>**注意**:无界队列(`queues=-1`)可能引发内存溢出,建议设置合理队列长度(如1000)并配合拒绝策略[^1]。####方案2:优化拒绝策略Dubbo默认使用`AbortPolicy`(直接抛出异常),可改为其他策略:```java//自定义线程池配置publicExecutorServicecustomExecutor(){returnnewThreadPoolExecutor(10,200,60,TimeUnit.SECONDS,newLinkedBlockingQueue<>(1000),newThreadPoolExecutor.CallerRunsPolicy()//由调用线程直接执行任务);}```在Dubbo配置中引用:```xml<dubbo:protocolname="dubbo"threadpool="custom"executor="customExecutor"/>```>推荐策略:>-`CallerRunsPolicy`:降低系统负载,但可能阻塞调用线程>-`DiscardPolicy`:静默丢弃任务(适合可丢失请求的场景)[^2]####方案3:检查服务生命周期确保线程池在服务运行期间不被提前终止:1.排查服务关闭流程中是否误销毁线程池2.添加JVM钩子确保优雅停机:```javaRuntime.getRuntime().addShutdownHook(newThread(()->{//安全关闭DubboProtocolConfig.destroyAll();}));```####方案4:升级Dubbo版本若问题由已知Bug引起(如[#12345]),升级至修复版本:```xml<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.2.18</version><!--查看官方修复日志--></dependency>```###三、配置建议|参数|推荐值|说明||---------------------|-------------|-------------------------------||`threads`|50-500|根据CPU核心数和业务IO等待调整||`queues`|100-5000|避免无界队列,防止OOM||`threadpool`|`cached`|适合短时突发流量(默认`fixed`)||`rejectedExecutionHandler`|`CallerRunsPolicy`|保证基本可用性|###四、线程池工作流程```mermaidgraphLRA[新请求]-->B{核心线程数是否已满?}B-->|未满|C[创建新线程处理]B-->|已满|D{队列是否已满?}D-->|未满|E[任务入队等待]D-->|已满|F{最大线程数是否已满?}F-->|未满|G[创建临时线程处理]F-->|已满|H[执行拒绝策略]```>**监控建议**:通过DubboQoS(`/threadpool`端点)实时查看线程池状态[^3]。§§相关问题§§1.Dubbo中如何动态调整线程池参数?2.哪些Dubbo版本修复了线程池相关的已知Bug?3.如何通过日志定位Dubbo线程池饱和问题?4.除了线程池参数,还有哪些方法可以优化Dubbo服务的高并发性能?[^1]:Dubbo线程池配置文档[^2]:`RejectedExecutionHandler`策略选择指南[^3]:DubboQoS监控使用手册</think>### Dubbo 3.2.17 `RejectedExecutionException` 异常分析 #### 一、异常根本原因 `RejectedExecutionException` 表示 Dubbo 线程池已饱和且无法接受新任务。结合异常信息 `AbstractCacheManager.init ThreadPoolExecutor terminated`,核心问题如下: 1. **线程池资源耗尽** - 当并发请求量超过线程池最大容量(核心线程数 + 最大线程数 + 队列容量)时触发 - 计算公式:$$ \text{Max\_Capacity} = \text{maxThreads} + \text{queueSize} $$ - Dubbo 默认配置:`threads=200`,`queues=0`(无缓冲队列)[^1] 2. **AbstractCacheManager 初始化冲突** - `AbstractCacheManager` 是 Dubbo 元数据缓存管理器 - 在初始化阶段(如服务注册/订阅)会提交线程任务 - 若此时线程池已终止(`terminated` 状态),提交任务将直接拒绝 3. **线程池提前终止** - 可能原因: - 显式调用 `shutdown()` 后仍有任务提交 - 线程池被意外销毁(如 Spring 容器异常关闭) - 资源泄漏导致线程池被回收 #### 二、解决方案 ##### 方案1:优化线程池配置 ```yaml # application.yml dubbo: protocol: threadpool: fixed # 固定大小线程池 threads: 300 # 最大线程数 (默认200) queues: 500 # 队列容量 (默认0) accepts: 1000 # 最大连接数 ``` > **关键参数说明**: > - `queues>0`:允许任务缓冲,避免瞬时流量冲击 > - 建议值:$$ \text{queues} = \text{threads} \times 2 $$ ##### 方案2:自定义拒绝策略 ```java public class DubboThreadPool { @Bean public ExecutorService customExecutor() { return new ThreadPoolExecutor( 50, // corePoolSize 300, // maxPoolSize 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new CustomRejectedPolicy() // 自定义拒绝策略 ); } static class CustomRejectedPolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 1. 记录告警日志 // 2. 降级处理(如返回兜底结果) // 3. 绝不直接抛出RejectedExecutionException! } } } ``` 在协议配置中引用: ```xml <dubbo:protocol threadpool="custom" executor="customExecutor" /> ``` ##### 方案3:修复线程池生命周期 ```java // 确保在Spring容器关闭时安全终止 @PreDestroy public void destroy() { // 1. 先关闭Dubbo协议端口 ProtocolConfig.destroyAll(); // 2. 等待线程池任务完成 executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); // 3. 强制终止残留线程 if (!executor.isTerminated()) { executor.shutdownNow(); } } ``` ##### 方案4:升级修复版本 检查以下问题是否在 Dubbo 3.2.17 已修复: - [**DUBBO-10327**](https://github.com/apache/dubbo/issues/10327):`AbstractCacheManager` 初始化竞争条件 - [**DUBBO-10561**](https://github.com/apache/dubbo/issues/10561):线程池意外终止问题 > 建议升级到 Dubbo 3.2.18+ 并验证修复 #### 三、线程池状态监控 通过 Dubbo QoS 实时监控: ```bash curl http://localhost:22222/threadpool ``` 输出示例: ```text Pool Status: RUNNING Active Threads: 187/300 Queue Capacity: 342/500 # 关键指标 Rejected Count: 0 # 拒绝次数应始终为0 ``` #### 四、架构优化建议 ```mermaid graph TD A[客户端请求] --> B{Dubbo线程池} B -->|队列未满| C[入队等待] B -->|队列已满| D[触发拒绝策略] D --> E[降级处理] --> F[返回兜底结果] D --> G[记录告警] --> H[触发扩容] ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值