黑帽联盟

 找回密码
 会员注册
查看: 2019|回复: 0
打印 上一主题 下一主题

[集群服务] 基于Redis的Session共享实战

[复制链接]

895

主题

38

听众

3322

积分

管理员

Rank: 9Rank: 9Rank: 9

  • TA的每日心情

    前天 13:01
  • 签到天数: 1643 天

    [LV.Master]伴坛终老

    在单机情况下,Session可由部署在服务器上的Web容器来管理 (如Tomcat、JBoss)。

    在负载均衡的集群环境下,负载均衡可能将请求分发到不同的服务器上去,在这种情况,需要将有状态的session统一管理起来。

    本文将给出一个简单的示例,将session存放到Redis统一管理。因为只是一个示例,所以Nginx只用1台,Tomcat使用2台,Redis一个或者简单的主从。

    b6QXmcW8PKbiHAetwbhHxFTAjabtTyNH.png

    环境准备准备Redis

    下载redis-3.2.3.tar.gz (Redis.io下载)

    解压缩redis

    tar -zvxf redis-3.2.3.tar.gz

    QRArx8MGRhxaAPbric8xmJ3aAizhr6df.png

    将解压缩后的redis文件名改成好记点的6379 (可以不重命名)。

    然后使用make && make install 完成安装。

    [root@dev18 redis]# mv redis-3.2.3 6379[root@dev18 redis]# cd 6379[root@dev18 6379]# make && make install

    安装成功之后,出现如下显示:

    cmEWa83FJRhEr2WZYWsQN7WppnSZQZwz.png

    因为本版本使用的Redis版本是3.2.3, 在这个版本中,有protected mode的属性(默认是yes),进入6379目录,修改redis.conf配置文件。从而,其它网段的程序可以去访问,否则可能会出现如下的错误。
    1. Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.       
    2.         at redis.clients.jedis.Protocol.processError(Protocol.java:117)
    3.         at redis.clients.jedis.Protocol.process(Protocol.java:151)       
    4.         at redis.clients.jedis.Protocol.read(Protocol.java:205)       
    5.         at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)       
    6.         at redis.clients.jedis.Connection.getIntegerReply(Connection.java:222)       
    7.         at redis.clients.jedis.Jedis.sadd(Jedis.java:1057)       
    8.         at jedis.example.Main.main(Main.java:36)
    复制代码
    WQFKAHaKZXBH3C6NQAxSakGQzYQ36iRx.png

    修改后保存。

    K334YKCnjtjMMErGHmRekzkDtsXB5SDS.png

    进入src目录,启动Redis服务
    1. [root@dev18 6379]# cd src
    2. [root@dev18 src]# ./redis-server
    复制代码
    成功启动显示如下:
    1. [root@dev18 src]# ./redis-server
    2. 10051:C 22 Dec 09:50:59.653 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/to/redis.conf
    3.                 _._                                                  
    4.            _.-``__ ''-._                                             
    5.       _.-``    `.  `_.  ''-._           Redis 3.2.3 (00000000/0) 64 bit
    6.   .-`` .-```.  ```\/    _.,_ ''-._                                   
    7. (    '      ,       .-`  | `,    )     Running in standalone mode
    8. |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
    9. |    `-._   `._    /     _.-'    |     PID: 10051
    10.   `-._    `-._  `-./  _.-'    _.-'                                   
    11. |`-._`-._    `-.__.-'    _.-'_.-'|                                 
    12. |    `-._`-._        _.-'_.-'    |           http://redis.io        
    13.   `-._    `-._`-.__.-'_.-'    _.-'                                   
    14. |`-._`-._    `-.__.-'    _.-'_.-'|                                 
    15. |    `-._`-._        _.-'_.-'    |                                 
    16.   `-._    `-._`-.__.-'_.-'    _.-'                                   
    17.       `-._    `-.__.-'    _.-'                                       
    18.           `-._        _.-'                                          
    19.               `-.__.-'                                               
    20.               
    21. 10051:M 22 Dec 09:50:59.656 # Server started, Redis version 3.2.3
    22. 10051:M 22 Dec 09:50:59.656 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    23. 10051:M 22 Dec 09:50:59.656 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    24. 10051:M 22 Dec 09:50:59.656 * The server is now ready to accept connections on port 6379
    复制代码
    准备Tomcat

    下载tomcat,并解压缩为两个tomcat,并修改各自server.xml中的端口,保证两者不冲突。

    PSPZsb87DbChf48Qh5JfihQNCaQsPdFi.png

    本示例中,tomcat_1的端口为8082
    1. <Connector port="8082" protocol="HTTP/1.1"
    2.                connectionTimeout="20000"
    3.                redirectPort="8443" />
    复制代码
    tomcat_2的端口为8083
    1. <Connector port="8083" protocol="HTTP/1.1"
    2.                connectionTimeout="20000"
    3.                redirectPort="8443" />
    复制代码
    准备Session-Manager

    大家可以通过如下路径获取Session-Manager的jar包和相关的依赖包,包括common-pool2和Jedis。

    https://pan.baidu.com/s/1hstBri0

    FXmmAAQK474NRDmkyCeKNTrs5ZyXE6f5.png

    下载好之后,我们首先将这三个jar包,放到Tomcat目录下的lib文件夹中。

    配置Context.xml,添加如下内容,具体的host和port由自己的环境决定。

    1. <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />  
    2.         <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"  
    3.          host="xxx.xx.xx.xxx"  
    4.          port="6379"  
    5.          database="0"  
    6.          maxInactiveInterval="60" />
    复制代码

    然后准备一个项目,为了方便,我直接将测试的war中的文件替换了

    Tomcat_Home/webapps中的ROOT的内容。也可以通过tomcat自带的examples示例来测试session。

    如:http://localhost:8082/examples/servlets/servlet/SessionExample

    Zen8mJnS8ndsZrPZdm7kkR4stSGxBDEa.png

    至此,两个测试的tomat就准备好了,并且已经配置了session管理,由redis来存储。接下来,我们就需要一个Nginx用于负载,配置两个tomcat的信息即可。

    准备Nginx

    下载Nginx,解压,然后进入Nginx的conf目录,修改nginx.conf文件内容,找到http的部分,添加upstream,就是我们上述提到的两个tomcat。

    1. http {       
    2.         upstream tomcat  {  
    3.                         server localhost:8082;  
    4.                         server localhost:8083;  
    5.         }
    复制代码
    本文Nginx的端口为8899, 自己设定了一个。
    1. server {        
    2.         listen       8899;
    复制代码
    MzJxcEbAT6RKeYAyyDEfTiiR2DQGi2HY.png

    至此Nginx, Tomcat, Session-Manager, Redis相关的环境就全部准备好了。

    接下来,要做的就是启动Nginx, Tomcat, Redis,来看看 session是否存入到Redis中,自己的Web工程能不能正常运行等。

    启动Nginx和Tomcat

    进入NGINX_HOME/使用 nginx命令启动Nginx服务器。

    pKx3FbmibbfsNmYJrC8wcnNwWQcGtHAX.png

    进入两个tomcat_1和tomcat_2,分别启动tomcat。登录自己在ROOT中放置的WEB工程,可以看到session在Redis中存储下来了。

    通过Redis-Desktop Manager查看Redis中session的信息。

    bDdhkRCnzRY8ssJdjdSyrssXtzKWbE6H.png

    配置一个Redis从服务器

    通过Redis-Desktop Manager查看Redis中session的信息。

    为上面的6379主服务器配置一个从服务器6380。

    在6380的redis.conf中指定 是6379的slave,如:
    1. slaveof 127.0.0.1 6379
    复制代码
    启动从服务器:
    1. [root@dev18 src]# ./redis-server ../redis.conf
    2.                 _._                                                  
    3.            _.-``__ ''-._                                             
    4.       _.-``    `.  `_.  ''-._           Redis 3.2.3 (00000000/0) 64 bit
    5.   .-`` .-```.  ```\/    _.,_ ''-._                                   
    6. (    '      ,       .-`  | `,    )     Running in standalone mode
    7. |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6380
    8. |    `-._   `._    /     _.-'    |     PID: 14302
    9.   `-._    `-._  `-./  _.-'    _.-'                                   
    10. |`-._`-._    `-.__.-'    _.-'_.-'|                                 
    11. |    `-._`-._        _.-'_.-'    |           http://redis.io        
    12.   `-._    `-._`-.__.-'_.-'    _.-'                                   
    13. |`-._`-._    `-.__.-'    _.-'_.-'|                                 
    14. |    `-._`-._        _.-'_.-'    |                                 
    15.   `-._    `-._`-.__.-'_.-'    _.-'                                   
    16.       `-._    `-.__.-'    _.-'                                       
    17.           `-._        _.-'                                          
    18.               `-.__.-'                                             
    19.               
    20.               
    21. 14302:S 22 Dec 12:02:55.810 # Server started, Redis version 3.2.3
    22. 14302:S 22 Dec 12:02:55.810 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    23. 14302:S 22 Dec 12:02:55.810 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    24. 14302:S 22 Dec 12:02:55.810 * The server is now ready to accept connections on port 6380
    25. 14302:S 22 Dec 12:02:55.810 * Connecting to MASTER 127.0.0.1:6379
    26. 14302:S 22 Dec 12:02:55.810 * MASTER <-> SLAVE sync started
    27. 14302:S 22 Dec 12:02:55.810 * Non blocking connect for SYNC fired the event.
    28. 14302:S 22 Dec 12:02:55.811 * Master replied to PING, replication can continue...
    29. 14302:S 22 Dec 12:02:55.811 * Partial resynchronization not possible (no cached master)
    30. 14302:S 22 Dec 12:02:55.815 * Full resync from master: c5038d1cbe197bbd8c8fee0e719370eac42bd6bc:1
    31. 14302:S 22 Dec 12:02:55.865 * MASTER <-> SLAVE sync: receiving 2741 bytes from master
    32. 14302:S 22 Dec 12:02:55.865 * MASTER <-> SLAVE sync: Flushing old data
    33. 14302:S 22 Dec 12:02:55.865 * MASTER <-> SLAVE sync: Loading DB in memory
    34. 14302:S 22 Dec 12:02:55.866 * MASTER <-> SLAVE sync: Finished with success
    复制代码
    使用Redis-Desktop Manager
    BDCzTWS38nywpnFFyXSHCC7hja6rfaxf.png

    可以看到,主服务6379和从服务6380都包含session的相关信息。
    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    勿忘初心,方得始终!
    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部