refactor: 增加一个清理后台session的定时任务

This commit is contained in:
CaptainB 2022-12-08 10:48:38 +08:00 committed by 刘瑞斌
parent d5adce88da
commit 3078c53c17
1 changed files with 68 additions and 0 deletions

View File

@ -0,0 +1,68 @@
package io.metersphere.job.schedule;
import com.fit2cloud.quartz.anno.QuartzScheduled;
import io.metersphere.commons.utils.JSON;
import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Component
public class CleanSessionJob {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisIndexedSessionRepository redisIndexedSessionRepository;
@Value("${spring.session.timeout:43200s}")
private Duration timeout;
/**
* 清理没有绑定user的session
* redisson 有时会把ttl设置成-1 https://github.com/redisson/redisson/issues/4200
*/
@QuartzScheduled(cron = "0 2 0 * * ?")
public void cleanSession() {
Map<String, Long> userCount = new HashMap<>();
ScanOptions options = ScanOptions.scanOptions().match("spring:session:sessions:*").count(1000).build();
try (
Cursor<String> scan = stringRedisTemplate.scan(options)
) {
while (scan.hasNext()) {
String key = scan.next();
if (StringUtils.contains(key, "spring:session:sessions:expires:")) {
continue;
}
Boolean exists = stringRedisTemplate.opsForHash().hasKey(key, "sessionAttr:user");
if (!exists) {
stringRedisTemplate.delete(key);
} else {
Object user = redisIndexedSessionRepository.getSessionRedisOperations().opsForHash().get(key, "sessionAttr:user");
Long expire = redisIndexedSessionRepository.getSessionRedisOperations().getExpire(key);
String userId = (String) MethodUtils.invokeMethod(user, "getId");
Long count = userCount.getOrDefault(userId, 0L);
count++;
userCount.put(userId, count);
LogUtil.info(key + " : " + userId + " 过期时间: " + expire);
if (expire != null && expire.intValue() == -1) {
redisIndexedSessionRepository.getSessionRedisOperations().expire(key, timeout);
}
}
}
LogUtil.info(JSON.toJSONString(userCount));
} catch (Exception e) {
LogUtil.error(e);
}
}
}