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

weblog 精帖
340

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

在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 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

 

猜你喜欢
  • blog nginx配置负载均衡以及负载均衡的策略的选取(linux)

    nginx配置负载均衡以及负载均衡的策略的选取(linux) 一、nginx配置负载均衡 安装nginx,修改conf/nginx.conf配置文件 在http块下添加 #配置动态服务器列表 upstream te
  • ofc java web项目获取nginx反向代理后的客户端的真实ip

    java web项目获取nginx反向代理后的客户端的真实ip
  • blog 汉诺塔

    汉诺塔:汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在
  • blog 温故01背包

    01背包是动态规划算法的一个经典例目: 在n种物品中选取若干件(每种物品只有一件只能选择一次) 放在空间为W的背包里,每种物品的体积为wigth[1],wigth[2],wigth[3],wigth[n], 与之相对应
  • blog 迷宫-js实现

    迷宫<!DOCTYPE html><html> <head> <meta charset='UTF-8'> <title></title> <script> var flag=true; window.onload = f
  • blog 枚举算法案例--熄灯

    熄灯1.描述有一个有按钮组成的矩阵,其中每行有6个按钮,5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上下左右)的灯都会改变一次。即(原来亮的变暗,原来暗的变亮)对矩阵中的每一盏灯设置一个初始状态。请你写一
  • ofc c#方法参数传值

    c#方法参数传值
  • blog 八皇后

    八皇后,是一个古老而著名的,是回溯算法的典型案例。该是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,有多少种摆法。1.方
  • blog springboot + thymeleaf样式引入和获取项目名称

    样式引入: <link rel='stylesheet' th:href='@{/layui/css/layui.css}'  media='all'> js引入: <script type='text/java
  • blog springboot打包分离资源文件时遇到的

    多么痛的领悟~分离资源打包后运行项目,启动失败数据源初始化失败~检查,这种情况下没有打印错误日志,首先配置一下日志,将错误报告在控制台中打印出来。resources文件夹下 创建一个 log4j.properties 文件log4j.r