记录一次排查OOM的过程
服务出现了oom:
查看类信息发现char[]类型实例特别多,占用堆内存特别大
跟踪几个char[]实例的GC root,发现都是保存token信息,并且根都是session
然后查看session的个数,发现有63W
我是用100并发压测的为什么会产生那么多个session?我突然想到我们是前后端分离的,那么前端ajax的时候有没有保持session呢,我调试了下发现我们没有保持session
通过计算
100个并发的话,每个产生一个session,10多分钟后oom,差不多就是100(并发数)*2(每个ajax2个sesionId)*10(十分钟)*60(60秒)*5(5个接口)正好60w
发现oom原因,就是因为前后端分离后没有做好保持session的工作
解决方案
方案1:禁用session
优点:修改简单
缺点:使用session的地方需要替换了,假如使用了session的地方比较多,那么修改工作量就会变大
方案2:使用session共享
优点:可以解决每次ajax都要带token的问题,减少数据传输的大小,减轻带宽压力;修改也相对简单
做法
后台
服务提供者中做以下配置
1、导入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、开启session共享(是通过redis来解决的)
spring:
session:
store-type: redis #开启session共享
3、配置redis
redis:
host: localhost
port: 6379
password: 123456
4、在启动类中开启session共享
@SpringBootApplication
@EnableRedisHttpSession //开启session共享
网关中需要做同样的配置
1、导入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、开启session共享(是通过redis来解决的)
spring:
session:
store-type: redis #开启session共享
3、配置redis
redis:
host: localhost
port: 6379
password: 123456
4、配置网关
需要在网关中配置不过滤session
zuul:
routes:
user:
path: /user/**
serviceId: CLOUD-MALL-USER
sensitive-headers: #把sensitive-headers设置为空,session不过滤
5、在启动类中开启session共享
@SpringBootApplication
@EnableFeignClients
@EnableZuulProxy
@EnableRedisHttpSession //开启session共享
前端
1、前端引入axios时,在main.js中做一个全局设置,设置允许携带cookie发起请求。
import axios from 'axios' //导入axios
axios.defaults.withCredentials = true //全局设置axios允许携带cookie进行访问
Vue.prototype.$axios = axios