nginx 负载均衡的几个问题

2016-08-16 11:29:20 +08:00
 spikeLIN
目前有三台服务器,ABC
A 在外网做负载均衡,利用 upstream 转发到 B,C
A 中 upstream 的设置里,B 和 C 都是一样的,为 max_fails=2 fail_timeout=30s
BC 的 upstream 设置只转发到本地的一个端口,后面也都写了 max_fails=2 fail_timeout=30s,但是应该是无效的.
现在有个问题就是某个请求会重复两次.
根据 log 里的内容,A 的 nginx 的 log 里此请求只出现了一次.
在 B 的 log 里出现了一次,B 中返回码为 499,request_time 为 60 秒
然后在 C 的 log 内也出现了一次,返回码为 200.

所以我的想法是,A 先转发到 B,B 接受请求后的后台程序执行了该请求,但是响应时间过长,导致返回 499,于是 A 的 nginx 以为请求没有被响应,就把此请求转发到 C,C 又重新接受了请求.导致了该请求被执行了两次.

如果真的是这种原因的话,那么我有几个小小的问题
第一,这个 60 秒是怎么算出来的?如果是按照 A 中的 max_fails=2 fail_timeout=30s 的设置得出的话,朝 B 转发两次,这样总共不应该是有三次请求的执行吗?(B 的两次和 C 的一次)
第二,A 中 nginx 的 log 在 B 失败之后转发的记录是没有被记录在 log 里的吗?
第三,这种情况有什么有效的处理方法吗?
望各位 nginx 大牛不吝赐教.
2744 次点击
所在节点    Linux
2 条回复
pangliang
2016-08-17 09:26:56 +08:00
这个 60 秒应该不是打 了两次 B, 是恰巧 B 的执行就是 60 秒; 或者说是这个 request 的执行时间过长, 超过了指定的最长时间, 容器主动终止了运行, (不知道你是不是 php, php 默认 max runtime 就是 60 秒, 也就是说你在 php 里 sleep(120) 是不行的)

另外 , 这个 fail_timeout 的意思不是告诉 A, 如果 B fail_timeout 秒不返回就算他 fail, 而是说, B 出现 max_fails 次 非 200 响应后, 把 B 打入冷宫 fail_timeout 秒

你这个问题其实跟 nginx 没什么关系, 这种业务都是要有"订单号" 并且 请求来了先判断这个订单是否已经被处理过 的判断
spikeLIN
2016-08-17 11:22:25 +08:00
@pangliang 原来是这样,十分感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/299584

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX