如果我们需要对项目进行横向扩展搭建集群,那么可以利用一些硬件或者软件工具(比如 Nginx)来做负载均衡,此时,来自同一个用户的 HTTP 请求就有可能被分发到不同的实例上去,如何保证各个实例之间 Session 的同步就成为一个必须解决的问题。
当一个请求到达 Nginx 服务器上时,首先请求分发,假设请求被 server1 处理了,server1 在处理请求时,无论存储还是读取 session 的操作,都是去操作 session 服务器而不是自身内存中的 session,其他 server 也是如此,这样就实现了 session 共享。
一、结合 Redis 进行 Session 共享配置
1,Redis 安装
2,项目配置
(1)编辑 pom.xml 文件,添加 Redis 和 Session 依赖:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </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 服务器上。
@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 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"”,我们直接回车即可。
5,开始测试
二、使用 Nginx 实现负载均衡
1,安装运行
(1)首先下载 Nginx 源码并解压:
wget https://nginx.org/download/nginx-1.17.0.tar.gz tar -zxvf nginx-1.17.0.tar.gz
(2)然后进入解压目录中执行编译安装:
cd nginx-1.17.0 ./configure make make install
(3)安装成功后,找到 Nginx 安装目录,执行 sbin 目录下的 nginx 文件启动 nginx,命令如下:
/usr/local/nginx/sbin/nginx
(4)启动后默认端口是 80,我们可以使用浏览器直接访问:
2,修改配置文件
vi /usr/local/nginx/conf/nginx.conf
(2)对 nginx.conf 文件进行编辑,编辑内容如下:
修改说明: 首先配置上游服务器,即两个 real server,两个 real server 的权重都是 1,意味着请求将平均分配到两个 real server 上。 然后在 server 中配置拦截规则,将拦截到的请求转发到定义好的 real server 上。
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:
/usr/local/nginx/sbin/nginx -s reload
3,请求分发测试
(1)首先调用 /save 接口存储数据。下图可以看到虽然调用的端口是 80,但实际请求被 Nginx 服务器转发到 8081 这个服务上: