• 记一次大事务优化历程(短信发送)


    问题背景

    短信服务数据库连接数告警,grafana查看数据库连接池被打满。

    问题分析

    在这段时间内,通过链路分析,发现最终调用第三方短信发送服务偶然耗时过长,分析了原有发送逻辑的代码,该实现在入口send处加了事务,导致后续的消息通道等逻辑判断,以及调用第三方发送逻辑全部在一个长事务里。

    解决方案

    由于环境因素,不同环境部署的中间件不一致,有些环境没有使用mq,所以mq不考虑在解决方案内

    1、双缓存队列+动态线程池
    在这里插入图片描述
    2、初始化线程处理
    在这里插入图片描述

    Q1:为什么不用线程池?

    为保证任务不丢失,线程池拒绝策略

    AbortPolicy - 抛出异常,中止任务。抛出拒绝执行 RejectedExecutionException 异常信息。线程池默认的拒绝策略。必须处理好抛出的异常,否则会打断当前的执行流程,影响后续的任务执行
    CallerRunsPolicy - 使用调用线程执行任务。当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。一般并发比较小,性能要求不高,不允许失败。但是,由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率上必然的损失较大
    DiscardPolicy - 直接丢弃,其他啥都没有
    DiscardOldestPolicy - 丢弃队列最老任务,添加新任务。当触发拒绝策略,只要线程池没有关闭的话,丢弃阻塞队列 workQueue 中最老的一个任务,并将新任务加入
    
    • 1
    • 2
    • 3
    • 4

    CallerRunsPolicy策略不会丢失任务,但是会使用提交线程执行任务,加入提交线程执行的任务超长耗时,将会导致整个线程池不可用

    Q2:使用固定线程数不会丢数据吗?怎么解决?

    在应用重启的时候,是会丢失极少部分数据,可以通过定时钟补偿。

  • 相关阅读:
    金仓数据库 KingbaseES 插件参考手册 M
    Eureka原理实践
    C#学习相关系列之常用符号介绍
    境外社交数据采集遇到的问题及云手机解决方案
    Tomcat安装及配置教程
    springboot web项目中 Set-Cookie 失败 办法
    【前端笔记】git的使用
    2022中国DevOps社区峰会 走进国产数据库的技术创新实践
    nginx配置详解
    如果有一天你不开心
  • 原文地址:https://blog.csdn.net/qq_31426247/article/details/127241855