LNMT群集基于Redis实现Session共享

前言:
为了使web能适应大规模的访问,需要实现应用的集群部署。集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无论用户的请求被转发到哪个服务器上都能保证用户的正常用,也就是需要实现session的共享机制。

在集群系统下实现session统一的有如下几种方案:
1、请求精确定位:sessionsticky,例如基于访问ip的hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器保存了用户的session登录信息,如果宕机,则等同于单点部署,会丢失,会话不复制。
2、session复制共享:sessionreplication,如tomcat自带session共享,主要是指集群环境下,多台应用服务器之间同步session,使session保持一致,对外透明。 如果其中一台服务器发生故障,根据负载均衡的原理,调度器会遍历寻找可用节点,分发请求,由于sessio已同步,故能保证用户的session信息不会丢失,会话复制,。
此方案的不足之处:
必须在同一种中间件之间完成(如:tomcat-tomcat之间).
session复制带来的性能损失会快速增加.特别是当session中保存了较大的对象,而且对象变化较快时, 性能下降更加显著,会消耗系统性能。这种特性使得web应用的水平扩展受到了限制。Session内容通过广播同步给成员,会造成网络流量瓶颈,即便是内网瓶颈。在大并发下表现并不好。
3、基于cache DB缓存的session共享:即使用cacheDB存取session信息,应用服务器接受新请求将session信息保存在cache DB中,当应用服务器发生故障时,调度器会遍历寻找可用节点,分发请求,当应用服务器发现session不在本机内存时,则去cache DB中查找,如果找到则复制到本机,这样实现session共享和高可用。

这里将使用第三种方案,实现session会话共享,将采用Redis来做cache DB。


博文大纲:
一、环境准备
二、配置Nginx反向代理服务器
三、配置Tomcat服务器
四、配置Redis服务器
五、配置Tomcat连接Redis
六、安装部署MySQL数据库
七、配置Tomcat连接MySQL数据库

一、环境准备

在进行下面配置前,先下载我提供的源码包,并自行上传至对应的服务器。

二、配置Nginx反向代理服务器

这里配置Nginx反向代理,只是实现它一个简单的代理功能,若想优化这个反向代理服务器,那么最好参考博文:Nginx安装、实现反向代理及深度优化进行配置。

以下操作均在192.168.20.2的Nginx服务器上进行

[[email protected] ~]# yum -y erase httpd       #卸载自带的web服务
[[email protected] ~]# yum -y install openssl-devel pcre-devel       #安装所需依赖
[[email protected] ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src      #解包
[[email protected] ~]# cd /usr/src/nginx-1.14.0/      #切换至解压后的目录
[[email protected] conf]# ./configure --user=www --group=www --prefix=/usr/local/nginx && make && make install
#编译安装
[[email protected] nginx-1.14.0]# cd /usr/local/nginx/conf/     #切换至Nginx配置文件主目录
[[email protected] conf]# vim nginx.conf              #编辑Nginx配置文件,写入以下内容
http {                    #在http字段添加以下内容
upstream backend {
        server 192.168.20.3:8080 weight=1 max_fails=2 fail_timeout=10s;
        server 192.168.20.4:8080 weight=1 max_fails=2 fail_timeout=10s;
    }
    server {                      #定位到server字段
 location / {                #在location字段下面添加以下内容,并注释掉下面开头两行
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://backend;       #主要写入这一行,以下的是优化,可选写入
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        }
             }
}
#修改完成后,保存退出即可
[[email protected] conf]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/           #对Nginx命令做软连接
[[email protected] conf]# useradd -M -s /sbin/nologin www   #创建运行用户
[[email protected] conf]# nginx -t          #检查配置文件
[[email protected] conf]# nginx            #启动Nginx服务

至此,这台Nginx就可以提供基本的反向代理功能了,接下来配置Tomcat服务器。

三、配置Tomcat服务器

以下操作需要在两台Tomcat服务器上分别配置

主机Tomcat1操作如下:

[[email protected] ~]# ls | grep tomcat    #上传下面的源码包
apache-tomcat-8.5.35.tar.gz
[[email protected] ~]# tar zxf apache-tomcat-8.5.35.tar.gz -C /usr/src
[[email protected] ~]# mv /usr/src/apache-tomcat-8.5.35 /usr/local/tomcat
[[email protected] ~]# cd /usr/local/tomcat/conf/
[[email protected] conf]# vim server.xml
<Host name="localhost"  appBase="webapps"    #找到Host字段
            unpackWARs="true" autoDeploy="true">   #在下面添加以下配置
        <Context docBase="/web/webapp1" path="" reloadable="true"/>
#以上是配置虚拟主机,指定网页根目录是/web/webapp1。添加后保存退出
[[email protected] conf]# mkdir -p /web/webapp1    #创建网页根目录
[[email protected] conf]# vim /web/webapp1/index.jsp    #编写首页文件如下
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>tomcat-1</title>    #稍后在tomcat2主机上,需修改title字段中的数字改为2,以便查看负载均衡效果
</head>
<body>
<h1><font color="red">Session serviced by tomcat</font></h1>
<table aligh="center" border="1">
<tr>
<td>Session ID</td>
<td><%=session.getId() %></td>
<% session.setAttribute("abc","abc");%>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
<html>
[[email protected] conf]# /usr/local/tomcat/bin/startup.sh     #启动tomcat服务

将以上Tomcat1主机的所有操作在Tomcat2主机上同样配置一次

当Tomcat2主机也配置完成后,即可使用客户端访问Nginx代理服务器(访问:192.168.20.2),多次刷新页面,会依次看到以下页面(注意,其Session ID并不一样):

接下来配置Redis缓存服务器,Redis缓存服务器存在的意义就是将客户端的session会话信息保存下来,用于Tomcat服务器共享这个session会话信息,从而使其不要每次客户端请求都更新session会话。

四、配置Redis服务器

[[email protected] ~]# ls | grep redis     #上传下面的源码包
redis-4.0.14.tar.gz
[[email protected] ~]# tar zxf redis-4.0.14.tar.gz -C /usr/src    #解包
[[email protected] ~]# cd /usr/src    #切换至解压后的路径
[[email protected] src]# mv redis-4.0.14/ /usr/local/redis    #直接移动到指定路径并重命名
[[email protected] src]# cd /usr/local/redis/    #切换至redis目录
[[email protected] redis]# make && make install    #无需配置,直接编译安装即可
[[email protected] redis]# cd utils/       #进入该子目录
[[email protected] utils]# ./install_server.sh     #对Redis进行初始化
#初始化的所有选项保持默认,一路回车确认即可
#是在确认监听端口、配置文件、日志文件、pid存放路径等信息
 .............#省略部分内容
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
#出现上述内容,则表示初始化成功
[[email protected] utils]# vim /etc/redis/6379.conf     #编辑Redis配置文件
bind 0.0.0.0           #找到没有被注释的这一行,修改为0.0.0.0
# requirepass foobared         #定位到改行,修改如下:
 requirepass 123.com            #Redis的密码为123.com
#修改完成后,保存退出即可。
[[email protected] utils]# /etc/init.d/redis_6379 restart     #重启Redis服务
[[email protected] utils]# redis-cli -h 192.168.20.5    #登录数据库
192.168.20.5:6379> set a b      #插入数据测试
(error) NOAUTH Authentication required.    #插入失败,因为没有进行密码验证
192.168.20.5:6379> AUTH 123.com    #使用AUTH进行验证,密码就是配置文件中定义的“123.com”
OK
192.168.20.5:6379> set a b       #再次插入数据
OK      #成功

至此,Redis服务器就配置成功了。接下来配置Tomcat,使其可以将Session信息写入到Redis。

五、配置Tomcat连接Redis

1、主机Tomcat1配置如下:

[[email protected] ~]# cd /usr/local/tomcat/lib/
[[email protected] lib]# rz            #将我网盘中的以下四个包文件上传至当前目录
commons-pool2-2.4.2.jar  mysql-connector-java-5.1.22.jar
jedis-2.9.0.jar          tomcat85-session-redis-1.0.jar
[[email protected] lib]# vim ../conf/context.xml    #编辑这个文件
    <Manager pathname="" />   #定位到这行,去掉其注释符号,并在该行下写入以下内容
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
    <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
    host="192.168.20.5"           #指定Redis服务器IP
    password="123.com"         #指定Redis的密码
    port="6379"                      #指定Redis监听端口
    database="0"                     #是否可以写入Redi数据库,0为是
</Context>     #以上的内容在末尾这行上面添加
#编辑完成后,保存退出即可,然后重启Tomcat
[[email protected] lib]# /usr/local/tomcat/bin/shutdown.sh
[[email protected] lib]# /usr/local/tomcat/bin/startup.sh
#上述在../conf/context.xml文件中写入的无注释配置如下:
    <Manager pathname="" />
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
    <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
    host="192.168.20.5"
    password="123.com"
    port="6379"
    database="0"
    maxInactiveInterval="60" />

上述在主机Tomcat1上进行的操作,需要在主机Tomcat2上进行相同的配置(自行配置,这里就不写了)。

主机Tomcat2配置完成后,客户端访问Nginx反向代理进行测试,会看到客户端的请求依然是分发到后端两台Tomcat主机上,但是session会话ID不会发生变化了,说明session会话信息已经保存在了Redis服务器上,两台Tomcat主机从Redis上获取session会话信息,多次刷新页面,session会话都不会变化,如下:

并且可以在Redis服务器上查看到保存的session会话信息,如下:

六、安装部署MySQL数据库

这里只是测试环境,直接下载我提供的源码包中的MySQL包及mysql.sh脚本文件,进行脚本安装即可,若需要优化配置MySQL数据库,还请参考博文:Centos7搭建MySQL数据库进行安装。

脚本安装过程如下:

[[email protected] ~]# ls | grep mysql     #上传下面两个文件到MySQL服务器上
mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz
mysql.sh
[[email protected] ~]# sh mysql.sh      #执行此命令后,先去进行第七节操作,这里安装时间较长
Starting MySQL... SUCCESS!      #输出此信息表示MySQL部署成功
mysql: [Warning] Using a password on the command line interface can be insecure.

七、配置Tomcat连接MySQL数据库

1、主机Tomcat1配置如下:

[[email protected] lib]# cd /usr/local/tomcat/webapps    #切换至源码包默认的网页根目录
[[email protected] webapps]# mv ROOT /web/webapp1/    #将ROOT目录复制到现在的根目录下

现在客户端访问主机Tomcat1的8080端口/ROOT,如下(这里主要是为了展示Tomcat为我们提供的连接MySQL数据库的方法,可以不跟做):

点击如下:

然后看到的页面就是官方给我们的连接MySQL数据库的文档:

接下来根据文档提示,在MySQL数据库上创建用于测试的用户及表等。

2、以下操作在MySQL数据库上进行配置:

[[email protected] ~]# mysql -uroot -p123     #登录到MySQL,脚本安装的默认密码是123
mysql> grant all on *.* to [email protected]‘192.168.20.%‘ identified by ‘javapasswd‘;
#创建测试用户
mysql> create database javatest;    #创建测试库
mysql> use javatest;      #切换至创建的库
mysql> create table testdata(id int not null auto_increment primary key,foo varchar(25),bar int);
#创建表
mysql> insert into testdata(foo,bar) values (‘hello‘,‘123456‘),(‘ok‘,‘654321‘),(‘lvtest‘,‘123123‘);
#向表中插入数据
mysql> select * from testdata;    #查询插入的数据如下:
+----+--------+--------+
| id | foo    | bar    |
+----+--------+--------+
|  1 | hello  | 123456 |
|  2 | ok     | 654321 |
|  3 | lvtest | 123123 |
+----+--------+--------+
3 rows in set (0.00 sec)

3、配置主机Tomcat1

[[email protected] ~]# vim /usr/local/tomcat/conf/context.xml     #编辑context.xml配置文件
#在文件末尾</Context> 之上添加以下内容
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="javauser" password="javapasswd" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://192.168.20.6:3306/javatest"/>
</Context>      #在最后这行上面添加以上内容
#添加后保存退出即可
[[email protected] ~]# mkdir /web/webapp1/WEB-INF   #创建目录
[[email protected] ~]# vim /web/webapp1/WEB-INF/web.xml   #写入以下内容
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>
#写入后,保存退出
[[email protected] ~]# cd /web/webapp1/   #切换至网页根目录
[[email protected] webapp1]# vim test.jsp     #编写测试文件
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
<html>
<head>
<title>MySQL-1</title>    #在第二台Tomcat进行操作时,修改title中的1为2,以便测试负载均衡效果
</head>
<body>
connect MySQL<br>
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://192.168.20.6:3306/javatest";    #指定MySQL监听IP及端口
String username = "javauser";         #连接MySQL的用户
String password = "javapasswd";     #用户密码
Class.forName(driverClass);
Connection conn=DriverManager.getConnection(url, username, password);
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from testdata");
while(rs.next()){
out.println("<br>foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
</body>
</html>
#写入后,保存退出即可,然后重启Tomcat服务
[[email protected] lib]# /usr/local/tomcat/bin/shutdown.sh
[[email protected] lib]# /usr/local/tomcat/bin/startup.sh 

配置至此,客户端访问主机Tomcat1的test.jsp文件,可以看到以下页面,说明主机Tomcat1连接数据库没有问题。得到的页面如下:

可以看到以上页面后,然后在Tomcat2进行以下操作(与主机Tomcat1一样的操作,所以就不写注释了)

4、配置主机Tomcat2:

[[email protected] ~]# vim /usr/local/tomcat/conf/context.xml
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="javauser" password="javapasswd" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://192.168.20.6:3306/javatest"/>
</Context>
[[email protected] ~]# mkdir /web/webapp1/WEB-INF
[[email protected] ~]# vim /web/webapp1/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>
[[email protected] ~]# cd /web/webapp1/
[[email protected] webapp1]# vim test.jsp
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
<html>
<head><title>MySQL-2</title>
</head>
<body>
connect MySQL<br>
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://192.168.20.6:3306/javatest";
String username = "javauser";
String password = "javapasswd";
Class.forName(driverClass);
Connection conn=DriverManager.getConnection(url, username, password);
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from testdata");
while(rs.next()){
out.println("<br>foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
</body>
</html>
[[email protected] lib]# /usr/local/tomcat/bin/shutdown.sh
[[email protected] lib]# /usr/local/tomcat/bin/startup.sh 

配置至此,客户端访问Nginx代理服务器(192.168.20.2/test.jsp),多次刷新,可以看到在Tomcat1和Tomcat2之间进行切换:

注意,在上面的环境中,Redis仅仅只是保存Session信息而已,不会像Memcached一样,缓存后端服务器的数据的。

———————— 本文至此结束,感谢阅读 ————————

原文地址:https://blog.51cto.com/14154700/2447238

时间: 2024-11-08 09:07:49

LNMT群集基于Redis实现Session共享的相关文章

项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXin(开源的微信开发SDK)开发的一款微信应用类系统,主要业务是围绕当下流行的微信元素,如:微官网.微商城.微分销.营销活动.会员卡等. 关于RabbitHub详情请戳: .NET 平台下的插件化开发内核(Rabbit Kernel) RabbitHub开源情况及计划 关于Rabbit.WeiXin详

.Net分布式架构(二):基于Redis的Session共享

一:Session简介 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台web服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台web服务器建立连接时,他就与这个服务器建立了一个Session,同时服务器会自动为其分配一个SessionID,用以标识这个用户的唯一身份.这个SessionID是由web服务器随机产生的一个由24个字符组成的字符串,我们会在下面的实验中见到它的实际样子. 二:Asp.Net中Session的集中模式和配置 (1)

Tomcat7基于Redis的Session共享实战二

目前,为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无论用户的请求被转发到哪个服务器上都能保证用户的正常使用,即需要实现session的共享机制. 在集群系统下实现session统一的有如下几种方案:(1) 应用服务器间的session复制共享(如tomcat自带session共享)(2) 基于cache DB缓存的session共享 一.应用服务器间

分布式中使用Redis实现Session共享(二)

上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+iis实现负载均衡搭建负载均衡站点了,这里我们会搭建两个站点来验证redis实现的session是否能共享. 阅读目录 Session实现原理 session共享实现方案 问题拓展 总结 回到顶部 Session实现原理 session和cookie是我们做web开发中常用到的两个对象,它们之间会不会

spring boot + redis 实现session共享

这次带来的是spring boot + redis 实现session共享的教程. 在spring boot的文档中,告诉我们添加@EnableRedisHttpSession来开启spring session支持,配置如下: @Configuration @EnableRedisHttpSession public class RedisSessionConfig { } 而@EnableRedisHttpSession这个注解是由spring-session-data-redis提供的,所以

nginx+redis实现session共享 .NET分布式架构

上两篇文件介绍了如何安装和封装redis 本篇主要是记录下怎么实现 nginx+redis实现session共享 目前session问题点 又爱又恨的Session 刚接触程序开发的人一定爱死Session了,因为Session让Http从无状态变成有状态了,页面之间传值.用户相关信息.一些不变的数据.甚至于查出来的DataTable也可以放进去,取值的时候只需要Session[Key]即可,真是方便极了.Session真是个利器,人挡杀人佛挡杀佛,但任何事物被封为利器基本也是双刃剑,Sessi

使用 Redis 实现 Session 共享

1    第4-3课:使用 Redis 实现 Session 共享 在微服务架构中,往往由多个微服务共同支撑前端请求,如果涉及到用户状态就需要考虑分布式 Session 管理问题,比如用户登录请求分发在服务器 A,用户购买请求分发到了服务器 B, 那么服务器就必须可以获取到用户的登录信息,否则就会影响正常交易.因此,在分布式架构或微服务架构下,必须保证一个应用服务器上保存 Session 后,其他应用服务器可以同步或共享这个 Session. 目前主流的分布式 Session 管理有两种方案.

springboot+redis实现session共享

1.场景描述 因项目访问压力有点大,需要做负载均衡,但是登录使用的是公司统一提供的单点登录系统,需要做session共享,否则假如在A机器登录成功,在B机器上操作就会存在用户未登录情况. 2. 解决方案 因项目是springboot项目,采用Springboot+Springsession+Redis来实现session共享. 2.1 pom.xml文件 <dependency> <groupId>org.springframework.boot</groupId> &

Spring Boot 多站点利用 Redis 实现 Session 共享

如何在不同站点(web服务进程)之间共享会话 Session 呢,原理很简单,就是把这个 Session 独立存储在一个地方,所有的站点都从这个地方读取 Session. 通常我们使用 Redis 来解决这个问题 Spring Boot 2.1.8 Redis 5.0.3 本项目源码 github 下载 本章解决前面文章 Spring Boot 利用 nginx 实现生产环境的伪热更新 产生的session共享问题. 1 Redis 准备 本示例使用 Redis 5.0.3 操作系统为 Mac