Apache会话保持

Apache的会话保持从发送协议上不同而有不同的配置,主要为http会话和ajp会话。

 

Apache与tomcat的结合非常好,默认情况下,采用最基本的配置即可做到ajp的会话保持,而http的会话保持就需要一些基础配置。

http的会话保持需要做到2点:

1.在单次通讯过程中,确保同一个client请求发送到相同的backend的ap;

2.当tcp连接断开,即tcp层面的连接超时后,会话session/cookie未超时的情况下,或已超时的情况下仍然将其发送至最初始的backend的ap;

因此常规思想是相同来源的ip发送至同一个backend的ap,这样会话保持的2点都可以做到,即简单原地址会话保持。这种做法最为简单,例如f5的会话保持策略,nginx的ip hash策略,都可以做到这种方式的负载均衡,但实际生产过程中还存在2个问题:

1.在实际的网络结构中,一个公网ip往往代表的是一个局域网的路由出口,所有的局域网内的client经过此出口出去后,在f5/nginx层面上会被视为同一来源,会将其转发至同一个backend的ap,造成backend的ap压力不均;

2.源地址会话保持是需要源地址信息的,某些网络结构或设备,如内网中的nginx、CDN网络,这种结构意味着负载均衡器无法接收到真正的client ip,大量的请求会转发到backend中的某一台ap上,造成负载不均;

额外说一下XFF hash的这种策略,XFF表面上解决了上述1,2两个问题,但实际上第一个问题并没有解决,因为你需要让client的出口路由主动添加XFF才能生效。

 

以上都是基于简单会话保持的讨论,除了简单会话保持之外常见的策略还有一种是基于sessionid的会话保持。

官方nginx版本没有这个功能,不过网上有第三方做的Nginx Sticky Module

From <https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/>

,据说Tengine用的也是这个;另外也有nginx-upstream-jvm-route

From <https://code.google.com/archive/p/nginx-upstream-jvm-route/>

。题外话 nginx pro是有这个功能的,不过要收费。F5做的sessionid的会话保持是存储sessionid与backend的ap映射关系,也就说有1W个请求,那么就有1W个映射关系,内存开销很大。

 

Apache提供的基于sessionid的会话保持的原理是,根据cookie的特定字段进行backend ap的路由匹配。例如apache官网给出的示例:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=1
    BalancerMember "http://192.168.1.51:80" route=2
    ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass        "/test" "balancer://mycluster"
ProxyPassReverse "/test" "balancer://mycluster"

From <http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html>

示例中给出的为通过cookie中的ROUTEID字段进行匹配的方式,当ROUTEID字段匹配到1,那么请求就发送到1.50这个ap上。没有的话遵循最小连接发送请求。

配置这个关键字基本上就能解决几乎所有的负载均衡问题,但是,这里有一个天坑,如果查询资料的话,apache官网会告诉你stickysession这个字段支持JSESSIONID|jsessionid 然后这段配置改成如下:

ProxyPass "/test" "balancer://mycluster" stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=node1
   
BalancerMember "http://192.168.1.51:80" route=node2
</Proxy>

From <http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html>

好了 按照此方法配置,会发现根本就不能会话保持!!!

这是因为apache的stickysession选择的字段需要有一个可识别后缀才可以识别出真正的转发凭据!!!

 

然后是最关键的地方,默认情况下当stickysession指定为JSESSIONID|jsessionid后,sticksession并不是完整的读取整个jsessionid,而且读取stickysessionsep所指定的符号之后的值,该开关默认情况下读取的是 “.",也就是说apache的jsessionid的会话保持实际上是读取jsessionid中的一部分信息,以此信息进行路由匹配来进行会话保持的。

 

例如Tomcat,需要在tomcat的server.xml的Engine配置中添加jvmRoute属性,eg:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">

jvmRoute的值要和apache转发配置文件中的route的值对应上,此时才完全做到了jsessionid的会话保持。

 

然后是Weblogic,WLS的jsessionid是由2部分构成的例如:

tAK1KJWjTMvsV6Ed3nEVXac5E8eh8NxtnGzNNTW7Rg-MGiLWdvzI!2084464100

以 “!”作为分隔符后面是primary_server_id,所以这里只需要知道只要后台的primary_server_id就可以负载均发,然而实际上不行,推荐使用mod_wl.so模块方式或者用添加routeid的方式进行负载均衡。

 

WAS的话好一些,使用“:”作为分隔符,但是比WLS好的地方在于重启之后WAS的id不会变,不过还是推荐用IBM自家的IHS和Plugin组合 。

 

有了这些就可以做到后台AP程序的真正的均匀分发请求,就可以用一个ap的压力程度来衡量整个系统的压力情况。同时可以在apache的日志模块中添加一些关键字,可以更加具体的知道请求去哪了。

日志关键字:

%{MYCOOKIE}C

The value contained in the cookie with name MYCOOKIE. The name should be the same given in the stickysession attribute.

%{Set-Cookie}o

This logs any cookie set by the back-end. You can track, whether the back-end sets the session cookie you expect, and to which value it is set.

%{BALANCER_SESSION_STICKY}e

The name of the cookie or request parameter used to lookup the routing information.

%{BALANCER_SESSION_ROUTE}e

The route information found in the request.

%{BALANCER_WORKER_ROUTE}e

The route of the worker chosen.

%{BALANCER_ROUTE_CHANGED}e

Set to 1 if the route in the request is different from the route of the worker, i.e. the request couldn't be handled sticky.

 

示例格式:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{JSESSIONID}C %{Set-Cookie}o %{BALANCER_SESSION_STICKY}e %{BALANCER_SESSION_ROUTE}e %{BALANCER_WORKER_ROUTE}e %{BALANCER_ROUTE_CHANGED}e"

 

日志样式:

192.168.32.1 - - [15/Oct/2019:16:42:28 +0800] "GET /test_session/ HTTP/1.1" 200 89 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" 3EED363F63C53F702B1604E7D152E8EF.jvm2 - JSESSIONID jvm2 jvm2 -

 

 

有时间测试nginx的那两个模块

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值