所有的模块功能使用参考如下:
官方文档http://nginx.org/en/docs/
功能介绍:
1、反向代理
2、负载均衡
3、缓存功能
4、动静分离
5、URL重写
6、SSL加密
7、压力测试
8、优化建议
9、网络IO模型
**
一、反向代理:
反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet上 的连接请求,
然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
代理服务器nginx配置
location / {
proxy_pass http://nginx.org/;
proxy_set_header Host $http_host; #让后端服务器能获取客户端所访问的真实代理服务器IP:PORT
proxy_set_header X-Real-IP $remote_addr; #让后端服务器能获取客户端的真实IP
}
后端nginx服务器配置
proxy_set_header X-Real-IP
r
e
m
o
t
e
a
d
d
r
;
需
要
在
后
端
n
g
i
n
x
的
日
志
中
的
添
加
′
remote_addr; 需要在后端nginx的日志中的添加'
remoteaddr;需要在后端nginx的日志中的添加′remote_addr后面添加: “$http_x_real_ip” 或者proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
log_format main '
r
e
m
o
t
e
a
d
d
r
"
remote_addr "
remoteaddr"http_x_real_ip" -
r
e
m
o
t
e
u
s
e
r
[
remote_user [
remoteuser[time_local] “$request” KaTeX parse error: Double superscript at position 35: … '̲status
b
o
d
y
b
y
t
e
s
s
e
n
t
"
body_bytes_sent "
bodybytessent"http_referer" ’
‘“
h
t
t
p
u
s
e
r
a
g
e
n
t
"
"
http_user_agent" "
httpuseragent""http_x_forwarded_for”’;
二、负载均衡
负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如:
Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,
通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载均衡策略,还有2种常用的第三方策略。
参考
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
算法一:
默认算法轮询(RR)
upstream nanyang {
server 20.0.0.132:8081;
server 20.0.0.132:8082;
}
server {
listen 10.0.0.131:80;
server_name localhost;
location / {
proxy_pass http://nanyang/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
算法二:基于权重,进行请求的分发
upstream nanyang {
server 20.0.0.132:8081 weight=1;
server 20.0.0.132:8082 weight=9;
}
server {
listen 10.0.0.131:80;
server_name localhost;
location / {
proxy_pass http://nanyang/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
算法三:对客户端第一次访问的后端服务器IP地址进行hash算法,和客户端IP进行绑定。帮助我们实现sesesion会话不丢失
upstream nanyang {
ip_hash;
server 20.0.0.132:8081;
server 20.0.0.132:8082;
}
server {
listen 10.0.0.131:80;
server_name localhost;
location / {
proxy_pass http://nanyang/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
其他参数使用:
backup:备份服务器,负载均衡实现了主备
down:关闭了,给服务器不再被调用
max_fails=3:失败最高次数
fail_timeout=30s:时间范围
第三方算法:(可选)
4、fair
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
5、url_hash
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
三、缓存功能
缓存的最根本的目的是为了提高网站性能,减轻频繁访问数据,而减少给服务器带来的压力。
合理的缓存,还会减轻程序运算时,对CPU带来的压力。在计算机现代结构中,操作内存中的数据比操作存放在硬盘上的数据是要快N个数量级的 。
例如:每次用户访问网站,都必须从数据库或者硬盘上读取网站的标题,每读一次需要15毫秒的时间,如果有100个用户(先不考虑同一时间访问),每小时访问10次,
那么就需要读取数据库或硬盘1000次,需要时间15000毫秒。如果把页面直接变成页面缓存,则每次访问就不需要去数据库读取或银盘,大大提升了网站性能。
第三方缓存工具Varnish
定义缓存池
proxy_cache_path /mnt levels=1:2 keys_zone=ny:10m;
location / {
proxy_pass http://20.0.0.132:8081;
proxy_cache ny; ##调用缓存池
proxy_cache_valid 200 10m; ##定义只缓存页面返回代码为200的页面,缓存10分钟
}
四、动静分离
Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术。动静分离技术其实是采用代理的方式,在server{}段中加入带正则匹配的location来指定匹配项针对PHP的动静分离:静态页面交给Nginx处理,动态页面交给PHP-FPM模块或Apache处理。在Nginx的配置中,是通过location配置段配合正则匹配实现静态与动态页面的不同处理方式。
server {
location ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js|html)$ {
root html;
}
location ~ \.(jsp|do|php)$ {
proxy_pass http://test;
}
}
五、URL重定向
Nginx的rewrite功能在企业里应用非常广泛,可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com。根据特殊变量、目录、客户端的信息进行URL调整等
rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持
参考官方:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。
rewrite [flag];
关键字 正则 替代内容 flag标记
关键字:关键字不能改变
正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement
flag标记:rewrite支持的flag标记
flag标记说明:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
regex 常用正则表达式说明
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“$”则匹配“$”
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
-
匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
-
匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“oll”,但不能匹配“o”
? 匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,"?“等效于”{0,1}"
. 匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式。
域名重定向举例:
server {
listen 80;
server_name abc.com;
return 444;
rewrite ^/(.*) http://www.abc.com/$1 permanent;
}
server {
listen 80;
server_name www.abc.com;
location / {
root html;
index index.html index.htm;
}
error_log logs/error_www.abc.com.log error;
access_log logs/access_www.abc.com.log main;
}
或者
server {
listen 80;
server_name abc.com;
if ( $host = ’ abc.com ’ ) {
rewrite ^/(.*) http://www.abc.com/$1 permanent;
}
}
目录重定向
server {
listen 80;
server_name www.abc.com;
location /ns {
if (!-e KaTeX parse error: Expected '}', got 'EOF' at end of input: …write ^/ns(.*) /ns1$1 last;
}
}
location /ns1 {
alias /mnt/;
index index.html index.htm;
}
}
或者
server {
listen 80;
server_name www.abc.com;
location /lzx1 {
if ( !-e $request_filename ) {
rewrite ^/(.) http://www.abc1.com/$1 redirect;
}
}
location /lzx2 {
if ( !-e $request_filename ) {
rewrite ^/(.) http://www.abc2.com/$1 redirect;
}
}
}
甚至还可以根据客户端浏览器类型进行页面重定向,将不同的浏览器访问不同的页面
if (KaTeX parse error: Expected '}', got 'EOF' at end of input: … rewrite ^/(.*) /firefox/KaTeX parse error: Expected 'EOF', got '}' at position 10: 1 break; }̲ if (http_user_agent ~ MSIE) {
rewrite ^(.)$ /msie/KaTeX parse error: Expected 'EOF', got '}' at position 10: 1 break; }̲ if (http_user_agent ~ Chrome) {
rewrite ^(.)$ /chrome/$1 break;
}
六、nginx SSL实现http加密,需要在安装nginx开启ssl模块,不然在重新加载配置文件时会报错。
举例:
为了配合测试证书自己手动生成,在生产环境下,需要去证书机构申请
进入你想创建证书和私钥的目录
cd /usr/local/nginx/conf
创建服务器私钥,命令会让你输入一个口令
openssl genrsa -des3 -out server.key 1024
创建签名请求的证书(CSR)
openssl req -new -key server.key -out server.csr
在加载SSL支持的Nginx并使用上述私钥时除去必须的口令
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
配置nginx
最后标记证书使用上述私钥和CSR
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
修改Nginx配置文件,让其包含新标记的证书和私钥
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/conf/server.crt; #添加证书路径
ssl_certificate_key /usr/local/nginx/conf/server.key; #添加私钥路径
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
七、压力测试
测试nginx的负载能力,需要借助压力测试工具。Apache服务器自带的一个web压力测试工具ApacheBench,简称ab。ab是一个命令行工具,即通过ab命令行,模拟多个请求同时对某一URL地址进行访问,因此可以用来测试目标服务器的负载压力。
也可以采用jmeter,该工具也是由apache提供
参考官方:http://www.jmeter.com.cn/2750.html
yum -y install httpd-tools
简单测试
ab -c 5000 -n 200000 http://10.0.0.131:80/index.html
-c:并发量
-n:总发量
在客户端开启
ulimit -n 20000
echo 50000 > /proc/sys/net/core/somaxconn
开启nginx监控功能
location /nginx_status {
stub_status on;
access_log off;
allow 10.0.0.0/24;
}
查看是否加载监控模块
~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module
八、优化建议
配置文件优化参考
#user nobody;
worker_processes 4; #nginx运行工作进程个数,一般设置cpu的核心或者核心数x2,
worker_cpu_affinity 0001 0010 0100 1000; #运行CPU亲和力,与worker_processes对应
worker_rlimit_nofile 65535; #Nginx最多可以打开文件数,与ulimit -n保持一致
#pid logs/nginx.pid;
events { #事件处理模型
use epoll; #nginx采用epoll事件模型,处理效率高,要根据系统类型不同选择不同的事务处理模型,选择有“use [ kqueue | rtsig |epool |dev/pool |select |pllo ];”
worker_connections 65535; #是单个worker进程允许客户端最大连接数,可以使用ulimit -n 8192进行调整,或者永久调整打开文件数 可在启动文件/etc/rc.d/rc.local末尾添加
multi_accept off; #告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on,设置为on后,多个worker按串行方式来处理连接,也就是一个连接只有一个worker被唤醒,其他的处于休眠状态,设置为off后,多个worker按并行方式来处理连接,也就是一个连接会唤醒所有的worker,直到连接分配完毕,没有取得连接的继续休眠。当你的服务器连接数不多时,开启这个参数会让负载有一定的降低,但是当服务器的吞吐量很大时,为了效率,可以关闭这个参数。
http {
include mime.types; #媒体类型,include只是一个在当前文件中包含另一个文件内容的指令
default_type application/octet-stream; #默认媒体类型,如:application/octet-stream;
#access_log logs/access.log main;
log_format main '$http_X_Real_IP $http_CLIENTIP $remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time';
sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。
tcp_nopush on; #必须在sendfile开启模式才有效,防止网路阻塞,积极的减少网络报文段的数量(将响应头和正文的开始部分一起发送,而不一个接一个的发送。)
##主要目的是保护服务器资源,CPU,内存,控制连接数,因为建立连接也是需要消耗资源的,
keepalive_timeout 60; #客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接
keepalive_requests 10240; #参数限制了一个HTTP长连接最多可以处理完成的最大请求数,默认是100。当连接处理完成的请求数达到最大请求数后,将关闭连接。
tcp_nodelay on; #也是防止网络阻塞,不过要包涵在keepalived参数才有效
client_header_buffer_size 4k; #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
open_file_cache max=102400 inactive=20s;#这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid 30s; #这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。
client_header_timeout 15; #设置请求头的超时时间。我们也可以把这个设置低些,如果超过这个时间没有发送任何数据,nginx将返回request time out的错误
client_body_timeout 15; #设置请求体的超时时间。我们也可以把这个设置低些,超过这个时间没有发送任何数据,和上面一样的错误提示
reset_timedout_connection on; #告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
send_timeout 15; #响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接
server_tokens off; #并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
client_max_body_size 10m; #上传文件大小限制
##使用gzip压缩功能,可能为我们节约带宽,加快传输速度,有更好的体验,也为我们节约成本,所以说这是一个重点。Nginx启用压缩功能需要你来ngx_http_gzip_module模块,apache使用的是mod_deflate。一般我们需要压缩的内容有:文本,js,html,css,对于图片,视频,flash什么的不压缩,同时也要注意,我们使用gzip的功能是需要消耗CPU的!
gzip on; #开启压缩功能
gzip_min_length 2k; #设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。
gzip_buffers 4 32k; #压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。
gzip_http_version 1.1; #压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可
gzip_comp_level 6; #压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。
gzip_types text/plain application/x-javascript text/css application/xml; #用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩)
gzip_vary on; #varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
server {
listen 80;
server_name localhost;
access_log /usr/local/logs/nginx/access.log main;
root html;
index index.html index.htm index.php;
#图片缓存时间
location ~* \.(ico|jpe?g|gif|png|bmp|swf|flv)$ {
expires 30d;
#log_not_found off;
access_log off;
}
#JS和CSS缓存时间
location ~* \.(js|css)$ {
expires 7d;
log_not_found off;
access_log off;
}
error_page 500 502 503 504 /50x.html;
location / {
try_files $uri $uri/ @rewrites;
}
location @rewrites {
rewrite ^ /index-development.php last;
}
location = /robots.txt {
access_log off;
log_not_found off;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
include conf.d/*;
}
cache