最近工作很无聊,所以学习 nginx+tomcat+redis 实现负载均衡和session共享来充实一下,下面记载了我的实现过程和遇到的各种问题。

1.实现负载均衡

1.1.下载nginx,我使用的是Windows版本,下载地址 http://nginx.org/en/download.html

    

redis集群负载均衡的方法 redis实现负载均衡_负载均衡

启动后控制台一闪而过,查看后台进程

redis集群负载均衡的方法 redis实现负载均衡_session共享_02

浏览器输入localhost

redis集群负载均衡的方法 redis实现负载均衡_session共享_03

则nginx已经启动,但是为什么会有两个进程?网上查阅了一下,得知这两个进程一个是master进程另一个是worker进程,所以这是正常现象。

1.2.修改nginx/conf目录下的nginx.conf文件

    修改后配置如下




redis集群负载均衡的方法 redis实现负载均衡_负载均衡_04



nginx -s reload即可重启nginx。我开始的时候主机名写的是localhost,请求会非常慢,大约一分钟左右才能完成一个请求,后来把localhost改成本地ip就好了。


1.3.测试


    我的Tomcat版本是apache-tomcat-7.0.57

redis集群负载均衡的方法 redis实现负载均衡_负载均衡_05

不断刷新页面,会看到两个Tomcat控制台交替输出,至此简单的nginx+Tomcat负载均衡已经实现了。

2. session共享

conf/contex.xml文件并在lib目录下引入相应jar包,我开始的时候采用这种方式,搭建好之后启动报错    java.lang.NoClassDefFoundError..................  查看jar包内并没有对应的类,有的人把源码重新编译或者更换jar包解决了这个问题,但是我总感觉不太健壮,同时我自己搭建的项目将来也要整合Redis,所以我放弃了这种方式。

        我采用的方式配置如下

        pom.xml下添加依赖

<dependency>
		      <groupId>org.springframework.session</groupId>
		      <artifactId>spring-session-data-redis</artifactId>
		      <version>1.1.1.RELEASE</version>
		      <type>pom</type>
		</dependency>

        新建redis.properties

redis_hostName=localhost
    redis_port=6379	
    redis_password=
    redis_timeout=900

        新建spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
         http://www.springframework.org/schema/context  
         http://www.springframework.org/schema/context/spring-context-3.1.xsd">  
    
    <!-- session设置 -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="900"></property>
    </bean>
    <!-- redis连接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"/>

    <!-- redis连接工厂 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis_hostName}"/>
        <property name="port" value="${redis_port}"/>
        <property name="password" value="${redis_password}"/>
        <property name="timeout" value="${redis_timeout}"/>
        <property name="poolConfig" ref="poolConfig"></property>
    </bean> 
</beans>

        spring配置文件中

redis集群负载均衡的方法 redis实现负载均衡_redis集群负载均衡的方法_06

web.xml下

redis集群负载均衡的方法 redis实现负载均衡_架构_07

      至此配置完成,启动项目。

 异常1

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available

redis集群负载均衡的方法 redis实现负载均衡_负载均衡_08

解决办法

redis集群负载均衡的方法 redis实现负载均衡_session共享_09

异常2

[08/03/18 09:48:55:055 CST] DEBUG jndi.JndiLocatorDelegate: Converted JNDI name [java:comp/env/spring.liveBeansView.mbeanDomain] not found - trying original name [spring.liveBeansView.mbeanDomain]. javax.naming.NameNotFoundException: Name [spring.liveBeansView.mbeanDomain] is not bound in this Context. Unable to find [spring.liveBeansView.mbeanDomain].
[08/03/18 09:48:55:055 CST] DEBUG jndi.JndiTemplate: Looking up JNDI object with name [spring.liveBeansView.mbeanDomain]
[08/03/18 09:48:55:055 CST] DEBUG jndi.JndiPropertySource: JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message

解决办法web.xml下添加

<context-param>
		<param-name>spring.profiles.active</param-name>  
	    <param-value>dev</param-value>  
	</context-param>  
	<context-param>  
	    <param-name>spring.profiles.default</param-name>  
	    <param-value>dev</param-value>  
	</context-param>
	<context-param>  
	    <param-name>spring.liveBeansView.mbeanDomain</param-name>  
	    <param-value>dev</param-value>  
	</context-param>

测试

启动Redis + 两个Tomcat + nginx

后台两个方法,index.html向session中付值,index1.html从session中取值。

使用redis desktop manager查看redis中的数据,初始时为空

redis集群负载均衡的方法 redis实现负载均衡_架构_10

向session中赋值并显示在页面

redis集群负载均衡的方法 redis实现负载均衡_session共享_11

查看redis desktop manager,redis中保存了session中的相关信息

 

redis集群负载均衡的方法 redis实现负载均衡_redis集群负载均衡的方法_12

关闭刚才的请求所在的Tomcat,访问index1.html

redis集群负载均衡的方法 redis实现负载均衡_redis集群负载均衡的方法_13

仍然可以从session中取值。

至此nginx+Tomcat+redis实现纵向负载均衡和session共享完成。