1,什么是会话
session是客户端和服务器的通信会话技术,例如,如果用户登录,则登录后会将用户信息保存在session中
2,会话原理
3 .简单的会话示例
@ restcontrollerpublicclassindexcontroller {
@requestmapping(/createsession ) ) publicstringcreatesession ) httpservletrequestrequest,String username
htpsessionsession=request.getsession (;
session.setattribute(username,username ); 返回' success ';
}
@requestmapping(/getsession ) ) publicstringgetsession ) httpservletrequestrequest
htpsessionsession=request.getsession (;
stringusername=(string ) session.getattribute ) (username );
系统. out.println (username : ) username );
String id=session.getId (;
system.out.println(sessionid ) id; 返回用户名称3360 '用户名称'======' ' session id 3360 ' id;
}
@requestmapping(/basedecode ) ) privatestring base64 decode (string base64 value ) try { byte [ ] decodedcookiebytes=base rue
}catch(exceptione ) {return null;
}
}
}
在服务器端,cdd 51 F6 c-e2ab- 490 B- a4 F8-291 f 184913 b 3在base64中加密后创建会话。 (y2 rkntfmnmtztjhyi 00 otbilwe0zjgtmjkxzje4ndkxm
对于getSession,也将y2 rkntfmnmtztjhyi 00 otbilwe0zjgtmjkxzje4ndkxm2hxd GS导入请求标头,并在服务器上解密以找到相应的session
4 .分布式会话一致性问题
在分布式群集环境中,sessionid位于客户机上,session位于服务器上。 由于是分布式群集,因此客户端的会话id和会话不匹配。
5 .分布式会话一致性问题的解决方案
解决方案1 :设置1:nginx:ip_hash负载平衡算法
详情:通过nginx负载均衡算法的ip_hash,即ip绑定方式,绑定了各个客户端的和服务器。 a客户端访问第一个服务器,来自后面的a客户端的请求分发到第一个服务器。
缺点:负载均衡消失
#配置上游服务器
upstream backServer{
服务器127.0.0.1:8080;
server 127.0.0.1:8082;
ip_hash;
}
服务器{
listen 80
server_name www.baiyue.com;
位置/{
proxy _ pass http://后台服务器;
索引索引. html index.htm;
}
}
使用解决方案spring-session框架,建议底层实现原理是重写httpsession
org.spring帧work.boot
spring-boot-starter-data-redis
org.springframework.session
spring-session-data-redis
redis.clients
杰迪斯
importorg.spring framework.beans.factory.annotation.value; importorg.spring帧work.context.annotation.bean; importorg.spring framework.data.redis.connection.jedis.jedisconnectionfactory; importorg.spring framework.session.data.redis.config.annotation.web.http.enableredishttpsession; //此类配置与redis服务器的连接//maxInactiveIntervalInSeconds为SpringSession的过期时间(秒)
@ enableredishttpsession (maxinactiveintervalinseconds=1800 ) publicclassessionconfig(/冒号之后的值表示没有配置文件时的制动压力默认值
@ value (' $ { redis.hostname : localhost } ' )
String HostName;
@value('${Redis.port:6379} ) intPort;
@value('${Redis.password} ' )
字符串密码;
@ beanpublicjedisconnectionfactoryconnectionfactory (
jedisconnectionfactoryconnection=newjedisconnectionfactory (;
connection.setport (端口;
connection.set hostname (hostname );
连接. set password (密码; 返回连接;
}
}
importorg.spring framework.session.web.context.abstracthttpsessionapplicationinitializer; 初始化会话配置
publicclasssessioninitializerextendsabstracthttpsessionapplicationinitializer { publicsessioninitializer () session
}
}
application.yml
服务器:
port: 8080
spring:
redis:
database: 0
host: 192.168.178.110
port: 6379
password: 123
jedis:
pool:
最大活动: 8
最大等待:-1
max-idle: 8
最小-空闲: 0
timeout: 10000
redis:
hostname: 192.168.178.110
port: 6379
password: 123
启动8080和8081模拟集群,还可以获得8080创建的session、8081,实现了session的共享,实际上将session保存在redis中
解决方案基于令牌方法的推荐
实际上是token在redis中缓存。 因为redis可以在服务群集时共享分布式缓存
每次都用token存起来,用token得到
@ servicepublicclasstokenservice {
@ autowiredprivateredisserviceredisservice; //重新返回token
公共字符串put (对象对象) {
String token=getToken (;
redisservice.setstring(Token,object ); 返回令牌;
//获取信息
公共字符串获取(字符串令牌) {
stringreuslt=re disservice.getstring (token ); returnreuslt;
}publicString getToken () {returnUUID.randomUUID ) ).toString );
}
}
东京控制器
@ restcontrollerpublicclasstokencontroller {
@ autowiredprivatetokenservicetokenservice;
@value((${server.port} )专用服务器端口;
@requestmapping(/put ) ) public string put (stringnamevalue ) {
string token=token服务. put (name value ); 返回令牌'-'服务器端口;
}
@requestmapping((/get ) ) publicstringget ) (stringtoken )。
string value=token service.get (token ); 返回值'-'服务器端口;
}
}