Nginx基础

1.nginx请求处理架构

1. Nginx处理连接架构图

image_1c0kt9gqn15441u4qnblqla1c9f9.png-227.8kB

Master

  • 读取配置文件和重新读取配置(reload)
  • 打开和重新打开日志文件
  • 创建监听套接字
  • 启动和重新启动worker进程
  • 向worker发信号(管理worker)

Worker

  • 连接并处理请求
  • 运行在事件模型下可同时处理多个请求

2.Nginx集群架构图

image_1c0ktjqp41f01up9qd91odm8tjm.png-255.6kB

3.相关配置

1.生产配置

user www-data;
worker_processes 8;                 #process进程8个

#worker和CPU亲和力绑定设置
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_rlimit_nofile 32768;         #单个worker打开的文件描述符最大数量

events {
        worker_connections 2048;    #每个worker同时最多处理2048个请求
        use epoll;                  #使用epoll事件处理模型
        multi_accept on;
}

2.关于亲和力的设置

生产环境绑定8个已经差不多了,再上去好像性能没提高

00000001    第一颗CPU0,从右往左数1在第几位就是第几个CPU
00000010    第二颗CPU1

#例子1-4个worker
#第一个worker用第一颗CPU0,第二个用第二颗,以此类推
worker_processes    4;
worker_cpu_affinity 0001 0010 0100 1000;

#例子2-一个worker可以绑定多个CPU
#第一个worker使用CPU0/CPU2,第二个worker使用CPU1/CPU3
worker_processes    2;
worker_cpu_affinity 0101 1010;


#1.9.10以后的版本支持自动绑定
worker_processes auto;
worker_cpu_affinity auto;

3.处理能力计算

并发量=worker数量*worker_connectinos

2.nginx服务管理

1.nginx信号

1.信号

信号 功能
TERM, INT 快速关闭
QUIT 优雅关闭
HUP 重新读取配置文件
USR1 重新打开日志文件
USR2 二进制包升级
WINCH 优雅关闭worker进程

2.如何发信号

nginx由master接受信号,因此要找到master的pid然后才能发信号

ps -ef|grep nginx|grep master
root       558     1  0 11月28 ?      00:00:00 nginx: master process /usr/sbin/nginx

2.信号使用示例

1.快速关闭-直接中断现有所有服务套接字

2.优雅关闭-关闭套接字监听但是会保留现在服务的,等所有目前链接都关闭时候才关闭nginx

3.重新读取配置-重新读取配置文件

4.重新打开日志文件-可用于日志切割

使用logrotate管理日志,这个工具就是管理日志自动切分

/var/log/nginx/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    
    postrotate
    [ -f /var/run/nginx.pid ] && kill -USR1 `cat
        /var/run/nginx.pid`
    endscript
}

5.升级

mv /usr/sbin/nginx /usr/sbin/nginx.old
mv objs/nginx /usr/sbin/nginx
kill -USR2 12995        #master进程号

3.nginx配置

优化

1.TCP优化

1.配置

http {
        server { 
                listen 80 default; 
                server_name _; 
                return 404; 
        }        
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        access_log off;
        error_log /var/log/nginx/error.log;
        gzip on;
        gzip_disable "msie6";

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
        client_max_body_size 30M;
}

2.sendfile

#默认发送数据流程
硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈

#开通senfile后
硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈

3.tcp_nopush只有打开sendfile的时候才生效

也就是说tcp_nopush = on 会设置调用tcp_cork方法,这个也是默认的,结果就是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞。

4.tcp_nodelay=on关闭

如果开启tcp-delay就是小数据包组成大的数据包的时候才发送,解决网络拥塞但是用户体验不好
打开nodelay就是说有小的数据包就发送

2.压缩优化

1.配置

gzip               on;
gzip_disable       "msie6";
gzip_http_version  1.0;
gzip_types         text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
  • gzip_disable 指令接受一个正则表达式,当请求头中的 UserAgent 字段满足这个正则时,响应不会启用 GZip,这是为了解决在某些浏览器启用 GZip 带来的问题。特别地,指令值 msie6 等价于 MSIE [4-6].,但性能更好一些。另外,Nginx 0.8.11 后,msie6 并不会匹配 UA 包含 SV1 的 IE6(例如 Windows XP SP2 上的 IE6),因为这个版本的 IE6 已经修复了关于 GZip 的若干 Bug。

  • 默认 Nginx 只会针对 HTTP/1.1 及以上的请求才会启用 GZip,因为部分早期的 HTTP/1.0 客户端在处理 GZip 时有 Bug。现在基本上可以忽略这种情况,于是可以指定 gzip_http_version 1.0 来针对 HTTP/1.0 及以上的请求开启 GZip。

4.nginx反向代理和缓存配置

1.反向代理配置实例

1.格式

location /example {
    proxy_pass http://upstream_server_name;
}

2.示例

location /download {
    proxy_pass http://192.168.0.1/media;
}

http://ip/download/a.png
http://192.168.0.1/media/a.png
ip/download==>http://192.168.0.1/media


location ~* ^/(index|content|sitemap)\.html$ {
    proxy_pass http://192.168.0.1/html/$1;
}

2.配置缓存

配置nginx缓存

proxy_cache_path  /data/nginx/cache/proj1  levels=1:2   keys_zone=proj1:10m max_size=10g;
#指定路径
#levels指定缓存目录层级
#定义名称proj1,大小10M
#最大10G

proxy_cache_key  "$request_uri";
#设置缓存使用的key
 
server {
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header  Host "www.test.com";
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        
        #开启反向代理缓存,
        proxy_cache proj1;
        #设置状态码为200 302过期时间为10分钟
        proxy_cache_valid  200 302  10m;
        #设置状态码404的过期时间为1分钟
        proxy_cache_valid  404      1m;
    }
    #清除缓存
    location ~ /purge(/.*) {
        #允许的IP
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge proj1 $host$1$is_args$args;
    }
}

5.管理nginx流量

1.入方向流量管理

1. 限制请求速率

参考
1.配置例子

http {
    limit_req_zone $binary_remote_addr zone=rate_limit1:12m rate=30r/m;
    #limit_req_zone 地址作为存储状态的key zone=名字:存储状态空间大小 rate=速率;
}
location / {
    limit_req zone=rate_limit1;     #调用已经定义的规则
}

2.木桶原理
image_1c0lk8h571ph214u6a6i7n41a9i9.png-42.6kB

  • 木桶的大小为12M作为存储状态(k-v结构),key自己定义
  • rate定义木桶流出的速度是恒定的30r/m(2秒一个请求)
  • 如果进来请求过多木桶放不下就会溢出,溢出的返回503

2.限制同时连接数

http {
    #定义名字为limit1的连接限制
    #状态信息空间为10M
    #以请求的地址为key(针对请求地址限制)
    
	limit_conn_zone $binary_remote_addr zone=limit1:10m;
	server {
		location  ^~ /download/ {  
		    #调用limit1规则
		    #每个IP同时最大连接数为4
			limit_conn limit1 4;
        }
	}
}

3. 限制传输速率

location /download {
    #限制每个请求最大传输速率为100k
    #针对每个请求,客户端同时打开多个请求带宽叠加
    limit_rate 100k;
    #从500k后才开始限制传输速度
    limit_rate_after 500k;
}

2.管理出口流量

1.多服务器之间分发出方向连接
2.配置后端服务器
3.配置长连接
4.限制从后端服务器读取时的传输速率

1.定义upstream服务器

upstream tomcats {
    server 192.168.1.1;
    server myserver.com;
}

2.调用后端服务器

http {
    upstream tomcats {
        server 192.168.1.1;
        server myserver.com;
    }

    server {
        listen 80;
        location / {
            proxy_pass http://tomcats;
        }
    }
}

3.负载均衡算法

1.默认是轮询,根据权重
2.ip_hash(相同地址的请求发送到一台主机)

upstream my-cluster {
    ip_hash;
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

3.根据cookie做hash

upstream my-cluster {
    hash "$cookie_uid";
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

4.组合变量hash

upstream my-cluster {
    hash "$remore_addr$http_user_agent";
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

4.备份服务器(CDN)

1.CDN架构图
image_1c0naho511lc516cn1igd1k2414prm.png-312.7kB

2.配置

upstream my-cache {
    server cache1.mycdn.com;
    server cache2.mycdn.com;
    server cache3.mycdn.com;
    server content1.mycdn.com backup;
    server content2.mycdn.com backup;
}

3.说明

默认会从cache服务器取返回内容,如果没有才会向cdn服务器请求

5.判断后端服务器是否可达

1.配置

upstream cgi-bin{
	server 10.123.45.78:8080 weight=1 max_fails=2 fail_timeout=10s; 
	server 10.123.45.79:8080 weight=1 max_fails=2 fail_timeout=10s; 
}
location /cgi-bin {
    proxy_connect_timeout 10s;
    proxy_read_timeout 10s;
	proxy_next_upstream http_404 http_500 http_502 http_503 http_504 error timeout invalid_header;
	proxy_pass http://cgi-bin;	
}

2.proxy_next_upstream指令

满足该指令定义的状态(服务器异常)则转发到下一台服务器

6.使用长连接

http无状态及cookie、session

1.长连接和短连接的区别

http协议无状态,每次请求是单独的,也就是说如果一个网页有各种图片资源在端连接的情况下客户端和服务器每传输一个资源就需要建立一次TCP连接,开销很大,有了长连接就可以复用之前建立的TCP通道。

短连接的操作步骤是:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输…(保持连接)…数据传输——关闭连接

2.http各个版本特点

http-1.0使用短连接,可以在请求头加Connection: Keep-Alive
http-1.1使用长连接
http-2.0长连接,同时加载资源异步(nginx-1.9.5支持http2.0)

3.配置

与后端服务器设置版本为1.1支持长连接,同事Connection字段为空

upstream my-cluster {
    keepalive 5;                    #设置时间
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

location @proxy {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

4.注意

长连接时长需要根据业务相关特性决定,不恰当的长连接可能会导致nginx服务器有大量的time_wait

7.限制到后端服务器的传输速率

location @proxy {
    proxy_pass http://backend;
    proxy_buffering on;
    proxy_limit_rate 200k;
}
posted @ 2017-12-07 14:09  西南运维  阅读(116)  评论(0)    收藏  举报