MENU

nginx代理,tomcat7.0集群,redis的Session共享实现方法

2016 年 10 月 18 日 • 杂乱文章

解释一下,什么是Session

Session(会话保持)是指在负载均衡器上有一种机制,在作负载均衡的同时,还保证同一用户相关连的访问请求会被分配到同一台服务器上。会话保持有什么作用呢,举例说明一下

如果有一个用户访问请求被分配到服务器A,并且在服务器A登录了,并且在很短的时间,这个用户又发出了一个请求,如果没有会话保持功能的话,这个用户的请求很有可能会被分配到服务器B去,这个时候在服务器B上是没有登录的,所以你要重新登录,但是用户并不知道自己的请求被分配到了哪里,用户的感觉就是登录了,怎么又要登录,用户体验很不好。

还有你在淘宝上面买东西,从登录=》拍得东西=》添加地址=》付款,这是一个一系列的过程,也可以理解成一次操作过程,所有这一系列的操作过程都应当由一台服务器完成,而不能被负载均衡器分配到不同的服务器上。

如果使用nginx的ip_hash;算法,将会出现很多问题,ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash。譬如使用的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的。还有就是三方插件jvm_route ,不是真正意义上的session共享,只是session的复制粘贴,如果后端服务器崩一个session就失效了,无法进行会话转移,这样不太好,所以说,还是用redis来做Session共享吧。

服务器环境

nginx 192.168.1.1:80 版本:Tengine/2.1.2
redis 192.168.1.2:6379 版本:redis-3.0.5
tomcat1 192.168.1.3:8080 版本:7.0.70
tomcat2 192.168.1.4:8080 版本:7.0.70

实现方法

忽略安装,nginx,tomcat,redis,很麻烦,懒得写了,从配置Session开始

1、由于源码构建基于 gradle,请先配置 gradle 环境。参考地址

http://jingyan.baidu.com/article/4d58d541167bc69dd4e9c009.html

2、从 github 获取 tomcat-redis-session-manager-master 源码,地址如下:

https://github.com/jcoleman/tomcat-redis-session-manager

3、找到源码中的 build.gradle 文件并修改,修改后的build.gradle 文件如下:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'signing'
group = 'com.orangefunction'
version = '2.0.0'
repositories {
  mavenCentral()
}
compileJava {
  sourceCompatibility = 1.7
  targetCompatibility = 1.7
}
dependencies {
  compile group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '7.0.27'
  compile group: 'redis.clients', name: 'jedis', version: '2.5.2'
  compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.2'
  //compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
  testCompile group: 'junit', name: 'junit', version: '4.+'
  testCompile 'org.hamcrest:hamcrest-core:1.3'
  testCompile 'org.hamcrest:hamcrest-library:1.3'
  testCompile 'org.mockito:mockito-all:1.9.5'
  testCompile group: 'org.apache.tomcat', name: 'tomcat-coyote', version: '7.0.27'
}
task javadocJar(type: Jar, dependsOn: javadoc) {
  classifier = 'javadoc'
  from 'build/docs/javadoc'
}
task sourcesJar(type: Jar) {
  from sourceSets.main.allSource
  classifier = 'sources'
}
artifacts {
  archives jar
  archives javadocJar
  archives sourcesJar
}
//signing {
//  sign configurations.archives
//}
task copyJars(type: Copy) {
  from configurations.runtime
  into 'dist'  
}
uploadArchives {
  repositories {
    mavenDeployer {
      beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
      //repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
      //  authentication(userName: sonatypeUsername, password: sonatypePassword)
      //}
      //repository(url: "https://oss.sonatype.org/content/repositories/snapshots") {
      //  authentication(userName: sonatypeUsername, password: sonatypePassword)
      //}
      pom.project {
        name 'tomcat-redis-session-manager'
        packaging 'jar'
        description 'Tomcat Redis Session Manager is a Tomcat extension to store sessions in Redis'
        url 'https://github.com/jcoleman/tomcat-redis-session-manager'
        issueManagement {
          url 'https://github.com:jcoleman/tomcat-redis-session-manager/issues'
          system 'GitHub Issues'
        }
        scm {
          url 'https://github.com:jcoleman/tomcat-redis-session-manager'
          connection 'scm:git:git://github.com/jcoleman/tomcat-redis-session-manager.git'
          developerConnection 'scm:git:git@github.com:jcoleman/tomcat-redis-session-manager.git'
        }
        licenses {
          license {
            name 'MIT'
            url 'http://opensource.org/licenses/MIT'
            distribution 'repo'
          }
        }
        developers {
          developer {
            id 'jcoleman'
            name 'James Coleman'
            email 'jtc331@gmail.com'
            url 'https://github.com/jcoleman'
          }
        }
      }
    }
  }
}
4、执行gradle命令构建源码,编译输出tomcat-redis-session-manager-master 及依赖jar包
gradle build -x test  copyJars
5.构建完成后会得到一下文件,但是只需要3个,路径分别在以下目录中
tomcat-redis-session-manager-master\dist
tomcat-redis-session-manager-master\build\libs

放到一起是这样,需要的是红色圈起来的

开始配置tomcat

需要做的事情

编辑测试页面。

tomcat session manager 配置

1.创建测试页面
[root@tomcat1 webapps]# pwd
/usr/local/tomcat/webapps
[root@tomcat1 webapps]# mkdir test
[root@tomcat1 webapps]# vim test/index.jsp

页面代码

<%@ pagelanguage="java" %>

<html>

  <head><title>TomcatA</title></head>

  <body>

   <h1style="color: red;">Tomcat A</h1>

    <tablealign="centre"border="1">

      <tr>

        <td>Session ID</td>

        <td><%= session.getId() %></td>

      </tr>

      <tr>

        <td>Created on</td>

        <td><%= session.getCreationTime() %></td>

     </tr>

    </table>

  </body>

</html>

sessionID:<%=session.getId()%>

<br>

SessionIP:<%=request.getServerName()%>

<br>

SessionPort:<%=request.getServerPort()%>

<%

out.println("This is Tomcat Server A");

%>

保存退出,两个都要放,server A 改成Server B 好区分。打开后自行查看,两个的Session不一致。

2.上传jar包

上传所需的那3个,两个都要传。

3.编辑配置文件

文件位置:$TOMCAT_HOME/conf/context.xml

在下面增加以下内容,两个都要加。分别重启两台服务器,确定没有报错。

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
      <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
           host="192.168.1.2"
           port="6379"
           database="0"
           maxInactiveInterval="60" />

启动完毕


自行配置nginx,开始检测,不要使用ip_hash;算法

要的结果就是无论怎么刷新,Session不变

不要在意最上面的那两个都是A,源码只是把下面的改了最后查看redis,会有以上Session的数据

实现了基于nginx负载均衡下 tomcat 集群的 session 一致性。
分享一下那三个jar包吧,有需要的自行下载,不要谢我。

最后编辑于: 2018 年 12 月 10 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码