一. 大致说一下nginx的负载均衡策略
1.轮询(默认):
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,则自动剔除故障机器,使用户访问不受影响。
2.weight:
指定轮询权重,weight值越大,分配到的几率就越高,主要用于后端每台服务器性能不均衡的情况。
3.ip_hash:
每个请求按访问IP的哈希结果分配,这样每个访客固定访问一个后端服务器,可以有效的解决动态网页存在的session共享问题。(此为解决session共享的一种方式)
4.fair(第三方):
更智能的一个负载均衡算法,此算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。如果想要使用此调度算法,需要Nginx的upstream_fair模块。
5.url_hash(第三方):
按访问URL的哈希结果来分配请求,使每个URL定向到同一台后端服务器,可以进一步提高后端缓存服务器的效率。如果想要使用此调度算法,需要Nginx的hash软件包。
二. 解决session共享问题常用的三种方式
1. nginx配置ip_hash为负载均衡策略即可解决session共享问题。
思路:因为ip_hash策略的结果是同一ip会访问同一台服务器,实际上session并没有共享,只是因为同一IP会一直访问一台服务器,自然不存在共享的问题。那么可想而知,换个IP,session并没有共享。
nginx配置示例:
upstream test{
ip_hash;
server 192.168.10.13:80;
server 192.168.10.15:8009 max_fails=3 fail_timeout=20s;
}
server {
location / {
proxy_pass http://test;
}
}
2. 服务器之间session复制(tomcat)
思路:直接让在集群中的服务器中都复制一份session呗,那么不管反代采用的是负载均衡策略,都不会出现session丢失的问题。
tomcat配置为如下两个步骤:
① 修改server.xml中的Cluster节点
② 修改应用的web.xml,增加节点: <distributable/>
两步实际上用的是tomcat自带的集群。
配置示例:
http://blog.csdn.net/wlwlwlwl015/article/details/48160433
这篇写的不错。
3. session统一缓存
思路:用redis统一缓存session,我们的应用需要连接到redis,用redis里的session就好了。下面是使用filter的原理。
(配置context.xml也可以,可以看下 https://lanjingling.github.io/2015/12/15/tomcat-redis-session/ 或者 https://www.jianshu.com/p/aa9f71d653af)
优缺点
配置步骤:
① 增加redis client和spring session的依赖(pom.xml)
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.2.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> </dependency>
② 修改web.xml,增加filter,注意:这个filter必须写到最前面
③ 修改Spring配置文件,在容器中注入spring session和redis相关的bean。
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="600" /> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="100" /> <property name="maxIdle" value="10" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"> <property name="hostName" value="localhost" /> <property name="port" value="6379" /> <property name="timeout" value="3000" /> <property name="usePool" value="true" /> <property name="poolConfig" ref="jedisPoolConfig" /> </bean>
需要注意的地方:
三. 三种应用的场景