我们上节说道,如果项目部署时是一台服务器的话本地缓存没有问题,如果是多台服务器部署,使用本地缓存就不行了,那么大家都知道使用redis进行操作,redis可以相当于一台集中式的服务器,专门用来处理缓存数据,好像也没啥问题。
那如果我们使用了springboot进行编码,在springboot的自动化加载中还加载了redis操作的工具类--redisTemplate操作非常方便,这里我就不在演示可自行百度。
一通改造代码之后,测试发现没有问题,但如果进行压力测试,会出现如下Bug:
以上Bug叫做堆外内存溢出。
springboot2.0以后默认使用lettuce作为操作redis的客户端,它使用netty进行网络通信。以上Bug就是netty搞的鬼,lettuce的Bug导致netty堆外内存溢出 ,那设置jvm的虚拟机内存从100m 变为 -Xms300m是否可行呢?你会发现好像好了那么一点儿,但还是会出现以上错误。这是因为netty如果没有指定堆外内存,默认使用-Xms300m作为堆外内存。那怎么指定netty的堆外内存呢,翻遍源码你发现有这么一个东西。
可以通过-Dio.netty.maxDirectMemory 进行设置。但一味的调整这个内存的大小也不是办法,解决方案如下:
解决方案:不能使用-Dio.netty.maxDirectMemory只去调整堆外内存
1)升级lettuce客户端 2)切换使用jedis进行操作。
但目前还没有成熟的lettuce客户端供我们使用,所以以上总结只有一句:
SpringBoot2.0默认操作的redis客户端有Bug,需要切换成Jedis进行操作,如何切换呢,也非常简单:
只需要在加载springboot的redis时,排除掉lettuce的核心包,并且引入jedis就可以了.
然后不需要动用任何代码,使用redisTemplate的时候默认使用的就是jedis客户端了。