解决分布式部署回话丢失:Spring Session+Redis

有这么一种场景,当一个服务部署好了,可能难以承载上万的并发,需要进行流量分发,一台主服务器,多台服务器(节点)共同承载,说白了就是所谓的负载均衡,可承载更大的流量。但是问题是当进入系统是通过节点A,已经在节点A完成登陆进入系统了,可能某一瞬间节点A挂了,或者这个用户被分到节点B了,难道还需要重新在节点B重新登陆吗,当然不是。其实如果节点B也有用户会话信息就可以解决问题了。spring session就是解决这个问题的,她把所有用户会话放在redis中,所有节点都从redis中获取会话信息,这样的话对于用户就好像是在同一个节点,用户是无感知的。具体操作如下:

一、引入maven依赖

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

</dependencies>

二、配置application.properties

server.port=8080
#下面3个不可省略
spring.redis.host=localhost
spring.redis.port=6379
# spring session使用存储类型
spring.session.store-type=redis

三、在启动类中加入@EnableRedisHttpSession  注解

package com.shyroke;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@EnableCaching
@EnableRedisHttpSession
@SpringBootApplication
public class SpringbootSessionApplication {

public static void main(String[] args) {
SpringApplication.run(SpringbootSessionApplication.class, args);
}
}

四、编写控制器

package com.shyroke.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = “/”)
public class IndexController {

@ResponseBody
@RequestMapping(value = “/session”)
public Map<String, Object> getSession(HttpServletRequest request) {
request.getSession().setAttribute(“username”, “admin”);
Map<String, Object> map = new HashMap<String, Object>();
map.put(“sessionId”, request.getSession().getId());
return map;
}

@ResponseBody
@RequestMapping(value = “/get”)
public String get(HttpServletRequest request) {
String userName = (String) request.getSession().getAttribute(“username”);

return userName;
}

}

五、测试

  • 先输入http://localhost:8080/session,在session中设置一个值

  • http://localhost:8080/get,获取session中的值



  • 复制这个工程,application.properties中的server.port=8081,然后访问“http://localhost:8081/get”,如下获取到了另一个工程中设置的session的值。

本站的文章多是老王开发工作中问题的记录,一个字一个字敲的,切实可行,可以分享,需要留个原文链接,至少也意思意思吧!
vsalw技术博客! » 解决分布式部署回话丢失:Spring Session+Redis

每个人都是以自己独特的方式体味生活,或许别人不理解,但自己知道:其中的酸甜苦辣就叫做幸福!

认同! 瞎扯淡!