本文主要是对nginx的配置做了一些简要的介绍,来源是nginx的官方文档,结合自己的理解做了下精简和翻译,一来,为了加深对各个配置的理解,二来,为下一步读nginx的源码做准备
location /blog {
root /site;
}
意味将url前缀为/blog的请求访问的文件都从/site目录里去找,/blog/post.html则实际上访问的是/site/blog/post.html
一个server可以配置一个server_name用于匹配request的Host。另外,一个nginx实例中可以配置多个server,意味着机器上可以配置多个站点,(注意站点和端口没有必然的一对一关系,可以多个server公用一个端口)。那么问题来了,一个请求过来了匹配到具体server的规则是什么:
前面说到,server_name可以有多种形式:(实际名称、通配符、正则表达式)
如果当请求的host匹配到多个server_name,那么最终选择server_name的规则是啥? 会按照如下优先级去选择:
实际名称、开始、结束通配符server_name会被存在绑定在监听端口的三个hash tables中,哈希表的size在配置阶段就被最优化了,以便以最少的cpu cahce miss去匹配name。这个hash表是用于找到对应的server的。
实际名称的hash表查的速度最快,通配符次之。正则没有hash表,而是一个一个地匹配的,因此不能大量去应用。建议是将一些被请求频率最高的host,设置为实际名称的server_name。
如果很多定义了很多server_name, 或者有些很长的server_name,那么server_names_hash_max_size和server_names_hash_bucket_size可能需要指定下
nginx支持三种负载均衡机制:
一个负载均衡配置的实例如下:
上面没有指定负载均衡的机制,默认是round-robin。所有的80端口上请求都被代理到myapp1集群上去,该例子代理的是http请求,如果后端支持https,直接替换成https即可,如果后端是fastCGI\uwsgi\SCGI\memcached,那么则需要fastcgi_pass/uwsgi_pass/scgi_pass/memcached_pas等指令了。
负责均衡除了上述几种机制外,还可以结合加权机制。在upstream中的server后面加上weight。
nginx还支持health check,主要通过两个指令,fail_timeout 和max_fails。fail_timeout指定一个时间区间,如果在这个区间内连续的不成功的尝试次数达到max_fails时认定服务不可用,max_fails指定连续探测几次后认定后端服务不可用,默认为1,为0时表示禁用health check功能。那么什么才是一次不成功的尝试呢?是由根据后端服务的类型而独立定义的(proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, memcached_next_upstream),它们指定了什么情景下请求将被转发到下一个后端机器上。比如proxy_next_upstream的使用如下:
注意上述的health-check类型是in-band health-check,意味着不主动去check,而是随着请求来的。nginx plus支持out-of-band的health-check,持续地check upstream中的服务可用性。
还有一点需要注意,指令都有上下文,在使用的时候记得查下文档看下指定的适用上下文。
上面介绍的只是配置nginx负载均衡的一些基本指令,更全面的的文档见ngx_http_upstream_module
首先得在server block里配置的listen指令里加上ssl参数,表示开始https认证
指定https的认证的参数(证书、private key file),证书是个public的实体,将会被发送给每个访问server的client。private key file是个secure entity,应该被限制访问,nginx的master进程应该具有读权限。(这个private key file到底在TLS协议中是什么)
HTTPS认证需要额外的计算量,减少计算量的方法有两种:
本节的内容主要翻译自nginx
先放一张nginx整体的架构示意图
图中可以看出:worker直接负责处理client的请求。然而,nginx中没有一个专门来分发连接到worker的机构,这是由OS内核的机制决定的。一旦nginx启动,一个listening socket集合就被创建了,worker就开始各自accpet连接,read/write socket。那么问题来了: 怎么对worker去分配listenging socket或者说listen port。
worker数量应该随着disk的使用和cpu的负载模式不同而有所调整。基本规则是,对于对于CPU密集的服务比如处理大量TCP/IP、 处理SSL、压缩等任务时,worker数量应该等于CPU核心数;对于瓶颈是I/O的服务,比如负载很重的代理、需要从disk加载不同的content的服务,worker的数量最好是CPU核心数的1.5-2倍。
在后续的nginx版本中,开发者将逐渐解决针对disk的block访问(EPOLL貌似不支持disk i/o)。就目前而言,如果没有足够的存储性能时worker的disk访问将会被阻塞。当然目前存在一些机制和指令去缓和这一情况比如:sendfile和AIO。
另一个nginx的问题是对于嵌入式脚本的支持有限,标准的nginx版本中,仅支持Perl脚本,对此也有个简单的解释:关键是嵌入式脚本可能会阻塞或者异常退出,这会导致worker被hang住。
nginx在内存在运行一个master进程,多个worker进程,还有一些特殊目的的进程(一个cache loader,一个cache manager)。所有进程都是单线程的,进程间主要使用shared-memory机制进行IPC。master进程以root用户运行。其他以unprivileged user运行。
master进程负责:
worker进程负责:
cache loader进程负责:checking the on-disk cache items and populating nginx’s in-memory database with cache metadata. Essentially, the cache loader prepares nginx instances to work with files already stored on disk in a specially allocated directory structure. It traverses the directories, checks cache content metadata, updates the relevant entries in shared memory and then exits when everything is clean and ready for use.
cache manager进程负责:cache过期校验。
nginx缓存的实现是一种基于文件系统的层次数据存储形式。具体使用见nginx官方文档的ngx_http_proxy模块。还有一篇专门介绍nginx反向代理cache使用的blog。