会话保持(Session Affinity),有时又称粘滞会话(Sticky Sessions), 是负载均衡领域设计需要着力解决的重要问题之一,也是一个相对比较复杂的问题。
会话保持是指在负载均衡器上的一种机制,在完成负载均衡任务的同时,还负责一系列相关连的访问请求会分配到一台服务器上。
当用户向服务器发起请求,服务器创建一个session,并把session id以cookie的形式写回给客户。
看一个例子:当我访问SAP UI5应用时,
在http请求的头部观察到客户端要求服务器返回以cookie的形式返回session id的请求字段:
在服务器响应的头部字段果然返回了session id:
这些cookie信息能够在Chrome开发者工具的Application标签页里的Cookies区域查看:
如此一来,只要客户的浏览器不关,再去访问服务器时,访问请求会自动附上session id去,服务器端检测到这个session id后,就会使用内存中维持的与这个id对应的session为客户端服务。
再回到我们讨论的会话保持这个话题。什么时候需要会话保持?举个大家每天都会遇到的例子,大家在淘宝或者京东上购物时,从完成用户身份认证到浏览店铺,选择心仪商品加入购物车,一直到最后下单完成支付,需要经过很多次和服务器的交互过程才能完成整个交易。由于这几次交互过程从顺序上和逻辑上是密切相关的,服务器在进行这些交互过程的某一个交互步骤时需要一个上下文(Context),即上一次交互过程的输出,因此要求这些相关的交互过程都由一台服务器完成。
在这种情况下,假设负载均衡器仍然把这些相关交互session分散到不同的服务器实例上,就会带来很糟糕的用户体验,比如客户在浏览器上每点击一次,都会弹出登录页面。或者即使用户输入了正确的验证码,却仍然提示验证码错误。由于服务器处理实例不一样,也有可能造成客户放入购物车的物品丢失。
这就是会话保持机制引入的原因:确保把来自同一客户的一个完整会话的请求转发至后台同一台服务器进行处理。
那么Cloud Foundry的Session Affinity是怎么实现的呢?
官方文档有介绍:
https://docs.cloudfoundry.org/concepts/http-routing.html#sessions
(1) To support sticky sessions, configure your app to return a JSESSIONID cookie in responses. The app generates a JSESSIONID as a long hash in the following format:
您的应用在响应结果里需要加上一个JSESSIONID字段,长度如下:
1A530637289A03B07199A44E8D531427
(2) If an app returns a JSESSIONID cookie to a client request, the CF routing tier generates a unique VCAP_ID for the app instance based on its GUID in the following format:
CF routing tier基于app生成的JSESSIONID生成一个VCAP_ID: 323f211e-fea3-4161-9bd1-615392327913
(3) 接下来客户每次发起请求,必须同时提供JSESSIONID和VCAP_ID。JSESSION_ID交给应用,用于实现session粘连。而VCAP_ID用于标识服务的应用实例,如果应用挂了,gorouter会把请求路由到另一个应用实例上。
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。