当前位置: 首页 > news >正文

记低版本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拉满问题时&#xff0c;把日志拉下来看发现很多http请求调用出错&#xff0c;项目使用的是okhttp 3.8.1版本。 二、问题描述 问题出在okhttp3.Dispatcher.finished(Dispatcher.java:201)代码如下&#xff1a; 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缓存对象数组

需求&#xff1a;使用uniapp&#xff0c;模拟key&#xff08;表名&#xff09;增删改查对象数组&#xff0c;每个key可以单独操作&#xff0c;并模拟面对对象对应表&#xff0c;每个key对应的baseInstance 类似一个操作类&#xff0c;当然如果你场景比较简单&#xff0c;可以改…...

腾讯云优惠券免费领取入口整理分享

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

功率放大器在PZT陶瓷薄膜压电传感器研究中的应用

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

Anaconda创建新的虚拟环境及Jupyter Notebok中、PyCharm中环境的使用

Anaconda创建新的虚拟环境 在windows开始菜单中【徽标键】&#xff0c;查找Anaconda文件夹并打开【Anaconda Prompt】 查看已有虚拟环境 conda env list1.创建 conda create --name mytest python3.7 # 创建一个名称为mytest&#xff0c;python版本为3.7的虚拟环境输入【…...

[QT] 如果你怎么试HTTP下载文件得到的QNetworkReply的readAll()都是空数据(长度为0),请看这里

1&#xff0c;首先你对比看看QT官方给出的例子 Download Data from URL - Qt Wiki 2&#xff0c;再看看是不是要设置重定向&#xff0c;如果要&#xff0c;要设置一下 QNetworkRequest request(imageUrl); request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, …...

使用docker部署flask接口服务 一

文章目录 一&#xff1a;说明二&#xff1a;dockerfile 参数说明1. 一般常用的 参数&#xff0c;以及它的含义2. 我自己的 dockerfile 三&#xff1a;示例操作1. Gunicorn Gevent启动服务的好处2. 用Gunicorn Gevent的好处&#xff1a;3. Gunicorn Gevent的 使用示例4. 创建…...

超实用的跟圈和一键转发好友朋友圈功能

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

口袋参谋:如何一键获取竞品数据?这招实用!

​在淘宝天猫上开店&#xff0c;市场竞争日益激烈&#xff0c;想要做好店铺&#xff0c;我们就不得不去分析竞品的数据了。 很多卖家开店后&#xff0c;一上来就直接卡在类目前10&#xff0c;折腾了一两个月才发现自己对标错了对象&#xff0c;最终竹篮打水一场空。 所以&…...

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&#xff1a;20.0.0.101 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群master02&#xff1a;20.0.0.106 k8s集群node01&#xff1a;20.0.0.102 kubelet kube-proxy docker k8s集群node02&#xff1a;20.0…...

【计算机网络】IP协议的相关特性

IP协议&#xff1a;互联网的核心组件 在当今高度数字化的世界中&#xff0c;互联网已成为人们生活、工作不可或缺的一部分。而在这个庞大的网络中&#xff0c;IP协议&#xff08;Internet Protocol&#xff09;作为核心的通信协议&#xff0c;发挥着至关重要的作用。本文将详细…...

如何在Potplayer中使用公网访问群晖WebDav?

文章目录 1 使用环境要求&#xff1a;2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透&#xff0c;映射至公网5 使用固定地址在potplayer访问webdav ​ 国内流媒体平台的内容让人一言难尽&#xff0c;就算是购买了国外的优秀作品&#xff0c;也总是在关键剧情上删删…...

如果你有一台服务器,你最想做那些事?

如果有一台服务器&#xff0c;可以做很多有趣的事情。本文将介绍服务器的基本知识&#xff0c;假设你拥有一台服务器后该如何使用它&#xff0c;以及管理服务器的最佳实践。 首先&#xff0c;让我们了解一下什么是服务器。服务器是指在网络上提供各种服务的计算机&#xff0c;如…...

Unity中Shader的Fallback

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

“菜鸟”程序员逆袭:独立开发iOS音乐应用,年底参加Amazon DeepRacer 全球锦标赛

“致一年前的小木土&#xff1a;任务完成。” 6月30日&#xff0c;在获得2023 Amazon DeepRacer自动驾驶赛车企业总决赛中国区冠军三天后的深夜&#xff0c;杜键文发了这条朋友圈&#xff0c;并配上比赛现场的9张图。 “小木土”是杜键文的网名&#xff0c;取其姓氏&#xff…...

nginx测试rewrite

nginx测试rewrite last :相当于 Apache 里的(L)标记&#xff0c;表示完成rewrite 匹配; break: 本条规则匹配完成后&#xff0c;终止匹配&#xff0c;不再匹配后面的规则。 # 其中last 和 break 用来实现 URL 重写时&#xff0c;浏览器地址栏URL 地址不变 redirect: 返回 302 …...

qt 多语言版本 QLinguist使用方法

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

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...