写在前面
公司项目里的静态资源是用Nginx加载的,一直想学习下,网上找了些视频。好坏参差不齐,看了看,继而找了这本书看,只看了第一部分内容。学习基本的配置方式,了解Nginx基本概念,第二部分编写HTTP模块,和第三部分深入Nginx以后有机会看。之后会补充一些常见的运维场景,生活加油。
笔记分为三部分:
- 《深入理解Nginx:模块开发与架构解析》第一部分笔记
- 看教学视屏整理笔记:
- 运维常见案例:
学习Nginx文档: nginx documentation
《深入理解Nginx:模块开发与架构解析》第一部分笔记
第1章研究Nginx前的准备工作
1.1 Nginx是什么
Web服务器的基本功能:基于REST架构风格 ,以统一资源描述符(Uniform Resource Identifier,URI)或者统一资源定位符(Uniform Resource Locator,URL)作为沟通依据,通 过HTTP为浏览器等客户端程序提供各种网络服务。
来自俄罗斯的Igor Sysoev在为Rambler Media(http://www.rambler.ru/ )工作期间,使用C 语言开发了Nginx。
Nginx是一个跨平台的Web服务器,可运行在Linux、FreeBSD、Solaris、AIX、Mac OS、 Windows等操作系统上,并且它还可以使用当前操作系统特有的一些高效API来提高自己的 性能。
对于高效处理大规模并发连接,它支持Linux上的epoll(epoll是Linux上处理大并发网络连接的利器。对于Linux,Nginx支持其独有的sendfile系统调用,这个系统调用可以高效地把硬 盘中的数据发送到网络上(不需要先把硬盘数据复制到用户态内存上再发送),这极大地减 少了内核态与用户态数据间的复制动作。
1.2为什么选择Nginx
更快:
- 在正常情况下,单次请求会得到更快的响应;
- 在高峰期(如有数以万计的并发请求),Nginx可以比其他Web服务器更快地响应请求。
高扩展性:
- Nginx的设计极具扩展性,它完全是由多个不同功能、不同层次、不同类型且耦合度极 低的模块组成。因此,当对某一个模块修复Bug或进行升级时,可以专注于模块自身,无须 在意其他。
- 在HTTP模块中,还设计了HTTP过滤器模块:一个正常的HTTP模块在处理 完请求后,会有一串HTTP过滤器模块对请求的结果进行再处理。这样,当我们开发一个新 的HTTP模块时,不但可以使用诸如HTTP核心模块、events模块、log模块等不同层次或者不 同类型的模块,还可以原封不动地复用大量已有的HTTP过滤器模块
高可靠性
- Nginx的高可靠性来自于其核心框架代码 的优秀设计、模块设计的简单性;另外,官方提供的常用模块都非常稳定,每个worker进程 相对独立,master进程在1个worker进程出错时可以快速“拉起”新的worker子进程提供服务。
低内存消耗
- 10000个非活跃的HTTP Keep-Alive连接在Nginx中仅消耗2.5MB的内存,这 是Nginx支持高并发连接的基础。
单机支持10万以上的并发连接
- 理论上,Nginx支持的并发连接上限取决于内存,10万远未封顶。 当然,能够及时地处理更多的并发请求,是与业务特点紧密相关的
热部署
- master管理进程与worker工作进程的分离设计,使得Nginx能够提供热部署功能,即可以 在7×24小时不间断服务的前提下,升级Nginx的可执行文件。当然,它也支持不停止服务就 更新配置项、更换日志文件等功能
最自由的BSD许可协议
- 这是Nginx可以快速发展的强大动力。BSD许可协议不只是允许用户免费使用Nginx,它还允许用户在自己的项目中直接使用或修改Nginx源码,然后发布。这吸引了无数开发者继 续为Nginx贡献自己的智慧。
在低并发压力下,用户可以获得高速 体验,而在高并发压力下,更多的用户都能接入,可能访问速度会下降。
Nginx先天的事件驱动型设计、全异步的 网络I/O处理机制、极少的进程间切换以及许多优化设计,都使得Nginx天生善于处理高并发 压力下的互联网请求,同时Nginx降低了资源消耗,可以把服务器硬件资源“压榨”到极致。
1.3准备工作
1.4编译安装Nginx
安装nginx 源码安装相关软件包
1.5 configure详解
1.6 Nginx的命令行控制
使用yum安装,使用systemclt start |enable|stop|restart nginx 的启动方式
使用编译安装 ,启动方式方式使用 /usr/sbin/nginx的方式启动,或者配置环境变量。具体可以使用命令行控制。
- 默认方式启动:/usr/sbin/nginx
- 另行指定配置文件的启动方式,会读取-c参数后指定的nginx.conf配置文件来启动Nginx: /usr/sbin/nginx -c tmpnginx.conf
- 另行指定安装目录的启动方式:使用-p参数指定Nginx的安装目录: /usr/sbin/nginx -p usrlocal/nginx/
- 另行指定全局配置项的启动方式,可以通过-g参数临时指定一些全局配置项: /usr/sbin/nginx -g "pid varnginx/test.pid;"
- 测试配置信息是否有错误 /usr/sbin/nginx -t
- 在测试配置阶段不输出信息 使用-q参数可以不把error级别以下的信息输出到屏幕,/usr/sbin/nginx -t -q
- 显示版本信息 /usr/sbin/nginx -v
- 显示编译阶段的参数 /usr/sbin/nginx -V
- 快速地停止服务 /usr/sbin/nginx -s stop
- “优雅”地停止服务 /usr/sbin/nginx -s quit
- 使运行中的Nginx重读配置项并生效 /usr/sbin/nginx -s reload /usr/sbin/nginx
- 日志文件回滚 /usr/sbin/nginx -s reopen
启动之后的欢迎页:阿里云yum安装默认是centoS 的欢迎页
把原来的欢迎页干
第2章Nginx的配置
2.1运行中的Nginx进程间的关系
部署Nginx时都是使用一个master进程来管理多个worker 进程,一般情况下,worker进程的数量与服务器上的CPU核心数相等。每一个worker进程都 是繁忙的,它们在真正地提供互联网服务,master进程则很“清闲”,只负责监控管理worker 进程。worker进程之间通过共享内存、原子操作等一些进程间通信机制来实现负载均衡等功能
master进程不会对用户请求提供服务,只用于管理真正提供服务的worker进程,
多个worker进程处理互联网请求不但可以提高服务的健壮性(一个worker进程出错 后,其他worker进程仍然可以正常提供服务),最重要的是,这样可以充分利用现在常见的 SMP多核架构,从而实现微观上真正的多核并发处理。
为什么要把worker进程数量设置得与CPU核心数量 一致呢?
这正是Nginx与Apache服务器的不同之处。在Apache上每个进程在一个时刻只处理 一个请求,因此,如果希望Web服务器拥有并发处理的请求数更多,就要把Apache的进程或 线程数设置得更多,通常会达到一台服务器拥有几百个工作进程,这样大量的进程间切换将带来无谓的系统资源消耗。而Nginx则不然, 一个worker进程可以同时处理的请求数只受限于 内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此,当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的。
2.2Nginx配置的通用语法
nginx目录
块配置项:块配置项由一个块配置项名和一对大括号组成。
块配置项之 后是否如“location / {...}”那样在后面加上参数,取决于解析这个块配置项的模块。块配置项可以嵌套。内层块直接继承外层块
配置项的语法格式 : 在行首的是配置项名,配置项名输入结束后,将以空格作为分隔符,其次是配置项值,它可以是数字或字符串(当然也包括正则表达式),配置项值之间仍然由空格符来分隔,每行配置的结尾需要加上分号。
- 如果配置项值中包括语法符号,比如空格符,那么需要使用单引号或双引号 括住配置项值。
- 配置项的注释:可以加“#”注释掉这一行配置。
- 配置项的单位: 大部分模块遵循一些通用的规定,如指定空间大小时不用每次都定义到字节、指定时间 时不用精确到毫秒。
- 在配置中使用变量: remote_addr是一个变量
2.3 Nginx服务的基本配置
Nginx在运行时,至少必须加载几个核心模块和一个事件类模块。这些模块运行时所支持的配置项称为基本配置——所有其他模块执行时都依赖的配置项。
基本配置项的用法:
- 用于调试、定位问题的配置项。 ·
- 正常运行的必备配置项。 ·
- 优化性能的配置项。 ·
- 事件类配置项(有些事件类配置项归纳到优化性能类,这是因为它们虽然也属于 events{}块,但作用是优化性能)。
用于调试进程和定位问题的配置项:
- 是否以守护进程方式运行Nginx 语法: daemon on|off; 默认: daemon on;
- 是否以master/worker方式工作 语法: master_process on|off; 默认: master_process on;
- error日志的设置 语法: error_logpathfile level; 默认: error_log logs/error.log error;
- pathfile也可以是/dev/null,这样就不会输出任何日志了, 这也是关闭error日志的唯一手段)
- 是否处理几个特殊的调试点 语法: debug_points[stop|abort]
- 通常不会使用这个配置项
- 仅对指定的客户端输出debug级别的日志 语法: debug_connection[IP|CIDR]
- 限制coredump核心转储文件的大小 语法: worker_rlimit_core size;
- 通过worker_rlimit_core配置可以限制core文件的大小,从而有效帮助用户定位问 题。
在Linux系统中,当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内 容(核心映像)写入一个文件(core文件),以作为调试之用,这就是所谓的核心转储 (core dumps)。当Nginx进程出现一些非法操作(如内存越界)导致进程直接被操作系统强 制结束时,会生成核心转储core文件,可以从core文件获取当时的堆栈、寄存器等信息,从 而帮助我们定位问题
- 指定coredump文件生成目录 语法: working_directory path;
正常运行的配置项:
- 定义环境变量 语法: env VAR|VAR=VALUE
- 嵌入其他配置文件 语法: include pathfile;
- pid文件的路径 语法: pid path/file;
- 但应确保Nginx有权在相应的目标中创建pid文件,该文 件直接影响Nginx是否可以运行。
- Nginx worker进程运行的用户及用户组 语法: user username[groupname]; 默认: user nobody nobody;
- user用于设置master进程启动后,fork出的worker进程运行在哪个用户和用户组下。当按 照“user username;”设置时,用户组名与用户名相同。
- 指定Nginx worker进程可以打开的最大句柄描述符个数 语法: worker_rlimit_nofile limit;
- 设置一个worker进程可以打开的最大文件句柄数。
- 限制信号队列 语法: worker_rlimit_sigpending limit;
- 设置每个用户发往Nginx的信号队列的大小,当某个用户的信号队列满了, 这个用户再发送的信号量会被丢掉。
优化性能的配置项:
- Nginx worker进程个数 语法: worker_processes number; 默认: worker_processes 1;
- 在master/worker运行方式下,定义worker进程的个数。每个worker进程都是单线程的进程,它们会调用各个模块以实现多种多样的功能,如果 这些模块确认不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程;反 之,如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程
- 绑定Nginx worker进程到指定的CPU内核 语法: worker_cpu_affinity cpumask[cpumask...]
- 假定每一个worker进程都是非常繁忙的,如果多个worker进程都在抢同一个CPU,那么这就会出现同步问题。反之,如果每一个 worker进程都独享一个CPU,就在内核的调度策略上实现了完全的并发。
- SSL硬件加速 语法: ssl_engine device;
- 如果服务器上有SSL硬件加速设备,那么就可以进行配置以加快SSL协议的处理速度。 用户可以使用OpenSSL提供的命令来查看是否有SSL硬件加速设备:
[root@liruilong ~]# openssl engine -t(rdrand) Intel RDRAND engine [ available ] (dynamic) Dynamic engine loading support [ unavailable ] [root@liruilong ~]#
- 系统调用gettimeofday的执行频率 语法: timer_resolution t;
- 默认情况下,每次内核的事件调用(如epoll、select、poll、kqueue等)返回时,都会执 行一次gettimeofday,实现用内核的时钟来更新Nginx中的缓存时钟)(一般不需要配置
- Nginx worker进程优先级设置 语法: worker_priority nice; 默认: worker_priority 0;
- 该配置项用于设置Nginx worker进程的nice优先级。
事件类配置项
- 是否打开accept锁 语法: accept_mutex[on|off] 默认: accept_mutext on;
- accept_mutex是Nginx的负载均衡锁,accept_mutex这把锁可以让多个worker进程轮流地、 序列化地与新的客户端建立TCP连接。当某一个worker进程建立的连接数量达到 worker_connections配置的最大连接数的7/8时,会大大地减小该worker进程试图建立新TCP连 接的机会,以此实现所有worker进程之上处理的客户端请求数尽量接近。(不建议关闭)
- lock文件的路径 语法: lock_file path/file; 默认: lock_file logs/nginx.lock;
- accept锁可能需要这个lock文件,致Nginx不支持原子锁,这时才会用lock文件锁实现accept锁
- 使用accept锁后到真正建立连接之间的延迟时间 语法: accept_mutex_delay Nms; 默认: accept_mutex_delay 500ms;
- 在使用accept锁后,同一时间只有一个worker进程能够取到accept锁。这个accept锁不是阻塞锁,如果取不到会立刻返回。如果有一个worker进程试图取accept锁而没有取到,它至 少要等accept_mutex_delay定义的时间间隔后才能再次试图取锁。
- 批量建立新连接 语法: multi_accept[on|off]; 默认: multi_accept off;
- 当事件模型通知有新连接时,尽可能地对本次调度中客户端发起的所有TCP请求都建立 连接。
- 选择事件模型 语法: use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport]; 默认: Nginx会自动使用最适合的事件模型。
- 对于Linux操作系统来说,可供选择的事件驱动模型有poll、select、epoll三种。
- 每个worker的最大连接数 语法: worker_connections number;
- 定义每个worker进程可以同时处理的最大连接数。
2.4用HTTP核心模块配置一个静态Web服务器
静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现.
所有的HTTP配置项都必须直属于http块、server块、location块、upstream块或if块等 (HTTP配置项自然必须全部在http{}块之内.,Nginx为配置一个完整的静态Web服务器提供了非常多的功能,下面会把这些配置项分为 以下8类进行详述:
虚拟主机与请求的分发、文件路径的定义、内存及磁盘资源的分配、网 络连接的设置、MIME类型的设置、对客户端请求的限制、文件操作的优化、对客户端请求 的特殊处理。
虚拟主机与请求的分发:
在nginx.conf中就可以按照server_name(对应用户请求中的主机域名)并通过server块来定义 虚拟主机,每个server块就是一个虚拟主机,它只处理与之相对应的主机域名请求。
监听端口 语法: listen address:port[default|default_server[backlog=num|rcvbuf=size|sndbuf=size|accept_filter=filter|deferred|bind|ipv6only=[on|off]|ssl]]; 默 认: listen 80;
- ·default:将所在的server块作为整个Web服务的默认server块。如果没有设置这个参数,那么将会以在nginx.conf中找到的第一个server块作为默认server块。为什么需要默认虚拟主机呢?当一个请求无法匹配配置文件中的所有主机域名时,就会选用默认的虚拟主机
- ·default_server:同上。
- ·backlog=num:表示TCP中backlog队列的大小。默认为–1,表示不予设置。在TCP建立三次握手过程中,进程还没有开始处理监听句柄,这时backlog队列将会放置这些新连接。可如果backlog队列已满,还有新的客户端试图通过三次握手建立TCP连接,这时客户端将会建立连接失败。
- ·rcvbuf=size:设置监听句柄的SO_RCVBUF参数。
- ·sndbuf=size:设置监听句柄的SO_SNDBUF参数。
- ·accept_filter:设置accept过滤器,只对FreeBSD操作系统有用。
- ·deferred:在设置该参数后,若用户发起建立连接请求,并且完成了TCP的三次握手,内核也不会为了这次的连接调度worker进程来处理,只有用户真的发送请求数据时(内核已经在网卡中收到请求数据包),内核才会唤醒worker进程处理这个连接。这个参数适用于大并发的情况下,它减轻了worker进程的负担。当请求数据来临时,worker进程才会开始处理这个连接。只有确认上面所说的应用场景符合自己的业务需求时,才可以使用deferred配置。
- ·bind:绑定当前端口/地址对,如127.0.0.1:8000。只有同时对一个端口监听多个地址时才会生效。
- ·ssl:在当前监听的端口上建立的连接必须基于SSL协议。
- 配置块: server : listen参数决定Nginx服务如何监听端口。在listen后可以只加IP地址、端口或主机名。
主机名称 语法: server_name name[...]; 默认: server_name"";
在开始处理一个HTTP请求时,Nginx会取出header头中的Host,与每个server中的 server_name进行匹配,有可能一个Host与 多个server块中的server_name都匹配,会根据匹配优先级来选择。匹配优先级如下:
- 1)首先选择所有字符串完全匹配的server_name,如www.testweb.com 。
- 2)其次选择通配符在前面的server_name,如*.testweb.com。
- 3)再次选择通配符在后面的server_name,如www.testweb.* 。
- 4)最后选择使用正则表达式才匹配的server_name,如~^\.testweb\.com$。
如果Host与所有的server_name都不匹配,这时将会按下列顺序选 择处理的server块。
- 1)优先选择在listen配置项后加入[default|default_server]的server块。
- 2)找到匹配listen端口的第一个server块。 如果server_name后跟着空字符串(如server_name"";),那么表示匹配没有Host这个 HTTP头部的请求
Nginx正是使用server_name配置项针对特定Host域名的请求提供不同的服务, 以此实现虚拟主机功能
- 配置块: server server_name后可以跟多个主机名称,如server_name www.testweb.com 、 download.testweb.com;。
server_names_hash_bucket_size 语法: server_names_hash_bucket_size size; 默认: server_names_hash_bucket_size 32|64|128;
为了提高快速寻找到相应server name的能力,Nginx使用散列表来存储server name。 server_names_hash_bucket_size设置了每个散列桶占用的内存大小。
- 配置块: http、server、location
server_names_hash_max_size 语法: server_names_hash_max_size size; 默认: server_names_hash_max_size 512;
server_names_hash_max_size会影响散列表的冲突率。server_names_hash_max_size越大, 消耗的内存就越多,但散列key的冲突率则会降低,检索速度也更快。 server_names_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能增高。
- 配置块: http、server、location
重定向主机名称的处理 语法: server_name_in_redirect on|off; 默认: server_name_in_redirect on;
该配置需要配合server_name使用。在使用on打开时,表示在重定向请求时会使用 server_name里配置的第一个主机名代替原先请求中的Host头部,而使用off关闭时,表示在重 定向请求时使用请求本身的Host头部。
- 配置块: http、server或者location
location 语法: location[=|~|~*|^~|@]/uri/{...}
location会尝试根据用户请求中的URI来匹配上面的/uri表达式,如果可以匹配,就选择 location{}块中的配置来处理用户请求。当然,匹配方式是多样的,下面介绍location的匹配 规则。
- =表示把URI作为字符串,以便与参数中的uri做完全匹配。例如:
- ~表示匹配URI时是字母大小写敏感的。
- ~*表示匹配URI时忽略字母大小写问题。
- ^~表示匹配URI时只需要其前半部分与uri参数匹配即可。例如:
@表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请 求。 当然,在uri参数里是可以用正则表达
- location是有顺序的,当一个请求有可能匹配多个location时,实际上这个请求会 被第一个location处理。查找顺序和优先级
- 1:带有“=“的精确匹配优先
- 2:没有修饰符的精确匹配
- 3:正则表达式按照他们在配置文件中定义的顺序
- 4:带有“^~”修饰符的,开头匹配
- 5:带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
- 6:没有修饰符的,如果指定字符串与URI开头匹配
- 配置块: server
文件路径的定义
以root方式设置资源路径 语法: root path; 默认: root html; 类似于拼接一个前缀
- 配置块: http、server、location、if
以alias方式设置资源路径 语法: alias path; alias也是用来设置文件资源路径的,类似于别名
它与root的不同点主要在于如何解读紧跟location后 面的uri参数,顾名思义,alias后面还可以添加正则表达式。
- 配置块: location
访问首页 语法: index file...; 默认: index index.html;
访问站点时的URI是/,用ngx_http_index_module模块提供的index配置实现。index后可以跟多个文件参数,Nginx 将会按照顺序来访问这些文件。Nginx首先会尝试访问path/index.php文件,如果可以访问,就直接返回文 件内容结束请求,否则再试图返回path/htmlindex.php文件的内容,
- 配置块: http、server、location
根据HTTP返回码重定向页面 语法: error_page code[code...][=|=answer-code]uri|@named_location
当对于某个请求返回错误码时,如果匹配上了error_page中设置的code,则重定向到新 的URI中。例如:
如果不想修改URI,只是想让这样的请求重定向到另一个location中进行处理,返回404的请求会被反向代理到http://backend 上游服务器中处理。
- 配置块: http、server、location、if
是否允许递归使用error_page 语法: recursive_error_pages[on|off]; 默认: recursive_error_pages off;
确定是否允许递归地定义error_page。
- 配置块: http、server、location
try_files 语法: try_files path1[path2]uri;
try_files后要跟若干路径,如path1 path2...,尝试 按照顺序访问每一个path,如果可以有效地读取,就直接向用户返回这个path对应的文件结 束请求,否则继续向下访问。如果所有的path都找不到有效的文件,就重定向到最后的参数 uri上。因此,最后这个参数uri必须存在,而且它应该是可以有效重定向的。
- 配置块: server、location
内存及磁盘资源的分配
HTTP包体只存储到磁盘文件中 语法: client_body_in_file_only on|clean|off; 默认: client_body_in_file_only off;
当值为非off时,用户请求中的HTTP包体一律存储到磁盘文件中,即使只有0字节也会存储为文件。当请求结束时,如果配置为on,则这个文件不会被删除(该配置一般用于调试、 定位问题),但如果配置为clean,则会删除该文件。
- 配置块: http、server、location
HTTP包体尽量写入到一个内存buffer中 语法: client_body_in_single_buffer on|off; 默认:client_body_in_single_buffer off;
用户请求中的HTTP包体一律存储到内存buffer中。当然,如果HTTP包体的大小超过了 下面client_body_buffer_size设置的值,包体还是会写入到磁盘文件中。
- 配置块: http、server、location
存储HTTP头部的内存buffer大小 语法: client_header_buffer_size size; 默认: client_header_buffer_size 1k;
上面配置项定义了正常情况下Nginx接收用户请求中HTTP header部分(包括HTTP行和 HTTP头部)时分配的内存buffer大小。有时,请求中的HTTP header部分可能会超过这个大 小,这时large_client_header_buffers定义的buffer将会生效。
配置块: http、server
存储超大HTTP头部的内存buffer大小 语法: large_client_header_buffers number size; 默认: large_client_header_buffers 48k;
large_client_header_buffers定义了Nginx接收一个超大HTTP头部请求的buffer个数和每个 buffer的大小。如果HTTP请求行(如GET/index HTTP/1.1)的大小超过上面的单个buffer,则 返回"Request URI too large"(414)。请求中一般会有许多header,每一个header的大小也不能超 过单个buffer的大小,否则会返回"Bad request"(400)。当然,请求行和请求头部的总和也不可 以超过buffer个数*buffer大小。
- 配置块: http、server
存储HTTP包体的内存buffer大小 语法: client_body_buffer_size size; 默认: client_body_buffer_size 8k/16k;
定义了Nginx接收HTTP包体的内存缓冲区大小。也就是说,HTTP包体会先 接收到指定的这块缓存中,之后才决定是否写入磁盘。
- 配置块: http、server、location
HTTP包体的临时存放目录 语法: client_body_temp_path dir-path[level1[level2[level3]]] 默认: client_body_temp_path client_body_temp;
在接收HTTP包体时,如果包体的大小大于 client_body_buffer_size,则会以一个递增的整数命名并存放到client_body_temp_path指定的目 录中。后面跟着的level1、level2、level3,是为了防止一个目录下的文件数量太多,从而导 致性能下降,因此使用了level参数,这样可以按照临时文件名最多再加三层目录
- 配置块: http、server、location
connection_pool_size 语法: connection_pool_size size; 默认: connection_pool_size 256;
Nginx对于每个建立成功的TCP连接会预先分配一个内存池,上面的size配置项将指定这 个内存池的初始大小(即ngx_connection_t结构体中的pool内存池初始大小
- 配置块: http、server
request_pool_size 语法: request_pool_size size; 默认: request_pool_size 4k;
Nginx开始处理HTTP请求时,将会为每个请求都分配一个内存池,size配置项将指定这 个内存池的初始大小(即ngx_http_request_t结构体中的pool内存池初始大小)用于减少内核对于小块内存的分配次数。TCP连接关闭时会销毁 connection_pool_size指定的连接内存池,HTTP请求结束时会销毁request_pool_size指定的 HTTP请求内存池,但它们的创建、销毁时间并不一致,因为一个TCP连接可能被复用于多 个HTTP请求。
- 配置块: http、server
网络连接的设置
读取HTTP头部的超时时间 语法: client_header_timeout time(默认单位:秒); 默认: client_header_timeout 60;
客户端与服务器建立连接后将开始接收HTTP头部,在这个过程中,如果在一个时间间 隔(超时时间)内没有读取到客户端发来的字节,则认为超时,并向客户端返回 408("Request timed out")响应。
- 配置块: http、server、location
读取HTTP包体的超时时间 语法: client_body_timeout time(默认单位:秒); 默认: client_body_timeout 60;
此配置项与client_header_timeout相似,只是这个超时时间只在读取HTTP包体时才有 效。
- 配置块: http、server、location
发送响应的超时时间 语法: send_timeout time; 默认: send_timeout 60;
这个超时时间是发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但客户 端一直没有去接收这个数据包。如果某个连接超过send_timeout定义的超时时间,那么Nginx 将会关闭这个连接。
- 配置块: http、server、location
reset_timeout_connection 语法: reset_timeout_connection on|off; 默认: reset_timeout_connection off;
连接超时后将通过向客户端发送RST包来直接重置连接。这个选项打开后,Nginx会在某 个连接超时后,不是使用正常情形下的四次握手关闭TCP连接,而是直接向用户发送RST重 置包,不再等待用户的应答,直接释放Nginx服务器上关于这个套接字使用的所有缓存(如 TCP滑动窗口)。相比正常的关闭方式,它使得服务器避免产生许多处于FIN_WAIT_1、 FIN_WAIT_2、TIME_WAIT状态的TCP连接。
- 配置块: http、server、location
lingering_close 语法: lingering_close off|on|always; 默认: lingering_close on;
该配置控制Nginx关闭用户连接的方式。
- always表示关闭用户连接前必须无条件地处理连 接上所有用户发送的数据。
- off表示关闭连接时完全不管连接上是否已经有准备就绪的来自用 户的数据。
- on是中间值,一般情况下在关闭连接前都会处理连接上的用户发送的数据,除了 有些情况下在业务上认定这之后的数据是不必要
- 配置块: http、server、location
lingering_time 语法: lingering_time time; 默认: lingering_time 30s;
lingering_close启用后,这个配置项对于上传大文件很有用。上文讲过,当用户请求的 Content-Length大于max_client_body_size配置时,Nginx服务会立刻向用户发送413(Request entity too large)响应。但是,很多客户端可能不管413返回值,仍然持续不断地上传HTTP body,这时,经过了lingering_time设置的时间后,Nginx将不管用户是否仍在上传,都会把连 接关闭掉。
- 配置块: http、server、location
lingering_timeout 语法: lingering_timeout time; 默认: lingering_timeout 5s;
lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果 超过lingering_timeout时间后还没有数据可读,就直接关闭连接;否则,必须在读取完连接缓 冲区上的数据并丢弃掉后才会关闭连接。
- 配置块: http、server、location
对某些浏览器禁用keepalive功能 语法: keepalive_disable[msie6|safari|none]... 默认: keepalive_disablemsie6 safari
HTTP请求中的keepalive功能是为了让多个请求复用一个HTTP长连接,这个功能对服务 器的性能提高是很有帮助的。但有些浏览器,如IE 6和Safari,它们对于使用keepalive功能的 POST请求处理有功能性问题。因此,针对IE 6及其早期版本、Safari浏览器默认是禁用
- 配置块: http、server、location
keepalive超时时间 语法: keepalive_timeout time(默认单位:秒); 默认: keepalive_timeout 75;
一个keepalive连接在闲置超过一定时间后(默认的是75秒),服务器和浏览器都会去关 闭这个连接。当然,keepalive_timeout配置项是用来约束Nginx服务器的,Nginx也会按照规范 把这个时间传给浏览器,但每个浏览器对待keepalive的策略有可能是不同的。
- 配置块: http、server、location
一个keepalive长连接上允许承载的请求最大数 语法: keepalive_requests n; 默认: keepalive_requests 100;
一个keepalive连接上默认最多只能发送100个请求。
- 配置块: http、server、location
tcp_nodelay 语法: tcp_nodelay on|off; 默认: tcp_nodelay on;
确定对keepalive连接是否使用TCP_NODELAY选项。
- 配置块: http、server、location
tcp_nopush 语法: tcp_nopush on|off; 默认: tcp_nopush off;
在打开sendfile选项时,确定是否开启FreeBSD系统上的TCP_NOPUSH或Linux系统上的 TCP_CORK功能。打开tcp_nopush后,将会在发送响应时把整个响应包头放到一个TCP包中 发送。
- 配置块: http、server、location
MIME类型的设置
MIME type与文件扩展的映射 语法: type{...};
定义MIME type到文件扩展名的映射。多个扩展名可以映射到同一个MIME type。
- 配置块: http、server、location
·默认MIME type 语法: default_type MIME-type; 默认: default_type text/plain;
当找不到相应的MIME type与文件扩展名之间的映射时,使用默认的MIME type作为 HTTP header中的Content-Type。
- 配置块: http、server、location
·types_hash_bucket_size 语法: types_hash_bucket_size size; 默认: types_hash_bucket_size 32|64|128;
为了快速寻找到相应MIME type,Nginx使用散列表来存储MIME type与文件扩展名。 types_hash_bucket_size设置了每个散列桶占用的内存大小。
- 配置块: http、server、location
·types_hash_max_size 语法: types_hash_max_size size; 默认: types_hash_max_size 1024;
types_hash_max_size影响散列表的冲突率。types_hash_max_size越大,就会消耗更多的内 存,但散列key的冲突率会降低,检索速度就更快。types_hash_max_size越小,消耗的内存就 越小,但散列key的冲突率可能上升。
- 配置块: http、server、location
对客户端请求的限制
按HTTP方法名限制用户请求 语法: limit_except method...{...}
Nginx通过limit_except后面指定的方法名来限制用户请求。方法名可取值包括:GET、 HEAD、POST、PUT、DELETE、MKCOL、COPY、MOVE、OPTIONS、PROPFIND、 PROPPATCH、LOCK、UNLOCK或者PATCH。
- 配置块: location
HTTP请求包体的最大值 语法: client_max_body_size size; 默认: client_max_body_size 1m;
浏览器在发送含有较大HTTP包体的请求时,其头部会有一个Content-Length字段, client_max_body_size是用来限制Content-Length所示值的大小的。因此,这个限制包体的配置 非常有用处,因为不用等Nginx接收完所有的HTTP包体——这有可能消耗很长时间——就可 以告诉用户请求过大不被接受
- 配置块: http、server、location
对请求的限速 语法: limit_rate speed; 默认: limit_rate 0;
此配置是对客户端请求限制每秒传输的字节数。speed可以使用2.2.4节中提到的多种单 位,默认参数为0,表示不限速。
- 配置块: http、server、location、if
limit_rate_after 语法: limit_rate_after time; 默认: limit_rate_after 1m;
此配置表示Nginx向客户端发送的响应长度超过limit_rate_after后才开始限速
- 配置块: http、server、location、if
文件操作的优化
sendfile系统调用 语法: sendfile on|off; 默认: sendfile off;
可以启用Linux上的sendfile系统调用来发送文件,它减少了内核态与用户态之间的两次 内存复制,这样就会从磁盘中读取文件后直接在内核态发送到网卡设备,提高了发送文件的 效率。
- 配置块: http、server、location
AIO系统调用 语法: aio on|off; 默认: aio off;
此配置项表示是否在FreeBSD或Linux系统上启用内核级别的异步文件I/O功能。注意, 它与sendfile功能是互斥的。
- 配置块: http、server、location
directio 语法: directio size|off; 默认: directio off;
此配置项在FreeBSD和Linux系统上使用O_DIRECT选项去读取文件,缓冲区大小为size, 通常对大文件的读取速度有优化作用。注意,它与sendfile功能是互斥的。
- 配置块: http、server、location
directio_alignment 语法: directio_alignment size; 默认: directio_alignment 512;
它与directio配合使用,指定以directio方式读取文件时的对齐方式。一般情况下,512B 已经足够了,但针对一些高性能文件系统,如Linux下的XFS文件系统,可能需要设置到4KB 作为对齐方式
- 配置块: http、server、location
打开文件缓存 语法: open_file_cache max=N[inactive=time]|off; 默认: open_file_cache off;
- max:表示在内存中存储元素的最大个数。当达到最大限制数量后,将采用 LRU(Least Recently Used)算法从缓存中淘汰最近最少使用的元素。 ·
- inactive:表示在inactive指定的时间段内没有被访问过的元素将会被淘汰。默认时间为 60秒。 ·
- off:关闭缓存功能。
文件缓存会在内存中存储以下3种信息:
- ·文件句柄、文件大小和上次修改时间。
- ·已经打开过的目录结构。
- ·没有找到的或者没有权限操作的文件信息。
- 配置块: http、server、location
检验缓存中元素有效性的频率 语法: open_file_cache_valid time; 默认: open_file_cache_valid 60s;
默认为每60秒检查一次缓存中的元素是否仍有效。
- 配置块: http、server、location
不被淘汰的最小访问次数 语法: open_file_cache_min_uses number; 默认: open_file_cache_min_uses 1;
它与open_file_cache中的inactive参数配合使用。如果在inactive指定的时间段内,访问次 数超过了open_file_cache_min_uses指定的最小次数,那么将不会被淘汰出缓存。
- 配置块: http、server、location
是否缓存打开文件错误的信息 语法: open_file_cache_errors on|off; 默认: open_file_cache_errors off;
此配置项表示是否在文件缓存中缓存打开文件时出现的找不到路径、没有权限等错误信 息。
- 配置块: http、server、location
对客户端请求的特殊处理
忽略不合法的HTTP头部 语法: ignore_invalid_headers on|off; 默认: ignore_invalid_headers on;
设置为off,当出现不合法的HTTP头部时,Nginx会拒绝服务,并直接向用 户发送400(Bad Request)错误。如果将其设置为on,则会忽略此HTTP头部。
- 配置块: http、server
HTTP头部是否允许下划线 语法: underscores_in_headers on|off; 默认: underscores_in_headers off;
默认为off,表示HTTP头部的名称中不允许带“_”(下划线)。
- 配置块: http、server
对If-Modified-Since头部的处理策略 语法: if_modified_since[off|exact|before]; 默认: if_modified_since exact;
出于性能考虑,Web浏览器一般会在客户端本地缓存一些文件,并存储当时获取的时 间。这样,下次向Web服务器获取缓存过的资源时,就可以用If-Modified-Since头部把上次获 取的时间捎带上,而if_modified_since将根据后面的参数决定如何处理If-Modified-Since头部.
- ·off:表示忽略用户请求中的If-Modified-Since头部。这时,如果获取一个文件,那么会 正常地返回文件内容。HTTP响应码通常是200。
- ·exact:将If-Modified-Since头部包含的时间与将要返回的文件上次修改的时间做精确比 较,如果没有匹配上,则返回200和文件的实际内容,如果匹配上,则表示浏览器缓存的文 件内容已经是最新的了,没有必要再返回文件从而浪费时间与带宽了,这时会返回304 Not Modified,浏览器收到后会直接读取自己的本地缓存。
- ·before:是比exact更宽松的比较。只要文件的上次修改时间等于或者早于用户请求中 的If-Modified-Since头部的时间,就会向客户端返回304 Not Modified。
- 配置块: http、server、location
文件未找到时是否记录到error日志 语法: log_not_found on|off; 默认: log_not_found on;
此配置项表示当处理用户请求且需要访问文件时,如果没有找到文件,是否将错误日志 记录到error.log文件中。这仅用于定位问题。
- 配置块: http、server、location
merge_slashes 语法: merge_slashes on|off; 默认: merge_slashes on;
此配置项表示是否合并相邻的“//”,例如,/test///a.txt,在配置为on时,会将其匹配为 location/test/a.txt;如果配置为off,则不会匹配,URI将仍然是//test///a.txt。
- 配置块: http、server、location
DNS解析地址 语法: resolver address...;
设置DNS名字解析服务器的地址
- 配置块: http、server、location
DNS解析的超时时间 语法: resolver_timeout time; 默认: resolver_timeout 30s;
此配置项表示DNS解析的超时时间。
- 配置块: http、server、location
返回错误页面时是否在Server中注明Nginx版本 语法: server_tokens on|off; 默认: server_tokens on;
表示处理请求出错时是否在响应的Server头部中标明Nginx版本,这是为了方便定位问 题。
- 配置块: http、server、location
ngx_http_core_module模块提供的变量
conf文档Demo
2.5 HTTP proxymodule配置一个反向代理服务器
反向代理(reverse proxy)方式是指用代理服务器来接受Internet上的连接请求,然后将 请求转发给内部网络中的上游服务器,并将从上游服务器上得到的结果返回给Internet上请求 连接的客户端。充当反向代理服务器也是 Nginx的一种常见用法(反向代理服务器必须能够处理大量并发请求)
反向代理和从定向的区别:
重定向:
- 1. 这种方式需要用户浏览器访问两次,性能较差
- 2. HTTP重定向服务器会的处理能力会成为负载均衡的瓶颈
- 3. HTTP重定向返回302,可能会使搜索引擎判定为SEO作弊,降低搜索排名
反向代理:
- 客户端与代理服务器 之间的网络环境会比较复杂,多半是“走”公网,代理服务器与上游服务器之间一般是“走”内网,或者有专线连接,传输速度较快
- 一次请求一次响应,
- 不返回3XX的状态吗
由于Nginx具有“强悍”的高并发高负载能力,因此一般会作为前端的服务器直接向客户 端提供静态文件服务。但也有一些复杂、多变的业务不适合放到Nginx服务器上,这时会用 Apache、Tomcat等服务器来处理。于是,Nginx通常会被配置为既是静态Web服务器也是反向 代理服务器。
与Squid等其他反向代理服务器相比,Nginx的反向代理功能有自己的特点:
当客户端发来HTTP请求时,Nginx并不会立刻转发到上游服务器,而是先把用户的请求 (包括HTTP包体)完整地接收到Nginx所在服务器的硬盘或者内存中,然后再向上游服务器 发起连接,把缓存的客户端请求转发到上游服务器。而Squid等代理服务器则采用一边接收客户端请求,一边转发到上游服务器的方式。
Nginx的这种工作方式有什么优缺点呢?
- 缺点是延长了一个请求的处理时间, 并增加了用于缓存请求内容的内存和磁盘空间。
- 优点则是降低了上游服务器的负载,尽量把压力放在Nginx服务器上。:原因:客户端与代理服务器 之间的网络环境会比较复杂,多半是“走”公网,网速平均下来可能较慢,因此,一个请求可能要持续很久才能完成。而代理服务器与上游服务器之间一般是“走”内网,或者有专线连 接,传输速度较快,Squid等反向代理服务器在与客户端建立连接且还没有开始接收HTTP包 体时,就已经向上游服务器建立了连接。例如,某个请求要上传一个1GB的文件,那么每次 Squid在收到一个TCP分包(如2KB)时,就会即时地向上游服务器转发。在接收客户端完整 HTTP包体的漫长过程中,上游服务器始终要维持这个连接,这直接对上游服务器的并发处 理能力提出了挑战。Nginx它在接收到完整的客户端请求(如1GB的文件)后,才会与上游服务器 建立连接转发请求,由于是内网,所以这个转发过程会执行得很快。
负载均衡的基本配置
作为代理服务器,一般都需要向上游服务器的集群转发请求。这里的负载均衡是指选择 一种策略,尽量把请求平均地分布到每一台上游服务器上。
(1)upstream块 语法: upstream name{...}
upstream块定义了一个上游服务器的集群,便于反向代理中的proxy_pass使用
- 配置块: http
(2)server 语法: server name[parameters];
server配置项指定了一台上游服务器的名字,这个名字可以是域名、IP地址端口、UNIX 句柄等,在其后还可以跟下列参数:
- weight=number:设置向这台上游服务器转发的权重,默认为1。 ·
- max_fails=number:该选项与fail_timeout配合使用,指在fail_timeout时间段内,如果向当前的上游服务器转发失败次数超过number,则认为在当前的fail_timeout时间段内这台上游 服务器不可用。max_fails默认为1,如果设置为0,则表示不检查失败次数。 ·fail_timeout=time:fail_timeout表示该时间段内转发失败多少次后就认为上游服务器暂 时不可用,用于优化反向代理功能。它与向上游服务器建立连接的超时时间、读取上游服务 器的响应超时时间等完全无关。fail_timeout默认为10秒。 ·
- down:表示所在的上游服务器永久下线,只在使用ip_hash配置项时才有用。 ·
- backup:在使用ip_hash配置项时它是无效的。它表示所在的上游服务器只是备份服务 器,只有在所有的非备份上游服务器都失效后,才会向所在的上游服务器转发请求。
- 配置块: upstream
(3)ip_hash 语法: ip_hash;
来自某一个用户的请求始终落到固定的一台上游服务器 中,假设上游服务器会缓存一些信息,如果同一个用户的请求任意地转发到集群中的 任一台上游服务器中,那么每一台上游服务器都有可能会缓存同一份信息,这既会造成资源 的浪费,也会难以有效地管理缓存信息。ip_hash首先根据客户端的IP地址计算出一个key,将key按照upstream集群里的上游服务器数量进行取模,然后以取模后的结果把请求转发到相应的上游服务器中。确保了同一个客户端的请求只会转发到指定的上游服务器中。
ip_hash与weight(权重)配置不可同时使用。如果upstream集群中有一台上游服务器暂 时不可用,不能直接删除该配置,而是要down参数标识,确保转发策略的一贯性。
- 配置块: upstream
(4)记录日志时支持的变量 如果需要将负载均衡时的一些信息记录到access_log日志中,那么在定义日志格式时可 以使用负载均衡功能提供的变量
反向代理的基本配置
(1)proxy_pass 语法: proxy_pass URL;
此配置项将当前请求反向代理到URL参数指定的服务器上,
- URL可以是主机名或IP地址 加端口的形式,
- 可以是UNIX句柄
- 还可以是上节负载均衡中所示,直接使用upstream块,
- 可以把HTTP转换成更安全的HTTPS
默认情况下反向代理是不会转发请求中的Host头部的。如果需要转发,那么必须加上配 置:
- 配置块: location、if
(2)proxy_method 语法: proxy_method method;
此配置项表示转发时的协议方法名。例如设置为:
- 配置块: http、server、location
(3)proxy_hide_header 语法: proxy_hide_header the_header;
Nginx会将上游服务器的响应转发给客户端,但默认不会转发以下HTTP头部字段: Date、Server、X-Pad和X-Accel-*。使用proxy_hide_header后可以任意地指定哪些HTTP头部 字段不能被转发
- 配置块: http、server、location
(4)proxy_pass_header 语法: proxy_pass_header the_header;
与proxy_hide_header功能相反,proxy_pass_header会将原来禁止转发的header设置为允许 转发。例如
- 配置块: http、server、location
(5)proxy_pass_request_body 语法: proxy_pass_request_body on|off; 默认: proxy_pass_request_body on;
作用为确定是否向上游服务器发送HTTP包体部分。
- 配置块: http、server、location
(6)proxy_pass_request_headers 语法: proxy_pass_request_headers on|off; 默认: proxy_pass_request_headers on;
作用为确定是否转发HTTP头部。
- 配置块: http、server、location
(7)proxy_redirect 语法: proxy_redirect[default|off|redirect replacement]; 默认: proxy_redirect default;
当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时, proxy_redirect可以重设HTTP头部的location或refresh字段。例如,如果上游服务器发出的响 应是302重定向请求,location字段的URI是http://localhost:8000/two/some/uri/ ,那么在下面的 配置情况下,实际转发给客户端的location是http://frontendonesome/uri/
- 配置块: http、server、location
(8)proxy_next_upstream 语法: proxy_next_upstream[error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off]; 默认: proxy_next_upstream error timeout;
此配置项表示当向一台上游服务器转发请求出现错误时,继续换一台上游服务器处理这 个请求
- 配置块: http、server、location
proxy_next_upstream的参数用来说明在哪些情况下会继续 选择下一台上游服务器转发请求。
- ·error:当向上游服务器发起连接、发送请求、读取响应时出错。
- ·timeout:发送请求或读取响应时发生超时。
- ·invalid_header:上游服务器发送的响应是不合法的。
- ·http_500:上游服务器返回的HTTP响应码是500。
- ·http_502:上游服务器返回的HTTP响应码是502。
- ·http_503:上游服务器返回的HTTP响应码是503。
- ·http_504:上游服务器返回的HTTP响应码是504。
- ·http_404:上游服务器返回的HTTP响应码是404。
- ·off:关闭proxy_next_upstream功能—出错就选择另一台上游服务器再次转发。
解析HTTP配置的流程
看教学视屏整理笔记:
Nginx是什么:Nginx是一款轻量级的Web服务器,也是一款轻量级的反向代理服务器。
Nginx能干什么:Nginx能干的事情很多,这里简要罗列一些:
- 1:直接支持Rails和PHP的程序
- 2:作为HTTP反向代理服务器
- 3:作为负载均衡服务器
- 4:作为邮件代理服务器
- 5:帮助实现前端动静分离
Nginx安装
源码安装
- 1:需要gcc,系统自带了,没有的话,需要先安装
- 2:需要pcre,安装的命令示例如下: yum install pcre*
- 3:需要zlib,安装的命令示例如下:yum install zlib zlib-devel
- 4:如果需要支持ssl的话,安装OpenSSL,安装的命令示例如下: yum install openssl openssl-devel
- 5:上http://nginx.org/去下载源码包,然后进行解压安装
示例如下:
- (1)先解压源码包,然后进入到这个包里面
- (2)安装命令示例如下:
- 第一步:./configure --prefix=/usr/common/nginx --with_http_stub_status_module --with-http_ssl_module 如果提示确少啥,就加上相应的选项,比如缺少pcre的话,就加上 --with-pcre=/usr/common/temp/pcre-8.34 (当然我们这里是不缺东西的)
- 第二步:配置后就依次 make , make install
常见的Nginx安装配置选项
编译参数可能会根据版本的不同进行变化,./configure --help查看编译参数列表,常见的选项如下:
- --prefix=<path> - 安装路径,如果没有指定,默认为/usr/local/nginx。
- --sbin-path=<path> - nginx可执行命令的文件,如果没有指定,默认为<prefix>/sbin/nginx。
- --conf-path=<path> - 在没有使用-c参数指定的情况下nginx.conf的默认位置,如果没有指定,默认为<prefix>/conf/nginx.conf。
- --pid-path=<path> - nginx.pid的路径,如果没有在nginx.conf中通过“pid”指令指定,默认为<prefix>/logs/nginx.pid。
- --lock-path=<path> - nginx.lock文件路径,如果没有指定,默认为<prefix>/logs/nginx.lock。
- --error-log-path=<path> - 当没有在nginx.conf中使用“error_log”指令指定时的错误日志位置,如果没有指定,默认为<prefix>/logs/error.log。
- --http-log-path=<path> - 当没有在nginx.conf中使用“access_log”指令指定时的访问日志位置,如果没有指定,默认为<prefix>/logs/access.log。
- --user=<user> - 当没有在nginx.conf中使用“user”指令指定时nginx运行的用户,如果没有指定,默认为“nobody”。
- --group=<group> - 当没有在nginx.conf中使用“user”指令指定时nginx运行的组,如果没有指定,默认为“nobody”。
- --builddir=DIR - 设置构建目录。
- --with-rtsig_module - 启用rtsig模块。
- --with-select_module –without-select_module - 如果在configure的时候没有发现kqueue, epoll,rtsig或/dev/poll其中之一,select模块始终为启用状态。
- --with-poll_module –without-poll_module - 如果在configure的时候没有发现kqueue, epoll,rtsig或/dev/poll其中之一,poll模块始终为启用状态。
- --with-http_ssl_module - 启用ngx_http_ssl_module,启用SSL支持并且能够处理HTTPS请求。需要OpenSSL,在Debian系统中,对应的包为libssl-dev。
- --with-http_realip_module - 启用ngx_http_realip_module
- --with-http_addition_module - 启用ngx_http_addition_module
- --with-http_sub_module - 启用ngx_http_sub_module
- --with-http_dav_module - 启用ngx_http_dav_module
- --with-http_flv_module - 启用ngx_http_flv_module
- --with-http_stub_status_module - 启用”server status”(服务状态)页
- --without-http_charset_module - 禁用ngx_http_charset_module
- --without-http_gzip_module - 禁用ngx_http_gzip_module,如果启用,需要zlib包。
- --without-http_ssi_module - 禁用ngx_http_ssi_module
- --without-http_userid_module - 禁用ngx_http_userid_module
- --without-http_access_module - 禁用ngx_http_access_module
- --without-http_auth_basic_module - 禁用ngx_http_auth_basic_module
- --without-http_autoindex_module - 禁用ngx_http_autoindex_module
- --without-http_geo_module - 禁用ngx_http_geo_module
- --without-http_map_module - 禁用ngx_http_map_module
- --without-http_referer_module - 禁用ngx_http_referer_module
- --without-http_rewrite_module - 禁用ngx_http_rewrite_module。如果启用,需要PCRE包。
- --without-http_proxy_module - 禁用ngx_http_proxy_module
- --without-http_fastcgi_module - 禁用ngx_http_fastcgi_module
- --without-http_memcached_module - 禁用ngx_http_memcached_module
- --without-http_limit_zone_module - 禁用ngx_http_limit_zone_module
- --without-http_empty_gif_module - 禁用ngx_http_empty_gif_module
- --without-http_browser_module - 禁用ngx_http_browser_module
- --without-http_upstream_ip_hash_module - 禁用ngx_http_upstream_ip_hash_module
- --with-http_perl_module - 启用ngx_http_perl_module
- --with-perl_modules_path=PATH - 为perl模块设置路径
- --with-perl=PATH - 为perl库设置路径
- --http-client-body-temp-path=PATH - 为http连接的请求实体临时文件设置路径,如果没有指定,默认为<prefix>/client_body_temp
- --http-proxy-temp-path=PATH - 为http代理临时文件设置路径,如果没有指定,默认为<prefix>/proxy_temp
- --http-fastcgi-temp-path=PATH - 为http fastcgi临时文件设置路径,如果没有指定,默认为<prefix>/fastcgi_temp
- --without-http - 禁用HTTP服务
- --with-mail - 启用IMAP4/POP3/SMTP代理模块
- --with-mail_ssl_module - 启用ngx_mail_ssl_module
- --with-cc=PATH - 设置C编译器路径
- --with-cpp=PATH - 设置C预处理器路径
- --with-cc-opt=OPTIONS - 变量CFLAGS中附加的参数,用于FreeBSD中的PCRE库,同样需要指定–withcc-opt=”-I /usr/local/include”,如果我们使用select()函数则需要同时增加文件描述符数量,可以通过–with-cc-opt=”-D FD_SETSIZE=2048”指定。
- --with-ld-opt=OPTIONS - 通过连接器的附加参数,用于FreeBSD中的PCRE库,同样需要指定–withld-opt=”-L /usr/local/lib”。
- --with-cpu-opt=CPU - 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4,athlon, opteron, amd64, sparc32, sparc64, ppc64
- --without-pcre - 禁用PCRE库文件,同时将禁用HTTP rewrite 模块,如果要在”location”指令中使用正则表达式,同样需要PCRE库。
- --with-pcre=DIR - 设置PCRE库源文件路径。
- --with-pcre-opt=OPTIONS - 在编译时为PCRE设置附加参数。
- --with-md5=DIR - 设置md5库源文件路径。
- --with-md5-opt=OPTIONS - 在编译时为md5设置附加参数。
- --with-md5-asm - 使用md5汇编源。
- --with-sha1=DIR - 设置sha1库源文件路径。
- --with-sha1-opt=OPTIONS - 在编译时为sha1设置附加参数。
- --with-sha1-asm - 使用sha1汇编源。
- --with-zlib=DIR - 设置zlib库源文件路径。
- --with-zlib-opt=OPTIONS - 在编译时为zlib设置附加参数。
- --with-zlib-asm=CPU - 为指定的CPU使用zlib汇编源进行优化,可用值为: pentium, pentiumpro。
- --with-openssl=DIR - 设置openssl库源文件路径。
- --with-openssl-opt=OPTIONS - 在编译时为openssl设置附加参数。
- --with-debug - 启用debug记录。
- --add-module=PATH - 增加一个在PATH中的第三方模块
Nginx的基本运行
见上面读书笔记
Nginx的基本配置
默认启动Nginx时,使用的配置文件是: 安装路径/conf/nginx.conf 文件可以在启动nginx的时候,通过-c来指定要读取的配置文件,常见的配置文件有如下几个:
- nginx.conf:应用程序的基本配置文件
- mime.types:MIME类型关联的扩展文件
- fastcgi.conf:与fastcgi相关的配置
- proxy.conf:与proxy相关的配置
- sites.conf:配置Nginx提供的网站,包括虚拟主机
Nginx的进程结构:启动Nginx的时候,会启动一个Master进程,这个进程不处理任何客户端的请求,主要用来产生worker进程,一个worker进程用来处理一个request。
Nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等
- 基本模块:所谓基本模块,指的是Nginx默认的功能模块,它们提供的指令,允许你使用定义Nginx基本功能的变量,在编译的时候不能被禁用,包括:
- 核心模块:基本功能和指令,如进程管理和安全
- 事件模块:在Nginx内配置网络使用的能力
- 配置模块:提供包含机制
常见的核心模块指令,大部分都是放置在配置文件的顶部具体的指令,请参看nginx的官方文档,非常详细,参见:
常见的events模块指令,大部分都是放置在配置文件的顶部
具体的指令,在上面那个文档里面,命令的context为events的就是events模块指令,只能在events里面使用
Nginx常用的核心模块指令(配置项)
见上面读书笔记中的配置项
核心模块指令,重点看看:error_log、include、pid、user、worker_cpu_affinity、worker_processes
error_log
日志有6个级别:debug|info|notice|warn|error|crit,
注意:error_log off不是禁用日志,而是创建一个名为off的日志,要禁用日志,可以这么写:error_log /dev/null crit;
Nginx支持将不同的虚拟主机的日志记录在不同的地方,如下示例:
http{error_log logs/http_error.log error; server{ server_name one; access_log logs/one_access.log; error_log logs/one_error.log error; } server{ server_name two; access_log logs/two_access.log; error_log logs/two_error.log error; } }
Nginx的HTTP基本配置
Nginx的HTTP配置主要包括三个区块,结构如下:
http { //这个是协议级别include mime.types; default_type application/octet-stream; keepalive_timeout 65; gzip on; server { //这个是服务器级别 listen 80; server_name localhost; location / { //这个是请求级别 root html; index index.html index.htm; } } }
Nginx的HTTP核心模块,包括大量的指令和变量,大都很重要,具体参见http: //nginx.org/en/docs/http/ngx_http_core_module.html
Location区段,见读书笔记,Location区段匹配示例
location = / { # 只匹配 / 的查询. [ configuration A ] } location / { # 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。 [ configuration B ] } location ^~ /images/ { # 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。 [ configuration C ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处 理。 [ configuration D ] }
- / → configuration A
- /documents/document.html → configuration B
- /images/1.gif → configuration C
- /documents/1.jpg → configuration D
Http反向代理
Nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离,以及负载均衡,从而大大提高服务器的处理能力。
- Http Proxy模块,功能很多,最常用的是proxy_pass,
- 如果要使用proxy_cache的话,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,形如./configure --add-module=../ngx_cache_purge-1.0
动静分离
- Nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,那么就直 接从Nginx发布的路径去读取,而不需要从后台服务器获取了。
- 但是要注意:这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync 做服务端自动同步或者使用NFS、MFS分布式共享存储。
负载均衡
Nginx通过upstream模块来实现简单的负载均衡,在upstream块内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:
upstream cctest1.com {server 127.0.0.1: 9080 weight=5; server 127.0.0.1: 8080 weight=5; server 127.0.0.1: 1111; }
请注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,翻墙等等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。
Geo和GeoIP模块
这两个模块主要用于做全局的负载均衡,可以根据不同的客户端ip来访问不同的 服务器,根据IP地址范围匹配生成新变量:geo模块
- 功能:基于已有的变量值生成新的变量值,根据客户端地址创建新变量
- ngx_http_geo_module:默认编译进nginx,通过--without-http_geo_module禁用
http{ geo $geo{ default default; 202.103.10.1/24 A; 179.9.0.3/24 B; } upstream default.server{ server 192.168.0.100; } upstream A.server{ server 192.168.0.101; } upstream B.server{ server 192.168.0.102; } server{ listen 80; location / { proxy_pass http: //$geo.server$request_uri; } } }
当访问 http: //202.103.10.1/24.server/$URl时,会走upstream A.server的负载均衡块
Rewrite模块配置
Rewrite模块:用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)。关于负载均衡和重定向的区别,可以看读书笔记那一块
Nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:
- ^ :必须以^后的实体开头
- $ :必须以$前的实体结尾
- . :匹配任意字符
- [ ] :匹配指定字符集内的任意字符
- [^ ] :匹配任何不包括在指定字符集内的任意字符串
- | :匹配 | 之前或之后的实体
- () :分组,组成一组用于匹配的实体,通常会有|来协助
捕获子表达式,可以捕获放在()之间的任何文本,比如:^(.*)(hello|sir)$ 字符串为“hi sir” 捕获的结果: $1=hi $2=sir这些被捕获的数据,在后面就可以当变量一样使用了
内部请求,外部请求是客户端的url,内部请求是Nginx通过特殊的指令触发。比如:error_page、index、rewrite、try_files、include等等
内部请求分成两种类型
- 1:内部重定向:URI被改变,可能会匹配到其他的Location
- 2:子请求:比如使用Addition模块,指令add_after_body允许你在原始的URI之后指定一个URI,会把该URI被处理后的结果,插入到原始的URI的body中。
- 内部重定向示例
server {server_name sishuok.com; location /abc/ { rewrite ^/abc/(.*)$ /bcd/$1 } location /bcd/{ internal; root pages; } }
条件结构的基本语法:
- 1:没有操作符:指定的字符串或者变量不为空,也不为0开始的字符串,取true
- 2:= , != ,例:if($request_method = POST){…}
- 3:~,~*,!~,!~* ,例:if($uri ~* “\.jsp$”){…}
- 4:-f,!-f :用来测试指定文件是否存在,例:if(-f $request_filename){…}
- 5:-d,!-d :用来测试指定目录是否存在
- 6:-e,!-e:用来测试指定文件、目录或者符号链接是否存在
- 7:-x,!-x:用来测试指定文件是否存在和是否可以执行
- 8:break:跳出if块
- 9:return:终止处理,并返回一个指定的http状态码
- 10:set:初始化或者重定义一个变量
其它模块
- Http Index模块,
- Http Referer模块 ,可用于防盗链
- Http Limit Zone模块 ,可用于会话的连接数控制,如限制每个IP的并发连接数等
- Http Access模块,用于简单的访问控制,
- Http Charset模块,重点看看:charset
- Gzip模块,
- Http Browser模块,用于按照请求头中的“User-agent”来创建一些变量,好为不同的浏览器创建不同的内容,暂时了解即可
- Memcached模块,这是把Nginx当作Memcached的客户端,用来连接Memcached的模块。
- Http Addition模块,可以在当前location内容之前或后添加内容,
- Http Empty Gif模块,这个模块在内存中保存一个能够很快传递的1×1透明GIF,
- Http Auth Basic模块,基于Http Basic认证的方式来保护虚拟主机或目录,
- Http AutoIndex模块,用于提供自动目录列表,该模块只有在找不到默认的index文件的时候才启用,
- Http Fcgi模块,用于与FastCGI进程交互,
- FLV Stream模块,支持当Http下载方式播放Flv时,可以支持进度条拖放,
- SSL模块,
- 邮件模块,
常见功能的配置片断
#server配置为监听ip和端口server{ listen 127.0.0.1: 9080; server_name 127.0.0.1; } #server配置为监听域名和端口 server{ listen 80; server_name www.sishuok.com sishuok.com *.sishuok.com; } #向后台服务器传递客户端的真实ip location ~ \.(jsp|action|mvc)$ { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http: //sishuok.com; } #在负载均衡里面,实现后端服务器故障转移的配置 location ~ \.(jsp|action|mvc)$ { proxy_next_upstream http_502 http_504 timeout; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http: //server_pool; } #简单的防盗链 location / { …… valid_referers blocked sishuok.com *.sishuok.com; if($invalid_referer){ rewrite ^/ http: //sishuok.com; } } #简单的限制下载速度 location / { limit_rate 256K; } 使用proxy_cache的配置 http{ #下面这两个path指定的路径必须在同一个分区 proxy_temp_path /cachetemp/proxy_temp_path; #设置名称为mycache,内存缓存100m,自动清除1天未使用的内容,硬盘缓存空间1g proxy_cache_path /cachetemp/proxy_cache_path levels=1: 2 keys_zone=mycache: 100m inactive=1d max_size=1g; server{ location ~ .*\.(gif|jpg|html|js|css)$ { proxy_cache mycache; #使用名称为mycache的缓存 #对不同的Http状态码设置不同的缓存时间 proxy_cache_valid 200 304 24h; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; #设置缓存的key值 proxy_cache_key $host$uri$is_args$args; } } }
Nginx的配置优化
如果没有足够的实力和必要去自己改写Nginx,那么Nginx的优化主要就是:优化Nginx的配置,做到合理高效的使用,优化的方向和目标:
- 1:尽量提高单台机器处理效率
- 2:尽量降低单台机器的负载
- 3:尽量降低磁盘I/O
- 4:尽量降低网络I/O
- 5:尽量减少内存使用
- 6:尽量高效利用CPU
- 生产环境下,应该使Nginx模块最小化,就是用到哪几个就开哪几个,这个需要在编译安装Nginx的时候做。
- 用户和组,生产环境下,最好是专为Nginx创建用户和组,并单独设置权限,这样会更安全。例如: user nginx nginx
- worker_processes :通常配置成cpu的总核数,或者其2倍,性能会更好。这可以减少进程间切换带来的消耗。
- 还可以同时使用worker_cpu_affinity来绑定cpu,使得每个worker进程独享一个cpu,实现完全的并发,性能更好,不过这个只对linux系统有效。
- events里面的事件模型,Linux推荐使用epoll模型,FreeBSD推荐采用kqueue
- worker_rlimit_nofile:描述一个nginx进程打开的最多的文件数目。配置成跟linux内核下文件打开数一致就可以了。可以通过ulimit -n 来查看,新装的系统默认是1024,CentOS中可以如下方式进行修改:
- 在/etc/security/limits.conf最后增加:
- worker_connections:每个进程允许的最多连接数,默认是1024,可以设置大一些。理论上并发总数是worker_processes和worker_connections的乘积,worker_connections值的设置跟物理内存大小有关,因为系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右,所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置。
- keepalive_timeout:设置到65左右就可以
- client_header_buffer_size:设置请求的缓存,设置为4k,通常为系统分页大小的整数倍,可以通过getconf PAGESIZE 来查看系统分页大小。
- 对打开文件设置缓存
- 尽量开启Gzip压缩,gzip_comp_level通常设置成3-5,高了浪费CPU
- Error日志优化:运行期间设置为crit,可以减少I/O
- access日志优化:如果使用了其他统计软件,可以关闭日志,来减少磁盘写,或者写入内存文件,提高I/O效率。
- sendfile指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,通常应设置成on,如果是下载等应用磁盘IO重负载应用,可设置为 off
- Buffers size优化:如果buffer size太小就会到导致nginx使用临时文件存储response,这会引起磁盘读写IO,流量越大问题越明显。client_body_buffer_size 处理客户端请求体buffer大小。用来处理POST提交数据,上传文件等。client_body_buffer_size 需要足够大以容纳需要上传的POST数据。同理还有后端的buffer数据。
- worker_priority进程优先级设置:Linux系统中,优先级高的进程会占用更多的系统资源,这里配置的是进程的静态优先级,取值范围-20到+19,-20级别最高。因此可以把这个值设置小一点,但不建议比内核进程的值低(通常为-5)
- 合理设置静态资源的浏览器缓存时间,尽量用浏览器缓存
- 负载均衡锁accept_mutex,建议开启,默认就是开启的
- 如果使用SSL的话,而且服务器上有SSL硬件加速设备的话,请开启硬件加速
运维实例:
查看服务相关进程及端口信息
Nginx 地址重写(重定向)
获得一个来访的URL请求,然后改写成服务器可以处理的另一个 URL。
rewrite 旧的地址(可使用正则) 新的地址 标签(可忽略)
Nginx反向代理
在配置文件中添加一个location,更新配置文件