Nginx+Tomcat+Redis实现session共享

  1. 云栖社区>
  2. 博客>
  3. 正文

Nginx+Tomcat+Redis实现session共享

技术小阿哥 2017-11-27 11:50:00 浏览4785
展开阅读全文

通过Nginx作为前端的负载,把请求分发到后端的Tomcat服务器上,提高并发数;但是单纯的通过Nginx的ip_hash负载是很多问题的。只要用户一切换网络或者后端Tomcat主机宕机session就失效;

架构图:

1.jpg

1
2
3
4
5
6
7
8
9
10
11
基本环境 
  
主机名 IP地址    安装软件    用途 
  
Nginx   192.168.122.10 nginx-1.8.1.tar.gz  负载均衡 
  
Tomcat1 192.168.122.12 apache-tomcat-7.0.68.tar.gz、jdk-7u79-linux-x64.gz   Tomcat服务 
  
Tomcat2 192.168.122.13 apache-tomcat-7.0.68.tar.gz、jdk-7u79-linux-x64.gz   Tomcat服务 
  
Redis   192.168.122.14 redis-3.0.7.tar.gz  Session存储

Tomcat要在Redis上实现Session共享的话就要以下几个依赖包:【把它们复制到/tomcat/lib/目录下】不同版本有可能造成错误。

commons-pool2-2.2.jar

jedis-2.5.2.jar

tomcat-redis-session-manage-tomcat7.jar


一、安装Nginx

1.建立用户和组:

1
2
groupadd nginx 
useradd –s /sbin/nologin –g nginx –M nginx –c “Nginx web user”

2.安装一些所需依赖包:

1
yum install gcc gcc-c++ zlib zlib-devel pcre-devel openssl-devel perl-devel perl-ExtUtils-Embed libxml2 libxml2-devel libxslt libxslt-devel -y

3.编译参数:【由于只做负载均衡,按需要安装相对的功能】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
./configure 
--prefix=/usr/local/nginx-1.8.1 \ 
--sbin-path=/usr/sbin/nginx 
--conf-path=/etc/nginx/nginx.conf \ 
--error-log-path=/var/log/nginx/error.log \ 
--http-log-path=/var/log/nginx/access.log \ 
--pid-path=/var/run/nginx/nginx.pid \ 
--lock-path=/var/lock/nginx.lock \ 
--user=nginx \ 
--group=nginx \ 
--with-http_ssl_module
--with-http_stub_status_module \ 
--with-http_gzip_static_module \ 
--with-http_realip_module 
  
make && make install

4.添加启动脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/bin/sh 
   
# nginx - this script starts and stops the nginx daemon 
   
# chkconfig: - 85 15 
  
# description: Nginx is an HTTP(S) server, HTTP(S) reverse 
  
# proxy and IMAP/POP3 proxy server 
  
# processname: nginx 
  
# config: /etc/nginx/nginx.conf 
  
# config: /etc/sysconfig/nginx 
  
# pidfile: /var/run/nginx.pid 
  
   
# Source function library. 
  
/etc/rc.d/init.d/functions 
  
# Source networking configuration. 
  
/etc/sysconfig/network 
   
# Check that networking is up. 
  
"$NETWORKING" "no" ] && exit 
  
nginx="/usr/sbin/nginx" 
  
prog=$(basename $nginx) 
   
NGINX_CONF_FILE="/etc/nginx/nginx.conf" 
   
  
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx 
  
  
lockfile=/var/lock/subsys/nginx  
  
start() { 
  
[ -x $nginx ] || exit 
  
[ -f $NGINX_CONF_FILE ] || exit 
  
echo -n $"Starting $prog: " 
  
daemon $nginx -c $NGINX_CONF_FILE 
  
retval=$? 
  
echo 
  
[ $retval -eq 0 ] && touch $lockfile 
  
return $retval 
  
}  
  
stop() { 
  
echo -n $"Stopping $prog: " 
  
killproc $prog -QUIT 
  
retval=$? 
  
echo 
  
[ $retval -eq 0 ] && rm -f $lockfile 
  
return $retval 
  
killall -9 nginx 
  
  
  
restart() { 
  
configtest || return $? 
  
stop 
  
sleep 
  
start 
  
  
  
reload() { 
  
configtest || return $? 
  
echo -n $"Reloading $prog: " 
  
killproc $nginx -HUP 
  
RETVAL=$? 
  
echo 
  
  
force_reload() { 
  
restart 
  
  
  
configtest() { 
  
$nginx -t -c $NGINX_CONF_FILE 
  
  
  
rh_status() { 
  
status $prog 
  
  
  
  
rh_status_q() { 
  
rh_status >/dev/null 2>&1 
  
  
  
case "$1" in 
  
start) 
  
rh_status_q && exit 
  
$1 
  
;; 
  
stop) 
  
rh_status_q || exit 
  
$1 
  
;; 
  
restart|configtest) 
  
$1 
  
;; 
  
reload) 
  
rh_status_q || exit 
  
$1 
  
;; 
  
force-reload) 
  
force_reload 
  
;; 
  
status) 
  
rh_status 
  
;; 
  
condrestart|try-restart) 
  
rh_status_q || exit 
  
;; 
  
*) 
  
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" 
  
exit 
  
esac

5.添加到开机启动

1
2
chkconfig --add nginx 
chkconfig nginx on

6.配置Nginx

1
2
3
4
5
6
7
8
9
10
11
upstream myServer { 
    server 10.0.10.121:8080 weight=1 max_fails=2 fail_timeout=30s;; 
    server 10.0.10.122:8080 weight=1 max_fails=2 fail_timeout=30s;; 
  
  server { 
    listen 80; 
    server_name a.test01.com; 
    location / { 
      proxy_pass http://myServer
    
}

7.启动Nginx [此时启动后是无法连接的,因为后端的服务都没安装]

1
service nginx start

二、配置Tomcat服务【10.0.10.121、10.0.10.122】

安装JDK环境

1
tar xf jdk-7u79-linux-x64.gz -C /usr/local/

配置环境变量:vim /etc/profile    【最后添加下面配置,根据情况配置】

1
2
3
4
5
6
JAVA_HOME=/usr/local/jdk1.7.0_79/ 
JAVA_BIN=$JAVA_HOME/bin 
JRE_HOME=$JAVA_HOME/jre 
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin 
CLASSPATH=$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/jre/lib/charsets.jar 
export  JAVA_HOME  JAVA_BIN JRE_HOME  PATH  CLASSPATH

1.安装Tomcat服务

1
tar xf apache-tomcat-7.0.68.tar.gz -C /usr/local/

作一个软连接:【软连接方便日志升级】

1
ln -s /usr/local//apache-tomcat-7.0.57/ /usr/local/tomcat7

2.修改配置文件,添加一个测试页。

1
2
3
4
5
6
7
8
9
10
11
12
13
vim /usr/local/tomcat7/conf/context.xml   【在<Context>中间添加 </Context>】 
  
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> 
  
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"   
  
         host="192.168.122.14"   
  
         port="6379"   
  
         database="0"   
  
         maxInactiveInterval="60" />

注释:上面host指Redis的主机IP,port就是端口,database就是数据库0,maxInactiveInterval超时时间为60秒,60秒后就会变化Session值。

setMaxInactiveInterval和session-config的优先级: 

1>、setMaxInactiveInterval的优先级高,如果setMaxInactiveInterval没有设置,则默认是session-config中设置的时间。 

2>、setMaxInactiveInterval设置的是当前会话的失效时间,不是整个web服务的。 

3>、setMaxInactiveInterval的参数是秒,session-config当中配置的session-timeout是分钟。

4>.测试页面:vim /usr/local/tomcat7/webapps/ROOT/test.jsp

1
2
3
4
5
6
7
8
9
10
Server Info: 
SessionID:<%=session.getId()%> 
<br> 
SessionIP:<%=request.getServerName()%> 
<br> 
SessionPort:<%=request.getServerPort()%> 
<br> 
<% 
out.println("127"); //标记后端节点 
%>

3.把几个Session同步的jar包复制到tomcat目录下的lib目录下:

  1. commons-pool2-2.2.jar 

  2. jedis-2.5.2.jar 

  3. tomcat-redis-session-manage-tomcat7.jar 

4.把/usr/local/jdk1.7.0_79/目录和/usr/local/apache-tomcat-7.0.57/ 目录,还有/etc/profile文件也同步到其它的Tomcat主机的相应目录下。

1
2
3
scp –r /usr/local/jdk1.7.0_79 10.0.10.122:/usr/local/ 
scp –r /data/apache-tomcat-7.0.57 10.0.10.122:/data/ 
scp –r /etc/profile 10.0.10.122:/etc/profile

三、安装Redis【10.0.10.123】

自动安装脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash 
#==================================================== 
# Author: Swper    EMail:hz328.com 
# Create Date: 2016-03-21 
# Description:redis单机单实例一键安装脚本  
#==================================================== 
# Filename: auto_install_redis.sh 
# 注意事项 
# 仅适用于Linux/Centos 64位 
# 安装时需联网 
  
# 步骤 
# 1.检查源码包是否存在,不存在就连网下载并安装redis 
# 2.配置redis 
# 3.准备redis启动停止脚本 
# 4.启动redis 
  
#定义存放软件目录 
software="/root/software" 
  
#如果软件目录不存在则新建该目录 
if [[ ! -e $software ]]; then 
    mkdir $software 
fi 
  
#定义判断是否安装成功函数 
function installIsOK(){ 
    if [[ $2 == 0 ]]; then 
        echo "$1 install ......  OK !" 
    else 
        echo "$1 install ......  Failure!" 
        exit 
    fi 
  
#进入软件目录 
cd $software 
  
  
# 1.下载并安装redis [判断是否存在] 
redis='redis-3.0.7' 
redis_dir='/data/redis' 
  
if [[ ! -f ${redis}.tar.gz ]]; then 
    curl -LO http://download.redis.io/releases/${redis}.tar.gz 
fi 
  
tar zxf ${redis}.tar.gz 
cd $redis 
make PREFIX=${redis_dir} install 
if [[ $? == 0 ]]; then 
    installIsOK ${redis} 0 
else 
    installIsOK ${redis} 3 
fi 
  
# 2.配置redis 
mkdir -p ${redis_dir}/{etc,run,log} 
mkdir -p ${redis_dir}/data/6379 
cp redis.conf ${redis_dir}/redis.conf 
#cp ${redis_dir}/redis.conf ${redis_dir}/etc/redis_6379.conf 
  
#生成配置文件 
redis_6379="${redis_dir}/etc/redis_6379.conf" 
cat >> ${redis_6379} << "EOF" 
daemonize yes 
pidfile /data/redis/run/redis_6379.pid 
port 6379 
#bind 127.0.0.1 
timeout 300 
loglevel notice 
logfile /data/redis/log/redis.log 
databases 16 
save 900 1 
save 300 10 
save 60 10000 
stop-writes-on-bgsave-error no 
rdbcompression yes 
rdbchecksum no 
dbfilename dump.rdb 
dir /data/redis/data/6379 
#slave-serve-stale-data yes 
maxmemory 256mb 
maxmemory-policy volatile-lru 
maxmemory-samples 3 
appendonly yes 
appendfsync everysec 
no-appendfsync-on-rewrite no 
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb 
lua-time-limit 5000 
slowlog-log-slower-than 10000 
slowlog-max-len 1024 
hash-max-ziplist-entries 512 
hash-max-ziplist-value 64 
list-max-ziplist-entries 512 
list-max-ziplist-value 64 
set-max-intset-entries 512 
zset-max-ziplist-entries 128 
zset-max-ziplist-value 64 
activerehashing yes 
client-output-buffer-limit normal 0 0 0 
client-output-buffer-limit slave 256mb 64mb 60 
client-output-buffer-limit pubsub 32mb 8mb 60 
EOF 
  
# 3.redis启动停止脚本 
redis_start="/etc/init.d/redis" 
cat >> ${redis_start} << "END" 
#!/bin/bash 
export PATH="/data/redis/bin:$PATH" 
EXEC="/data/redis/bin/redis-server" 
CLIEXEC="/data/redis/bin/redis-cli" 
PIDFILE="/data/redis/run/redis_6379.pid" 
CONF="/data/redis/etc/redis_6379.conf" 
PORT="6379" 
  
case "$1" in 
    start) 
        if [ -f $$PIDFILE ] 
        then 
                echo "$PIDFILE exists, process is already running or crashed." 
        else 
                echo "Starting Redis server..." 
                $EXEC $CONF 
        fi 
        ;; 
    stop) 
        if [ ! -f $PIDFILE ] 
        then 
                echo "$PIDFILE does not exist, process is not running." 
        else 
                PID=$(cat $PIDFILE) 
                echo "Stopping ..." 
                $CLIEXEC -p $PORT shutdown 
                while [ -x /proc/${PID} ] 
                do 
                    echo "Waiting for Redis to shutdown ..." 
                    sleep 
                done 
                echo "Redis stopped." 
        fi 
        ;; 
    restart) 
        $0 stop && $0 start 
        ;; 
    *) 
        echo "Usage: $0 {start|stop|restart}" >&2 
        exit 
        ;; 
esac 
  
END 
  
#增加可执行权限 
chmod u+x ${redis_start} 
  
# 4.启动redis 
${redis_start} start 
if [[ $? == 0 ]]; then 
    echo "redis start ......  OK" 
else 
    echo "redis start ...... Failure" 
fi

执行脚本自动安装

1
sh auto_install_redis.sh

执行后会自动在/root/目录下创建一个software目录,同时会自动下载redis。完成后自动启动。

ss –lnt 检查端口6379是否在使用即说明正常运行。

完成上面操作后启动服务:

1、启动redis,由于安装时已经启动了就不需要手工启动。

2、启动Tomcat服务

3、启动Nginx服务

Nginx简单配置:

vim /etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
upstream myServer {  
    server 192.168.122.12:8080 weight=1 max_fails=2 fail_timeout=30s;  
    server 192.168.122.13:8080 weight=1 max_fails=2 fail_timeout=30s;  
}  
server {  
    listen 80;  
    server_name a.test01.com;  
    location / {  
        proxy_ignore_client_abort on;  
        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_pass http://tomcat_server;  
        client_max_body_size    10m;  
        client_body_buffer_size 128k;  
        proxy_connect_timeout   300;  
        proxy_send_timeout      300;  
        proxy_read_timeout      300;  
        proxy_buffer_size       4k;  
        proxy_buffers           4 32k;  
        proxy_busy_buffers_size 64k;  
        proxy_temp_file_write_size 64k;  
    }  
}

测试效果:打开浏览器访问nginx的IP即可看到成功访问页面。

2.jpg

此时如果一直刷新存入到redis的session值是不会变的,但是如果30秒用户没反应就会失效。

可以通过修改tomcat目录conf/web.xml文件:

1
2
3
<session-config> 
    <session-timeout>300</session-timeout
</session-config>

此处默认为60,分钟为单位;但是经过redis的包时就变成了60秒,此处是个问题;所以这里修改成300变成秒了;注意上面的注释,由于setMaxInactiveInterval在这里没有配置,所以优先级以session-timeout;

通过redis-c查看到失效时间:

1
2
127.0.0.1:6379> ttl 7B088CABA49FAADF8BF1F23801104958 
(integer) 291   #此处为秒数,如果客户端刷新一下网页,此值就会又人300开始;

总结:其实此处用到的jar存在着很多问题,不建议在正式的生产环境使用;



本文转自 dengaosky 51CTO博客,原文链接:http://blog.51cto.com/dengaosky/2053456,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术小阿哥
+ 关注