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

weblog 4041 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

 

猜你喜欢
java基础 6226 多线程带来的:线程有时候回和其他线程一些资源,比如内存、数据库等。当多个线程同时读写同一份资源的时候,可能会发生冲突。这时候,我们就需要引入线程“同步”机制,即各位线程之间要有顺序使用
算法基础,linux 1087 描述springboot项目在跨域名调用接口,并且需要传自定义的请求头时报错:AccesstoXMLHttpRequestat'http://ydatestapi.libawall.com
框架 6812 多么痛的领悟~分离资源打包后运行项目,启动失败数据源初始化失败~检查,这种情况下没有打印错误日志,首先配置一下日志,将错误报告在控制台中打印出来。resources文件夹下创建一个
weblog 5303 执行一个脚本时会检查访的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访。那么什么是跨域呢?跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域时,
数据结构与算法 6296 八皇后,是一个古老而著名的,是回溯算法的典型案例。该是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行
weblog 226 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。包含关系:一个进程内可以有多个线程(默认有一个主线程),线程是进程的一部分,必须依赖于进程而存在,不能独立存在。资源:进程之间是不资源的,多个线程之间是资源的,所以存在资源竞争的
框架 2556 样式引入:linkrel="stylesheet"th:href="@{/layui/css/layui.css}"media="all"js引入:scripttype="text/javascript"th:src="@{/js/utf8-jsp/third-party/SyntaxHighlighter/shCore.js}"/scripta标签:ath:href="@{/forgetPass
数据结构与算法 2859 迷宫!DOCTYPEhtmlhtml head metacharset="UTF-8" title/title script varflag=true; window.onload
目录