一、Nginx的模块和工作原理
nginx由内核和模块组成:
1.内核:其设计非常微小和简洁,完成的工作也非常简单。仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用例URL匹配),而在这个location中所配置的每个指令将会启动不同的模块取完成相应的工作。
2.从结构上分为‘核心模块、基础模块、第三方模块’:
核心模块:HTTP模块、EVENT模块、MAIL模块。
基础模块:HTTP Access模块、HTTPFastCGI模块、HTTP Proxy模块、HTTP Rewrite模块。
第三方模块:HTTP Upstream Request Hash模块、Notice模块、HTTP Access Key模块以及根据需求自己开发的模块。
3.从功能上划分为‘Handlers、Filters、Proxies’:
Handlers(处理器模块):此类模块直接出来请求,并输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
Filters(过滤器模块):此类模块主要对其他处理器模块输出的内容进行修改操作,最后有nginx输出。
Proxies(代理类模块):此类模块是nginx的HTTP Upstream质量的模块,这些模块主要与后端一些服务(例如FastCGI)进行交互,实现服务代理和负载均衡等功能。
如下图,展示了Nginx模块常规的HTTP请求和响应过程:
nginx本身做的工作很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块取完成工作,因此模块可以看做nginx真正的劳动工作者。通常一个location的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用一个模块)。handler模块负责处理请求,完成相应内容的生成,而filter模块对相应内容进行处理。
nginx的模块直接被编译仅nginx,隐藏属于静态编译方式。启动nginx后,nginx的模块被自动加载,不想Apache,首先将模块编译成一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,nginx每个模块都有可能处理某个请求,但是同一个处理请求只能由一个模块完成。
二、、nginx能做什么
1.正向代理
简单的说,我是一个用户,我无法直接访问一个网站,但是我能访问一个代理服务器,这个代理服务器能访问我不能访问的网站,预算我先连上代理服务器,告诉它我需要访问那个无法访问的网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录。结论是,正向代理,是一个位于客户端与原始服务器(origin server)之间的服务器,为了从原始服务器取得内,客户端向代理发送一个请求并指定原始目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
2.反向代理
例如需要访问localhost:8080/views/test1这个页面,但view对应的服务器上没有test1这个资源,它是从另外一个服务器调用的资源。这样,view对应的服务器就使用了反向代理。即,用户只需要把请求发给特定的反向代理服务器,用户不需要知道请求具体是谁处理的,由代理服务器统一处理。反向代理,对于客户端而言,它就像是原始的服务器,客户端不需要做任何特别的设置。客户端向反向代理的命名空间(namespace)中的内容发送普通请求,接着反向代理服务器讲判断向何处(原始服务器)转交请求,并将返回的内容(就像这些内容原本是它自己一样)返回给客户端。
正向代理的典型用途是在为防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。总之而已,正向代理,对应客户端而言,代理服务器代理客户端,转发请求,并将获得的内容返回给客户端;反向代理,对于客户端而言,代理服务器就像原始服务器,代理集群的web节点服务器返回结果。nginx就是一台反向代理服务器。
3.负载均衡
负载均衡也是nginx常用的一个功能,所谓负载均衡即分摊多个操作单元上进行执行,例如web服务器、ftp服务器、企业关键应用服务器和其他关键任务服务器等,从而共同完成工作任务。简单而言就是,当有2台或者以上服务器时,根据规则随机地将请求分发到制定的服务器处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。目前nginx提供3种自带的负载均衡,还有2种常用的第三方策略。
3.1 RR:安装轮询(默认)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。虽然这种方式简便、成本低,但缺点是:可靠性低和负载分配不均衡。
3.2 权重:指定轮询几率,weight和访问比例成正比,用于后端服务器性能不均的情况。
此时,8080和8081分别占90%和10%。
3.3 ip_hash:上面2种方式都有一个问题,就是下一个请求来的时候,请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用session保存数据),这个时候,就有一个很大的问题,比如把登录信息保存到了session中,那么跳转到另外一个服务器的时候就需要重新登录了,所以很多时候,我们只需要一个客户只访问一个服务器,那么就需要用到iphash。iphash的每个请求按访问ip的hash结果分配,这个每个访客访问一个后端服务器,可以解决session问题。
3.4 fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
3.5 url_hash(第三方):按访问URL的hash结果进行分配请求,使每个URL定向到同一个后端服务器,后端服务器为缓存时比较有效。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用hash算法。
4.HTTP服务器(包括动静分离)