Nginx系统卷-高性能web服务器详解与运维
目录:
第一章 Nginx的功能
基本HTTP功能
- 提供静态文件和Index文件,生成自动索引,打开文件描述符缓存
- 使用缓存加速反向代理,简单的负载均衡和容错
- 使用缓存加速远程fastcgi服务的访问,简单的负载均衡和容错
- 模块化结构,包括gzip,字节range,chunk(分块)响应,图像大小处理
- 支持SSL和TLS SNI
其他HTTP功能
- 基于名称和IP的虚拟服务器
- 支持keepalive和管道化连接
- 日志
- 重写模块
- 重定向
- FLV流文件
- 速度限制
- 基于HTTP的PUT,DELETE等方法
- 限制连接数或者IP的请求
- 嵌入式Perl语言解析
邮件服务器代理
nginx是基于模块化的构建方式
从功能分是核心模块(内核模块和事件驱动模块)和HTTP服务模块(HTTP内核模块,标准模块和可选HTTP模块)
Nginx内核模块
Nginx内核模块用于控制nginx服务器的基本功能
命令
worker_processes auto;
worker_cpu_affinity auto;
worker_priority -19;
user nobody;
pid /app/webserver/nginx/var/nginx.pid;
- daemon 后台运行
- env 用于定义环境变量
error_log
用于记录错误日志,如果想置空可以error_log
- user 指定启动用户
等等很多命令参考ngx_core_module
变量
只提供了两个应用场景
$PID
nginx服务进程号$realpath_root
Nginx事件模块
主配置的events配置
events {
...
}
用于控制nginx如何处理连接
accept_mutex_delay
默认为500ms,如果一个worker process没有互斥锁就会在一个设定值的时间之后才被回收worker_connections
默认值为1024,设置worker进程所能处理的连接数,client的最大连接数为worker_processes*worker_connections
,在反向代理的环境下最大客户端连接数需要除以4
Nginx的HTTP内核模块
从HTTPCoreModule开始
http {
server {
listen 80;
server_name www.whysdomain.com;
...
}
}
指令
- alias 用于指定一个路径
location /i/ {
alias /www/html/;
}
这样访问/i/就是访问/www/html/,如果是root则访问/i/访问/www/html/i/
location /download/(.*)$ {
alias /www/html/$1;
}
client_body_buffer_size
Client请求体缓存的大小,默认是两个页的大小,如果请求体大于该缓存大小,则整个请求的部分会写入临时文件client_body_temp_path
上述临时文件的目录client_body_timeout
读取请求体超时时间,默认60s,超过会返回408client_header_buffer_size
Client请求头的大小,默认是1k,如果放不下会使用large_client_header_buffers
的设置client_header_timeout
同理超时时间client_max_body_size
用于指定Client接收的请求体的最大值,如果大于会返回413default_type
指定默认的MIME类型,默认为text/plain
,没有指定则使用此MIMEerror_page
对访问错误请求到指定URL
提供了很多的示例
error_page 500 502 503 504 /50x.html;
error_page 404 =200 /empty.gif;
error_page 404 = /404.php;
error_page 404 =301 http://example.com/notfound.html;
location / {
error_page 404 = @fallback;
}
location @fallback {
proxy_pass http://backend;
}
internal
可以将location只允许内部请求,内部请求包括error_page
重定向,nginx_http_ssi_module
模块的include_virtual指令创建的子请求,由rewrite指令的改变请求方向keepalive_timeout
用于设置client的keepalive时间,默认值为75keepalive_request
用于设置nginx服务器能够保持的活跃连接数,默认为100arge_client_header_buffers
默认一个页大小limit_except
用于限制location的HTTP方法
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
limit_rate
和limit_rate_after
流量限制lingering_close
在socker上启用SO_LINGER,延迟关闭,在nginx关闭连接的时候先关闭写连接,等待一段时间再去关闭读连接,在nginx接收到错误的时候更多会关闭连接,并将错误返回给Client,nginx调用write()的系统调用返回错误信息,但是返回了并不代表数据到Client,有可能还在tcp的write的buffer,如果直接执行关闭close()调用来关闭连接,内核会检查read buffer有没有Client的数据,如果有就发送给Client reset报文来关闭tcp连接并丢弃write buffer的数据,如果没有则等待write buffer的数据发送完再通过四次挥手断开连接,第一种情况就会造成client不能获取错误信息。更多可以参考read/write数据读写传输方式lingering_time
默认为30slingering_timeout
默认为5s,nginx在client关闭之前,两个读操作之间的等待时间listen
监听的IP和端口,当然也支持监听套接字,其中default参数用于设置默认的server,location
用来匹配urllog_subrequest
由rewrite规则等产生的SSI请求是否产生访问日志open_file_cache
用于文件缓存post_action
定义一个请求完成之后的动作之后调用该urlreset_timedout_connection
重用设置连接超时resolver
用于设定DNS服务器root
文档根目录server
用于配置虚拟主机server_name
域名,可以使用全域名,通配符,正则表达式(按照配置文件引入顺序),没有匹配的使用default_server,再没有就还是按照配置引入顺序server_tokens
在错误页面是否返回版本号tcp_nodelay
是否允许使用TCP_NODELAY,当keepalive的时候生效tcp_nopush
是否允许使用TCP_NOPUSH,当sendfile的时候生效,如果允许nginx会在单个TCP数据包try_file
用于检测文件是否存在,如果不存在依次去匹配后边的URL或者location,最后一个一定要保持存在types
设置请求文件的文件类型
变量
参考nginx的Embedded Variables
$arg_PARAMETER
GET请求行的单个参数$arg
GET请求行的参数汇总$binary_remote_addr
二进制格式客户端地址$body_bytes_sent
响应体大小$content_length
请求头中的Content-Length字段的值$document_root
root的值$document_uri
等于$uri
$host
请求头中的Host值$hostname
由gethostname返回的值$is_args
如果设置了$arg
则为?,否则为""$limit_rate
允许限制的速率$nginx_version
nginx版本$remote_addr
客户端IP地址$request_body
body信息$request_method
请求方法$request_uri
请求的URI
第2章 Nginx的模块管理和进程管理
模块管理
nginx的模块一旦被编译就不能卸载,只能重新编译,core模块不能被禁用,其他的可以,可以通过tree src
获取的
$ tree ./src/ -L 1
./src/
|-- core
|-- dtrace
|-- event
|-- http
|-- mail
|-- misc
|-- os
`-- stream
在编译的configure --help
中可以看到,with的是默认启用的,without是默认未启用的,使用第三方模块则需要--add-module
参数
master进程和worker进程
现在的nginx应该都是使用epoll模型。
对于每一个请求都是master进行接收,但是请求是由worker进程进行处理
master可以处理的信号
信号 | 功能 |
---|---|
TEAM,INT | 快速关闭 |
USER1 | 重新打开日志文件 |
USER2 | 平滑升级可执行程序 |
HUP | 重新装载配置,在新的工作进程中使用新的配置,从容关闭旧的工作进程 |
WINCH | 从容关闭worker进程 |
QUIT | 从容关闭master进程 |
worker可以处理的信号
信号 | 功能 |
---|---|
TEAM,INT | 快速关闭 |
QUIT | 从容关闭worker进程 |
针对linux的系统优化
- 关闭系统不需要的服务
- 优化磁盘写操作 挂载的noatime参数
- 优化资源限制 ulimit
- 优化TCP内核参数
优化nginx服务器
- 关闭日志
- 使用epoll
- nginx配置优化
第3章 nginx如何处理一个请求
IP和域名的处理
通过请求头的HOST字段获取域名,如果没有匹配的可以使用default,如果没有default则直接使用第一个配置文件
URL部分的处理
通过location,可以是正则表达式
第4章 服务器名字
准确名字和通配符的名字作为hash值存在hash表中,这些hash值被绑定到监听端口
匹配顺序依次为
- 准确名字
- 由星号开头
- 由星号结尾
第5章 协助用户操作nginx工具(略)
第6章 5xx错误及处理(略)
第7章 使用TCMalloc优化nginx(略)
第8章 PCRE正则表达式(略)
第9章 nginx高可用的实现(略)
第10章 10个QA(略)
第11章 限制流量
limit_rate
用于指定向客户端传输数据的速度,速度为每秒传输的字节数,对于每一个连接设置的limit_rate_after
在传输配置大小的数据后进行限速,imit_rate_after 3m
以最大速度下载3MB后
limit_rate_after 3m;
limit_rate 512k;
第12章 限制用户并发连接数
limit_zone
用于定义一个zone,用于存储会话状态,能够存储的会话数量是由分配交付的变量和memory_max_size
的大小决定的limit_conn
一个会话的最大连接数,如果超过这个限制会报503limit_conn_log_level
设置日志的错误级别,默认为error
limit_zone flv_down $remota_addr 10m;
limit_conn fiy_down 2;
第13章 修改或者隐藏nginx的版本号
编译的时候修改src/core/nginx.h
第14章 配置FLV服务器
通过HttpFlvStreamModule模块,支持FLV文件
使用flv指令来实现,另外还有yamdi,支持H264
第15章 Nginx的访问控制
通过HttpAccessModule模块实现
deny 192.168.0.1;
all 192.168.0.0/24;
denyall;
第16章 提供FTP下载(略)
第17章 Nginx与编码
URL的编码是以UTF-8的方式编码向后端服务器发送的,如果系统的字符集不一致就会出现解码的问题,导致访问不了资源,静态资源内容也同理
通过HttpCharsetModule
- charset 返回给浏览器的编码
- source_charset 原编码
第18章 页面压缩传输
通过HttpGzipModule页面压缩,另外还支持HttpGzipStaticModule,防止每次请求都进行压缩
第19章 控制nginx如何记录日志(略)
第20章 map模块的使用
定义映射,更多是用于rewrite
第21章 Nginx预防应用层DDoS攻击
最基本的DDoS就是请求占用过多的服务器资源
limit_req_log_level warn;
limit_req_zone $remote_addr zone=ONLY_one:10m rate=1r/s;
limit_req zone=ONLY 5;
ONLY_one
为zone名字,存储的会话空间10m,rate=1r/s
为每秒处理请求,limit_req
指定zone的最大突发请求数,如果rate超过这个值请求会被限制超时
访问测试
ab -n 1000 -c 100 http://192.168.0.1/
第22章 为Nginx添加,清除或改写响应
通过HttpHeadersModule可以设置HTTP头,但是不能重写
add_header
增加http的响应头expires
设置生存期标志
还有ngx_headers_more
,可以用来设置或者清除
设置的区别
add_header "Access-Control-Allow-Origin" $http_origin;
add_header "Access-Control-Allow-Methods" "GET, POST";
add_header "Access-Control-Allow-Headers" "X-Requested-With";
add_header "Access-Control-Allow-Credentials" "true";
more_set_headers 'Access-Control-Allow-Origin: $http_origin';
more_set_headers 'Access-Control-Allow-Methods: "GET, POST"';
more_set_headers 'Access-Control-Allow-Headers: X-Requested-With';
more_set_headers 'Access-Control-Allow-Credentials: true';
还可以通过-s指定状态码,通过-t指定响应类型
第23章 重写URL
rewrite重写后location中仍有rewrite,这种重复周期为10次,如果10次之后还没有具体的URL则会返回500错误
- break 完成当前规则组,不会处理任何rewrite请求
- if 判断条件
- return 直接执行规则
- rewrite 重写url
- rewrite_log 重写日志是否开启,默认为off
- set 定义变量
uninitialized_variable_warn
默认为on,用于开启记录有关没有被初始化的变量
第24章 Nginx与服务器端包含(略)
第25章 Nginx与X-Sendfile
X-accel允许后台返回的头来决定投递静态文件。
流程就是Client请求后端服务,后端服务进行认证后返回一个响应头给Nginx,Nginx接收到这个响应头,返回文件给Client,这种功能就是X-Sendfile,由X-Accel-Redirect
不过现在一般的操作都是程序返回cdn等URL了
第26章 在Nginx的响应体之前或之后添加内容
通过Http-Addition-Module实现的,需要编译时添加--with-http_addition_module
参数
模块使用chunked编码的方式提供动态请求体,暂时不知道是啥用途
第27章 Nginx与访问者信息
通过Http-Geoip-Module实现的,需要编译时添加--with-http_geoip_module
参数
第28章 Nginx的图像处理
通过Http-Image-Filter-Module模块实现,是一个过滤器,主要用于裁剪过大的图片,需要编译时添加--with-http-image-filter-module参数
image_filter (test|size|resize width height|crop width height)
- test 用于检测响应的是否是peg,gif或png格式,否则会返回415错误
- size 用于返回图片返回给定图片的尺寸信息
- resize 将按比例将图像缩小到指定大小
- crop 将按比例将图像缩小到指定大小,并且会裁剪多余的边缘
其他指令
image_filter_buffer
读取图片的最大缓存值image_filter_jpeg_quality
设置jpeg图片损失的质量比例,默认为75image_filter_transparency
第29章 location中随机显示文件
需要编译时添加--with-http_random_index_module
参数
location / {
random on;
}
第30章 后台Nginx服务器记录原始客户端的IP地址
用于后端的Nginx
第31章 解决防盗链
referer模块的vaild_referers
location /phone/ {
vaild_referers none blocked www.whysdomain.com whysdomain.com
if ($invalid_referer) {
return 403
}
}
如果referer被认为无效,那么invalid_referer
将被设置为1,对于vaild_referers
指令的相关参数,none为Referer头缺失的情况下也会被认为是有效的,blocked为由防火墙伪装的Referer也会被认为有效,server_names为指定名字的服务器被认为是有效的referer,其值可以是一个列表来列举多个服务器,可以使用*号
还有需要请求资源时加入认证参数的Accesskey模块
第32章 Nginx提供HTTPS服务
SSL模块默认不会被包含,需要编译时指定--with-http_ssl_module
查看操作系统支持的openssl
$ openssl ciphers
第33章 监控Nginx的工作状态
需要编译时指定--with-http_stub_status_module
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
第34章 使用empty_gif(略)
第35章 Nginx实现对响应体内容的替换(略)
可以nginx来做,但是为什么不让业务实现呢
第36章 Nginx的webdav
可以让nginx实现PUT,DELETE等方法,但是为什么不让业务实现呢
第37章 Nginx的Xslt模块(略)
第38章 Nginx的基本认证方式(略)
第39章 Nginx的cookies(略)
可以在nginx的响应中植入cookie,但是为什么不让业务实现呢
第40章 Nginx基于客户端请求头的访问分类
直接if判断不好吗
第41章 通过upstream模块使得Nginx实现后台服务器集群(略)
第42章 根据浏览器选择主页(略)
直接if判断不好吗
第43章 关于nginx提供下载.ipa和.apk文件的处理方法(略)
扔CDN上的
第44章 SCGI (略)
第45章 Expries与ETag
可以直接使用
expires 10d;
FileETag on;
第46章 使用upstream_keepalive模块实现keep-alive(略)
第47章 后台服务器的健康监测
第48章 使用sticky模块实现粘性会话(略)
第49章 略
第50章 Nginx使用redis数据库(略)
第51章 Nginx访问mongodb(略)
第52章 Nginx访问mogilefs(略)
第53章 缓存技术——proxy_cache(略)
第54章 缓存技术——proxy_store(略)
第55章 缓存技术——memcached(略)
第56章 缓存技术——ncache(略)
第57章 缓存技术——varnish(略)
对于动态数据并没有什么好的缓存,最好是能创建为静态页