nginx学习笔记
nginx的工作模式
-
nginx的工作模式有两种:
- master-worker
- 单进程模式
其中mater-worker模式应用更常用。该模式一个master进程搭配多个或一个worker进程进行工作。
mater进程负责处理系统信号,加载配置,管理worker进程(启动、杀死、监控、处理信号等)。
worker进程负责具体的业务处理。
-
master-woker模式的优势:
- 稳定性高,只要还有worker进程存活,就能够提供服务,并且一个worker进程挂掉master进程会立即启动一个新的worker进程,保证worker进程数量不变,降低服务中断的概率。
- 配合linux的cpu亲和性配置,可以充分利用多核cpu的优势,提升性能
- 处理信号/配置重新加载/升级时可以做到尽可能少或者不中断服务
网络事件
- nginx(多进程)采用异步非阻塞的方式来处理网络事件,类似于Libevent(单进程单线程),具体过程如下图:
master进程先建好需要listen的socket后,然后再fork出多个woker进程,这样每个work进程都可以去accept这个socket。当一个client连接到来时,所有accept的work进程都会受到通知,但只有一个进程可以accept成功,其它的则会accept失败。Nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个work进程在accept连接,从而解决惊群问题。当一个worker进程accept这个连接后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完成的请求就结束了。
工作进程与连接数
- worker_processes 通常设置成与cpu的核心数一致;
- worker_connections 不同的设备最大连接数不一样,可以在linux的终端输入命令:ulimit -n即可得到最大的连接数。
location的匹配规则
标识符 | 描述 |
---|---|
= | **精确匹配:**用于标准uri前,要求请求字符串和uri严格匹配。如果匹配成功就停止匹配,立即执行该location里面的请求。 |
~ | **正则匹配:**用于正则uri前,表示uri里面包含正则,并且区分大小写。 |
~* | **正则匹配:**用于正则uri前,表示uri里面包含正则,不区分大小写。 |
^~ | **非正则匹配;**用于标准uri前,nginx服务器匹配到前缀最多的uri后就结束,该模式匹配成功后,不会使用正则匹配。 |
无 | **普通匹配(最长字符匹配);**与location顺序无关,是按照匹配的长短来取匹配结果。若完全匹配,就停止匹配。 |
真实ip透传
再location字段中添加4行:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
适用于日志中对user IP的分析。
fastcgi相关的设置
#用于fastcgi优化的配置项
#为fastcgi缓存制定一个文件路径、目录结果登记、关键字区域村纯实践和非活动删除时间。
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
#制定连接到fastcgi的超时时间。
fastcgi_connect_timeout 300;
#制定向fastcgi传送请求的超时时间,这个值是已经完成两次握手之后向fastcgi传送请求的超时时间。
fastcgi_send_timeout 300;
#指定接收fastcgi应答的超时时间。
fastcgi_read_timeout 300;
#用于读取fastcgi应答第一部分(应答头)需要的缓冲区大小.
fastcgi_buffer_size 64k;
#指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等。
fastcgi_buffers 4 64k;
#默认热fastcgi_buffers的两倍
fastcgi_busy_buffers_size 128k;
#表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍。
fastcgi_temp_file_write_size 128k;
#表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也会引起很多问题,要视具体情况而定。
fastcgi_cache TEST;
#用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时,将301应答缓存1天,其他应答均缓存1分钟。
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
反向代理
反向代理是nginx的最主要的功能。利用nginx可以有效的规避真是IP的泄露,同时利用nginx的优异的负载均衡、动静分离的特性实现服务器的高并发。
server_demo
server {
listen 80;#监听所有端口为80的IP请求
server_name www.123.com;#请求的地址
location / {
proxy_pass http://127.0.0.1:8080;#转发地址
index index.html index.htm index.jsp;#请求文件。
}
}
listen
- listen *:80 | *:8080 #监听所有80端口和8080端口
listen IP_address:port #监听指定的地址和端口号
listen IP_address #监听指定ip地址所有端口
listen port #监听该端口的所有IP连接
server_name
-
server_name 123.com www.123.com; #多个域名
server_name *.123.com www.123.;#通配符
server_name ~^www\d+.123.com$;#正则表达式
location用于匹配URL
proxy_pass
- 指令用于设置被代理服务器的地址。可以是主机名称、IP地址加端口号的形式。
- URL 为被代理服务器的地址,可以包含传输协议、主机名称或IP地址加端口号,URI等。
index
- 指令用于设置网站的默认首页。
- 后面的文件名称可以有多个,中间用空格隔开
负载均衡
当多个请求到来时,由负载均衡服务器负责将请求按照实现设定好的规则向Web服务器进行分发,从而增加系统整体吞吐量.
upstream web{
server 127.0.0.1:81 weight=1;
server 127.0.0.1:82 weight=1;
server 127.0.0.1:83 weight=1;
server 127.0.0.1:84 weight=1;
}
#server为负载服务器的ip:port
#weight是负载服务器设置的权重。
-
负载均衡中服务器的调度状态
-
down:当前的server暂时不参与负载均衡
-
backup:预留的备份服务器
-
max_conns:限制最大的接收的连接数
-
max_fails:允许请求失败的次数
-
fail_timeout:经过max_fails失败后,服务暂停的时间
upstream zzm { server localhost:8001 down; server localhost:8002 backup; server localhost:8003 max_fails=1 fail_timeout=10s; }
-
nginx搭配lua实现redis_pool
upstream redis_pool {
server 172.18.0.1:63791;#设置了redis的IP和port
keepalive 1024;#指定最大的长连接数
#keepalive 16;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
access_log /data/logs/host.access.log main;
default_type text/html;
lua_need_request_body on;
set $resp_body "";
#设置lua脚本
body_filter_by_lua '
local resp_body = string.sub(ngx.arg[1], 1, 1000)
ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
if ngx.arg[2] then
ngx.var.resp_body = ngx.ctx.buffered
end
';
location /lua{
lua_code_cache off;
content_by_lua_block{
ngx.say("hhello lua")
}
location /baichuan_advertisement_fetchvgop/baic_redis_get {
#default_type 'text/plain';
set $userid '';
#重新书写lua脚本
rewrite_by_lua '
local request_method = ngx.var.request_method
if "GET" == request_method then
local arg = ngx.req.get_uri_args()["userid"] or 0
ngx.var.userid = arg
elseif "POST" == request_method then
ngx.req.read_body()
local arg = ngx.req.get_post_args()["userid"] or 0
ngx.var.userid = arg
end';
redis2_query auth '123456@123';#redis的密码
#redis2_query select 14;#设置redis的数据库
redis2_query get $userid;#设置get参数
redis2_pass redis_pool;#被代理的服务
}
}