转自:http://blog.csdn.net/brainkick/article/details/8531857
网上搜过upstream相关分析的同学可能都已经有了大概的了解了,而且很多大牛分析的也很棒,我这里为什么还要多说几句呢?一来是总结自己的一些理解,二来是对前辈分析的一些补充,希望能带给大家更多启发。
先给出阿里技术牛们的总结和分析,供大家参考:
http://tengine.taobao.org/book/chapter_05.html
http://www.pagefault.info/?p=251
看nginx官方wiki给出的配置例子(稍作修改):
- upstream backend {
- server 211.20.10.11 weight=5;
- server 198.172.10.9:8080 weight=10;
- }
- server {
- location / {
- proxy_pass http://backend;
- }
- }
(事先声明下,upstream中的后端连接选择算法不是这里讨论的重点,我们仅仅会涉及round robbin算法,像ip_hash或者更新的机制如keepalive不在讨论之列)
对于上述的upstream配置,在系统初始化阶段会创建一个结构来保存它,注意是该结构是初始化阶段分配的内存,它的生命周期不跟随一个具体的request。这里必须强调的一点就是,在分析nginx代码时,我们要记清楚什么结构的生存期是跟随request的,什么结构不是。这个对你从总体上把握系统的框架很有用。参考函数ngx_http_upstream_init_round_robin。
其实upstream模块的运作,主要的驱动是xxx_pass,比如上面的proxy_pass。除此之外,还有memcache_pass,fastcgi_pass等,upstream相关配置结构的建立,并不一定是非要配置upstream这个指令才会去做,有时proxy_pass直接就是跟一个可解析的域名,这个时候upstream的初始化工作也会正常运转起来,这里我们不讨论这个情况。
那么一个具体的request如何跟这个upstream配置系统相关联?一般是通过peer.init函数指针,在这里round robbin使用的是ngx_http_upstream_init_round_robin_peer,当然ip_hash有自己的处理函数。从配置上看,凡是请求到location /的request,他们都关联到同一个upstream配置,这点没有问题,我们设计也会这么做,但是既然大家公用一个结构,那么需不需要互斥呢?如果大家都要修改其中的某个成员。。。实际上,nginx中一个请求不会中多个进程中同时处理,一个request生老病死都在一个worker内。其次,由于在单个进程内,nginx非阻塞对各个请求请求进行异步处理,具体来讲,在一个请求处理在发生EAGAIN(一些系统调用,或者主动放弃情况)之前,是不会转去处理另一个请求的,所以也就不存在互斥的问题。好像扯远了。。。我们继续讨论。
通过示例配置,可以看出upstream结构管理了两个后端服务器,那么在使用时,通过选择优先级最高(round robbin)的一个后端,来发起连接。算法如何去选择,大家可以直接去读源码。这里我们关心的是,连接异常的后续处理,毕竟异常和及其细节处理的好坏直接决定一个服务是否稳定。
情况1:当前选择的后端机器,连接异常(超时或者出错)
因为这里的socket都是非阻塞的,所以我们直接connect往往不会立即成功,一般会返回经典的EINPROGRESS错误码,这种情况下,你需要做的就是加一个定时器,并且如果之前没有向epoll添加读事件的话,还要加一个read event。为什么这么做是必要的(事实上nginx就是这么做的)?首先,如果连接成功或者出错,我们注册的读事件会被epoll上报,我们在事件处理函数中,会做处理;如果连接超时了(如对端物理断网了),那么我们的超时定时器就会触发。这样,无论失败还是成功,这个连接我们都可以合理的处理掉,面对异常你不能置之不理。
那么超时或者出错之后,upstream需要做什么呢?nginx使用ngx_http_upstream_next来处理,超时和出错分别用状态NGX_HTTP_UPSTREAM_FT_TIMEOUT和NGX_HTTP_UPSTREAM_FT_ERROR表示。在ngx_http_upstream_next中,如果确实是某个后端连接出了问题,一般nginx会再次调用ngx_http_upstream_connect,来找其他可用的后端尝试连接。
这里值得的一提的是,一个后端连接出问题,会被nginx记小本本的。当所以的后端都出问题的时候(获取后端连接返回NGX_BUSY),nginx只好找备胎来用了,如果有的话。如果没有备胎,或者备胎也出问题了,那没辙, 502给你好了。
情况2:后端连接成功,但是nginx收到的响应头是异常的
这里的异常我们简单的认为成不是我们期望的状态码,比如我们想得到“200 OK”,但是却得到了 “404 Not found”或者其他。那nginx后续的处理怎样?我认为可以有两种处理,第一就是直接将这个响应发给客户端。这样做的问题就是,nginx无法感知后端机器上内容,也就是说当前连接的后端上面根本没有客户端想要的文件,但是其他机器上可能有。面对的后端是一个内容上面的集群,在内容上这样处理显然不合适。所以比较合适的处理是,让nginx再次去后端尝试。。。但是这样也不是办法,如果你有很多后端机器,只有一个有客户端想要的内容,那么运气差的话。。。
先不讨论集群方面的优化,我们看nginx是怎么处理的。
当upstream收到异常响应时,不得不提一个指令“proxy_next_upstream”,看官方介绍吧。
关于用法,描述的很明确。再看一些相应的代码:
- static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 },
- { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
- { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
- };
上述的信息告诉我们proxy模块中支持的特殊响应码处理有哪些,当然fastcgi和memcache等这些用到upstream的模块都有类似的数组。对于proxy_next_upstream指令配置中的给出的http_xxx,意思是让nginx在后端返回这些响应时,去尝试其他的后端(函数ngx_http_upstream_test_next)。当然nginx原生支持的就这些,如果大家有自己的需求,可以尝试去改这块代码。不过个人的建议是,改nginx的核心代码要慎重。
相关推荐
此资源有两个文件,含 nginx-upstream-jvm-route 和 nginx 对应版本,都是tar.gz文件。 安装方法网上很多就不写了,亲测可用。 不用担心版本不匹配造成安装失败,再浪费积分去到处下载尝试的烦恼。 此资源有两个文件...
总的来说,"nginx-upstream-jvm-route-1.15"是一个针对Nginx 1.15版本的解决方案,它允许用户通过upstream模块更灵活地管理与JVM应用服务器的交互,并解决了配置过程中可能出现的特定错误。通过深入理解和应用该项目...
官方nginx 镜像不带主动健康,本镜像将 nginx_upstream_check健康检查 打包到了镜像中。
在Nginx中,upstream模块是处理后端服务器群的重要组件,它负责将客户端请求转发到适当的服务器上。"nginx-upstream-fair-master.zip"是一个包含Nginx公平负载均衡(fair)第三方模块的压缩包,该模块使得Nginx可以...
在`nginx_upstream_hash-0.3.1`版本中,我们可以看到以下关键特性: 1. **哈希算法选择**:该模块支持多种哈希算法,可以根据业务需求选择合适的算法以保证哈希结果的均匀分布。 2. **键值设置**:通过`hash $...
在Nginx配置文件中,`nginx_upstream_check_module`的使用涉及到一些特定的指令,如`check`、`check_interval`、`check_timeout`等。以下是一个简单的示例: ```nginx http { upstream backend { server backend1...
patch -p0 < ../nginx_upstream_check_module-master/check_1.9.2+.patch ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module --with-http_stub_status_module --with-pcre \ --with-...
借助淘宝技术团队开发的nginx模快nginx_upstream_check_module来检测后方realserver的健康状态,如果后端服务器不可用,则会将其踢出upstream,所有的请求不转发到这台服务器。当期恢复正常时,将其加入upstream。 ...
在 Nginx 的配置中,`upstream` 模块是用于处理负载均衡的,它允许将客户端请求分发到一组后端服务器上。而 `nginx_upstream_hash` 是一个第三方模块,它扩展了 Nginx 的负载均衡策略,提供了基于请求参数或特定头部...
在IT行业中,Nginx是一款广泛应用的高性能反向代理服务器,因其高效稳定和灵活的配置而备受青睐。这里我们关注的是一个包含特定模块的Nginx配置:`nginx1.16`,`nginx-upstream-check-module-master` 和 `nginx-...
5. **公平算法(fair)**:这个资源包中的`nginx-upstream-fair`实现的是公平算法,它根据服务器的实际响应时间动态调整权重,响应时间短的服务器将得到更多请求。 配置公平算法(fair)的示例如下: ```nginx ...
在Nginx配置中,"upstream"模块是用于定义后端服务器组,它允许Nginx将请求分发到这些服务器,实现负载均衡。而"hash"策略则是Nginx upstream模块中的一个功能,用于根据特定的请求属性(例如URL)来决定请求应被...
以下是关于 Nginx upstream 及该管理脚本的一些关键知识点: 1. **Nginx Upstream 模块**: - Upstream 模块允许 Nginx 将来自客户端的请求转发到一组后端服务器,如 Web 服务器、数据库服务器等。 - Upstream ...
`nginx_upstream_check_module-master` 是一个由淘宝技术团队开发的Nginx扩展模块,主要用于健康检查和负载均衡器中的服务器状态监控。这个模块对于运行大规模分布式系统,尤其是那些依赖Nginx作为反向代理和负载...
在解压后的"nginx_upstream_jvm_route"目录中,我们可以找到Nginx的配置示例、Java应用程序的部署配置以及可能的脚本文件。这些资源可以帮助我们配置Nginx以识别和利用JVM Route,确保Session数据在Tomcat集群中的...
nginx_upstream_jvm_route 是一个 Nginx 的扩展模块,用来实现基于 Cookie 的 Session Sticky 的功能。 安装方法(进入Nginx源码目录): #patch -p0 # ./configure --prefix=/usr/nginx-0.8.1 --with-...
在Nginx配置文件中,我们可以定义一个upstream块,并启用check模块,如下所示: ``` upstream backend { server 192.168.1.1:80 check; server 192.168.1.2:80 check; check interval=5000 rise=2 fall=5 ...
3. **设置Zabbix Agent**:在Nginx服务器上的Zabbix Agent配置文件(通常为`/etc/zabbix/zabbix_agentd.conf`)中,添加自定义脚本的路径,如`UserParameter=nginx_upstream[*], /path/to/nginx_upstream_script.py ...
nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的相关指令来完成当后端节点出现故障时,自动切换到健康节点来提供访问。