SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)

    如果我们需要对项目进行横向扩展搭建集群,那么可以利用一些硬件或者软件工具(比如 Nginx)来做负载均衡,此时,来自同一个用户的 HTTP 请求就有可能被分发到不同的实例上去,如何保证各个实例之间 Session 的同步就成为一个必须解决的问题。

    Spring Boot 提供了自动化的 Session 共享配置,它结合 Redis 可很方便地解决这个问题。使用 Redis 解决 session 共享的原理非常简单,就是把原本储存在不同服务器上的 session 拿出来放到一个独立的服务器上:

SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)_第1张图片

 

    当一个请求到达 Nginx 服务器上时,首先请求分发,假设请求被 server1 处理了,server1 在处理请求时,无论存储还是读取 session 的操作,都是去操作 session 服务器而不是自身内存中的 session,其他 server 也是如此,这样就实现了 session 共享。 
 

一、结合 Redis 进行 Session 共享配置 

1,Redis 安装

首先我们需要一个 Redis 服务来作为 Session 服务器,Redis 的安装可以参考我之前的文章:

  • Redis - 安装和部署教程1(CentOS下单个Redis实例安装)

 

2,项目配置

(1)编辑 pom.xml 文件,添加 Redis 和 Session 依赖:

    除了 Redis 依赖之外,这里还要提供 spring-session-data-redis 依赖,Spring Session 可以做到透明化地替换掉应用的 Session 容器。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<dependency>

    <groupId>org.springframework.bootgroupId>

    <artifactId>spring-boot-starter-data-redisartifactId>

    <exclusions>

        <exclusion>

            <groupId>io.lettucegroupId>

            <artifactId>lettuce-coreartifactId>

        exclusion>

    exclusions>

dependency>

<dependency>

    <groupId>redis.clientsgroupId>

    <artifactId>jedisartifactId>

dependency>

<dependency>

    <groupId>org.springframework.sessiongroupId>

    <artifactId>spring-session-data-redisartifactId>

dependency>


(2)接着在 application.properties 中配置 Redis 连接信息:

# 基本连接信息配置
spring.redis.database=0
spring.redis.host=192.168.60.133
spring.redis.port=6379
spring.redis.password=123
# 连接池信息配置
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0

 

3,创建测试接口

    创建一个 Contoller 用来执行测试操作,里面提供了两个方法:一个 save 接口用来向 Session 中存储数据,还有一个 get 接口用来从 Session 中获取数据。

  • 为方便演示,这里注入了项目启动的端口号 server.port,主要是为了区分到底是哪个服务器提供的服务。
  • 虽然这里还是操作的 HttpSession,但是实际上 HttpSession 容器已经被透明替换,真正的 Session 此时存储在 Redis 服务器上。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@RestController

public class HelloController {

    @Value("${server.port}")

    String port;

 

    @GetMapping("/save/{name}")

    public String saveName(@PathVariable("name")String name, HttpSession session) {

        session.setAttribute("name", name);

        return port;

    }

 

    @GetMapping("/get")

    public String getName(HttpSession session) {

        Object s =session.getAttribute("name");

        return port + ":" + session.getAttribute("name").toString();

    }

}

 

4,运行项目

(1)最后将项目打成 jar 包上传到 CentOS 上,然后执行如下两条命令启动 2 个项目(使用不同端口):

nohup 表示不挂断程序运行,即当终端窗口关闭后,程序依然在后台运行,最后的 & 表示让程序在后台运行。

1

2

nohup java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8080 &

nohup java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8081 &


(2)如果上面执行后可能会显示“nohup: 忽略输入并把输出追加到"nohup.out"”,我们直接回车即可。

SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)_第2张图片

 

5,开始测试

(1)首先我们访问 8080 这个项目的 /save 接口存放一个 session:

SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)_第3张图片

 

(2)接着访问 8081 项目的 /get 接口获取 session,可以发现虽然它们是不同的项目,但是 session 是共享的。

原文:SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)

 

二、使用 Nginx 实现负载均衡

1,安装运行

(1)首先下载 Nginx 源码并解压:

1

2

wget https://nginx.org/download/nginx-1.17.0.tar.gz

tar -zxvf nginx-1.17.0.tar.gz


(2)然后进入解压目录中执行编译安装:

1

2

3

4

cd nginx-1.17.0

./configure

make

make install


(3)安装成功后,找到 Nginx 安装目录,执行 sbin 目录下的 nginx 文件启动 nginx,命令如下:

1

/usr/local/nginx/sbin/nginx


(4)启动后默认端口是 80,我们可以使用浏览器直接访问:

SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)_第4张图片

 

2,修改配置文件

(1)接下来进入 Nginx 安装目录修改配置文件:

1

vi /usr/local/nginx/conf/nginx.conf


(2)对 nginx.conf 文件进行编辑,编辑内容如下:修改说明:

  • 首先配置上游服务器,即两个 real server,两个 real server 的权重都是 1,意味着请求将平均分配到两个 real server 上。
  • 然后在 server 中配置拦截规则,将拦截到的请求转发到定义好的 real server 上。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

upstream hangge.com {

    server 192.168.60.133:8080 weight=1;

    server 192.168.60.133:8081 weight=1;

}

 

server {

    listen       80;

    server_name  localhost;

 

    #charset koi8-r;

 

    #access_log  logs/host.access.log  main;

 

    location / {

        proxy_pass http://hangge.com;

        proxy_redirect default;

    }


(3)配置完成后,执行如下命令重启 Nginx:

1

/usr/local/nginx/sbin/nginx -s reload

 

3,请求分发测试

(1)首先调用 /save 接口存储数据。下图可以看到虽然调用的端口是 80,但实际请求被 Nginx 服务器转发到 8081 这个服务上:

原文:SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)

 

(2)接着调用 /get 接口获取数据,可以看到这次请求被分发到 8080 这个服务上。同时也可以发现,它们的 session 是共享的。

SpringBoot - 结合Redis实现Session共享、结合Nginx实现负载均衡(请求分发)_第5张图片


原文出自:www.hangge.com  转载请保留原文链接:https://www.hangge.com/blog/cache/detail_2650.html

你可能感兴趣的:(java)