SpringBoot 2.0 学习(十)Nginx负载均衡与session共享
负载均衡的使用场景
当项目上线后,如果要修复bug或扩充功能,都需要重启tomcat服务。此时,正在使用应用的用户们就需要等待服务器的重启,而这就会造成不好的用户体验。还有,当仅仅只有一台tomcat服务时,如果CPU或内存达到极限,就会很难顶住压力。而负载均衡就是解决这些问题的方案。
session同步
session在多个服务或服务器间共享,应用实例数量的多少不会影响用户登录状态,多用于(SSO)单点登录
如何在SpringBoot中实现
第一步:添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-data-redis</artifactId>
</dependency>
<!-- 2.0以上高版本redis的lettuce需要commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
第二步:控制层controller类编写
redis的配置和序列化的代码参考上篇博文SpringBoot 2.0 学习(九)集成redis缓存技术
@Controller
public class MainController {
private static final String STR_SESSION_KEY = "name";
@GetMapping("/")
public String index() {
return "index";
}
@PostMapping("/setSession")
@ResponseBody
public Map<String, Object> setSession(String value, HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
request.getSession().setAttribute(STR_SESSION_KEY, value);
map.put("msg", "ok");
return map;
}
@PostMapping("/getSession")
@ResponseBody
public Map<String, Object> getSession(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
HttpSession session = request.getSession();
Object value = session.getAttribute(STR_SESSION_KEY);
map.put("value", value);
map.put("id", session.getId());
map.put("port", request.getLocalPort());
map.put("msg", "ok");
return map;
}
}
第三步:前端显示页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>spring boot 2.0——负载均衡与session同步</title>
<style type="text/css">
/*<![CDATA[*/
tr {
text-align: center;
COLOR: #0076C8;
BACKGROUND-COLOR: #F4FAFF;
}
/*]]>*/
</style>
<script src="//cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
var app = angular.module('app', []);
app.controller('MainController', function($rootScope, $scope, $http) {
$scope.value = '老陈';
$scope.setSession = function() {
$http({
url : '/setSession?value=' + $scope.value,
method : 'POST'
});
}
$scope.getSession = function() {
$http({
url : '/getSession',
method : 'POST'
}).success(function(r) {
$scope.sesssionId = r.id
$scope.sesssion = r.value
$scope.port = r.port
});
}
});
/*]]>*/
</script>
</head>
<body ng-app="app" ng-controller="MainController">
<h1>玩转spring boot——负载均衡与session同步</h1>
<h4>
<a href="https://blog.csdn.net/sinat_38798245">from 皎洁de时光的博客</a>
</h4>
<input type="text" ng-model="value" />
<input type="button" value="设置" ng-click="setSession()" /><br />
<input type="button" value="获取" ng-click="getSession()" /><br />
<h3>结果:</h3>
<table cellspacing="1" style="background-color: #a0c6e5">
<thead>
<tr>
<td>属性</td>
<td>值</td>
</tr>
</thead>
<tr>
<td>session id</td>
<td>{{sesssionId}}</td>
</tr>
<tr>
<td>session值</td>
<td>{{sesssion}}</td>
</tr>
<tr>
<td>本地端口</td>
<td>{{port}}</td>
</tr>
</table>
<br />
</body>
</html>
第四步:配置nginx环境,实现负载均衡,启动redis服务,实现session同步
首先,官网下载nginx版本,我这里用的是1.14.2版本
upstream节点为负载均衡配置
下面指定了两个server实例,对于localhost的8080和8081端口
server节点监听80端口,会跳转到反向代理的名称为协议“http://tomcat”的upstream上
这里的“http://tomcat”,要与upstream设置的名称相同
解压文件里面的nginx.exe可执行文件双击,或者如下操作,则nginx配置成功
第五步:复制项目,分别命名为demo1和demo2,端口分别为8081和8082
- 启动项目,可以先打包成jar包形式,然后在文件目录使用 java -jar 项目包
- 直接在开发工具里面运行springboot项目,确保运行正常
- 输入网址http:localhost,访问页面,效果如下
点击获取,可以发现本地端口会随机改变,但是session id和session值是不会随之改变的,这就实现了将一台服务器上的压力分给了两台服务器,同时还保证了session值一直,实现数据共享。
文章参考
刘冬的博客