Python 官方文档:入门教程 => 点击学习
目录1、引入背景2、使用方法3、工作流程4、缓存机制5、事件订阅6、总结1、引入背景 Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请
Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例session共享问题随之而来。
应用部署在Tomcat时,session是由Tomcat内存维护,如果应用部署多个实例,session就不能共享。spring Session就是解决为了解决分布式场景中的session共享问题。
Spring Session支持存储在Hazelcast 、Redis、mongoDB、关系型数据库,本文主要讨论session存储在Redis。
WEB.xml配置:
<!-- spring session -->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>
private void touch(String key) {
//并不是直接删除 key,而只是访问 key,通过惰性删除确保spring:session:sessions:expires键实时删除,
// 同时也保证多线程并发续签的场景下,key移动到不同spring:session:expirations键里面时,
//以spring:session:sessions:expires键实际ttl时间为准
this.redis.hasKey(key);
}
ConfigureNotifyKeyspaceEventsAction,开启键空间通知:
public void configure(RedisConnection connection) {
String notifyOptions = getNotifyOptions(connection);
String customizedNotifyOptions = notifyOptions;
if (!customizedNotifyOptions.contains("E")) {
customizedNotifyOptions += "E";
}
boolean A = customizedNotifyOptions.contains("A");
if (!(A || customizedNotifyOptions.contains("g"))) {
customizedNotifyOptions += "g";
}
if (!(A || customizedNotifyOptions.contains("x"))) {
customizedNotifyOptions += "x";
}
if (!notifyOptions.equals(customizedNotifyOptions)) {
connection.setConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS, customizedNotifyOptions);
}
}
RedishttpsessionConfiguration,注册监听事件:
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
RedisConnectionFactory connectionFactory,
RedisOperationsSessionRepository messageListener) {
......
//psubscribe del和expired事件
container.addMessageListener(messageListener,
Arrays.asList(new PatternTopic("__keyevent@*:del"),
new PatternTopic("__keyevent@*:expired")));
//psubscribe created事件
container.addMessageListener(messageListener, Arrays.asList(new PatternTopic(
messageListener.getSessionCreatedChannelPrefix() + "*")));
return container;
}
RedisOperationsSessionRepository,事件处理:
public void onMessage(Message message, byte[] pattern) {
......
if (channel.startsWith(getSessionCreatedChannelPrefix())) {
...
//处理spring:session created事件
handleCreated(loaded, channel);
return;
}
//非spring:session:sessions:expires事件不做处理
String body = new String(messageBody);
if (!body.startsWith(getExpiredKeyPrefix())) {
return;
}
boolean isDeleted = channel.endsWith(":del");
if (isDeleted || channel.endsWith(":expired")) {
......
if (isDeleted) {
//处理spring:session:sessions:expires del事件
handleDeleted(sessionId, session);
}
else {
//处理spring:session:sessions:expires expired事件
handleExpired(sessionId, session);
}
......
return;
}
}
事件订阅样例:
@Component
public class SessionExpiredListener implements ApplicationListener<SessionExpiredEvent> {
@Override
public void onApplicationEvent(SessionExpiredEvent event) {
......
}
}
Spring Session给我们提供了很好的分布式环境下资源共享问题解决思路,其基于Servlet 规范实现,业务使用时只需要简单配置就可以实现session共享,做到与业务低耦合,这都是以后我们项目开发中可以借签的设计理念。
以上就是浅谈Spring Session工作原理的详细内容,更多关于Spring Session的资料请关注编程网其它相关文章!
--结束END--
本文标题: 浅谈Spring Session工作原理
本文链接: https://www.lsjlt.com/news/128458.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0