首页 > 技术文章 > nginx实现共享以及实现原理

houstao 2018-01-10 12:45 原文

一、Nginx
注意:集群的配置中,各个node服务器上的时间要保持一致。
1.nginx的负载均衡配置中默认是采用轮询的方式,这种方式中,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除,但存在各个服务器的session共享问题。
2.另外一种方式是ip_hash:每个请求按访问的ip的hash结果分配,如果访问的IP是固定的,那么在正常情况下,该用户的请求都会分配到后台的同一台服务器去处理,但是如果用户每次请求的IP都不同呢?所以这种方式也同1的方式一样都存在这么一个问题:session在各个服务器上的共享问题。
3.如果集群中的服务器的性能不一,可以通过配置各个服务器的权值来实现资源利用率的最大化,即性能好的优先选择。
解决服务器共享session问题:使用redis来共享各个服务器的session,并同时通过redis来缓存一些常用的资源,加快用户获得请求资源的速度(个人比较喜欢redis,当然你们也可以使用memcache来实现,不过,memcache不能做到持久化,这样这台服务器一挂掉,那么所有的资源也都没有了......)。
二、实现session共享:
1、基于cookie
简单、方便,每次通过判断cookie中的用户状态信息判断用户的登录状态;但是用户信息要存在客户端,存在安全隐患,除非有相当安全的加密措施,如果加密码负载,也会 增加运算的成本。
2、基于db(各种关系型数据库和非关系型数据库)
登录信息存储到db中,虽然安全,但每次需要验证用户的登录状态是都需要从db中进行IO操作,并发量高是势必会增加数据库的负载。
3、基于redis+cookie共享session
此种方式将将用户的登录信息存储到redis中,因为是基于内存的读取,因此效率不会是响应效率的瓶颈,cookie中存储着jsessionid,不需要加密或处理,只需要存储redis中的key保存统一客户通过cookie中的key可以准确的登录信息或是其他有效的信息,此种方式,cookie的存储不需要加密计算成本,其次redis将信息存储到缓存中,存取效率高,后面会详细介绍此种方式实现过程。
三、原理实现:
1)、登录成功时,将还有redis的key保存到cookie中,将登录用户的信息保存到redis中;
2)、配置拦截器,拦截需要验证登录状态的请求,从cookie中获得redis的key,从redis中获得当前cookie对应的用户信息,对其登录状态进行验证。
4、基于ip_hash
此种方式配置最为简单,但是有一定的局限性,其原理就是同一个ip的所有请求都会被nginx进行ip_hash进行计算,通过结果定位到指定的后台服务器即一个用户如果ip不变,那么每次请求其实请求的都是同一后台服务器;首先最外层的代理要保证源ip在请求 的过程不会被修改,如果你的架构里在最外层方式不单单是nginx服务,而是类似于请求分发的服务服务器,那么意味着一个人的请求可能被定位到不同的服务器上,那么ip_hash就没有意义了。
5、基于tomcat容器session
此种方式在根本上实现共享session,他的实际情况是通过tomcat管理配置将一个tomcat下的session复制到其他的tomcat的session池中,实现真实上的session共享;此种方式需要兼容tomcat配置及需要对其进行扩展,依赖性太强。
四、jvm_route的原理:
通过session cookie的方式来获取session粘性。如果在cookie和url中并没有session,则这只是个简单的round-robin 负载均衡。
1. 一开始请求过来,没有带session信息,jvm_route就根据round robin(轮询调度,无状态的调度)的方法,发到一台tomcat上面。
2. tomcat添加上session 信息,并返回给客户。
3. 用户再此请求,jvm_route看到session中有后端服务器的名称,它就把请求转到对应的服务器上。


推荐阅读