Nginx系统卷-高性能web服务器详解与运维

时间:Jan. 2, 2019 分类:

目录:

第一章 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;
        ...
    }
}

参考HTTPCoreModule

指令

  • 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,超过会返回408
  • client_header_buffer_size Client请求头的大小,默认是1k,如果放不下会使用large_client_header_buffers的设置
  • client_header_timeout 同理超时时间
  • client_max_body_size 用于指定Client接收的请求体的最大值,如果大于会返回413
  • default_type 指定默认的MIME类型,默认为text/plain,没有指定则使用此MIME
  • error_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时间,默认值为75
  • keepalive_request 用于设置nginx服务器能够保持的活跃连接数,默认为100
  • arge_client_header_buffers 默认一个页大小
  • limit_except用于限制location的HTTP方法
limit_except GET {
    allow 192.168.1.0/32;
    deny  all;
}
  • limit_ratelimit_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 默认为30s
  • lingering_timeout 默认为5s,nginx在client关闭之前,两个读操作之间的等待时间
  • listen 监听的IP和端口,当然也支持监听套接字,其中default参数用于设置默认的server,
  • location 用来匹配url
  • log_subrequest 由rewrite规则等产生的SSI请求是否产生访问日志
  • open_file_cache 用于文件缓存
  • post_action 定义一个请求完成之后的动作之后调用该url
  • reset_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 一个会话的最大连接数,如果超过这个限制会报503
  • limit_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图片损失的质量比例,默认为75
  • image_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(略)

对于动态数据并没有什么好的缓存,最好是能创建为静态页