SpringBoot 2.0 学习(十)Nginx负载均衡与session共享

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

  1. 启动项目,可以先打包成jar包形式,然后在文件目录使用 java -jar 项目包
  2. 直接在开发工具里面运行springboot项目,确保运行正常
  3. 输入网址http:localhost,访问页面,效果如下
    在这里插入图片描述
    在这里插入图片描述
    点击获取,可以发现本地端口会随机改变,但是session id和session值是不会随之改变的,这就实现了将一台服务器上的压力分给了两台服务器,同时还保证了session值一直,实现数据共享。

文章参考
刘冬的博客

猜你喜欢

转载自blog.csdn.net/sinat_38798245/article/details/87860567