个人随笔
目录
十二、nginx做轮询负载均衡后每次会返回新JSESSIONID原因分析
2021-04-02 22:48:47

一、背景

前端用nginx做横向扩展负载均衡,然后我这里用的是轮询策略,但是发现,在第一个节点登录后,访问第二个节点显示没有登录,此时是正常的,但是后面又访问了第一个节点,显示也没有登录,感觉每次轮询切换cookie中的id就变了一样,为什么呢?

二、过程分析

这里对同一个应用七两个节点,一个是8080,一个是8081,然后应用又两个接口,一个是登录,一个是下单,下单只有在登录的情况下才能下单,下面是浏览器访问过程分析。

1、第一次请求登录

在浏览器请求登录

  1. http://127.0.0.1/login

Request Cookies为:925BF72A36EA953A7D908F19AF9BFEA5
Response Cookies为:C865EB29BEC515D7260AA6FB8F719692

因为第一次访问,请求的是8081那台机,后台session中没有JSESSIONID所以新生成一个,后续请求就以第二个JSESSIONID来请求。

2、第二次请求下单

在浏览器请求下单

  1. http://127.0.0.1/order

Request Cookies为:C865EB29BEC515D7260AA6FB8F719692
Response Cookies为:B817F3B455CA8876A7C73E3042492514

因为nginx做了负载均衡,所以第二次亲求的是8080那台机,后台session中也没有JSESSIONID所以又新生成一个,后面就又用新生成的JSESSIONID来请求。

3、第三次请求下单

在浏览器请求下单

  1. http://127.0.0.1/order

Request Cookies为:B817F3B455CA8876A7C73E3042492514
Response Cookies为:50B1182935BC7A0F1B773C86F7234669

因为nginx做了负载均衡,所以第三次请求的是8081那台机,但还是没有登录,因为你第二次新返回了JSESSIONID,跟第一次请求返回的不同,所以后台又生成了一个新的JSESSIONID,所以用户相当于没有登录了。

三、原因总结以及解决方案

1、原因总结

通过上面的测试可以知道,因为后台做了负载均衡,并且不是绑定IP的负载策略,用的是轮询的策略,所以每次轮询切换后,后端在内存中都找不到对应的JSESSIONID,判定为session失效而重新创建session,之前在session中保存的信息就会失效,所以当然登录失败啦,就算轮询到最初登录的那台机也没有用,中间已经生成了新的JSESSIONID给客户端。

2、解决办法

所以用轮询模式而不是用IP绑定的模式做负载均衡,需要将JSESSIONID做共享,比如放到数据库,或者redis,对于java来说用spring session是很方便的。

 47

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号