🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
问题描述
多线程+连接池+代理 运行一段时间线程阻塞
使用多线程+httpClient连接池+ip代理 请求第三方接口。运行一段时间 出现线程阻塞的情况。目前看线程阻塞都在一个调用的请求里面。
@Retryable(
value = {Exception.class}, // 指定哪些异常需要重试
maxAttempts = 3, // 重试次数
backoff = @Backoff(delay = 3000) // 每次重试间隔2秒
)
@ApiLog(title = "XXXX",businessType = "拼接cookie请求第一部分",resultType = false)
public String disneyByCookies01(String token) throws IOException {
RequestConfig requestConfig = RequestConfig.custom()
// .setSocketTimeout(10000)
// .setConnectTimeout(10000)
.setRedirectsEnabled(false)
.build();
HttpGet httpGet = new HttpGet("https://XXXXXXXX.cn/XXX/XXXXXX-svc-gw/api/auth_code/authorize/v1?activity_code=6119&redirect_type=0&redirect_uri=https://XXXX.activity-24.m.duiba.com.cn/customShare/share?id=Did1NTcxODM&");
httpGet.setConfig(requestConfig);
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Linux; Android 10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.74 Mobile Safari/537.36");
httpGet.setHeader("Cookie", "piXX-m-sid=" + token + "; platform=8; app_version_code=282; app_version_name=5.1.9; app_device_type=android");
httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
// 执行请求并获取响应
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
Header contentTypeHeader = response.getFirstHeader("Location");
String location = contentTypeHeader.getValue();
String accessCode = null;
if (location != null) {
String regex = "&access_code=([^&]*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(location);
if (matcher.find()) {
accessCode = matcher.group(1); // 提取匹配组中的access_code值
log.info("【success】[线程:" + threadName + "]拼接cookie请求第一部分请求成功" + accessCode);
}
} else {
log.info("【error】[线程:" + threadName + "]拼接cookie请求第一部分请求异常response中获取location失败" + response);
throw new IllegalStateException("【error】[线程:" + threadName + "]拼接cookie请求第一部分请求异常response中获取location失败");
}
return accessCode;
友情提示:
如上问题有的来自我自身项目开发,有的收集网站,有的来自读者…如有侵权,立马删除。再者,针对此专栏中部分问题及其问题的解答思路或步骤等,存在少部分搜集于全网社区及人工智能问答等渠道,若最后实在是没能帮助到你,还望见谅!并非所有的解答都能解决每个人的问题,在此希望屏幕前的你能够给予宝贵的理解,而不是立刻指责或者抱怨!如果你有更优解,那建议你出教程写方案,一同学习!共同进步。
解决方案
如下是上述问题的解决方案,仅供参考:
在使用多线程结合HttpClient连接池和IP代理请求第三方接口时,出现线程阻塞的情况可能由多种原因引起。以下是一些可能的原因和相应的解决方案:
1. 连接池配置不当
连接池可能没有正确配置,导致连接耗尽或重用不当。
- 解决方案:检查连接池的配置,确保最大连接数和路由策略合理。
2. 请求超时
请求可能因为超时而阻塞。
- 解决方案:在
RequestConfig
中设置合理的超时时间:
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000) // 读取超时时间
.setConnectTimeout(10000) // 连接超时时间
.setRedirectsEnabled(false)
.build();
3. 代理服务器问题
代理服务器可能不稳定或响应慢,导致请求阻塞。
- 解决方案:监控代理服务器的性能,考虑更换代理或增加代理服务器。
4. 第三方接口限制
第三方接口可能对请求频率有限制,超出限制可能导致请求被拒绝或延迟。
- 解决方案:检查第三方接口的使用限制,并相应调整请求频率。
5. 异常处理不当
异常处理可能导致线程无法正确释放资源。
- 解决方案:确保异常被捕获并正确处理,避免线程因异常而阻塞。
6. 资源竞争
多线程环境下可能存在资源竞争,导致线程阻塞。
- 解决方案:使用同步代码块或锁来管理资源访问,避免竞争条件。
7. 死锁
死锁可能导致线程阻塞。
- 解决方案:检查代码中是否存在死锁情况,并优化锁的使用。
8. 日志记录
日志记录可能会影响性能,尤其是在高并发环境下。
- 解决方案:优化日志记录策略,避免在关键路径上进行大量日志输出。
9. 重试机制
重试机制可能导致线程阻塞。
- 解决方案:优化重试逻辑,避免在失败时立即重试,可以考虑引入随机退避策略。
10. HttpClient配置
HttpClient的配置可能影响性能。
- 解决方案:检查HttpClient的配置,确保其适用于高并发场景。
示例代码优化
以下是一些优化后的示例代码:
@Retryable(
value = {Exception.class},
maxAttempts = 3,
backoff = @Backoff(delay = 3000)
)
public String disneyByCookies01(String token) throws IOException {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000)
.setConnectTimeout(10000)
.setRedirectsEnabled(false)
.build();
HttpGet httpGet = new HttpGet("https://XXXXXXXX.cn/XXX/XXXXXX-svc-gw/api/auth_code/authorize/v1?activity_code=6119&redirect_type=0&redirect_uri=https://XXXX.activity-24.m.duiba.com.cn/customShare/share?id=Did1NTcxODM&");
httpGet.setConfig(requestConfig);
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Linux; Android 10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.74 Mobile Safari/537.36");
httpGet.setHeader("Cookie", "piXX-m-sid=" + token + "; platform=8; app_version_code=282; app_version_name=5.1.9; app_device_type=android");
httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
Header contentTypeHeader = response.getFirstHeader("Location");
String location = contentTypeHeader != null ? contentTypeHeader.getValue() : null;
String accessCode = null;
if (location != null) {
String regex = "&access_code=([^&]*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(location);
if (matcher.find()) {
accessCode = matcher.group(1); // 提取匹配组中的access_code值
log.info("【success】[线程:" + Thread.currentThread().getName() + "]拼接cookie请求第一部分请求成功" + accessCode);
}
} else {
log.info("【error】[线程:" + Thread.currentThread().getName() + "]拼接cookie请求第一部分请求异常response中获取location失败" + response);
throw new IllegalStateException("【error】[线程:" + Thread.currentThread().getName() + "]拼接cookie请求第一部分请求异常response中获取location失败");
}
return accessCode;
}
总结
线程阻塞可能是由多种因素引起的,需要综合考虑网络、资源、配置等多方面因素。通过优化代码和配置,可以提高系统的稳定性和性能。
希望如上措施及解决方案能够帮到有需要的你。
PS:如若遇到采纳如下方案还是未解决的同学,希望不要抱怨&&急躁,毕竟影响因素众多,我写出来也是希望能够尽最大努力帮助到同类似问题的小伙伴,即把你未解决或者产生新Bug黏贴在评论区,我们大家一起来努力,一起帮你看看,可以不咯。
若有对当前Bug有与如下提供的方法不一致,有个不情之请,希望你能把你的新思路或新方法分享到评论区,一起学习,目的就是帮助更多所需要的同学,正所谓「赠人玫瑰,手留余香」。
☀️写在最后
ok,以上就是我这期的Bug修复内容啦,如果还想查找更多解决方案,你可以看看我专门收集Bug及提供解决方案的专栏《CSDN问答解惑-专业版》,都是实战中碰到的Bug,希望对你有所帮助。到此,咱们下期拜拜。
码字不易,如果这篇文章对你有所帮助,帮忙给 bug菌 来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。
同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!
📣关于我
我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿哇。