最近工作很无聊,所以学习 nginx+tomcat+redis 实现负载均衡和session共享来充实一下,下面记载了我的实现过程和遇到的各种问题。
1.实现负载均衡
1.1.下载nginx,我使用的是Windows版本,下载地址 http://nginx.org/en/download.html
启动后控制台一闪而过,查看后台进程
浏览器输入localhost
则nginx已经启动,但是为什么会有两个进程?网上查阅了一下,得知这两个进程一个是master进程另一个是worker进程,所以这是正常现象。
1.2.修改nginx/conf目录下的nginx.conf文件
修改后配置如下
nginx -s reload即可重启nginx。我开始的时候主机名写的是localhost,请求会非常慢,大约一分钟左右才能完成一个请求,后来把localhost改成本地ip就好了。
1.3.测试
我的Tomcat版本是apache-tomcat-7.0.57
不断刷新页面,会看到两个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配置文件中
web.xml下
至此配置完成,启动项目。
异常1
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available
解决办法
异常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中的数据,初始时为空
向session中赋值并显示在页面
查看redis desktop manager,redis中保存了session中的相关信息
关闭刚才的请求所在的Tomcat,访问index1.html
仍然可以从session中取值。
至此nginx+Tomcat+redis实现纵向负载均衡和session共享完成。