Nginx(发音为“ engine x”)是由俄罗斯软件工程师Igor Sysoev编写的免费开源Web服务器。是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。
那么Nginx可以做些什么呢?
关于反向代理,首先我们要与正向代理相区分,简单来说,正/反向代理是与代理属于客户端还是服务端有关,如代理服务器与客户端绑定则为正向代理,代理服务器与服务端绑定则为反向代理服务器,如下图所示:
关于API服务器,nginx采用模块化设计,一些第三方模块可以直接读写数据库,所以nginx可以通过安装第三方模块来操作数据库,有lua模块提供这样的操作。
OpenResty是一个基于 NGINX 的可伸缩的 Web 平台,提供了很多高质量的第三方模块。OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,在性能方面,OpenResty可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。
Nginx具备以下特点:
如果是使用Apache作为Web服务器软件,由于Apache一个进程就是创建一个对应的连接。假设您有1,000个同时连接的客户端,他们请求了类似的内容。如果每个客户端仅分配1 MB的额外内存,则将导致1000 MB(约1 GB)的额外内存专用于仅为1000个客户端提供100 KB的内容。事实上,典型的基于Apache的Web服务器通常为每个连接分配超过1 MB的额外内存,对于持久连接,处理并发性的问题更加明显,因为要避免与建立新的HTTP连接相关的延迟,客户端将保持连接状态,并且对于每个连接的客户端,Web服务器都会分配一定数量的内存。如下所示Nginx市场趋势如下:
Nginx配置文件结构目录如下图所示:
具体模块功能分工如下:
- 全局块
该部分配置主要影响Nginx全局,通常包括下面几个部分:配置运行Nginx服务器用户(组)、worker process数、Nginx进程PID存放路径、错误日志的存放路径配置文件的引入。
- events块
该部分配置主要影响Nginx服务器与用户的网络连接,主要包括:设置网络连接的序列化、是否允许同时接收多个网络连接、事件驱动模型的选择、最大连接数的配置。
- http块
定义MIMI-Type自定义服务日志、允许sendfile方式、传输文件连接超时时间、单连接请求数上限。
- server块
配置网络监听基于名称的虚拟主机配置、基于IP的虚拟主机配置。
- location块
location配置请求根目录配置、更改location的URI、网站默认首页配置。
Nginx的配置语法如下:
如示例:
配置示例:
user nobody nobody; worker_processes 3; error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid; worker_rlimit_nofile 65535;
指令格式:user user [group];
user:指定可以运行Nginx服务器的用户
group:可选项,可以运行Nginx服务器的用户组。
如果user指令不配置或者配置为user nobody nobody,则默认所有用户都可以启动Nginx进程(window下不指定)。
Nginx服务器实现并发处理服务的关键,指令格式:worker_processes number | auto;
number:Nginx进程最多可以产生的worker process数。
auto:Nginx进程将自动检测并设定worker process数。
worker_processes设置为多少,Nginx的主进程就会创建多少个worker_processes子进程,根据硬件调整,通常worker_process数等于CPU数量或者2倍于CPU。
Nginx进程是作为系统守护进程在运行,需要在某文件中保存当前运行程序的主进程号,Nginx支持该保存文件路径的自定义。
指令格式:pid file;
file:指定存放路径和文件名称如果不指定默认置于路径 logs/nginx.pid。
指定格式:error_log file | stderr;
file:日志输出到某个文件。
filestderr:日志输出到标准错误输出。
这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg。
error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info;
worker_rlimit_nofile 65535;
这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
配置示例:
use epoll; accept_mutex on; multi_accept on; worker_connections 1024; keepalive_timeout 60; client_header_buffer_size 4k; open_file_cache max=65535 inactive=60s; open_file_cache_valid 80s; open_file_cache_min_uses 1;
use epoll;
使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
补充说明:与apache相类,nginx针对不同的操作系统,有不同的事件模型。
A)标准事件模型
Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll。
B)高效事件模型
Kqueue:适用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X。使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
Epoll:适用于Linux内核2.6版本及以后的系统。
/dev/poll:适用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
Eventport:适用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
指令格式:accept_mutex on | off;
该指令默认为on状态,但在1.11.3的后续版本中默认为off。表示会对多个Nginx进程接收连接进行序列化,防止多个进程对连接的争抢。也就是防止“惊群现象”发生,就Nginx的场景来解释的话大致的意思就是:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。
所以在这里,如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态。
Changes with nginx 1.11.3 26 Jul 2016 *) Change: now the "accept_mutex" directive is turned off by default.
这个值的开关与否其实是要和具体场景挂钩的。
指令格式:multi_accept on | off;
该指令默认为off状态,意指每个worker process 一次只能接收一个新到达的网络连接。若想让每个Nginx的worker process都有能力同时接收多个网络连接,则需要开启此配置。
worker_connections 512;
每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,默认512,理论上每台nginx服务器的最大连接数为:worker_processes*worker_connections。
keepalive_timeout 60; #keepalive超时时间。 #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。 #分页大小可以用命令getconf PAGESIZE 取得。但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。 client_header_buffer_size 4k; #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache max=65535 inactive=60s; #这个是指多长时间检查一次缓存的有效信息。 open_file_cache_valid 80s; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如下例,如果有一个文件在inactive时间内一次没被使用,它将被移除。 open_file_cache_min_uses 1;
#设定mime类型,类型由mime.type文件定义 include mime.types; #指定默认文件类型,默认为text/plain。MIME-Type指的是网络资源的媒体类型,也即前端请求的资源类型include指令将mime.types文件包含进来 default_type application/octet-stream;
我们通过cat mime.types来查看mime.types文件内容,我们发现其就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名字,如下所示:
指令格式:access_log path [format],适用于HTTP全局模块、Server全局模块。
path:自定义服务日志的路径 + 名称
format:可选项,自定义服务日志的字符串格式。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; log_format log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location'; #用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径; access_log logs/access.log main; access_log logs/host.access.404.log log404;
日志格式如下所示:
$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址; $remote_user:用来记录客户端用户名称; $time_local: 用来记录访问时间与时区; $request: 用来记录请求的url与http协议; $status: 用来记录请求状态;成功是200, $body_bytes_sent :记录发送给客户端文件主体内容大小; $http_referer:用来记录从那个页面链接访问过来的; $http_user_agent:记录客户浏览器的相关信息;
注意:通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
open_file_cache max指令指定缓存是否启用,可以适用于在HTTP全局模块、server全局模块以及location模块进行使用,如下所示:
# 这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache max=65535 inactive=60s; # 语法:open_file_cache_errors on | off ,默认值:off # 配置适用模块:http, server, location,这个指令指定是否在搜索一个文件是记录cache错误。 open_file_cache_errors on #语法:open_file_cache_min_uses number 默认值:1 # 配置适用模块:http, server, location,这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态. open_file_cache_min_uses 2 # 语法:open_file_cache_valid time 默认值:60 # 配置适用模块:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息. open_file_cache_valid 30s
sendfile参数用于开启高效文件传输模式,也就是基于IO的零拷贝技术,其配置说明如下:
# sendfile指令指定nginx是否调用sendfile函数(zero copy方式)来输出文件,对于普通应用,必须设为on。 # 如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。 # 默认为off,可以在http块,server块,location块。 sendfile on | off; # size>0,则Nginx进程的每个worker process每次调用sendfile()传输的数据了最大不能超出此值;若size=0则表示不限制。默认值为0 sendfile_max_chunk size; #如100K # 在FreeBSD上使用TCP_NOPUSH套接字选项, 在Linux上使用TCP_CORK套接字选项。 在Linux和FreeBSD 4.*上将响应头和正文的开始部分一起发送;此选项仅在使用sendfile的时候使用。 tcp_nopush on; # 这个选项仅在将连接转变为长连接的时候才被启用。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞; tcp_nodelay on;
gzip模块支持在线实时压缩输出数据流,浏览器请求会告诉服务端当前浏览器支持的压缩类型,服务端会将数据根据浏览器支持的压缩类型进行压缩返回。浏览器请求时会附带支持的压缩类型,如下图所示:
配置示例及含义如下:
# 用于设置开启或者关闭gzip模块,“gzip on”表示开启GZIP压缩,实时压缩输出数据流; gzip on; # 设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大; gzip_min_length 1K # 表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果; gzip_buffers 4 16k; # 用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可; gzip_http_version 1.1; # 用来指定GZIP压缩比(1~9),1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗cpu资源; gzip_comp_level 2; # 用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的; gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
# 选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据。 gzip_vary o
效果如下所示(原始文件+效果):
upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。upstream常见参数如下:
service:反向服务地址 加端口。 weight:权重。 max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误;并认为主机已挂掉则,踢出。 fail_timeout:踢出后重新探测时间,也就是在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。 down:表示当前的server暂时不参与负载均衡; backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻; max_conns:允许最大连接数。 slow_start:当节点恢复,不立即加入,而是等待 slow_start 后加入服务对列。
注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
upstream支持以下几种负载均衡算法,配置如下所示:
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream backserver { server 192.168.0.14; server 192.168.0.15; }
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backserver { server 192.168.0.14 weight=8; server 192.168.0.15 weight=10; }
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决分布式session的问题。
upstream backserver { ip_hash; server 192.168.0.14:8888; server 192.168.0.15:8080; }
把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
upstream backserver { least_conn; #把请求转发给连接数较少的后端服务器 server localhost:8080 weight=2; server localhost:8081; server localhost:8082 backup; server localhost:8083 max_fails=3 fail_timeout=20s; }
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver { server server1; server server2; fair; }
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
server_names_hash_bucket_size 128; # 保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。 # 参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。 # 如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。 # 第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小。 client_header_buffer_size 4k; # 客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。 # 分页大小可以用命令getconf PAGESIZE取得。 large_client_header_buffers 8 128k; # 客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。 client_max_body_size 300m; # 设定通过nginx上传文件的大小。 proxy_connect_timeout 90; #后端服务器连接的超时时间_发起握手等候响应超时时间。 proxy_read_timeout 180; # 连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)。 proxy_send_timeout 180; # 后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据。 proxy_buffer_size 256k; # 设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头。 # 默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小。 proxy_buffers 4 256k; # 设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; # 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长 proxy_temp_path /data0/proxy_temp_dir; # proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; # 设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。 keepalive_timeout 120; # keepalive超时时间。 client_body_buffer_size 512k; # 如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。 # 如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。 # 无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误 proxy_intercept_errors on; # 表示使nginx阻止HTTP应答代码为400或者更高的应答。
listen 80; # listen用于指定虚拟主机的服务端口。 server_name 192.168.8.18 cszhi.com; # server_name用来指定IP地址或者域名,多个域名之间用空格分开。 index index.html index.htm index.php; # index用于设定访问的默认首页地址。 root /wwwroot/www.cszhi.com # root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。 charset gb2312; # Charset用于设置网页的默认编码格式。 access_log logs/www.ixdba.net.access.log main; # access_log用来指定此虚拟主机的访问日志存放路径,最后的main用于指定访问日志的输出格式。 error_page 404 /404.html; error_page 500 502 503 504 /50x.html; # 错误页,如果返回对应错误码则跳到对应错误页面
location URL配置块位于Server模块之内,URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。使用location URL匹配配置还可以实现反向代理,用于实现PHP动态解析或者负载负载均衡。location语法为是 location[=|~|~*|^~|@]/uri/{……} ,uri前面的方括号中的内容是可选项,解释如下:
如果根据匹配规则,多条location命中,则按照优先级进行匹配,其流程如下流程图所示:
优先级:(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
如下所示示例:
location = / { return 250; } location / { return 251; } location /documents/ { return 252; } location ~ /documents/Abc { return 253; } location ^~ /images/ { return 254; } location ~* \.(gif|jpg|jpeg)$ { return 255; } location /images/abc { return 256; } location ~ /images/abc/ { return 257; }
测试结果如下:
http://localhost/ -> return 250 http://localhost/downloads/download.html -> return 251 http://localhost/images/1.gif -> return 254 http://localhost/images/abc -> return 256 此处实验和理论结果冲突,理论上该是返回254,欢迎大家实验指正 http://localhost/images/abc/def -> return 257 此处试验和理论结果冲突,理论上该是返回254,欢迎大家实验指正 http://localhost/documents/document.html -> return 252 http://localhost/documents/1.jpg -> return 255 http://localhost/documents/Abc.jpg -> return 253
指令语法:rewrite regex replacement[flag];
应用位置:server、location、if
rewrite是实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到replacement,结尾是flag标记。
如:
location /rewrite_to_baidu { rewrite ^/ http://www.baidu.com; }
效果如下,访问http://localhost/rewrite_to_baidu,直接跳转到了http://www.baidu.com。
rewrite会用到以下语法。
注:last和break最大的不同在于,break是终止当前location的rewrite检测,而且不再进行location匹配 - last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则。
另外,还可以通过if判断进行rewrite,语法如下:
Syntax: if (condition) { ... } Default: — Context: server, location
能作为条件的内容如下:
0
”,则为false;否则为true (在1.0.1版之前,任何以“ 0
”开头的字符串都被视为错误值。)。=
”和“ !=
”运算符将变量与字符串进行比较;~
”(区分大小写的匹配)和“ ~*
”(不区分大小写的匹配)的正则表达式进行匹配。正则表达式也可以使用占位符用于以后通过$1
..$9
变量进行填充。也可使用非运算符“ !~
”和“ !~*
”。如果正则表达式包含“ }
”或“ ;
”字符,则整个表达式应用单引号或双引号引起来。-f
”和“ !-f
”运算符检查文件是否存在;-d
”和“ !-d
”运算符检查目录是否存在;-e
”和“ !-e
”运算符检查文件,目录或符号链接是否存在;-x
”和“ !-x
”运算符检查可执行文件。常见参数如下:
$args #这个变量等于请求行中的参数。 $content_length #请求头中的Content-length字段。 $content_type #请求头中的Content-Type字段。 $document_root #当前请求在root指令中指定的值。 $host #请求主机头字段,否则为服务器名称。 $http_user_agent #客户端agent信息 $http_cookie #客户端cookie信息 $limit_rate #这个变量可以限制连接速率。 $request_body_file #客户端请求主体信息的临时文件名。 $request_method #客户端请求的动作,通常为GET或POST。 $remote_addr #客户端的IP地址。 $remote_port #客户端的端口。 $remote_user #已经经过Auth Basic Module验证的用户名。 $request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。 $query_string #与$args相同。 $scheme #HTTP方法(如http,https)。 $server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 $server_addr #服务器地址,在完成一次系统调用后可以确定这个值。 $server_name #服务器名称。 $server_port #请求到达服务器的端口号。 $request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。 $uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。 $document_uri #与$uri相同。
示例:
# 多目录转成参数 abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2 if ($host ~* (.*)\.domain\.com) { set $sub_name $1; rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last; } # 目录对换 /123456/xxxx -> /xxxx?id=123456 rewrite ^/(\d+)/(.+)/ /$2?id=$1 last; # 例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下: if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /nginx-ie/$1 break; } # 目录自动加“/” if (-d $request_filename){ rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; } # 所有路径为 /images/*.png|jpg的请求都转发到/test下,try_files会依次顺序访问接下来的路径,前一个路径不存在则访问下一个。 # 如下例,要是$arg_file不存在则最后会返回"image not found exception" location / { rewrite '^/images/(.*)\.(png|jpg)$' /test?file=$1.$2; set $image_file $1; set $image_type $2; } location /test { root html; try_files /$arg_file /image404.html; } location /image404.html { return 404 "image not found exception"; }
最后一个示例如下所示:
proxy_pass主要用作代理转发,相较rewrite,proxy_pass不影响浏览器地址栏的url。在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。
假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问。 # 第一种:代理到URL:http://127.0.0.1/test.html location /proxy/ { proxy_pass http://127.0.0.1/; } # 第二种(相对于第一种,最后少一个 / ),代理到URL:http://127.0.0.1/proxy/test.html location /proxy/ { proxy_pass http://127.0.0.1; } # 第三种:代理到URL:http://127.0.0.1/aaa/test.html location /proxy/ { proxy_pass http://127.0.0.1/aaa/; } # 第四种(相对于第三种,最后少一个 / ),代理到URL:http://127.0.0.1/aaatest.html location /proxy/ { proxy_pass http://127.0.0.1/aaa; } # 另外可与负载均衡upstream进行配合使用,如下所示,会被负载到:http://30.4.4.4:9999/proxy/test.html或者http://30.4.4.5:8888/proxy/test.html upstream apptest { server 30.4.4.4:9999; server 30.4.4.5:8888; } location /proxy { proxy_pass http://apptest; proxy_set_header Host whhealth.org.cn:2005; }
Nginx的deny和allow指令是由ngx_http_access_module模块提供,Nginx安装默认内置了该模块。 除非在安装时有指定 --without-http_access_module。
语法:allow/deny address | CIDR | unix: | all
它表示,允许/拒绝某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问。注意:unix在1.5.1中新加入的功能。在nginx中,allow和deny的规则是按顺序执行的。
# 示例1:这段配置值允许192.168.0.0/24网段和127.0.0.1的请求,其他来源IP全部拒绝。 location / { allow 192.168.0.0/24; allow 127.0.0.1; deny all; } # 示例2:访问的uri中包含admin的请求,只允许110.21.33.121这个IP的请求。 location ~ "admin" { allow 110.21.33.121; deny all } # 禁止多个目录 location ~ ^/(cron|templates)/ { deny all; break; }
效果如下所示:
#第一个必选规则是直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 #这里是直接转发给后端应用服务器了,也可以是一个静态首页 location = / { proxy_pass http://tomcat:8080/index } # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项 # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } # 第三个规则就是通用规则,用来转发动态请求到后端应用服务器 # 非静态文件请求就默认是动态请求 location / { proxy_pass http://tomcat:8080/ }
我们可以通过crontab生成定时任务,定时对nginx日志进行归档。
# 列出当前用户的定时任务crontab crontab -l # 编辑crontab crontab -e # 分 时 日 月 星期 command MAILTO=“” 0 0 * * * sh /usr/local/nginx/logs/rotate.sh # 重启crontab systemctl restart crond.service # 查看crontab状态 systemctl status crond.service
编写rotate.sh脚本进行日志归档操作。
#!/bin/bash log_path="/usr/local/nginx/logs/" datetime=$(date -d "-1 day" "+%Y%m%d") mkdir -p $log_path/history mv $log_path/access.log $log_path/history/access.log_$datetime.log mv $log_path/error.log $log_path/history/error.log_$datetime.log # 像Nginx主进程发送USR1信号重新生成日志文件 kill -USE1 $(cat $log_path/nginx.pid)
正向代理,是指客户端与目标服务器之间增加一个代理服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 。这个过程当中客户端需要知道代理服务器地址,并配置连接。
# 正向代理 location = /baidu.html { proxy_pass http://www.baidu.com; }
反向代理,是指客户端访问目标服务器,在目标服务内部有一个统一接入网关将请求转发至后端真正处理 的服务器并返回结果。这个过程当中客户端不需要知道代理服务器地址,代理对客户端而言是透明的。
# 反向代理 location = /fox { proxy_pass http://127.0.0.1:8080/; }
代理相关参数
proxy_pass # 代理服务 proxy_redirect off; # 是否允许重定向 proxy_set_header Host $host; # 传 header 参数至后端服务 proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP地址 proxy_connect_timeout 90; # 连接代理服务超时时间 proxy_send_timeout 90; # 请求发送最大时间 proxy_read_timeout 90; # 读取最大时间 proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
代理缓存,获取服务器端内容进行缓存,详情可参考官网,http://nginx.org/en/docs/http/ngx_http_proxy_module.html
#proxy_cache_path 缓存路径 #levels 缓存层级及目录位数 #keys_zone 缓存区内存大小 #inactive 有效期 proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name localhost *.yuanma.com; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://backend/; proxy_cache my_cache; #以全路径md5值作为Key proxy_cache_key $host$uri$is_args$args; } }
缓存参数详细说明:
缓存清除 ,添加ngx_cache_purge模块,步骤如下:
#下载ngx_cache_purge 模块包 wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz #查看已安装模块 ./sbin/nginx -V #进入nginx安装包目录 重新构建 --add-module为模块解压的全路径 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with- http_ssl_module --with-debug --add-module=/root/ngx_cache_purge-2.3 #重新编译 make #热升级 kill -SIGUSR2 nginx的pid号
清除缓存配置如下:
location ~ /clear(/.*) { #允许访问的IP allow 192.168.3.1; #禁止访问的IP deny all; #配置清除指定缓存区和路径(与proxy_cache_key一致) proxy_cache_purge my_cache $host$1$is_args$args; }
生成自签名证书,https://www.cnblogs.com/hnxxcxg/p/7610582.html
# 使用openssl工具生成一个RSA私钥 openssl genrsa -des3 -out server.key 1024 # 生成CSR(证书签名请求) openssl req -new -key server.key -out server.csr # 删除私钥中的密码 openssl rsa -in server.key -out server.key # 生成自签名证书 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
配置https服务 : http://nginx.org/en/docs/http/configuring_https_servers.html
http { #监听本机443端口为https协议 server { listen 443 ssl; server_name localhost; ssl_certificate cert.pem; #SSL证书路径 ssl_certificate_key cert.key; #SSL证书key路径 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://localhost:8080 #将监听443的https服务转发到本机的8080 http服务 } } }