Nginx高端成长之路Api设计

【充电】《Nginx核心知识100讲》proxy模块:上游出现失

2019-01-19  本文已影响7人  言十年

极客专栏《Nginx核心知识100讲》95小节,笔记
注意:这个是看专栏视频,敲的哈。这个专栏让我收货蛮大的。

95 | 上游出现失败时的容错方案

我们讨论了nginx作为反向代理时,从客户端接收http body,到完整的接收上游的响应并转发响应的流程。其中在nginx与上游服务建立连接时。提到过proxy_next_upstream指令。这个指令可以在第一台的错误的响应返回给客户端这样的功能。这节课讨论这个功能是怎么使用的。

上游失败的处理方法

image.png

能够生效的前提是没有向客户端发送一个字节。只要向客户端已经发送了一个字节了。说明上游的服务已经生效了,就不能选用一个新的上游服务了。它一定是在接收到并开始转发一个字节之前nginx判定为错误,这个功能才能生效。proxy_next_upstream后面可以跟很多不同的参数(error、timeout那些)。

配置

error:nginx与上游建立连接读取响应,发送请求等等这些过程中,只要出现错误等等。error都可以满足这样的场景。这种错误主要是网络错误。比如TCP层、IP层的错误。

timeout:超时有connection timeout 、read timeout、 write timeout,这个timeout可以命中这些场景。当出现这种场景的时候将执行重选另一个上游服务。

invalid_header则是我们收到的上游服务http header,它是不合法的。

http_:http_可以跟一个明确的响应code。上游返回一个403或500,其实它既不是网络错误,也不是超时,也不是invalid_header。但是我们就是可以针对这样的错误从新选择一个新的upstream上游去处理。

non_idempotent:根据RFC 7231文档中规定了post、lock等method的请求。在上游服务不能使用next_upstream上游服务的,去重选一个新的服务时候,当我们配置了这个non_idempotent就可以启用proxy_next_upstream功能。

off:关闭 proxy_next_upstream功能。

image.png

演示

第一个演示,error 的演示

反向代理nginx 配置

image.png

proxy_next_upstream设置为off。为了很快的显示出错误的结果,connect_timeout 设置了1s。

上游的配置

image.png

能从8011和8013的返回的错误看出区别。

image.png

下面把8011改成8014

image.png

因为8013端口不存在了。所以报错了。

image.png

把proxy_next_upstream改成error。

image.png image.png

出现上图的原因是。虽然使用的是round-robin算法。但是每次都能获取返回值。但其实8013端口不在监听了。原因是proxy_next_upstream生效了,发现8013不存在了,就会重新改用新的upstream来为用户服务,这个功能可以让nginx把错误屏蔽掉。这是对于分布式集群下非常好用的功能。客户端每一次api或一次请求都没有拿到错误。

第二个演示,对返回状态码做处理

8014再改回到8013端口。

image.png

http_500的意思是,当我收到500的错误码,我仍然把它当成错误从新选择一个新的upstream,而不把这个500返回给客户端。

image.png

看结果,因为把500做处理,所以请求中无法看到8013的返回。nginx重新选择8011作为返回结果。

拦截上游失败响应

image.png

proxy_intercept_errors 默认off。这个时候上游返回怎样的响应。客户端就会原封不动的拿到这个响应。比如上游返回来一个404,我们的error_page 配置的404是不会生效的。只有把proxy_intercept_errors 设置为on的时候error_page 就会生效了。

演示

nginx配置,proxy_intercept_errors 为off

image.png

8013 返回500的错误

image.png

proxy_intercept_errors 为on时,配置了error_page,发现500错误码的时候返回test1.txt。

image.png image.png

这次看到请求的返回值变成了test1(也就是test1文件的内容)。

留言问题

1.nginx 默认的proxy_next_upstream 应该是配置了error和timeout,max_fails=1 fail_timeout=10s。这样如果后端的设备不是全部故障的话,应该不会出现异常的页面吧。

但是我这里使用了缓存后,就不会自动切换了,不知为何,配置如下。
proxy_cache_path /home/yum_cache/ levels=1:2 keys_zone=cache1:1024m inactive=1d max_size=30g;

upstream "yumproxy" {
server 192.168.1.10:80;
server 192.168.2.10:80 backup;
}

location ~ .(php|xml){ proxy_set_header Hosthost;
proxy_set_header X-Forwarded-For remote_addr; proxy_pass http://yumproxy; proxy_cache cache1; proxy_cache_keyhosturiis_args$args;
access_log logs/cache.log main;
proxy_cache_valid 200 304 301 302 1m;

在此指定时间过期后,会主动去源服务器更新数据信息

proxy_cache_valid any 0s;
}

location / {
proxy_pass http://yumproxy;
}

根据这个配置,如果主节点异常了,理论上backup的节点应该会被直接访问到,但是当我把主节点停掉的时候,再访问这个缓存节点的时候,就会出现502的错误。

 作者回复
你用的是哪个版本的Nginx?我根据你的配置,在我的服务器上修改后,发现主节点异常后仍然正常跳到backup节点,没有收到502。
我用的是最新的Nginx版本。

2.测试了一把,需要在upstream 中的每一条后端记录上添加这个指标 max_fails=1 fail_timeout=60s。然后可以实现异常后自动将其摘除60s。

可以实现自动检测的 貌似可以用淘宝的模块nginx_upstream_check_module-master 实现

 作者回复
淘宝的模块可以定期通过心跳检查上游,与本节课介绍方式不太一样:-)

上一篇下一篇

猜你喜欢

热点阅读