转自: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 镜像不带主动健康,本镜像将 nginx_upstream_check健康检查 打包到了镜像中。
nginx-upstream-jvm-route 支持nginx版本1.15 解决nginx: [emerg] invalid parameter "srun_id=tomcat1" 问题
NGINX第三方模块:nginx_upstream_hash-0.3.1.tar.gz。
nginx1.16版本 后端节点健康检查、自动隔离+nginx_upstream_check_module-master+nginx-upload-module
NGINX第三方模块:nginx_upstream_hash-0.3.2版本。。。
nginx_upstream_jvm_route 是一个 Nginx 的扩展模块,用来实现基于 Cookie 的 Session Sticky 的功能。 安装方法(进入Nginx源码目录): #patch -p0 # ./configure --prefix=/usr/nginx-0.8.1 --with-...
Nginx upstream urlhash url hash 反向代理 Nginx upstream urlhash url hash 反向代理
这是一个很小的脚本文件用来管理 Nginx 的 upstream 配置。 使用方法:upstream_manager.py <cluster> <action> [...]
nginx_upstream_check_module模块,2019年11月6日18:11:19下载的
docker容器中编译安装第三方后端检查模块nginx_upstream_check_module 使用方法见:https://blog.csdn.net/pcn01/article/details/105182600
nginx配置upstream的资源文件文件,下载下来直接上传至服务解压即可
nginx-upstream-jvm-route-0.1.tar.gz 用来实现Nginx Tomcat 集群session复制的问题!
nginx_upstream_jvm_route 是一个 Nginx 的扩展模块,用来实现基于 Cookie 的 Session Sticky 的功能。 安装方法(进入Nginx源码目录): #patch -p0 # ./configure --prefix=/usr/nginx-0.8.1 --with-...
nginx_upstream_check_module-master,淘宝技术团队开发的,适用1.11
借助淘宝技术团队开发的nginx模快nginx_upstream_check_module来检测后方realserver的健康状态,如果后端服务器不可用,则会将其踢出upstream,所有的请求不转发到这台服务器。当期恢复正常时,将其加入upstream。 ...
Nginx所需环境的安装,及nginx安装,nginx相关功能开启,后端节点健康检查插件安装,静态资源缓存插件,缩略图插件安装等。
Nginx均衡负载-fair(第三方)模块,要实现这种均衡负载操作,必须给Nginx添加这个模块,否则,无法进行!
nginx后端节点健康检查模块插件,非常好用,淘宝开发。