springboot集群session共享问题(springSession+redis+nginx)
单服务架构到分布式/集群的演变
在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 Session 共享问题,但是在分布式/集群项目中,Session 共享则是一个必须面对的问题。
在这样的集群架构中,如果不去解决session共享问题,那么就会给程序带来问题。
如果在某次登录时,nginx将请求分发给tomcat1,登录完以后tomcat1将session记下,后续的请求可能又会分发给tomcat2,但是toncat2中没有session信息,那么就会让你去重新登录。
或者是分布式项目,登录状态是在多个项目中共享的。
如何解决session共享问题
解决办法很简单,把所有项目的共享数据放入一个公共的容器中,大家都从这个容器中存取就可以了,主流的方案就是Redis缓存。
当所有的服务存储session时都向redis中存,需要session数据时就向redis中取这样就解决了session共享问题。那么对于springboot项目该如何实现呢?
springboot集成springSession+redis实战
创建springboot项目,选中redis ,web ,springSession如图,在这里选择的版本是2.1.4如果是2.1.5以上版本的话还需要加Spring Security依赖。
配置redis
server.port=8081
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.database=0
编写测试接口测试
package com.example.demo.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping("set")
public R set(String msg,HttpSession session,HttpServletRequest request) {
int port=request.getServerPort();
String sessionId = session.getId();
session.setAttribute("user",msg);
return new R(1,null,port,sessionId);
}
@RequestMapping("get")
public R get(HttpSession session,HttpServletRequest request) {
int port=request.getServerPort();
String sessionId = session.getId();
return new R(2,session.getAttribute("user"),port,sessionId);
}
public class R{
private int code;
private Object msg;
private int port;
private String sessionId;
public R(int code,Object msg,int port,String sessionId){
this.code = code;
this.msg = msg;
this.port = port;
this.setSessionId(sessionId);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getMsg() {
return msg;
}
public void setMsg(Object msg) {
this.msg = msg;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
}
}
就这摩多,是不是特简单,下面就打包运行试试。
为了测试我们打两个包
分别启动两个项目,注意端口不能一样呦~。
首先调用8080端口的set接口
再调用8081端口的get接口
实验结果证明这种方法实现session共享成功
然后再去redis数据库中看看是否存在此session,不用看了,肯定存在~
下边使用nginx代理的方式访问
首先是nginx的配置
upstream session.test{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://session.test;
proxy_redirect default;
}
}
从配置中看到,nginx监听80端口。而且两个服务的权重是一致的。
启动nginx后访问测试,注意端口都变成了80
测试结果是ok的一样能够共享session
猜你喜欢
框架
1442
一、创建项目创建两个项目projectA,projectB二、pom文件相同parentartifactIdspringSession/artifactIdgroupIdorg.example/groupIdversion1.0-SNAPSHOT/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIda
blog
rabbitmq集群搭建
rabbitmq,mqtt协议
965
集群目的就是为了实现rabbitmq的高可用性,集群分为2种普通集群:主备架构,只是实现主备方案,不至于主节点宕机导致整个服务无法使用镜像集群:同步结构,基于普通集群实现的队列同步普通集群
blog
线程的同步问题
java基础
7636
多线程带来的问题:线程有时候回和其他线程共享一些资源,比如内存、数据库等。当多个线程同时读写同一份共享资源的时候,可能会发生冲突。这时候,我们就需要引入线程“同步”机制,即各位线程之间要有顺序使用
算法基础,linux
4641
问题描述springboot项目在跨域名调用接口,并且需要传自定义的请求头时报错:AccesstoXMLHttpRequestat'http://ydatestapi.libawall.com
javascript,加密算法
259
js示例代码
functiongeneratePrivateKey(length=64){
constbytes=newUint8Array(length);
window.crypto.getRandomValues(bytes);
returnBigInt(`0x${bytes.reduce((data,byte)=data+('00'+byte.toString(16)).slice(-
框架
8115
多么痛的领悟~分离资源打包后运行项目,启动失败数据源初始化失败~检查问题,这种情况下没有打印错误日志,首先配置一下日志,将错误报告在控制台中打印出来。resources文件夹下创建一个
rabbitmq,haproxy
812
搭建完成rabbitmq镜像集群后,客户端可以根据每个节点的ip进行连接,但是如果将某节点的ip地址写死在代码里,那将失去了扩展性,而且不利于维护。此时需要一个代理服务器,来让三台mq服务平摊压
weblog
8521
执行一个脚本时会检查访问的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。那么什么是跨域呢?跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域时,
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。