个人感觉ip_hash更适用于一个小的应用,单台机器本身就是可以承载所有请求,之所以使用集群是用来提高服务的高可用,但是集群又有session共享问题,所以使用ip_hash作为解决方案就是个不错的选择。
上面这段是一个文章的话,使用ip_hash如何解决session共享问题?
个人感觉ip_hash更适用于一个小的应用,单台机器本身就是可以承载所有请求,之所以使用集群是用来提高服务的高可用,但是集群又有session共享问题,所以使用ip_hash作为解决方案就是个不错的选择。
上面这段是一个文章的话,使用ip_hash如何解决session共享问题?
ip_hash 指令能够将某个客户端 IP 的请求通过哈希算法定位到同一台后端服务器上
那就等于同一个 ip 访问的就是同一个真实服务器,本身 session 就是存在的。
如果同一个 ip 访问的不是同一个真实服务器,那么在新的机器上是找不到 session 的,所以需要其他共享 session 的方法
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
ip_hash是通过对客户端ip进行hash运算来确定请求的是集群中的哪一台服务器
所以在客户端ip不变的情况下,每次请求的都是同一台服务器,对应的session依然是存在的,变相的解决了session共享问题
upstream backend{
ip_hash;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
设置就是这么简单。
另外除了在nginx上配置外。还可以考虑在业务层做。每个语言的框架都是可以支持设置session信息存放位置的。可以把session信息都放在redis memchache
以上并不是最优解。现在的主流已经是前后端分离+jwt 这样可以完全解决集群的所有session问题。
10 回答11.1k 阅读
15 回答8.4k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
传统应用的 Session 是进程/节点内的,如果你有多个进程,彼此之间的 Session 是不共享的。
那么在做负载均衡的时候就带来一个问题:同一个客户端发起两次请求、被负载到不同的节点上了、Session 还不共享、怎么办?
于是乎自然想到,能不能像银行“专属客户经理”似的,如果识别到是同一个客户,就由固定的经理(节点)来接待(提供服务)。
那么怎么能“识别到是同一个客户”呢?现实中有银行卡号、身份证号,那在网络中就是客户端 IP 了 —— 只要 IP 不变,就始终负载到同一个节点上去,这样一来自然也就没有前面提到的问题了。
这种机制就叫“会话保持”。
【扩展】
这道题本来到这里就结束了,但再多啰嗦几句。
ip_hash 看似很美好,但随着移动互联网的蓬勃发展,也暴露了一个很致命的缺陷 —— 客户端 IP 是会变的。你不能说用户拿着手机在这儿的时候、IP 是 A、被负载到 ① 节点上了;过了一会儿用户坐地铁到另一个地方去了、IP 变成 B、结果被负载到 ② 节点上了,被识别成未登录用户或者登录过期了,那这体验岂不是很糟糕?
所以 ip_hash 就只能适用于客户端 IP 不会变、或者说变的频率比较低的场景了,比如说内网通信。
那么怎么解决 IP 会变、但我还得识别是同一个客户端的这个问题呢?大致可分为三类途径:
第一种是既然 IP 会变,那我再找一个不会变的来标识同一个客户端不就好了?比较有代表性的方案是 Cookie 粘连,即为每个客户端在首次请求时分配一个特定的 Cookie 值,后续识别到携带相同的 Cookie 的请求,就会被识别成同一个客户端。主流的公有云服务的负载均衡器服务基本均支持此项设定。
第二种是既然传统的 Session 是进程内的、那我想办法让它能跨进程共享不就行了?比较有代表性的方案就是集中式 Session 存储,比如把 Session 存到 Redis 或者数据库里、甚至是网关层,负载均衡时随意分配节点即可,无需担心 Session 共享问题。
第三种是既然 Session 这么多毛病,那我就不用 Session 好了。比较有代表性的方案就是 JWT 等机制。