windows 环境下nginx + tomcat群 + redis 实现session共享

摘要:
作为负载平衡器,nginx根据定义将不同的用户请求分发到不同的服务器,同时也解决了由于单点部署服务器故障而导致整个应用程序无法访问的问题。加入nginx后,如果一个或多个服务器出现故障,用户的正常使用将不会受到影响,用户请求将被分发到可以提供服务的服务器。本节中的实例只实现了一个nginx+两个tomcat+redis,以实现java web应用程序的自由切换,并维护用户会话信息,这对于前端用户来说是完全不可见的。

nginx作为负载均衡根据定义将不同的用户请求分发到不同的服务器,同时也解决了因单点部署服务器故障导致的整个应用不能访问的问题

在加入nginx之后,如果多个服务器中的一个或多个(不是全部)发生故障,均不影响用户的正常使用,会将用户请求分发到可以提供服务的服务器上

本节实例仅实现 一个nginx + 2个tomcat + redis实现java web应用的自由切换,并保持用户会话信息,对前端用户完全不可见。

会话的共享是为了保证用户在首次登录系统后已经后续的会话不会因为nginx重新分发到其他服务器而再次登录,达到会话信息共享

本例在windows下采用的是

nginx 1.9.13  

tomcat 7.0.64

redis 2.8

操作步骤:

① 准备两个tomcat,并修改端口,修改tomcat/webapps/ROOT中index.jsp内容为:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String username = request.getParameter("username");
    System.out.println("username:"+username);
    
    if(username!=null){
        session.setAttribute("userSession", username);
        System.out.println("value in session is :" + session.getAttribute("userSession"));
    }
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ngix+tomcat+redis session共享验证</title>
</head>
<body>


<form action="index.jsp">
     <input type="text" name="username" value=""/>
     <br/>
     <input type="submit" value="保存信息到session"/>
</form>

<hr/>

<!-- 不同tomcat请使用不同mark 以便识别  -->
你访问的tomcat 端口为:8898   tomcat001
<br/>
session值为: <%=session.getAttribute("userSession") %>
</body>
</html>

并保证两个tomcat都能正常启动,并能正常访问

② 下载ngix并修改conf文件如下

windows 环境下nginx + tomcat群 + redis 实现session共享第1张windows 环境下nginx + tomcat群 + redis 实现session共享第2张
#Nginx所用用户和组
#user  niumd niumd;

#工作的子进程数量(通常等于CPU数量或者2倍于CPU)
worker_processes  1;

#错误日志存放路径
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

#指定pid存放文件
pid        logs/nginx.pid;

events {
        #使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue
    #use epoll;
    
    #允许最大连接数
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

        #定义日志格式
    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '"$status" $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  off;
    access_log  logs/access.log;

    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;
 
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    #keepalive_timeout  75 20;

    include    gzip.conf;
       upstream localhost {
         #ip_hash
      #ip_hash; #测试时请不要打开ip_hash 否则不会在不同server间跳转,第一次访问的哪一个就会一直访问哪一个server
      
      #下面为配置的server列表,weight表示权重,值越大分配到的请求就越多,默认为1.
      server localhost:8898 weight=1;
      server localhost:8899 weight=1;
     }

    server {
            listen       8888; #8888为监听的端口,所以访问时就要通过 ip:8888来访问
            server_name  localhost;   

            location / {
                    proxy_connect_timeout   3;
                    proxy_send_timeout      30;
                    proxy_read_timeout      30;
                    proxy_pass http://localhost; #这里的名字要和上面upstream后面跟的名字一致
            }
            
   }
}
View Code

 2016-06-06增加静态资源缓存设置和获取真实客户端

windows 环境下nginx + tomcat群 + redis 实现session共享第3张windows 环境下nginx + tomcat群 + redis 实现session共享第4张
#Nginx所用用户和组
#user  niumd niumd;

#工作的子进程数量(通常等于CPU数量或者2倍于CPU)
worker_processes  1;

#错误日志存放路径
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

#指定pid存放文件
pid        logs/nginx.pid;

events {
    #使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue
    #use epoll;
    
    #允许最大连接数
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

        #定义日志格式
    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '"$status" $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  off;
    access_log  logs/access.log;

    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;
 
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    #keepalive_timeout  75 20;

    include    gzip.conf;
       upstream localhost {
         #ip_hash
      #ip_hash; #测试时请不要打开ip_hash 否则不会在不同server间跳转,第一次访问的哪一个就会一直访问哪一个server
      
      #下面为配置的server列表,weight表示权重,值越大分配到的请求就越多,默认为1.
      server localhost:8898 weight=1;
      server localhost:8899 weight=1;
     }

    server {
            listen       8888; #8888为监听的端口,所以访问时就要通过 ip:8888来访问
            server_name  localhost;   

            #charset koi8-r;
            #access_log  logs/host.access.log  main;
        
            location / {
                    proxy_connect_timeout   3;
                    proxy_send_timeout      30;
                    proxy_read_timeout      30;
                    proxy_pass http://localhost; #这里的名字要和上面upstream后面跟的名字一致
                    
                    root   html;
                    index  index.aspx index.html index.htm;
                    
                    #设置主机头和客户端真实地址,以便服务器获取客户端真实IP
                    proxy_set_header   Host             $host; 
                    proxy_set_header   X-Real-IP        $remote_addr; 
                    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            }
            
            #静态资源缓存设置
            location ~ .(jpg|png|jpeg|bmp|gif|swf|css)$
            { 
                expires 30d;
                root /nginx-1.9.3/html;#root:
                break;
            }
            
            #error_page  404              /404.html;

            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }           
   }
}
View Code

③ cmd窗口中启动nginx  停止用nginx -s stop命令

④下载redis并在cmd中执行server.exe启动,可根据需要修改redis.conf中的端口 port 6379 ,默认端口为6379 停止使用 redis-cli shutdown

⑤ 新建maven工程并选择和本地java_home版本一致的jdk,将https://github.com/jcoleman/tomcat-redis-session-manager 代码加入依赖并打包(打好的jar包在文章末尾有下载地址

⑥ 修改tomcat/conf下context.xml为 

windows 环境下nginx + tomcat群 + redis 实现session共享第5张windows 环境下nginx + tomcat群 + redis 实现session共享第6张
<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- The contents of this file will be loaded for each web application -->
<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->
    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
        <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="localhost" 
         port="6379" 
         database="0" 
         maxInactiveInterval="60" />
</Context>
View Code

⑦修改tomcat/conf/server.xml中engine信息  增加jvmRoute 标示

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm8899">

⑧ 拷贝第⑤步打好的jar包以及依赖的jedis-2.7.2.jar commons-pool2-2.4.1.jar到每个tomcat的lib目录下

⑨ 先启动redis,再启动所有tomcat,最后启动nginx 输入nginx监听的端口进行访问,结果如下:

最开始没有输入session信息时,多次刷新将显示访问到了两个不同的tomcat

windows 环境下nginx + tomcat群 + redis 实现session共享第7张      windows 环境下nginx + tomcat群 + redis 实现session共享第8张

在输入框中输入信息并保存,再不断刷新

windows 环境下nginx + tomcat群 + redis 实现session共享第9张   windows 环境下nginx + tomcat群 + redis 实现session共享第10张

在执行过程中,也会看见redis控制台不停的有相应信息输出

windows 环境下nginx + tomcat群 + redis 实现session共享第11张

后期我会将所有的实例代码及配置文件全部放到我的网盘,欢迎下载验证,相互交流

 下载地址: http://pan.baidu.com/s/1pK7GIbp

下一篇文章我将以具体demo方式展示在linux环境下,采用keepalived+mysql主主双活, 在某个mysql遇见故障不能提供服务时进行mysql自动切换

mysql主从同步请参考我之前的文章:http://www.cnblogs.com/xiaochangwei/p/4824355.html 

免责声明:文章转载自《windows 环境下nginx + tomcat群 + redis 实现session共享》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇php CI框架目录结构及运行机制禅道安装在不同系统下搭建步骤下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# 通过ServiceStack 操作Redis——Set类型的使用及示例

Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据 /// <summary> /// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据 /// 1.共同好友、二度好友 /// 2.利用唯一性,可以统计访问网站的所有独立 IP /// </summar...

javascript 获取当前页面的URL

如图所示:点击录入按钮实际的请求路径是“http://localhost:8081/dodiscovery/ordertaoziController.do?goAdd&_=1622601413035” 接下来测试js脚本获取url路径中的不同信息 1、获取完整URL var url; url = window.location.href;  结果...

开启tp3.2.3的Admin模块

默认生成Admin模块 1)定义应用名称及定义绑定Admin模块,运行项目可生成Admin模块 <?php //+---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +--...

Nginx压力测试及通用优化

nginx压测工具AB:ab由httpd-tools软件自带 1、安装压测工具AB [root@client1 /]# yum install httpd-tools -y 2、了解压测工具的使用方式 [root@client1 /]# ab -n 200 -c 2 http://127.0.0.1/ -n总的请求熟练 -c并发请求数 -k是否开启长连接...

redis Lua学习与坑

1.在写lua脚本往redis中添加zadd 有序集合的时候一直报 "value isnotavalid float"的错误,经过查询相关资料,最后发现,是顺序写反了。 相关代码 --[错误代码] redis.call('zadd',@TimeOrderKey,objRecord.ActivityID,@TimeScore);--[应该时间在前,value...

Spring Cloud 配置中心多环境配置bootstrap.yml

https://www.leftso.com/blog/900.html 我们知道spring boot可以通过文件名来区分配置,如下:application.ymlapplication-dev.yml #开发环境application-test.yml #测试环境application-prod.yml #正式环境但是spring cloud用上了配置...