美文网首页码出未来互联网科技老男孩的成长之路
原创 记一次小事故解决方案:Spring Redis开启事务支持

原创 记一次小事故解决方案:Spring Redis开启事务支持

作者: 老男孩_Misaya | 来源:发表于2020-07-09 21:53 被阅读0次

1.事故背景

在APP访问服务器接口时需要从redis中获取token进行校验,服务器上线后发现一开始可以正常访问,但只要短时间内请求量增长服务则无法响应

2.排查流程

(1)使用top指令查看CPU资源占用还远远达不到瓶颈,排查因为CPU资源不足导致服务不可用的可能

(2)查看tomcat线程池配置,默认最大线程数为200,理论上可以支持目前服务器的访问量

(3)使用jmap指令保存堆栈信息,jmap -dump:format=b,file=dump.log pid,pid为进程号

(4)使用Java visualVM打开保存的堆栈日志dump.log,发现绝大部分的线程都阻塞在从redis连接池中获取连接的代码,如下图所示

3.原理分析

根据堆栈日志所显示得知线程访问redis前需要从连接池队列中推出一个连接,当连接池没有连接时,则会阻塞等待,阻塞等待的时间可以自行设置MAA_WAIT参数,默认是-1表示不限时等待,目前项目使用默认配置,所以所有的线程都会一直阻塞在获取连接的步骤,如果设置了最大等待时间,当超过最大等待时间会报出Could not get a resource from the pool的异常

(1)在spring配置文件中的stringRedisTemplate对象配置参数中打开了事务支持,而redis的事务支持是用MUTI和EXEC指令来支持,以下事务实例截图来自菜鸟教程 https://www.runoob.com/redis/redis-transactions.html

(2)如果要保证在事务能正常执行,那么在一个方法中多次操作redis必须是同一条连接,这样才能保证事务能正常执行,所以在stringRedisTemplate会将连接绑定在当前线程,当第二次访问redis时直接从当前线程中获取连接,绑定连接源码如下:

(3)按照流程,先绑定连接,最后在finally代码块中释放连接,看起来并没有问题,但跳进去releaseConnection方法的代码发现连接需要在事务提交后才能释放,也就是说service方法上必须使用@Transation注解修饰,但因为业务方法上少写了@Transation注解导致连接将一直绑定第一次获取他的线程上,当线程池的线程被获取完之后,其他线程就会进入阻塞等待状态,导致服务不可用

(4)如果加上@Transation注解,那么方法执行完之后将会执行TransactionSynchronizationUtils.invokeAfterCompletion这个方法,mysql事务也是在这个方法执行commit操作,如下图所示方法的第一个参数是List<TransactionSynchronization> synchronizations,代表可以有多个事务,redis,mysql等,都会此进行事务提交操作,这里使用多态,根据对象的具体类型执行不同的方法,redis则执行redis的事务提交操作,mysql则执行mysql的事务提交操作

(5)以下为redis事务提交的代码,也跟我们上面提到的一样,发送exec指令提交事务

4.如何修改代码

(1)确认实际需求是否需要事务支持,如果需要则在对应方法上加上@Transaction注解

(2)如果不需要事务支持则将enableTransactionSupport设置为false

推荐阅读:

相关文章

  • 原创 记一次小事故解决方案:Spring Redis开启事务支持

    1.事故背景 在APP访问服务器接口时需要从redis中获取token进行校验,服务器上线后发现一开始可以正常访问...

  • Redis事务

    转载自Redis之Redis事务 Redis事务的概念: Redis 事务的本质是一组命令的集合。事务支持一次执行...

  • Spring中实现事务方式

    Spring 中实现事务的方式 Spring 并不直接支持事务,只有当数据库支持事务时,Spring 才支持事务,...

  • Redis学习笔记(2)

    1. 事务 1.1 Redis事务的概念: Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个...

  • spring事务的实现原理

    spring实现事务的原理 Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring...

  • redis中的事物、消息订阅、持久化

    Redis 中的事务 Redis支持简单的事务 Redis与 mysql事务的对比 注: rollback与dis...

  • 深入理解Redis(五)----Redis事务

    Redis事务的概念: Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被...

  • Redis事务

    1 Redis事务的概念 Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会...

  • 分布式事务实践之hmily

    hmily简介Hmily 一款金融级的分布式事务解决方案,支持 Dubbo、Spring Cloud、Motan ...

  • Redis事务

    Redis事务的概念 Redis事务的本质是一系列命令的集合。事务支持一次执行多个命令,一个事务中所有的命令都会被...

网友评论

    本文标题:原创 记一次小事故解决方案:Spring Redis开启事务支持

    本文链接:https://www.haomeiwen.com/subject/rxlgfktx.html