springboot集群session共享问题(springSession+redis+nginx)

weblog 6630 0 0

单服务架构到分布式/集群的演变

在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 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
rabbitmq,mqtt协议 965 目的就是为了实现rabbitmq的高可用性,分为2种普通:主备架构,只是实现主备方案,不至于主节点宕机导致整个服务无法使用镜像:同步结构,基于普通实现的队列同步普通
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 执行一个脚本时会检查访的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访。那么什么是跨域呢?跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域时,
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。