深入解析与解决高并发下的线程池死锁问题

news2024/11/16 17:43:25
问题背景

在现代互联网应用中,高并发场景是常态,为了高效处理大量用户请求,后端服务通常会采用线程池来管理线程资源。然而,在一个复杂的微服务架构项目中,我们遇到了一个棘手的问题:在业务高峰期,系统频繁出现响应延迟甚至超时的情况,经过初步排查,发现部分服务存在线程池死锁现象,严重影响了系统的稳定性和用户体验。

问题分析

该系统采用Spring Boot框架构建,核心业务模块负责处理用户订单,包括订单创建、支付状态更新以及库存调整等操作。为了提高处理效率,我们为每个处理逻辑配置了独立的线程池。问题主要出现在订单支付成功后的库存减少操作上,具体代码片段如下:

@Service
public class OrderService {

    @Autowired
    private StockService stockService;

    @Async("stockThreadPool")
    public void deductStockAfterPaymentSuccess(Order order) {
        stockService.deduct(order.getProductId(), order.getQuantity());
        // 更新订单状态等后续逻辑...
    }
}

其中,stockThreadPool 是一个自定义配置的线程池,用于处理库存相关的异步操作,以避免库存操作阻塞主线程。然而,在高并发环境下,该线程池经常达到最大线程数,新来的请求因无法获取线程而被无限期地等待,导致线程池死锁。

排查过程
  1. 监控工具辅助:首先,利用JVisualVM、arthas等工具监控系统线程状态,发现stockThreadPool中的线程大多处于WAITING状态,说明存在线程等待资源释放的情况。
  2. 代码审查:检查StockService.deduct()方法实现,发现内部使用了悲观锁(如synchronized或Lock的lock()方法),在高并发下容易形成锁竞争,导致线程等待时间过长。
  3. 日志分析:通过增加详细的日志记录,观察到在某些时间点,多个线程同时尝试锁定相同的商品库存记录,形成了锁链,进而引发了死锁。
解决方案
  1. 优化锁策略:将悲观锁改为乐观锁。在库存服务中,使用版本号或时间戳进行并发控制,减少直接的线程等待。例如,使用@Version注解结合Spring Data JPA的乐观锁机制。
@Entity
public class Product {
    @Id
    private Long id;
    private Integer stock;
    @Version
    private Long version;
    // getters and setters
}
@Service
public class StockService {

    @Transactional
    public boolean deduct(Long productId, Integer quantity) {
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new ResourceNotFoundException("Product not found"));
        
        if (product.getStock() < quantity) return false;
        
        int updatedStock = product.getStock() - quantity;
        product.setStock(updatedStock);
        
        try {
            product = productRepository.save(product);
        } catch (OptimisticLockException e) {
            // 处理乐观锁失败,通常重试或记录日志
            return false;
        }
        return true;
    }
}

线程池配置优化:根据业务负载情况动态调整线程池参数,如核心线程数、最大线程数、队列大小及拒绝策略等,避免固定配置在高并发下成为瓶颈。使用ThreadPoolExecutor自定义配置,并考虑使用ThreadPoolExecutor.CallerRunsPolicy作为拒绝策略,让调用者线程执行任务,避免直接丢弃任务。

@Configuration
public class ThreadPoolConfig {

    @Bean(name = "optimizedThreadPool")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数,根据CPU核心数和业务需求合理设定
        executor.setCorePoolSize(4 * Runtime.getRuntime().availableProcessors());
        // 最大线程数,防止线程数无限制增长导致资源耗尽
        executor.setMaxPoolSize(executor.getCorePoolSize() * 2);
        // 队列大小,当核心线程都被占用时,新任务将在队列中等待
        executor.setQueueCapacity(500);
        // 拒绝策略,这里采用CallerRunsPolicy,让调用者线程执行任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置线程空闲时间,超过该时间的空闲线程将被终止
        executor.setKeepAliveSeconds(60);
        // 线程名前缀,方便日志追踪
        executor.setThreadNamePrefix("OptimizedThreadPool-");
        // 初始化线程池
        executor.initialize();
        return executor;
    }
}

在服务类中使用自定义线程池:

@Service
public class OrderService {

    @Autowired
    @Qualifier("optimizedThreadPool") // 使用自定义线程池
    private ThreadPoolTaskExecutor executor;

    public void deductStockAfterPaymentSuccess(Order order) {
        executor.execute(() -> {
            stockService.deduct(order.getProductId(), order.getQuantity());
            // 更新订单状态等后续逻辑...
        });
    }
}

增加超时与重试机制:对于可能引起长时间等待的操作,如数据库操作、远程服务调用等,设置合理的超时时间,并在超时后实施重试逻辑,以减少单次请求对系统资源的占用, 使用Future结合自定义的超时和重试。

@Service
public class OrderService {

    // ... 其他代码 ...

    public void deductStockWithRetry(Order order) {
        int retryCount = 0;
        final int maxRetries = 3; // 最大重试次数
        while (retryCount <= maxRetries) {
            try {
                Future<Boolean> resultFuture = executor.submit(() -> stockService.deduct(order.getProductId(), order.getQuantity()));
                // 使用自定义的超时时间,5秒
                if (resultFuture.get(5, TimeUnit.SECONDS)) {
                    System.out.println("库存扣减成功");
                    break; // 成功则跳出循环
                } else {
                    throw new RuntimeException("库存不足,扣减失败");
                }
            } catch (TimeoutException e) {
                System.out.println("库存扣减操作超时,准备重试...");
            } catch (InterruptedException | ExecutionException e) {
                System.out.println("操作异常,准备重试... " + e.getMessage());
            }

            retryCount++;
            if (retryCount > maxRetries) {
                System.out.println("重试次数已达上限,操作失败");
                break;
            } else {
                try {
                    Thread.sleep(1000); // 退避策略,重试前等待一秒
                } catch (InterruptedException ignored) {}
            }
        }
    }
}
成果与思考

经过上述改造,系统在高并发场景下的表现有了显著提升,线程池死锁问题得到有效解决,用户请求响应时间和系统稳定性得到了大幅改善。监控数据显示,线程池利用率更加合理,未再出现请求堆积和长时间等待的情况。

此次经历让我们深刻认识到:

  • 并发控制策略的重要性:合理选择锁策略(乐观锁与悲观锁),能够有效避免死锁和性能瓶颈。
  • 线程池配置的灵活性:动态调整线程池参数,根据实际业务需求和系统负载进行优化,是保障系统稳定的关键。
  • 全面的监控与日志:良好的监控和日志体系是问题定位和系统调优的基石,能够快速定位并解决问题。

总之,面对高并发挑战,开发人员需要综合运用多种技术手段,不断优化和调整,才能确保系统的高效稳定运行。

欢迎扫码关注 微信公众号:JAVA和人工智能
                                                           获取更多免费书籍、资源、优质资料 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解锁分布式云多集群统一监控的云上最佳实践

作者&#xff1a;在峰 引言 在当今数字化转型加速的时代&#xff0c;随着混合云、多云多集群环境等技术被众多企业广泛应用&#xff0c;分布式云架构已成为众多企业和组织推动业务创新、实现弹性扩展的首选&#xff0c;分布式云容器平台 ACK One&#xff08;Distributed Clou…

ONLYOFFICE 文档 8.1 现已发布:功能全面的 PDF 编辑器、幻灯片版式、优化电子表格的协作等等

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、ONLYOFFICE简介1. 文档编辑器2. 电子表格编辑器3. 演示文稿编辑器4. 项目管理5. 邮件和日历6. 客户关系管理&#xff08;CRM&#xff09;7. 安全性和权限管理8. 多平台和第三方集成 三、安装1. Windows/Mac 安装…

斯坦福大学 AI 研究部门推出的“7 周人工智能学习计划”

①AI Python 基础&#xff0c;包括计算机原理、语法、判断语句等&#xff1b; ②AI Python 进阶&#xff0c;涉及 Linux 命令、多任务编程等&#xff1b; ③机器学习&#xff0c;涵盖算法、数据结构等&#xff1b; ④计算机视觉与图像处理&#xff0c;包含图像分类、目标检测…

每日鲜语携手中国国家高尔夫球队队员殷若宁征战巴黎,打响中国高端鲜奶品牌“鲜”声量

近日&#xff0c;高端鲜奶品牌每日鲜语宣布携手蒙牛品牌代言人、中国国家高尔夫球队队员殷若宁&#xff0c;共赴巴黎奥运赛场&#xff0c;为梦想挥杆而上。邀请众多消费者开启高品质、健康的生活方式。此举不仅彰显了每日鲜语作为高端鲜奶新标杆的品牌定位&#xff0c;也同时延…

COMSOL Multiphysics物理模拟软件 下载安装,COMSOL Multiphysics 卓越的模拟性能

COMSOL Multiphysics&#xff0c;它不仅具备卓越的模拟性能&#xff0c;还以其创新的多物理场耦合分析能力&#xff0c;为各类复杂问题提供了前所未有的解决方案。 这款软件的出现&#xff0c;犹如为科研工作者和工程师们插上了一双智慧的翅膀&#xff0c;使他们能够在物理世界…

RubyMine 2024 mac/win版:智慧编程,从心出发

JetBrains RubyMine 2024 是一款专为Ruby和Rails开发者打造的高效集成开发环境(IDE)。它凭借其卓越的性能和丰富的功能&#xff0c;帮助开发者在Ruby和Rails的开发过程中提升效率&#xff0c;减少错误。 RubyMine 2024 mac/win版获取 RubyMine 2024 提供了强大的代码编辑功能&…

VR加密方案常见问题有哪些?

在数字化时代&#xff0c;随着虚拟现实&#xff08;VR&#xff09;技术的迅速发展与普及&#xff0c;VR视频内容的安全传输成为关注焦点。为保护版权及敏感信息免遭非法复制或篡改&#xff0c;VR视频加密技术显得尤为重要。 首先&#xff0c;高效的加密算法对确保数据安全性至关…

60.Python-web框架-Django手动删除了一个数据库表,migrate问题

目录 1.问题产生 2.解决方法&#xff1a; 1.问题产生 今天手欠&#xff0c;删了一个数据库表&#xff0c;然后迁移不进来了。 当你在Django项目中手动删除了数据库模型&#xff08;models&#xff09;的表后&#xff0c;想要Django通过makemigrations命令重新创建或识别这些更…

第四届机械设计与智能制造国际会议(MDSM2024)

第四届机械设计与智能制造国际会议(MDSM2024) 4th International Conference on Mechanical Design and Smart Manufacturing 会议日期&#xff1a;2024年8月23-25日 会议地点&#xff1a;中国-武汉 会议官网&#xff1a;https://www.iaast.cn/meet/home/Bx118v7D 【支持单位】…

Java版商城:Spring Cloud+SpringBoot b2b2c实现多商家入驻、直播带货及免费小程序商城搭建

用技术&#xff1a; Spring CloudSpring BootMybatis微服务服务监控可视化运营 B2B2C平台&#xff1a; 平台管理端(包含自营) 商家平台端(多商户入驻) PC买家端、手机wap/公众号买家端 微服务&#xff08;30个通用微服务如&#xff1a;商品、订单、购物车、个人中心、支付…

C语言结构体包含结构体

C语言结构体可以包含另一个结构体&#xff1b; 下面通过一个例子看一下&#xff1b; struct Date {int day;int month;int year; };struct Person {char *name;struct Date birthday; }; ...... void CTestView::OnDraw(CDC* pDC) {CTestDoc* pDoc GetDocument();ASSERT_VAL…

.NET也能玩量化【2】搭建本地财经数据获取服务,以及获取复权历史大A数据演示...

直接动手&#xff0c;不写前言了。 创建.NET 8的一个webapi项目备用 本地安装python库 aktools 输安装完毕以后&#xff0c;输入 python -m aktools 即可启动有关服务 启动以后&#xff0c;主页地址&#xff1a;http://127.0.0.1:8080/ 查看swwager的api文档说明。我们主要使用…

Unity面试题 UGUI调整UI与粒子特效的显示层级

首先&#xff0c;必须保证Canvas画布的渲染模式为了相机渲染 方法:一&#xff1a;将需要控制UI显示层级的Image换成Sprite 1.创建一个粒子系统&#xff0c;和两张Sprite. 2.设置Sprite1的Order in Layer为 -1&#xff0c;设置Sprite2的Order in Layer为 1&#xff0c;粒子的Ord…

ANSYS Electronics 电磁场仿真工具下载安装,ANSYS Electronics强大的功能和灵活性

ANSYS Electronics无疑是一款在电磁场仿真领域表现卓越的软件工具。它凭借强大的功能和灵活性&#xff0c;帮助用户在产品设计阶段就能精确预测和优化电磁场性能&#xff0c;从而极大地降低了实际测试成本&#xff0c;并显著提升了产品的可靠性。 这款软件不仅在电子设计领域有…

【专利】一种光伏产品缺陷检测AI深度学习算法

申请号CN202410053849.9公开号&#xff08;公开&#xff09;CN118037635A申请日2024.01.12申请人&#xff08;公开&#xff09;超音速人工智能科技股份有限公司发明人&#xff08;公开&#xff09;张俊峰(总); 叶长春(总); 廖绍伟 摘要 本发明公开一种光伏产品缺陷检测AI深度…

破解App推广困局:Xinstall如何助力游戏盒子代理快速扩大用户池?

在互联网流量日益分散的今天&#xff0c;游戏盒子代理推广面临着前所未有的挑战。如何迅速搭建起能时刻满足用户需求的运营体系&#xff0c;成为了众多企业急待解决的问题。Xinstall作为一款专业的App推广和运营工具&#xff0c;凭借其强大的功能和独特优势&#xff0c;为游戏盒…

ONLYOFFICE 编辑器8.1,一个功能全面的编辑器

目录 官网地址&#xff1a;ONLYOFFICE - 企业在线办公应用软件 | ONLYOFFICE 一、PDF编辑 二、PPT播放 1. 多样化的幻灯片样式与布局 2. 强大的文本编辑与格式化功能 3. 丰富的图形与图表插入功能 4. 灵活的过渡效果与动画设置 5. 舒适的呈现与演讲辅助功能 6. 便捷的团…

Java--Data类

1.Data类 java.util.Date.表示指定的时间信息&#xff0c;不支持国际化 构造方法 new Date()&#xff1a;当前系统日期和时间 new Date(long)&#xff1a;给定日期和时间 主要方法&#xff1a; after(Date):判断当前日期对象是否在给定日期对象之后 before(Date):判断当前日期…

关于文章“python+百度语音识别+星火大模型+讯飞语音合成的语音助手”报错的修改

前言 关于我的文章&#xff1a;python百度语音识别星火大模型讯飞语音合成的语音助手&#xff0c;运行不起来的问题 文章地址&#xff1a; https://blog.csdn.net/Phillip_xian/article/details/138195725?spm1001.2014.3001.5501 1.报错问题 如果运行中报错&#xff0c;且…

Banded Grid Views

标注栏网格视图&#xff08;BandedGridView&#xff09;以表格形式显示数据&#xff0c;并将列组织到标注栏中。 Advanced Banded View&#xff08;AdvBandedGridView&#xff09;也有同样的功能&#xff0c;并额外支持数据单元格的复杂布局。 标注栏和列 BandedGridView和…