记低版本okhttp超时会导致死锁
一、问题起源
在处理一次生产环境cpu拉满问题时,把日志拉下来看发现很多http请求调用出错,项目使用的是okhttp 3.8.1版本。
二、问题描述
问题出在okhttp3.Dispatcher.finished(Dispatcher.java:201)
代码如下:
void finished(AsyncCall call) {finished(runningAsyncCalls, call, true);
}
void finished(RealCall call) {finished(runningSyncCalls, call, false);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {int runningCallsCount;Runnable idleCallback;synchronized (this) { //201行if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");if (promoteCalls) promoteCalls();runningCallsCount = runningCallsCount();idleCallback = this.idleCallback;}if (runningCallsCount == 0 && idleCallback != null) {idleCallback.run();}
}private void promoteCalls() {if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {AsyncCall call = i.next();if (runningCallsForHost(call) < maxRequestsPerHost) {i.remove();runningAsyncCalls.add(call);executorService().execute(call);}if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.}
}
三、分析代码
在OkHttpClient中final Dispatcher dispatcher;
作为成员对象,而我们代码中OkHttpClient作为连接池是单例的,这里是对dispatcher做synchronized。
追踪代码发现,在finished的调用方法中,我们方法中使用的是异步AsyncCall
,而这里synchronized
方法中的promoteCalls
被置为true。所以会调用promoteCalls()
方法, 而promoteCalls()
方法中会继续调用executorService().execute(call);
,就是这里,问题大了,synchronized
中执行http请求,那上面代码中的超时不就长时间占用锁了?怪不得进程blocked了。
关于线程的BLOCKED,需要知道:
- java.lang.Thread.State: BLOCKED:等待监视器锁而被阻塞的线程的线程状态,当进入 synchronized 块/方法或者在调用 wait()被唤醒/超时之后重新进入 synchronized 块/方法, 但是锁被其它线程占有,这个时候被操作系统挂起,状态为阻塞状态。若是有线程长时间处于 BLOCKED 状态,要考虑是否发生了死锁(deadlock)的情况。
- blocked的线程不会消耗cpu,但频繁的频繁切换线程上下文会导致cpu过高。线程被频繁唤醒,而又由于抢占锁失败频繁地被挂起. 因此也会带来大量的上下文切换, 消耗系统的cpu资源。
四、解决方案
okttp关于这个问题已经有过解答:
Dispatcher no longer has quadratic behaviour by iamdanfox · Pull Request #4581 · square/okhttp · GitHub
[improvement] okhttp 3.12.0 -> 3.13.1, to pick up perf improvements to okhttp3.Dispatcher by iamdanfox · Pull Request #940 · palantir/conjure-java-runtime · GitHub
解决方案就简单多了:升级okhttp到3.14.9,虽然目前最新稳定版本为4.9.3,但是OkHttp 4发布,从Java切换到Kotlin。谨慎一点,还是小版本升级吧。
在3.14.9中,这部分代码被优化为:
private boolean promoteAndExecute() {assert (!Thread.holdsLock(this));List<AsyncCall> executableCalls = new ArrayList<>();boolean isRunning;synchronized (this) {for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {AsyncCall asyncCall = i.next();if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.i.remove();asyncCall.callsPerHost().incrementAndGet();executableCalls.add(asyncCall);runningAsyncCalls.add(asyncCall);}isRunning = runningCallsCount() > 0;}for (int i = 0, size = executableCalls.size(); i < size; i++) {AsyncCall asyncCall = executableCalls.get(i);asyncCall.executeOn(executorService());}return isRunning;
}
执行HTTP请求被移出了synchronized方法了。
相关文章:
记低版本okhttp超时会导致死锁
一、问题起源 在处理一次生产环境cpu拉满问题时,把日志拉下来看发现很多http请求调用出错,项目使用的是okhttp 3.8.1版本。 二、问题描述 问题出在okhttp3.Dispatcher.finished(Dispatcher.java:201)代码如下: void finished(AsyncCall c…...

idea必装的插件 Spring Boot Helper 插件(创建 Spring Boot 项目)
Spring Spring让Java程序更加快速,简单和安全.Spring对于速度、简单性和⽣产⼒的关注使其成为 世界上最流⾏的Java框架。Spring官⽅提供了很多开源的项⽬,覆盖范围从Web开发到⼤数据,Spring发展到了今天,已经形成了⾃ ⼰的⽣态圈.我们在开发时,也倾向于使⽤Spring官⽅提供的技术…...

Scrum(敏捷开发)的前端定位
1. Scrum(敏捷开发)的开发流程 Scrum将整个开发过程分为多次迭代(称为Sprint,冲刺),一般为期2~4周,最常见的为2周。Scrum并非以一段时间集中完成一个过程,而是将所有过程中必须的每一部分集中在这段时间内完成。需求、设计、编码、测试、上线都必须在一个迭代中完成,每…...
uniapp缓存对象数组
需求:使用uniapp,模拟key(表名)增删改查对象数组,每个key可以单独操作,并模拟面对对象对应表,每个key对应的baseInstance 类似一个操作类,当然如果你场景比较简单,可以改…...

腾讯云优惠券免费领取入口整理分享
腾讯云作为国内领先的云服务提供商,为了回馈用户的支持和信任,经常推出各种优惠活动,并提供优惠券供用户使用。本文将整理和分享腾讯云优惠券的免费领取入口,帮助用户在购买腾讯云产品时享受更多的优惠和福利。 一、腾讯云优惠券介…...

功率放大器在PZT陶瓷薄膜压电传感器研究中的应用
随着科技的进步和工业发展的需求,对于压力测量和控制的需求日益增加。压力传感器作为一种关键的传感器器件,在机械、自动化、医疗、航空等多个领域都有广泛应用。PZT陶瓷薄膜压电传感器由于其响应速度快、精度高、稳定性好等优点,成为了许多应…...

Anaconda创建新的虚拟环境及Jupyter Notebok中、PyCharm中环境的使用
Anaconda创建新的虚拟环境 在windows开始菜单中【徽标键】,查找Anaconda文件夹并打开【Anaconda Prompt】 查看已有虚拟环境 conda env list1.创建 conda create --name mytest python3.7 # 创建一个名称为mytest,python版本为3.7的虚拟环境输入【…...
[QT] 如果你怎么试HTTP下载文件得到的QNetworkReply的readAll()都是空数据(长度为0),请看这里
1,首先你对比看看QT官方给出的例子 Download Data from URL - Qt Wiki 2,再看看是不是要设置重定向,如果要,要设置一下 QNetworkRequest request(imageUrl); request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, …...

使用docker部署flask接口服务 一
文章目录 一:说明二:dockerfile 参数说明1. 一般常用的 参数,以及它的含义2. 我自己的 dockerfile 三:示例操作1. Gunicorn Gevent启动服务的好处2. 用Gunicorn Gevent的好处:3. Gunicorn Gevent的 使用示例4. 创建…...

超实用的跟圈和一键转发好友朋友圈功能
一键转发朋友圈/跟圈 想转发别人的朋友圈内容,通常需要手动复制粘贴,一个个复制保存实在是太麻烦耗费时间。 有时候咱也不可能随时都看朋友圈嘛,那又想及时转发朋友的圈的,有什么办法可以轻松实现呢? 操作步骤 单击…...

口袋参谋:如何一键获取竞品数据?这招实用!
在淘宝天猫上开店,市场竞争日益激烈,想要做好店铺,我们就不得不去分析竞品的数据了。 很多卖家开店后,一上来就直接卡在类目前10,折腾了一两个月才发现自己对标错了对象,最终竹篮打水一场空。 所以&…...
python 生成html文件并端口展示
1.生成相关的html文件 import json import os import calc import requests import numpy as npwith open(picture, r,encodingutf-8) as f:lines f.readlines() html <html>\n<html lang"zh">\n<head>\n<meta charset"UTF-8">…...

二进制部署 Kubernetes(master和node)
二进制搭建 Kubernetes v1.20 k8s集群master01:20.0.0.101 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群master02:20.0.0.106 k8s集群node01:20.0.0.102 kubelet kube-proxy docker k8s集群node02:20.0…...

【计算机网络】IP协议的相关特性
IP协议:互联网的核心组件 在当今高度数字化的世界中,互联网已成为人们生活、工作不可或缺的一部分。而在这个庞大的网络中,IP协议(Internet Protocol)作为核心的通信协议,发挥着至关重要的作用。本文将详细…...

如何在Potplayer中使用公网访问群晖WebDav?
文章目录 1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透,映射至公网5 使用固定地址在potplayer访问webdav 国内流媒体平台的内容让人一言难尽,就算是购买了国外的优秀作品,也总是在关键剧情上删删…...
如果你有一台服务器,你最想做那些事?
如果有一台服务器,可以做很多有趣的事情。本文将介绍服务器的基本知识,假设你拥有一台服务器后该如何使用它,以及管理服务器的最佳实践。 首先,让我们了解一下什么是服务器。服务器是指在网络上提供各种服务的计算机,如…...

Unity中Shader的Fallback
文章目录 前言一、解决 Pass 复用的方案方案一:使用之前的UsePass方案,把ShadowCaster的Pass提出来到一个单独的Shader中,在使用的时候直接使用 UsePass方案二:使用Fallback功能 前言 Unity中Shader的Fallback,我们在…...

“菜鸟”程序员逆袭:独立开发iOS音乐应用,年底参加Amazon DeepRacer 全球锦标赛
“致一年前的小木土:任务完成。” 6月30日,在获得2023 Amazon DeepRacer自动驾驶赛车企业总决赛中国区冠军三天后的深夜,杜键文发了这条朋友圈,并配上比赛现场的9张图。 “小木土”是杜键文的网名,取其姓氏ÿ…...
nginx测试rewrite
nginx测试rewrite last :相当于 Apache 里的(L)标记,表示完成rewrite 匹配; break: 本条规则匹配完成后,终止匹配,不再匹配后面的规则。 # 其中last 和 break 用来实现 URL 重写时,浏览器地址栏URL 地址不变 redirect: 返回 302 …...

qt 多语言版本 QLinguist使用方法
在使用qt开发一款软件时,可能需要考虑显示文本中英文等多语言版本。可以使用qt语言家的方式实现。 步骤: 1、代码中给控件设置文本时,记得带上QObject::tr() 2、工程pro文件中加入 TRANSLATIONS demo2_en.ts 3、Qt creator点击“工具”—“外…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...