Nginx
基础知识点
特点
1 Nginx是一个很牛的高性能Web和反向代理服务器,它具又很多非常优越的特性 2 在高连接并发的情况下,Nginx是Apache服务器不错的替代品,Nginx是做虚拟主机不错的软件平台之一 3 能够支持50000个并发连接数的响应,Nginx选择了epoll and kqueue作为开发模型
Nginx作为负载均衡服务器
既可以在内部直接支持和PHP程序对外进行服务,也可以支持作为HTTP代理服务器对外进行服务
Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比Perlbal要好很多
优点
1. 高并发连接 官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接数 2. 内存消耗少 在3万并发连接下,开启的10个Nginx进程才消耗150M内存 3. 配置文件简单 风格跟程序一样通俗易懂 4. 成本低廉 Nginx为开源软件,可以免费使用 5. 支持Rewrite重写规则 能够根据域名、URL的不同,将HTTP请求分发到不同的后端服务器群组 6. 内置的健康检查功能 如果Nginx Proxy后端的某Web服务器宕机了,不会影响到前端访问 7. 节省带宽 支持GZIP压缩,可以添加浏览器本地缓存的Header头 8. 稳定性高 用于反向代理,宕机的概率微乎其微 9. 模块化设计 模块可以动态编译 10. 外围支持好 文档全、二次开发和模块较多 11. 支持热部署 可以不停机重载配置文件 12. 支持事件驱动、AsynI/O、mmap等性能优化
Nginx常用用法
1. 使用Nginx结合FastCGI运行PHP、JSP、Perl等程序 静态页面Nginx直接发送给客户端,动态页面通过FastCGI交给其他Web服务后端处理 客户发送请求先到Nginx,Nginx将请求发给PHP,PHP处理完请求将结果发送给Nginx,Nginx最后再将结果发送给客户端,四次Nginx交互 2. 使用Nginx作反向代理、负载均衡、规则过滤 3. 使用Nginx运行静态页面HTML页、图片 4. Nginx与他新技术的结合应用
Nginx的模块和工作原理
组成
Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单
仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配)
而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作
Nginx模块
核心模块
HTTP模块
EVENT模块
MAIL模块
...
基础模块
HTTP Access模块
HTTP FastCGI模块
HTTP Proxy模块
HTTP Rewrite模块
...
第三方模块
HTTP Upstream模块
Requests Hash模块
Notice模块
HTTP Access Key模块
...
Nginx模块分类
1. Handlers处理器模块 此类模块直接处理请求,并进行输出内容和修改header信息等操作。handlers处理器模块一般只能有一个 2. Filters过滤器模块 此类模块主要是对其它处理器模块输出的内容进行修改操作,最后由Nginx输出 3. Proxies代理类模块 就是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能
官网文档 http://www.nginx.org
下载安装
下载Nginx源码包
1 wget http://nginx.org/download/nginx-1.12.2.tar.gz
解压
1 tar -zxvf nginx-1.12.2.tar.gz
查看版本变更修改
1 cd nginx-1.12.2/ 2 vim CHANGES
查看源码安装定制参数
1 ./configure --help
重要依赖包安装
# 支持正则表达式包下载 yum install pcre-devel
创建用户
1 useradd nginx -s /sbin/nologin
创建日志目录
1 mkdir -p /data/logs/nginx
编译安装(使用部分模块)
1 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --http-log-path=/data/logs/nginx/access.log --error-log-path=/data/logs/nginx/error.log --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module 2 make 3 make install
自添加第三发模块
wget下载第三发模块,这里以echo输出模块为例 wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz 编译时追加参数 --add-module=/usr/local/src/echo-nginx-module-0.61
配置文件解析
常用配置文件
nginx.conf 应用程序的基本配置文件
mime.types MIME类型关联的扩展文件
fastcgi.conf 与fastcgi相关的文件
proxy.conf 与proxy相关的文件
sites.conf 配置Nginx提供的网站,包括虚拟主机
配置文件结构
main
event
http协议级别
server服务器级别
location请求级别
配置文件管理
将管理work的配置从nginx.conf中分离出来,方便管理 tail -84 nginx.conf > server.conf 在nginx.conf中导入子配置文件 vim nginx.conf include server.conf; nginx.conf主要控制nginx性能 server.conf主要控制业务相关以及映射关系
nginx.conf部分配置参数
main段
指定运行用户 user nginx; 指定pid pid logs/nginx.pid; 指定工作进程数(一般等于核心数或很核心数-1,减少进程切换) worker_processes 4; 绑定CPU和进程关系,避免抖动,带来的缓存频繁刷新(与工作进程数相关) worker_cpu_affinity 0001 0010 0100 1000; 修改worker进程最大打开的文件数 worker_rlimit_nofile 65535; 修改worker进程的最大连接数 event{ worker_connections 20000; }
http段
Web页面的工作目录 root /data/w3 日志格式配置 log_format ... 访问日志相关参数配置(缓冲、缓存、压缩...) access_log ... 内存单独开辟数据空间,减少内核空间到用户空间的数据交互 sendfile on; http长连接 keepalive 65; gzip压缩相关 gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml; gzip_comp_level 6; #默认是1,最高是9
server段
监听端口 listen 127.0.0.1:8000 default_server; 虚拟主机名 server_name www.example.com; server_name *.example.com; server_name ~^\.example\.com$;
location段
location优先级URL
= ---> "绝对路径" ---> ^~ ---> ~ ---> ~* 精确匹配检查 = location = / { root a; } 正则表达式模式匹配检查,区分大小写 ~ location ~ /document/ { root b; } 正则表达式模式匹配检查,不区分大小写 ~* location ~* \.php$ { fcgipass; } URI前半部分匹配,不支持正则表达式 ^~ location ^* /document/ { root d; }
root 工作起始路径 如果server中定义了root而location中未定义,则默认使用server中定义的 如果只写目录名(a),则默认以编译时prefix的路径为相对路径,即/usr/local/nginx/a allow 访问控制(顺序匹配) allow 192.168.1.1/32; deny 访问控制 deny all; error_page code [...] [=code] URI | @name 根据http响应状态码来指明特用的错误页面 error_page 404 /404_customed.html [=code] 以指定的响应码进行响应,而不是默认的原来的响应, 定制访问日志 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main;
SSL配置
自签名CA cd /etc/pki/CA (umask 077;openssl genrsa -out private/cakey.pem 2048) openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 9999 touch serial index.txt echo 01 >> serial CA端NginxSSL文件 cd /usr/local/nginx/conf mkdir ssl (umask 077;openssl genrsa -out nginx.key 1024) openssl req -new -key nginx.key -out nginx.csr CA对NginxSSL文件进行签发 openssl ca -in nginx.csr -out nginx.crt -days 9999 编辑server.conf文件中https段 ssl_certificate /usr/local/nginx/conf/ssl/nginx.crt; ssl_certificate_key /usr/local/nginx/conf/ssl/nginx.key;
基于用户认证
Auth_basic auth_basic "Welcome nuc" Auth_basic_user_file auth_basic_user_file "/usr/local/nginx/conf/vipuser" 生成一个密钥串 htpasswd -bc /usr/local/nginx/conf/vipuser aaa 123456 vim /usr/local/nginx/conf/vipuser aaa:$apr1$ojbCkPri$OObek39XPEpxpoCLvPMne/ useradd aaa
安全状态页面
location /status { stub_status on; } 参数解析 Active connection 3 当前所有处于打开状态的连接数 server accepts handled requests 100 120 402 100个连接 120创建握手 111个请求 Reading:0 Writing:1 Waiting:2 Reading:nginx读取到客户端的Header信息数 Writing:nginx返回给客户端的Header信息数 Waiting:开启keep-alive的情况下,这个值等于active - ( reading + writing ) Nginx已经处理完成正在等候下一次请求指令的驻留连接
Rewrite用法
功能:实现URL重写,用户请求重定向 语法:rewrite regex replacement flag; flag last 如果用户的URL被重写后,后续将不被其它rewrite规则匹配 而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程 如果再被匹配则继续 break 此rewrite重写完成之后,由User Agent对新的URL重新发起请求 且不在会被任何rewrite规则检查 redirect 以302响应码(临时重定向)返回新的URL permament 以301响应吗(永久重定向)返回新的URL 例子: rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
if使用
语法:if(condition){...} 应用段:server、location condition 1. 变量名 变量值为空串、以零开始则为false 2. 以变量为操作数构成的表达式 可以使用=、!=、<、>等操作符 3. 正则表达式的模式匹配操作 ~ 区分大小写的模式匹配检查 ~* 不区分大小写的模式匹配检查 !~和!~* 以上两种取反 4. 测试目标为文件 -f filename !-f 5. 测试指定路径为目录 -d !-d 6. 测试文件的存在性 -e !-e 7. 检查文件是否有执行权限 -x !-x 例子:判断客户端浏览器是否为IE if($http_user_agent ~* MSIE){ rewrite ^(.*)$ /msie/$1 break; }
防盗链
只要不是example.com域名的引用,皆为不合法引用 location ~* \.(jpg|gif|jpeg|png)${ valid_referer none blocked www.example.com; if($valid_referer){ rewrite ^/ http://www.example.com/403.html; } }
网络连接相关配置
1. keepalive_timeout #; 长连接的超时时长,默认75S 2. keepalive_requests #; 在一个长连接上所能够允许请求的最大资源数 3. keepalive_disable [msie6|safari|none] 为指定类型的User Agent禁用长连接 4. tcp_nodelay on|off 合并小资源请求,将多个小资源合并成一个大资源在响应给客户端,缺点,客户端请求资源周期延长,一般禁用 5. client_header_timeout #; 读取http请求报文首部的超时延长,如果我们的服务器很繁忙那么就应该延长点时间等待客户端 6. client_body_timeout #; 读取http请求报文body部分的超时延长,如果我们的服务器很繁忙那么就应该延长点时间等待客户端 7. send_timeout #; 发送响应报文的超时时长
Work进程作用
1. 响应用户请求 2. 为后端Web服务器做反向代理 3. 从本地缓存加载内容
Cache Loader作用
1. 使用缓存元数据建立内存数据库 2. 检查缓存存储的中的数据对象 3. 加载缓存数据
Cache manager作用
1. 清理过期失效的缓存
Nginx核心(core)模块
反馈给用户获取资源的类型 # 自定义响应首部 add_header server { add_header X-Via $server_addr; add_header X-Cache $upstream_cache_status; ... }
Nginx反向代理(proxy)模块
官方文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } 例子 1. 直接映射 location /monitor { proxy_pass http://192.168.1.254:8080/cmdb; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } 2. 正则模式匹配,非URL映射 location ~* \.(jpg|png|gif|css|js)$ { proxy_pass http://192.168.1.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } proxy_ssl_* 内网HTTPs proxy_connect_timeout 与后端服务器的超时时长 proxy_hide_header 由代理服务器响应客户端时,隐藏的首部 proxy_buffer* 应用服务器发送响应信息到代理服务器需要缓冲的信息大小 proxy_cache_bypass string 设置在何种情况下nginx将不从cache取数据:$cookie_nocache $arg_nocache $http_authorization 代理缓存 重要 定义缓存路径 proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time]; 使用缓存区域 proxy_cache zone | off; 缓存请求方法定义 proxy_cache_methods GET | HEAD | POST ...; 资源最少请求几次就加入缓存 # Default: proxy_cache_min_uses 1; proxy_cache_min_uses number; 修剪缓存请求 # 后端服务器中加入了新的资源,需要清除旧的资源 proxy_cache_path /data/nginx/cache keys_zone=cache_zone:10m; map $request_method $purge_method { PURGE 1; default 0; } server { ... location / { proxy_pass http://backend; proxy_cache cache_zone; proxy_cache_key $uri; proxy_cache_purge $purge_method; } } 重新验证过期缓存 proxy_cache_revalidate on | off; 如何处理被拿来响应的过期缓存 proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...; 自定义缓存时间 proxy_cache_valid [code ...] time; proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; 实例: http{ proxy_cache_path /data/cache/nginx/ levels=1:1 keys_zone=my_cache:32m; } makdir -pv /data/cache/nginx chown nginx:nginx location /monitor { proxy_cache mycache; proxy_cache_valid 200 1d; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://192.168.1.254:8080/cmdb; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
Nginx负载均衡(upstream)模块
官方文档:http://nginx.org/en/docs/http/ngx_http_upstream_module.html # 可定义服务器组 proxy_pass, fastcgi_pass, uwsgi_pass # 只能定义在http中 upstream backend { server backend1.example.com weight=5; server backend2.example.com:8080; server unix:/tmp/backend3; server backup1.example.com:8080 backup; server backup2.example.com:8080 backup; } server { location / { proxy_pass http://backend; } } 调度算法 默认加权轮询 sh算法 upstream backend { ip_hash; } sticky 基于cookie的方式 sticky cookie srv_id expires=1h domain=.example.com path=/; 基于路由的方式使用 route ... 基于交互行为判定 learn ... wlc算法 least_conn 健康检查参数(跟在server后) max_fails=; # 检查失败的次数大于几次就标识Server主机不可达,并移除 fail_timeout=; # 检查失败的超时时长 down; # 标记Server主机不可用(维护) backup; # 备用服务器(升级中) 对于后端不同的资源类型使用保活状态 # 后端服务器是apache时,不建议开启keepalive功能 upstream backend { keepalive 32; } 外部模块health_check健康检测 # 只能应用于location中 # 建议关闭访问日志 定时检测 interval=time 失败次数限定(状态:正常--->失败) fails=number 通过次数 passes=number 指明请求的资源 uri=uri 关键性资源检测 match=name 例子: location / { proxy_pass http://backend; health_check match=welcome; } match welcome { status 200; header Content-Type = text/html; body ~ "Welcome to nginx!"; } # status is not one of 301, 302, 303, or 307, and header does not have "Refresh:" match not_redirect { status ! 301-303 307; header ! Refresh; } # status ok and not in maintenance mode match server_ok { status 200-399; body !~ "maintenance mode"; }
Nginx_fastcgi模块
官方文档:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html 部分参数解析及使用 fastcgi缓存path定义,http only fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m inactive=3m max_size=1g; location中调用fastcgi_cache_path location ~ \.php$ { fastcgi_cache one; ... } 缓存允许的请求方法 fastcgi_cache_methods GET HEAD; 至少使用几次资源就将该资源加载至缓存 fastcgi_cache_min_uses 1; 设置cache状态码对应的有效时长 fastcgi_cache_valid 200 302 10m; fastcgi_cache_valid 404 1m; 是否使用已过期的cache fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | http_429 | off ...; 请求速率限制 fastcgi_limit_rate rate; 当fastcgi处理产生的数据非常大时,需要一个临时缓存目录存储数据(一般不推荐使用,会影响效率。最好加大fastcgi_buffer大小) fastcgi_temp_path path [level1 [level2 [level3]]]; 实例:LNMP基础上使用 yum install -y php-fpm php-mysql location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; } 修改/etc/nginx/fastcgi_params内容为 fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; 并在所支持的主页面格式中添加php格式页面 location / { root html; index index.html index.htm index.php; } 测试抗压能力 # 2000个请求并发为100个 ab -n 2000 -c 100 http://192.168.1.1/test.php
淘宝开源Web项目tengine
1 官方文档:http://tengine.taobao.org/ 2 中文文档,功能强大