Nginx
是一个高性能的HTTP和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器
反向代理
负载均衡
HTTP服务器(包含动静分离)
正向代理
优点:
1.占有内存少,Nginx官方表示保持 10,000 个没有活动的连接,它只占 2.5M 内存
2.并发能力强,有报告表明能支持高达 50,000 个并发连接数。
3.Nginx 支持热部署。它的启动特别容易, 并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动。
4.Nginx 采用 master-slave 模型,能够充分利用 SMP 的优势,且能够减少工作进程在磁盘 I/O 的阻塞延迟。
5.高效的反向代理、负载平衡
Nginx架构:
主进程(Master): 主程序的主要目的是读取和评估配置文件以及维护工作进程Worker。
工作进程(Worker):工作进程执行请求的实际处理,提供反向代理和过滤功能。
控制Nginx:
nginx -s quit #正常关闭
nginx -s reload #重新加载配置文件
nginx -s reopen #重新打开日志文件
nginx -s stop #立即关闭
PS: 在修改了nginx的配置后必须要重新载入配置或重启nginx
Nginx作为WEB服务器
Step1 设置虚拟服务器(配置nginx.conf中的http节点)
http {
server {
listen 3000;
server_name www.test.com;
root /usr/local/redmine/public;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}
PS: 如果存在多个server节点,请求匹配规则(server_name):
a.确切的名字(完整准确的名称)
b.以星号开头的最长通配符,例如: *.example.org
c.以星号结尾的最长通配符,如:mail.*
d.第一个匹配正则表达式(按照出现在配置文件中的顺序)
PS: 如果主机头字段与服务器名称不匹配,则NGINX会将请求路由到请求到达端口的默认服务器。 默认服务器是nginx.conf文件中列出的第一个服务器(也可以通过关键字default_server指定默认服务器)
Step2 配置位置(location)
根据参数请求URI去匹配每一个location,指示虚拟服务器向一个代理服务器发送一些请求,将其他请求发送到不同的代理服务器。
server {
location /images/ {
root /data;
}
location / {
proxy_pass http://www.example.com;
}
}
location匹配时候两种方式:
第一种:前缀字符串(路径名)
第二种:正则表达式
PS: 存在多个location时的匹配规则:
a.测试所有URI的前缀字符串。
b.=(等号)修饰符定义了URI和前缀字符串完全匹配。如果找到完全匹配,则搜索停止。
c.如果^~(插入符号)修饰符预先添加最长匹配前缀字符串,则不会检查正则表达式。
d.存储最长匹配的前缀字符串。
e.根据正则表达式测试URI。
f.断开第一个匹配的正则表达式并使用相应的位置。
g.如果没有正则表达式匹配,则使用与存储的前缀字符串相对应的位置。
PS: 默认前缀字符串规则优先级高于正则表达式,可以通过^~修饰符对正则表达式给予更高的优先级。
PS: root指令指定要在其中搜索要提供的静态文件的文件系统路径。
PS: location后面配置的path在实际使用中会被拼接到root路径里:
例如:
对于上面例子的配置,要响应/images/logo.png的请求,NGINX提供服务器本地实际对应文件是:/data/images/logo.png。
Step3 返回特定状态码
可以直接在nginx.conf中配置使用http状态码:
例如:
location /wrong/url {
return 404;
}
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
Step4 重写URI请求(rewrite)
rewrite:该指令具有一个可选参数和两个必需参数。 第一个(必需)参数是请求URI必须匹配的正则表达式。 第二个参数是用于替换匹配URI的URI。 可选的第三个参数是可以停止进一步重写指令的处理或发送重定向(代码301或302)的标志。
例:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
...
}
last - 停止执行当前服务器或位置上下文中的重写指令,但是NGINX会搜索与重写的URI匹配的位置,并且应用新位置中的任何重写指令(URI可以再次更改,往下继续匹配) — 类似于for循环中的continue。
break - 像break指令一样,在当前上下文中停止处理重写指令,并取消搜索与新URI匹配的位置。新位置(location)块中的rewrite指令不执行 — 类似于for循环中的break。
Step5 重写HTTP响应
使用sub_filter指令来定义要应用的重写。 该指令支持变量和替代链,使更复杂的更改成为可能。
例:
location / {
sub_filter /blog/ /blog-staging/;
sub_filter_once off;
}
使用error_page指令,您可以配置NGINX返回自定义页面以及错误代码,替换响应中的其他错误代码,或将浏览器重定向到其他URI。
location / {
error_page 404 /404.html;
}
Nginx配置静态内容服务器
1.根目录和索引文件
root 指令指定将用于搜索文件的根目录。
try_files 指令可用于检查指定的文件或目录是否存在并进行内部重定向,如果没有指定的文件或目录,则返回特定的状态代码.
sendfile 默认情况下,NGINX会自动处理文件传输,并在发送文件之前将其复制到缓冲区中。 启用sendfile指令将消除将数据复制到缓冲区中的步骤,并允许将数据从一个文件描述符直接复制到另一个文件描述符。
tcp_nopush 与sendfile一起使用。 该选项将使NGINX能够通过sendfile获取数据块之后,在一个数据包中发送HTTP响应头
tcp_nodelay 仅用于Keepalive连接,启用Nagle的算法,可以立即发送数据。
2.动静分离
动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作。
upstream test{
server localhost:8080;
server localhost:8081;
}
server {
listen 80;
server_name localhost;
location / {
root e:/wwwroot;
index index.html;
}
# 所有静态请求都由nginx处理,存放目录为html
location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
root e:/wwwroot;
}
# 所有动态请求都转发给tomcat处理
location ~ .(jsp|do)$ {
proxy_pass http://test;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root e:/wwwroot;
}
}
Nginx反向代理
当NGINX接收请求时,它将请求发送到指定的代理服务器,获取响应,并将其发送回客户端。 真实的服务器不会直接被外部网络访问。
1.通过proxy_pass指令实现 例:
location /some/path/ {
proxy_pass http://www.example.com/;
}
匹配/some/path/的请求将会被代理到http://www.example.com/
2.传递请求标头
nginx可以设置请求头的信息,为了防止头域被传递给代理服务器,可以将其设置为空字符串:
location /some/path/ {
proxy_set_header Accept-Encoding "";
proxy_pass http://localhost:8000;
}
3.配置缓冲区
启用缓冲时,NGINX允许代理服务器快速处理响应,而NGINX存储响应时间与客户端需要下载的时间一样长。
默认情况下,它被设置为开启且缓冲已启用。
proxy_buffers 指令控制分配给请求的缓冲区的大小和数量。
例:
location /some/path/ {
proxy_buffers 16 4k;
proxy_buffer_size 2k;
proxy_pass http://localhost:8000;
}
PS: 如果缓存被禁用,则在从代理服务器接收缓冲时,响应将同步发送到客户端。
禁用缓存:
location /some/path/ {
proxy_buffering off;
proxy_pass http://localhost:8000;
}
4.选择传出IP地址
在需要选择特定的源IP地址才能连接到代理服务器或上游的情况下,可以配置绑定的ip地址.
location /app1/ {
proxy_bind 127.0.0.1;
proxy_pass http://example.com/app1/;
}
location /app2/ {
proxy_bind 127.0.0.2;
proxy_pass http://example.com/app2/;
}
Nginx正向代理
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
resolver 114.114.114.114 8.8.8.8;
server {
resolver_timeout 5s;
listen 81;
access_log e:/wwwrootproxy.access.log;
error_log e:/wwwrootproxy.error.log;
location / {
proxy_pass http://$host$request_uri;
}
}
resolver是配置正向代理的DNS服务器,listen 是正向代理的端口,配置好了就可以在ie上面或者其他代理插件上面使用服务器ip+端口号进行代理了。
Nginx压缩和解压
压缩:
server {
gzip on;
gzip_types text/plain application/xml;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1000;
...
}
解压:
location /storage/ {
gunzip on;
...
}
发送压缩文件:
location / {
gzip_static on;
}
PS:在发送压缩文件指令时,NGINX尝试查找并发送文件/path/to/file.gz。 如果文件不存在,或客户端不支持gzip,则NGINX将发送未压缩版本的文件。
PS:gzip_static指令不启用即时压缩。它只是使用压缩工具预先压缩的文件。要在运行时即时压缩内容(而不仅仅是静态内容),请使用gzip指令。
负载均衡:
将请求分摊到多个操作单元上进行执行,当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。
负载均衡模式:
1.RR(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream test {
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
2.权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream test {
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
3.ip_hash
需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
4.fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
5.url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
Nginx配置日志
1.设置错误日志(error.log)
error_log logs/error.log warn;
在这种情况下,将记录 warn, error crit, alert 和 emerg 级别的消息。
2.设置访问日志(access.log)
NGINX在访问日志中写入有关客户端请求的信息。
access_log /spool/logs/nginx-access.log
3.启用条件日志记录
条件记录允许从访问日志中排除琐碎或不重要的日志条目。
map $status $loggable {
~^[23] 0; default 1;
}
access_log /path/to/access.log combined if=$loggable;
Nginx内容缓存
当启用缓存时,NGINX将响应保存在磁盘缓存中,并使用它们来响应客户端,而不必每次都为同一内容代理请求。
1.在顶层的http上下文中包含proxy_cache_path指令。
2.在服务器响应(server)的上下文(协议类型,虚拟服务器或位置)中包含proxy_cache指令
3.默认情况下,NGINX首次从代理服务器接收到响应后,缓存对HTTP GET和HEAD方法的请求的所有响应。当Nginx接受到请求后,会比较请求中和缓存相应中的密钥(标识符),如果相同,将缓存的响应发送给客户端。
4.可以在http, server, 或 location上下文中包含各种指令,以控制哪些响应被缓存:
proxy_cache_key "$host$request_uri$cookie_user"; // 更改在计算密钥时使用的请求字符
proxy_cache_min_uses 5; //控制缓存响应之前必须进行具有相同密钥的请求的最小次数
proxy_cache_methods GET HEAD POST; //控制缓存请求方式 5.限制或绕过缓存 proxy_cache_valid 200 302 10m; //限制缓存响应与特定状态代码被认为有效的时间 proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment; //定义NGINX不会向客户端发送缓存响应的条件
proxy_no_cache $http_pragma $http_authorization; //不缓存
6.字节缓存(slice),缓存大文件时使用
location / {
slice 1m;
proxy_cache cache;
proxy_cache_key $uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 1h;
proxy_pass http://localhost:8000;
}
7.从缓存中清除内容:NGINX可以从缓存中删除过期的缓存文件。
第一步:通过设置一个配置来标识使用“PURGE” HTTP方法的请求并删除匹配的URL。
http {
...
map $request_method $purge_method {
PURGE 1;
default 0;
}
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://localhost:8002;
proxy_cache mycache;
proxy_cache_purge $purge_method;
}
}
第二步:发送清除命令
curl -X PURGE -D – "http://www.example.com/*"
PS: 可以配置限制只有一部分IP可以发送清除缓存命令:
geo $purge_allowed {
default 0; # deny from other
10.0.0.1 1; # allow from localhost
192.168.0.0/24 1; # allow from 10.0.0.0/24
}
map $request_method $purge_method {
PURGE $purge_allowed;
default 0;
}
缓存清除配置示例
http {
...
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;
map $request_method $purge_method {
PURGE 1;
default 0;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://localhost:8002;
proxy_cache mycache;
proxy_cache_purge $purge_method;
}
}
geo $purge_allowed {
default 0;
10.0.0.1 1;
192.168.0.0/24 1;
}
map $request_method $purge_method {
PURGE $purge_allowed;
default 0;
}
}
nginx缓存综合例子:
http {
...
proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 loader_files=200 max_size=200m;
server {
listen 8080;
proxy_cache one;
location / {
proxy_pass http://backend1;
}
location /some/path {
proxy_pass http://backend2;
proxy_cache_valid any 1m;
proxy_cache_min_uses 3;
proxy_cache_bypass $cookie_nocache
$arg_nocache$arg_comment;
}
}
}