原地址:春季会议原则
欢迎访问我的博客:https://blog.duhbb.com
介绍
今天我正在编写一个外部接口。该接口的一般原理是通过过滤器中的令牌获取用户信息,然后创建会话。接下来的过程是控制器→服务→刀
向上
这种发展不像以前那么愚蠢了。我想了想。当对方呼叫时,没有会话id,即每次认证后都会创建一个会话。假设呼叫次数非常高,那么可能会出现一个大问题。如果会话数过多,会导致会话数过多,可能导致系统崩溃。
让我看看如何在系统中使用session。
春季课程探索
跟踪代码
首先要做的是打破请求获取会话的代码,确实有这样的说法!
request.getSession()
文件
@SuppressWarnings("deprecation")
@Order(SessionRepositoryFilter.DEFAULT_ORDER)
public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerRequestFilter {
public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class.getName();
public static final int DEFAULT_ORDER = Integer.MIN_VALUE + 50;
private final SessionRepository<S> sessionRepository;
private ServletContext servletContext;
private MultiHttpSessionStrategy httpSessionStrategy = new CookieHttpSessionStrategy();
文件
public void setAttribute(String name, Object value) {
// It's quite particular, checkState before setting attr
checkState ();
session.setAttribute(name, value);
}
checkState ()
它也很简单,只需检查无效
这是真的吗?
private void checkState () {
if(无效) {
throw new IllegalStateException("The HttpSession has already be 无效.");
}
}
它’s有点难找到它从代码,但我找到了:
文件
文件
文件
验证redis中的数据
最后一个调试会话的键是:春天:会议:会议:62359810 - d2cb - 4378 a619 e2c31bb8242c
,似乎存储了一个哈希结构。
在redis中获取散列的命令是:
HGETALL hkey
执行:
127.0.0.1:6379> HGETALL 春天:会议:会议:62359810 - d2cb - 4378 a619 e2c31bb8242c
1) "maxInactiveInterval"
2) "xacxedx00x05srx00x11java.lang.Integerx12xe2xa0xa4xf7x81x878x02x00x01Ix00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x01Qx80"
3) "lastAccessedTime"
4) "xacxedx00x05srx00x0ejava.lang.Long;x8bxe4x90xccx8f#xdfx02x00x01Jx00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x01x82x00:x99x0e"
5) "creationTime"
6) "xacxedx00x05srx00x0ejava.lang.Long;x8bxe4x90xccx8f#xdfx02x00x01Jx00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x01x82x00:x99x0e"
好像里面还是没有商业数据。哇,我发现我是一个白痴,断点还没有释放,redis根本没有存储这些业务数据。
再执行一次:
127.0.0.1:6379> HGETALL 春天:会议:会议:62359810 - d2cb - 4378 a619 e2c31bb8242c
1) "creationTime"
2) "xacxedx00x05srx00x0ejava.lang.Long;x8bxe4x90xccx8f#xdfx02x00x01Jx00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x01x82x00:x99x0e"
3) "lastAccessedTime"
4) "xacxedx00x05srx00x0ejava.lang.Long;x8bxe4x90xccx8f#xdfx02x00x01Jx00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x01x82x00Dx1f["
5) "sessionAttr:HumanSession"
6) "xacxedx00x05srx00#cn.com.xxx.base.bean.HumanSessionx8fxbbxb6dxf6x04x8axd5x02x00x1fDx00x0bcoordinateXDx00x0bcoordinateYZx00tvalidFlagLx00x0fautoReceiveFlagtx00x13Ljava/lang/Integer;Lx00x0ebrowserVersiontx00x12Ljava/lang/String;Lx00ndataUnitIDqx00~x00x01Lx00afromCasqx00~x00x01Lx00tfromTokenqx00~x00x01Lx00thumanCodeqx00~x00x02Lx00ahumanIDqx00~x00x01Lx00thumanNameqx00~x00x02Lx00nhumanStyleqx00~x00x02Lx00ninvalidMsgqx00~x00x02Lx00x02ipqx00~x00x02Lx00rleaderLevelIDqx00~x00x01Lx00x05logIDqx00~x00x01Lx00tosVersionqx00~x00x02Lx00npatrolFlagqx00~x00x01Lx00bportraitqx00~x00x02Lx00bproxyUrlqx00~x00x02Lx00nregionCodeqx00~x00x02Lx00bregionIDqx00~x00x01Lx00nregionNameqx00~x00x02Lx00nregionTypeqx00~x00x01Lx00bserverIpqx00~x00x02Lx00x06targetqx00~x00x02Lx00ttelMobileqx00~x00x02Lx00aunionIDqx00~x00x01Lx00x06unitIDqx00~x00x01Lx00bunitNameqx00~x00x02Lx00buserNameqx00~x00x02xpx00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x01pppsrx00x11java.lang.Integerx12xe2xa0xa4xf7x81x878x02x00x01Ix00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x00x00qx00~x00x06tx00rwizdom:100433sqx00~x00x04x00x01x88Qtx00x05xxxxxx00bdarkblueptx00x0f192.168.213.161pppqx00~x00x06tx00x00ppqx00~x00x06psqx00~x00x04x00x00x00x01tx00t127.0.0.1ptx00x0b17700000000sqx00~x00x04x00x00x02xbesqx00~x00x04x00x00x00x02tx00x0fxe5xb8x82xe7x9bx91xe7x9dxa3xe4xb8xadxe5xbfx83tx00x05xxx"
7) "maxInactiveInterval"
8) "xacxedx00x05srx00x11java.lang.Integerx12xe2xa0xa4xf7x81x878x02x00x01Ix00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x01Qx80"
9) "sessionAttr:UnionAuthToken"
10) "xacxedx00x05tx00$125ba47c-fe01-42b6-b5a2-8a87eb266ddc"
这次有,而且还有更多。
如何设置过期时间?
事实上,你可以添加一个过滤器并像往常一样设置会话的过期时间:
req.getSession().setMaxInactiveInterval(expireTime);
filterChain.doFilter(servletRequest, servletResponse);
会话存储摘要
Spring Session将会话封装在JavaWeb一层中,写业务时的接口保持不变,但底层存储已经从Tomcat中的内存变为Redis,用户还没有感知到。
如果能够使用哨点模式来保证Redis的高性能,感觉可以解决分布式会话的问题。
Session’s无效实现
HttpSession session = request.getSession();
if(session != null){
session.removeAttribute(/* here is your attr name*/);
session.invalidate ();
}
好像主要在这里session.invalidate ()
向上
// org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper.
// HttpSessionWrapper#invalidate
public void invalidate() {
checkState ();
this.无效 = true;
requestedSessionInvalidated = true;
setCurrentSession(null);
sessionRepository.delete(getId());
}
按id删除会话:
// org.springframework.session.data.redis.RedisOperationsSessionRepository#delete
public void delete(String sessionId) {
ExpiringSession session = getSession(sessionId, true);
if(session == null) {
return;
}
String key = getKey(sessionId);
expirationPolicy.onDelete(session);
// always delete they key since session may be null if just expired
this.sessionRedisOperations.delete(key);
}
数据也会在onDelete中删除:
public void onDelete(ExpiringSession session) {
long toExpire = roundUpToNextMinute(expiresInMillis(session));
String expireKey = getExpirationKey(toExpire);
expirationRedisOperations.boundSetOps(expireKey).remove(session.getId());
}
一张被盗的照片
文件
回到我的问题
第三方通过令牌调用接口创建会话非常简单,并且在调用完成后会话将失效。
哈哈
原地址:春季会议原则
欢迎访问我的博客:https://blog.duhbb.com
