美文网首页Nginx高端成长之路Api设计
【充电】《Nginx核心知识100讲》proxy模块:上游出现失

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

作者: 言十年 | 来源:发表于2019-01-19 22:18 被阅读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 实现

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/epizdqtx.html