HAProxy-会话保持

引言:原文链接http://www.mamicode.com/info-detail-1734969.html


 

        任何一个七层的http负载均衡器,都应该具备一个功能:会话保持。会话保持是保证客户端对动态应用程序正确请求的基本要求。

        还是那个被举烂了却最有说服力的例子:客户端A向服务端B请求将C商品加入它的账户购物车,加入成功后,服务端B会在某个缓存区域中记录下客户端A和它的商品C,这个缓存的内容就是session上下文环境。而识别客户端的方式一般是设置session ID(如PHPSESSID、JSESSIONID),并将其作为cookie的内容交给客户端。客户端A再次请求的时候(比如将购物车中的商品下订单)只要携带这个cookie,服务端B就可以从中获取到session ID并找到属于客户端A的缓存内容(商品C),也就可以继续执行下订单部分的代码。

        假如这时使用负载均衡软件对客户端的请求进行负载,就必须要保证能将客户端A的请求再次引导到服务端B,而不能引导到服务端X、服务端Y,因为X、Y上并没有缓存和客户端A对应的session内容,也就无法为客户端A下订单。

        因此,反向代理软件必须具备将客户端和服务端"绑定"的功能,也就是所谓的提供会话保持,让客户端A后续的请求一定转发到服务端B上。

        这里讨论的对象是http的动态应用请求,它要求会话保持。更通用地,只要负载均衡软件负载的不是"无状态"的协议或服务,就应该提供会话保持能力,除非它是四层负载软件。

haproxy提供了3种实现会话保持的方式:

  • (1).源地址hash;
  • (2).设置cookie;
  • (3).会话粘性表stick-table;

一、源地址hash(用户IP识别)

        haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令)。

        缺陷——当后端一台服务器挂了以后会造成部分session丢失。

#配置指令:

backend SOURCE_srv

  mode   http

  balance  source

  server app-node1  10.31.1.179:80  check port 80 inter 3000  rise 3  fall 3

  server app-node2  10.31.1.191:80  check port 80 inter 3000  rise 3  fall 3

  server app-node3   10.31.0.35:80  check port 80 inter 3000  rise 3  fall 3  

二、cookie 识别  

        haproxy 将WEB服务端返回给客户端的cookie中插入haproxy中特定的字符串(或添加前缀)在后端的服务器COOKIE ID。

backend COOKIE_srv

   mode    http

   cookie SERVERID insert indirectnocache

   server app-node1 10.31.1.179:80 check  port 80 cookie  a  inter 3000  rise 3  fall 3

   server app-node2 10.31.1.191:80 check  port 80 cookie  b  inter 3000  rise 3  fall 3

   server app-node3 10.31.0.35:80  check  port 80 cookie  c inter 3000  rise 3  fall 3

cookie参数说明:

        cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]

1)[ rewrite | insert | prefix ]  /*三者互斥,只能选一*/

       rewrite  //表示cookie由服务器生成并且haproxy会在其值中注入该服务器的标识符;此关键字不能在HTTP隧道模式下工作。
       insert  //表示如果客户端没有cookie信息且有权限访问服务器时,持久性cookie必须通过haproxy穿插在服务器的响应报文中。当服务器收到相同名称的cookie并且没有“preserve(保存)”选项时,将会移除之前已存的cookie信息。因此,insert可视作"rewrite"的升级版。cookie信息仅仅作为会话cookie且不会存到客户端的磁盘上。默认除非加了“indirect(间接)”选项,否则服务器端会看到客户端端发送的cookie信息。由于缓存的影响,最好加上“nocache”或“postonly”选项。
       prefix  //表示不依赖专用的cookie做持久性,而是依赖现成的。用在某些特殊的场景,如客户端不支持一个以上的cookie和应用程序需求它。每当服务器建立一个名为<name>的cookie时,它将以服务器的标识符和分隔符为前缀。来自于客户端的请求报文中的前缀将会被删除以便服务器端能识别出它所发出的cookie,由于请求和响应报文都被修改过,所以此模式不能工作在隧道模式中。且不能和“indirect”共用,否则服务器端更新的cookie将不会被发到客户端.

2)[ indirect ]    //指定此选项时,将不会向客户端发送服务器已经处理过请求的且可用的cookie信息。如果服务器设置这样一个cookie本身,它将被删除,除非“保存”选项也设置。在“插入”模式下,将从发送给服务器的请求中删除cookie,使持久机制从应用程序的角度完全透明。

3)[ nocache ]    //当客户端和haproxy间存在缓存时,使用此选项和insert搭配最好,以便确保如果一个cookie需要被插入时,可被缓存的响应会被标记成不可缓存。这很重要,举个例子:如果所有的持久cookie被添加到一个可缓存的主页上,之后所有的客户将从外部高速缓存读取页面并将共享相同的持久性cookie,会造成服务器阻塞。

 

       在LB1上配置好HAProxy后,LB1将接受用户的所有请求。如果一个用户请求不包含任何cookie,那这个请求将被HAProxy转发到一台可用的WEB服务器。可能是webA,webB,webC或webD。然后HAProxy将把处理这个请求的WEB服务器的cookie值插入到请求响应中。如SERVERID=A。当这个客户端再次访问并在HTTP请求头中带有SERVERID=A,HAProxy将会把它的请求直接转发给webA处理。在请求到达webA之前,cookie将被移除,webA将不会看到这个cookie。如果webA不可用,对应的请求将被转发到其他可用的WEB服务器,相应的cookie值也将被重新设置。

三、基于session

       haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。

       配置参数:appsession JSESSIONID len 64 timeout 5h request-learn

backend APPSESSION_srv

    mode    http

    appsession JSESSIONID len 64 timeout 5h request-learn

    server REALsrv_70       184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1

    server REALsrv_120      220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1

注意使用事项;

(1).如果客户端使用HTTP1.1(keep-alive),只有第一个响应才会被插入cookie,并且HAProxy只会分析每个session的第一个请求。在使用cookie的插入模式下,可能不会造成什么问题,因为HAProxy会立即在第一个响应中插入cookie,同一个session中的所有请求将被转发到同一台服务器上。但是,到达服务器端的请求中的cookie不会被删除,所以这要求后端服务器对来历不明的cookie不作敏感处理。如果不想引起其他的问题,可以使用以下参数关掉keep-alive

 option httpclose

(2).由于一些原因,一些客户端不能识别多个cookie,并且后端应用已经设置了cookie,如果HAProxy再对响应插入cookie后,这些客户端可能不能识别cookie。这种情况下,可以使用cookie的prefix模式。

(3).LB1成为整个架构中的瓶颈,如果LB1不可用,那么客户端的所有请求都得不到响应。可以使用Keepalived配置HAProxy解决LB1单点故障的问题。

(4).在以上配置中后端服务器是看不到客户端的真实IP地址的。可以使用 forwardfor 参数,它能够在客户端的请求头中增加 X-Forwarded-For 字段。同时需要配置使用 httpclose 参数,确保每个请求都被重写,而不只是第一个请求被重写。

 option httpclose

 option forwardfor

 后端WEB服务器上的Nginx的日志格式需要增加$http_x_forwarded_for 变量;

 log_format  main  ‘$remote_addr - $remote_user [$time_local] "$request" ‘

         ‘$status $body_bytes_sent "$http_referer" ‘

        ‘"$http_user_agent" "$http_x_forwarded_for"‘;

(5).在有些情况下,一些用户会将他们的浏览器的cookie功能关闭。这时候可能没法访问WEB服务器的内容。这种情况下,可以使用HAProxy的 source 负载均衡算法替代  roundroubin算法。source 算法可以确保来自同一个IP的所有请求都到达同一台WEB服务器,但是前提是,可用的服务器的数量保持不变。

(6).不要在一个小型网络和代理服务器后面使用source 算法,因为请求分发会不太公平,但是在大型内部网络或互联网上使用source算法,转发效率很好。对于那些具有动态IP地址的客户端,只要它们能够接收cookie,那么请求转发就不会受到影响,因为HAProxy对cookie的处理具有较高优先级。


本文非原创,转载请注明原文链接!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
HAProxy中进行会话保持可以通过使用Cookie或基于源IP的方法来实现。 1. 使用Cookie进行会话保持HAProxy可以通过在响应中设置Cookie来实现会话保持。当客户端发送请求时,HAProxy会检查请求中是否包含有效的会话Cookie。如果存在,它将根据Cookie的值将请求路由到相应的后端服务器。如果不存在,HAProxy可以选择一个后端服务器,并在响应中设置一个新的会话Cookie,以便客户端在后续请求中使用。 以下是一个示例配置: ``` frontend my_frontend bind 0.0.0.0:80 mode http default_backend my_backend backend my_backend mode http balance roundrobin cookie JSESSIONID prefix server backend1 192.168.0.1:8080 cookie server1 server backend2 192.168.0.2:8080 cookie server2 ``` 在上述配置中,HAProxy使用名为"JSESSIONID"的Cookie来进行会话保持。"cookie"关键字指定了Cookie的名称,并使用"prefix"参数表示Cookie值由HAProxy自动生成。 2. 使用基于源IP的方法进行会话保持:另一种常见的方法是基于源IP的会话保持HAProxy可以根据客户端的源IP地址将请求路由到同一台后端服务器,从而实现会话保持。这种方法适用于无状态的应用,其中会话信息不需要存储在后端服务器上。 以下是一个示例配置: ``` frontend my_frontend bind 0.0.0.0:80 mode http default_backend my_backend backend my_backend mode http balance source server backend1 192.168.0.1:8080 server backend2 192.168.0.2:8080 ``` 在上述配置中,"balance source"指示HAProxy使用源IP地址进行负载均衡,并实现会话保持。 无论使用哪种方法,都可以根据具体需求进行配置。请注意,会话保持可能会增加服务器的负载和复杂性,因此需要根据实际情况进行权衡和调优。 希望能对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼刺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值