Nginx 四种分配方式——session处理

https://blog.csdn.net/lyj1101066558/article/details/54346110

 

最近迷上了Nginx,真实麻雀虽小,五脏俱全..功能实在强大..

nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、ip哈希、URL哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。

如果只有一台服务器时,这个服务器挂了,那么对于网站来说是个灾难.因此,这时候的负载均衡就会大显身手了,它会自动剔除挂掉的服务器.

下面简单的介绍下我使用Nginx做负载的体会

下载---安装Nginx这些不介绍了,前篇有介绍.

windows和Linux下配置Nginx负载的写法一样,故不分开介绍.

Nginx负载均衡一些基础知识:

nginx 的 upstream目前支持 4 种方式的分配 
1)、轮询(默认) 
      每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
2)、weight 
      指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 
2)、ip_hash 
      每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。  
3)、fair(第三方) 
      按后端服务器的响应时间来分配请求,响应时间短的优先分配。  
4)、url_hash(第三方)

配置:

在http节点里添加:

#定义负载均衡设备的 Ip及设备状态    

upstream myServer {   

    server 127.0.0.1:9090 down; 
    server 127.0.0.1:8080 weight=2; 
    server 127.0.0.1:6060; 
    server 127.0.0.1:7070 backup; 
}

在需要使用负载的Server节点下添加

proxy_pass http://myServer;

upstream 每个设备的状态:

down 表示单前的server暂时不参与负载 
weight  默认为1.weight越大,负载的权重就越大。 
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误 
fail_timeout:max_fails 次失败后,暂停的时间。 
backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

Nginx还支持多组的负载均衡,可以配置多个upstream  来服务于不同的Server.

配置负载均衡比较简单,但是最关键的一个问题是怎么实现多台服务器之间session的共享

下面有几种方法(以下内容来源于网络,第四种方法没有实践.)

1) 不使用session,换作cookie

能把session改成cookie,就能避开session的一些弊端,在从前看的一本J2EE的书上,也指明在集群系统中不能用session,否则惹出祸端来就不好办。如果系统不复杂,就优先考虑能否将session去掉,改动起来非常麻烦的话,再用下面的办法。

2) 应用服务器自行实现共享

asp.net可以用数据库或memcached来保存session,从而在asp.net本身建立了一个session集群,用这样的方式可以令 session保证稳定,即使某个节点有故障,session也不会丢失,适用于较为严格但请求量不高的场合。但是它的效率是不会很高的,不适用于对效率 要求高的场合。

以上两个办法都跟nginx没什么关系,下面来说说用nginx该如何处理:

3) ip_hash

nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,ip_hash是在upstream配置中定义的:

upstream backend {
  server 127.0.0.1:8080 ;
  server 127.0.0.1:9090 ;
   ip_hash;
}

ip_hash是容易理解的,但是因为仅仅能用ip这个因子来分配后端,因此ip_hash是有缺陷的,不能在一些情况下使用:

1/ nginx不是最前端的服务器。ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash。譬如使用的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的。

2/ nginx的后端还有其它方式的负载均衡。假如nginx后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上。这么算起来,nginx后端只能直接指向应用服务器,或者再搭一个squid,然后指向应用服务器。最好的办法是用location作一次分流,将需要session的部分请求通过ip_hash分流,剩下的走其它后端去。

4) upstream_hash

为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享:

假如前端是squid,他会将ip加入x_forwarded_for这个http_header里,用upstream_hash可以用这个头做因子,将请求定向到指定的后端:

可见这篇文档:http://www.sudone.com/nginx/nginx_url_hash.html

在文档中是使用$request_uri做因子,稍微改一下:

hash   $http_x_forwarded_for;

这样就改成了利用x_forwarded_for这个头作因子,在nginx新版本中可支持读取cookie值,所以也可以改成:

hash   $cookie_jsessionid;

假如在php中配置的session为无cookie方式,配合nginx自己的一个userid_module模块就可以用nginx自发一个cookie,可参见userid模块的英文文档:
http://wiki.nginx.org/NginxHttpUserIdModule
另可用姚伟斌编写的模块upstream_jvm_route:http://code.google.com/p/nginx-upstream-jvm-route/

===============================================

https://blog.csdn.net/chao_1990/article/details/54405759

 

共享session应用场景,基于分布式,session的原理大致如下(以tomcat为例),

tomcat有一套自己的session管理机制,每次创建连接的时候都会通过客户端传过来的jsessionid从session连接池中获得sessionId对应的session,如果存在,那么直接从池中获得session连接信息,如果没有通过程序中设置判断是否创建一个新的session信息保存到池中。

nginx贡献session的方式,大体上有ip_hash(nginx自带),redis共享session,基于cookie,基于db(各种关系型数据库和非关系型数据库)。

 

1、基于cookie

简单、方便,每次通过判断cookie中的用户状态信息判断用户的登录状态;但是用户信息要存在客户端,存在安全隐患,除非有相当安全的加密措施,如果加密码负载,也会 增加运算的成本。

 

2、基于db(各种关系型数据库和非关系型数据库)

登录信息存储到db中,虽然安全,但每次需要验证用户的登录状态是都需要从db中进行IO操作,并发量高是势必会增加数据库的负载。

 

3、基于redis+cookie共享session

此种方式将将用户的登录信息存储到redis中,因为是基于内存的读取,因此效率不会是响应效率的瓶颈,cookie中存储着jsessionid,不需要加密或处理,只需要存储redis中的key保存统一客户通过cookie中的key可以准确的登录信息或是其他有效的信息,此种方式,cookie的存储不需要加密计算成本,其次redis将信息存储到缓存中,存取效率高,后面会详细介绍此种方式实现过程。

 

4、基于ip_hash

此种方式配置最为简单,但是有一定的局限性,其原理就是同一个ip的所有请求都会被nginx进行ip_hash进行计算,通过结果定位到指定的后台服务器即一个用户如果ip不变,那么每次请求其实请求的都是同一后台服务器;首先最外层的代理要保证源ip在请求 的过程不会被修改,如果你的架构里在最外层方式不单单是nginx服务,而是类似于请求分发的服务服务器,那么意味着一个人的请求可能被定位到不同的服务器上,那么ip_hash就没有意义了。

 

5、基于tomcat容器session

此种方式在根本上实现共享session,他的实际情况是通过tomcat管理配置将一个tomct下的session复制到其他的tomcat的session池中,实现真实上的session共享;此种方式需要兼容tomcat配置及需要对其进行扩展,依赖性太强。

 

已实现的共享方式:

首先配置3个web容器,tomcat1(3301),tomcat2(3302)、tomcat3(3303)

1、ip_hash

nginx的配置这里不再说明,主要说明ip_hash的配置,简直是简单到节点

 

 
  1. upstream backend {

  2. ip_hash;

  3. server localhost:3301 max_fails=2 fail_timeout=30s ;

  4. server localhost:3302 max_fails=2 fail_timeout=30s ;

  5. server localhost:3303 max_fails=2 fail_timeout=30s ;

  6. }

nginx的配置文件nginx.conf引入upstram数据,启动即可。

 

验证:

过访问web应用,例如http://localhost:8080/login.jsp登录后存储session信息,每次访问这个页面都需要验证session的状态,页面实现的是tomcat1表示,此ip的请求被转发到了tomcat1的服务器上,无论怎么刷新页面,页面显示的都是tomcat1,此时停掉tomcat1,再次刷新页面,页面显示的是tomcat2或是tomcat3的登录页面,此时表示nginx负载目的已经达到,但是session没有共享;局限性显而易见。

 

2、redis+cookie共享session

原理实现:

1)、登录成功时,将还有redis的key保存到cookie中,将登录用户的信息保存到redis中;

2)、配置拦截器,拦截需要验证登录状态的请求,从cookie中获得redis的key,从redis中获得当前cookie对应的用户信息,对其登录状态进行验证。

验证:

取消nginx的ip_hash配置,登录web,例如例如http://localhost:8080/login.jsp登录后存储session信息,首页显示tomcat1,此时不需要关闭任何tomcat,直接不停的刷新主页就会发现主页的再tomcat1、tocmat2、tomcat3之间来回切换,表示session已正常共享。个人认为此种方式是比较推荐的。

 

观点:

从功能的核心来看,其目的就是共享session,究其原因就是客户端和服务之间需要一个唯一的值来建立关联关系,此值就是sessionId,无论请求哪个网站通过工具查看cookie都会有发现,有jsessionid的值,此值在于服务器建立连接以后是基本不会变的(后台主动创建新的session)。及时上面的描述的共享方式5,基于session连接池的session管理,也是要依赖sessionid的,通过查看tomcatsession管理的源码,不难发现其也是通过cookie获得的sessionid,那么如果客户端请强制禁用了cookie,该如何获得jsessionId? 之前查阅过资源(未亲自证实),当浏览器禁用cookie后,请求的地址会被重定向,重定向后会在请求的url中拼接上jsessionid,这个容器就能获得sessionid,也就可以验证session 状态;此种场景有待证实。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Nginx是一款高性能的Web服务器和反向代理服务器,它可以通过反向代理的方式来代理会话。通过Nginx代理会话,可以实现负载均衡和高可用性。 在Nginx中代理会话的方式有多种,其中一种常见的方式是使用Nginx的负载均衡模块来实现。通过配置负载均衡模块,可以将请求转发给多个后端服务器,从而分担服务器的负载。一般来说,可以使用轮询、权重、IP哈希等方式来决定请求应该转发到哪个后端服务器上。 当用户发起一个新的会话请求时,Nginx可以根据预先定义的规则将请求转发给一个后端服务器,并在其中创建一个session。在这个会话过程中,Nginx会记录并管理与该会话相关的所有信息,包括会话的状态、用户的身份验证信息、会话的生命周期等。 通过Nginx代理session,可以实现会话的无缝切换和高可用性。当一个后端服务器出现故障或需要维护时,Nginx可以将该会话转发给其他可用的后端服务器,以确保用户的请求得到处理。这种方式可以提高系统的可用性和稳定性。 总结来说,Nginx代理会话是通过配置负载均衡模块来实现的,可以将会话请求转发给多个后端服务器,并在其中管理和记录会话的相关信息。这种方式可以实现负载均衡和高可用性,提高系统的性能和稳定性。 ### 回答2: nginx代理session是指通过nginx服务器来转发和处理HTTP请求中的session信息。在大多数情况下,nginx主要用于代理和负载均衡,不能直接处理请求的session信息。然而,在一些特定的场景下,如高并发情况下的负载均衡、高可用性等需求,我们可以使用nginx来代理session。 具体而言,当客户端发送请求到nginx服务器时,nginx会将请求转发给后端的应用服务器进行处理。为了确保多个应用服务器之间的session一致性,我们可以采用一些策略来实现nginx代理session。 一种常见的策略是使用"sticky session",即粘性会话。当客户端首次发送请求到nginx服务器时,nginx会根据一定的规则将该请求分发给特定的应用服务器,并且将该请求与特定的应用服务器建立关联。后续的请求都会通过nginx转发到同一个应用服务器上,从而保持session的一致性。 另一种策略是使用第三方模块,如ngx_http_upstream_session_sticky_module。该模块提供了基于cookie和参数的session粘性会话,并且可以配置session粘性的过期时间、session键和值等。 通过上述策略,nginx代理session的工作原理是,当客户端发送请求到nginx服务器时,nginx会根据特定的算法或配置规则将请求转发给特定的应用服务器,并将该请求与特定的应用服务器建立关联。后续的请求都会通过nginx转发到同一个应用服务器上,并且保持session的一致性,从而实现nginx代理session的功能。 总之,nginx代理session能够帮助我们实现session一致性和负载均衡,并提高系统的性能和可用性。它是在特定场景下使用nginx服务器的一种有效的解决方案。 ### 回答3: nginx是一款开源的高性能Web服务器和反向代理服务器。它可以作为代理服务器,用于将客户端的请求转发给后端的服务器,并将服务器的响应返回给客户端。当需要实现基于Session的负载均衡时,可以使用nginx作为代理服务器来实现。 首先,在nginx配置文件中,需要定义一个upstream块来配置后端服务器列表。通过在upstream块中添加多个后端服务器的IP地址和端口号,nginx可以将请求按照一定的算法分发给后端服务器。 其次,可以通过nginx的location指令来配置Session的保持方式。可以使用proxy_pass指令将请求转发给后端服务器,并使用proxy_set_header指令来设置HTTP头信息,包括Cookie信息。这样,当客户端再次发送请求时,nginx会带上之前的Session信息,保持Session的连续性。 此外,为了实现Session的负载均衡,可以使用nginxSession Sticky模块。该模块可以通过检查请求的Cookie信息或者自定义的参数来判断该请求应该转发到哪个后端服务器。这样可以确保同一个客户端的请求总是被分发到同一个后端服务器,保证Session的正确性和连续性。 总结来说,使用nginx作为代理服务器,可以通过配置upstream块来实现Session的负载均衡,通过配置location指令和使用Session Sticky模块来保持Session的连续性。这样可以提高系统的可用性和性能,实现高效的Web应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值