美文网首页
实战Nginx

实战Nginx

作者: 巨子联盟 | 来源:发表于2018-06-30 14:56 被阅读0次

    该书代码:
    http://zyan.cc/book/nginx/code/ 360浏览器编码改成GBK
    官方文档

    grep -Ev "^$|#" conf.d/default.conf 排除空行和注释行

    • 安装
    yum -y install gcc gcc-c++ autoconf automake
    yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
    
    • DOS 命令
    nginx -s stop quit reopen reload
    
    • Nginx 信号控制
      • TERM INT 快速关闭
      • QUIT 从容关闭
      • HUP 平滑启动,重新加载配置文件
      • USR1 重新打开日志文件,在日志切割时用
      • USR2 平滑升级可执行程序
      • WINCH 从容关闭工作线程
      kill -TERM `cat nginx.pid`
      kill -QUIT `cat nginx.pid`
      kill -USR2 `cat nginx.pid`
      pkill -9 nginx
      
    • 虚拟主机
    1. 基于域名
    2. 基于IP,一个机子几个IP
    3. 基于端口
    • 日志格式可以用变量,但是有几个限制,so..方便起见还是老实一个个写吧
      access_log logs/$server_name.log combined;


      image.png
    • cut_nginx_log.sh

    #!/bin/bash
    #这个脚本必须每天00:00运行
    
    echo "start..."`date`
    #nginx的日志文件存放路径
    logs_path="/var/log/nginx"
    logs_backup_path=${logs_path}/$(date -d "yesterday" +"%Y")$(date -d "yesterday" +"%m")
    mkdir -p ${logs_backup_path}
    mv ${logs_path}/access.log ${logs_backup_path}/access_$(date -d "yesterday" +"%Y%m%d").log
    kill -USR1 `cat /var/run/nginx.pid`
    echo "over..."`date`
    
    • 下载站点
        location /zzjdownload {
            alias /home/download;
            charset utf-8,gbk;
            autoindex on ;
            autoindex_exact_size on;
            autoindex_localtime on;
    
            auth_basic "Byedbl";
            auth_basic_user_file conf.d/htpasswd ;
        }
    #printf "byedbl1:$(openssl passwd -crypt xxxx)\n" >>conf.d/htpasswd
    
    • Nginx站点状态 with-http_stub_status_module
             location /ng-status {  
                 allow xxx;
                 deny all;
                 stub_status on;  
                 access_log  off;  
            }
    
    • 获取nginx的主进程ID
      ps -ef | grep "nginx: master process" | grep -v 'grep' | awk -F ' ' '{print $2}'
    • 修改日志格式,改源码...
    log_format access '$remote_addr $time_iso8601 "$request" '
                                                  '$status $body_bytes_sent "$http_referer" '
                                                  '"$http_user_agent" "$http_x_forwarded_for"'
    
    • 跨域
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods GET,POST,PUT;
        add_header Access-Control-Allow-Headers accept,content-type,x-iamservice-appid,x-iamservice-appkey;
    
    • 本地srm配置
    #配置worker进程的用户和用户组
    #user  nobody;
    
    #worker进程启动数量
    #与CPU核心处理器数量相同
    worker_processes  2;
    
    #所有错误写入的文件,其他地方也可以单独指定
    #第二个参数值有: debug(在编译时配置了with-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;
    
    #记录主进程ID
    #pid        logs/nginx.pid;
    
    
    events {
        #单个worker_processes的并发连接的最大数
        worker_connections  1024;
    }
    
    #包含其他的配置
    #nginx -t -c ../*.conf 测试配置语法的正确性,包括include 文件
    #include /opt/local/etc/nginx/vhost/*.conf;
    
    http {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods GET,POST,PUT;
        add_header Access-Control-Allow-Headers accept,content-type,x-iamservice-appid,x-iamservice-appkey;
        include       mime.types;
        default_type  application/octet-stream;
    
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
        
        #直接复制数据从一个到另一个文件描述符
        sendfile        on;
        
        #设置一个sendfile在拷贝中的最大数据大小
        #sendfile_max_chunk 
        
        #仅依赖sendfile使用,能够使得Nginx在一个数据包中尝试发送响应头,以及在一个数据包中发送一个完整文件
        #tcp_nopush     on;
    
        #启用或禁用 TCP_NODELAY 选项,用于keep-alive连接
        #tcp_nodelay on ;
        
        #指定keep-alive连接连续多久
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        
        #指定server_name 哈希表的最大大小
        server_names_hash_max_size 1024;
        
        gzip  on;
    
        #这段的作用是丢弃这种缺乏Host头的请求
        server {
            listen 80;
            
            error_page  444              error/404.html;
            return 444;
            
            location / {
                #当502或504时,将请求转发到负载均衡中正常server中
                #proxy_next_upstream http_502 http_504 error timeout invalid_header;
                proxy_connect_timeout   10;  
                proxy_send_timeout      3000;  
                proxy_read_timeout      3000;           
                proxy_pass http://srm_portal_server;  
                proxy_redirect    off;
                #若nginx为最前端时,后端获得X-Real-IP传递的ip即为实际ip,若nginx不是最前端时,实际ip为X-Forwarded-For值。
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header        X-Real-IP       $remote_addr;  
                proxy_set_header Host  $host:8096;
                proxy_pass_request_headers              on;
                index  index.html;
            }
        }
           upstream srm_portal_server{  
                server 127.0.0.1:8096;    
           }
           
        #虚拟服务器部分,根据server_name逻辑分割的资源
        server {
            listen       8097;
            #配置可接受通配符,如:*.example.com .example.com(将匹配*.example.com和example.com本身)
            #server_ name ~^ www\. example\. com$; 可用正则表达式
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            #location = / {
            #    #root   html;
            #   root test;
            #
            #    #index  index.html index.htm;
            #   index  index/html/index.html;
            #}
            
            error_page  404              error/404.html;
    
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  error/50x.html;
            location = /50x.html {
                root   html;
            }
            location = /404.html {
                root   html;
            }
            #静态文件交给nginx处理
            location ~ .*\.(js|css||gif|jpg|jpeg|png|bmp|swf|ioc|flv|woff|woff2|ttf|map)$
            #location ~/static/.*
            {
                proxy_connect_timeout   10;  
                proxy_send_timeout      3000;  
                proxy_read_timeout      3000;           
                proxy_pass http://10.100.21.114:80;  
                proxy_redirect    off;
                #若nginx为最前端时,后端获得X-Real-IP传递的ip即为实际ip,若nginx不是最前端时,实际ip为X-Forwarded-For值。
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header        X-Real-IP       $remote_addr;  
                proxy_pass_request_headers              on;     
                    #root D:\\mytask\\SRM\\res;
                    #expires   30d;
            }
    
    
            location /static/
            {
    
                proxy_connect_timeout   10;  
                proxy_send_timeout      3000;  
                proxy_read_timeout      3000;           
                proxy_pass http://10.100.21.114:80;  
                proxy_redirect    off;
                #若nginx为最前端时,后端获得X-Real-IP传递的ip即为实际ip,若nginx不是最前端时,实际ip为X-Forwarded-For值。
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header        X-Real-IP       $remote_addr;  
                proxy_pass_request_headers              on;         
                    #root D:\\mytask\\SRM\\res;
            }
            
            location ~ .*\.html$
            {
                proxy_connect_timeout   10;  
                proxy_send_timeout      3000;  
                proxy_read_timeout      3000;           
                proxy_pass http://10.100.21.114:80;  
                proxy_redirect    off;
                #若nginx为最前端时,后端获得X-Real-IP传递的ip即为实际ip,若nginx不是最前端时,实际ip为X-Forwarded-For值。
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header        X-Real-IP       $remote_addr;  
                proxy_pass_request_headers              on;         
                    #root D:\\mytask\SRM\\res\\index;
                    #expires   30d;
            }   
            
            #location ~ .*\.html$
            #{
            #        root D:\mytask\SRM\res\index;
            #        expires   30d;
            #}                      
            
            location / {
                #当502或504时,将请求转发到负载均衡中正常server中
                #proxy_next_upstream http_502 http_504 error timeout invalid_header;
                proxy_connect_timeout   10;  
                proxy_send_timeout      3000;  
                proxy_read_timeout      3000;           
                proxy_pass http://srm_portal_server;  
                proxy_redirect    off;
                #若nginx为最前端时,后端获得X-Real-IP传递的ip即为实际ip,若nginx不是最前端时,实际ip为X-Forwarded-For值。
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header        X-Real-IP       $remote_addr;  
                proxy_set_header Host  $host:8096;
                proxy_pass_request_headers              on;
                index  index.html;
            }
            
        }
    
    
    
    }
    
    
    • 反向代理:多个网络用户从Internet访问内网的固定服务器

    • 正向代理:内网用户通过代理服务器访问多个Internet站点

    • WEB负载均衡方法

    1. 下载页提供不同的站点
    2. DNS轮询,添加二级域名和A记录
    C:\Users\zengzhijun.QK>nslookup www.baidu.com
    服务器:  qkdc1.qk.qiku.com
    Address:  xxx
    
    非权威应答:
    名称:    www.a.shifen.com
    Addresses:  14.215.177.38
              14.215.177.39
    Aliases:  www.baidu.com
    
    
    C:\Users\zengzhijun.QK>nslookup www.taobao.com
    服务器:  qkdc1.qk.qiku.com
    Address:  xxx
    
    非权威应答:
    名称:    www.taobao.com.danuoyi.tbcache.com
    Address:  220.170.91.114
    Aliases:  www.taobao.com
    
    

    Linux用dig命令

    yum install -y bind-utils 
    [root@iZwz9j1m4fpjustyk6ar1iZ nginx]# dig www.baidu.com
    
    ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> www.baidu.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47626
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;www.baidu.com.         IN  A
    
    ;; ANSWER SECTION:
    www.baidu.com.      672 IN  CNAME   www.a.shifen.com.
    www.a.shifen.com.   41  IN  A   220.181.111.188
    www.a.shifen.com.   41  IN  A   220.181.112.244
    
    ;; Query time: 5 msec
    ;; SERVER: 100.100.2.138#53(100.100.2.138)
    ;; WHEN: Thu Jun 21 15:57:21 CST 2018
    ;; MSG SIZE  rcvd: 90
    
    

    百度有两条A记录
    该方法不好,负载不均衡,可靠性不高,缓存生效时间不定.

    1. 四/七层负载均衡设备,F5(硬件) LVS(软件4层) Nginx,HAProxy(软件7层)
      物理层->数据链路层->网络层->传输层->会话层->表示层->应用层

    2数据链路层: 保证了数据在不可靠的物理线路上进行可靠的传递
    3网络层,IP,路由,地址协议解析(ARP)
    4传输层:TCP,UDP,该层起到缓冲的作用,为会话层提供可靠保障
    5会话层:保持会话同步,决定通信是否中断,中断时决定从何处重传
    6表示层:加解密,解码和编码
    7应用层:Telnet,FTP,HTTP,为操作系统和网络应用程序提供网络服务的接口

    • 配置
     upstream php_server_pool {
      ip_hash;
       server   192.168.1.10:80 weight=4 max_fails=2 fail_timeout=30s;
       server   192.168.1.14:3245 down;
       server   192.168.1.14:3245 backup;
    }
    

    location
    proxy_next_upstream http_502 http_504 error timeout invalid_header;

    • 日志中可以用的几个配置
    $upstream_status upstream 服务器的应答状态;
    $upstream_addr 处理请求upstream服务器地址;
    $upstream_response_time Upstream服务器响应时间,多个以冒号和逗号分隔;
    $upstream_http_$HEADER 任意HTTP协议头,如:$upstream_http_host;
    
    • Nginx负载均衡服务器的双机高可用


      image.png

      见实战Nginx摘录-文档 nginx_ha2.sh脚本

    • 正则表达式网站

    • Nginx rewrite
    rewrite ^/b/(.*)\.html /play?v=$1 break;
    if (! -f $request_filename)
    {
     rewrite ^/img/(.*)$ /site/$host/images/$1 last;
    }
    
    • break:

    使用环境:server location if
    作用:完成当前的规则集,不再处理rewrite指令

    if ($slow) {
        limit_rate 10k;
        break;
    }
    
    • if:
      使用环境: server location
      作用: 用于检查条件是否符合,不支持多个条件 && 和 || 处理


      image.png
    if($http_user_agent ~ MSIE){
        rewrite ^(.*)$ /msie/$1 break;
    }
    
    if( $request_method = POST ) {
      return 405;
    }
    
    if( $http_cookie ~* "id=([^;]+)(?:;|$)" ){
      set $id $1;
    }
    
    if( !-f $request_filename){
      break;
      proxy_pass http://127.0.0.1;
    }
    
    if ($slow) {
        limit_rate 10k;
        break;
    }
    
    if( $arg ^~ post=140){
      rewrite ^ http://127.0.0.1;
    }
    
    • rewrite指令 ,根据配置文件的顺序来执行
      语法:rewrite regex replacement flag[last,break,redirect 302,permanent 301]
      使用环境:server location if
    if ( $host ~* www\.(.*)) {
        set $host_without_www $1;
        rewrite ^(.*)$ http://$host_without_www$1 permanent;
    }
    

    alias --> last last注意死循环问题
    proxy_pass --> break


    image.png

    在跟location中和server中推荐用last,在非根的location中推荐用break;

    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    /photos/12345 重定向到 /path/to/photos/12/1234/12345.png
    rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})"  /path/to/photos/$1/$1$2/$1$2$3.png;
    
    • set指令 赋值
      使用环境:server location if
      set $varname hello

    • rewrite能用的变量

    $args : #这个变量等于请求行中的参数,同$query_string
    $content_length : 请求头中的Content-length字段。
    $content_type : 请求头中的Content-Type字段。
    $document_root : 当前请求在root指令中指定的值。
    $host : 请求主机头字段,否则为服务器名称。
    $http_user_agent : 客户端agent信息
    $http_cookie : 客户端cookie信息
    $limit_rate : 这个变量可以限制连接速率。
    $request_method : 客户端请求的动作,通常为GET或POST。
    $remote_addr : 客户端的IP地址。
    $remote_port : 客户端的端口。
    $remote_user : 已经经过Auth Basic Module验证的用户名。
    $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
    $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相同
    

    PCRE正则表达式语法

    image.png
    image.png
    • 实例
    #文件和目录不存在时跳转首页
    if ( !-e $request_filename){
        rewrite ^/(.*)$ /index.html last;
    }
    #多目录转成参数
    if ($host ~* (.*)\.domain\.com){
        set $sub_name $1;
        rewrite ^/sort\/(\d+)\/?$ /index.do?act=sort&cid=$sub_name&id=$1 last;
    }
    #禁止访问多个目录
    location ~* ^/(cron|tempalte)/ {
            deny all;
            break;
    }
    #禁止访问以/data开头的文件,可以放到location里面,会直接跳首页
    location ~* ^/data {
        deny all;
    }
    #设置某些文件的浏览器过期时间
    location ~ .*\.(js|css)?$
    {
        expires 1h;
    }
    
    #将多级目录下的文件转换成一个文件 /job-123-456-789.html 指向 /job/123/456/789.html
    #注意与跳首页的先后顺序,放外面就直接跳首页了,放里面要放到下面的规则里
            location ~ .*\.html$
            {
                    rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /$1/$2/jobshow_$3.html last;
                    if ( !-e $request_filename){
                           rewrite ^/(.*)$ /index.html last;
                    }
    
                    root /usr/share/nginx/html;
                    location ~ ^/data {
                            deny all;
                    }
    
            }
    
    #允许指定的域名访问本站,其他域名一律跳转 http://www.bbb.com
    if ($host ~* ^(.*)?\.aaa\.com$){
        set $var '1';
    }
    if ($host ~* ^192\.168\.1\.(.*?)$){
        set $var '1';
    }
    if ($host ~* ^localhost){
        set $var '1';
    }
    if ($var !~ '1'){
        rewrite ^/(.*)$ http://www.bbb.com redirect;
    }
    #跳转到其他网站,或者没有输入www点的跳有www点的
    server
    {
            listen 80;
            server_name www.byedbl2.com;
            rewrite ^/(.*)$ http://www.byedbl.com/ permanent;
            access_log /var/log/nginx/access_1.log  main;
    }
    #静态文件的代理
       location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|html|shtml)$
       {
             proxy_cache cache_one;
             proxy_cache_valid  200 10m;
             proxy_cache_valid  304 1m;
             proxy_cache_valid  301 302 1h;
             proxy_cache_valid  any 1m;
             proxy_cache_key $host$uri$is_args$args;
             proxy_set_header Host  $host;
             proxy_set_header X-Forwarded-For  $remote_addr;
             proxy_pass http://bbs_server_pool;
       }
    #限制下载速度
       location /
       {
             #限制下载速度为256kB/秒
             limit_rate  256k;
             proxy_pass http://xx.xx.xx.19;
             proxy_set_header Host  $host;
             proxy_set_header X-Forwarded-For  $remote_addr;
       }
    #播放视频
    server
    {
     listen 80;
     server_name flv.byedbl.com ;
     index index.html index.htm;
     root /usr/share/nginx/html/flv;
     #30M之后开始限速
     limit_rate_after 30m;
     limit_rate 512k;
     
     location ~ \.flv
     {
        flv;
     }
    }
    

    很详细的配置

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
    codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" height="120" width="190"> 
    <param name="movie" 
    value="http://www.byedbl.com/static/vcastr22.swf?vcastr_file=http://flv.byedbl.com/1.flv"> 
    <param name="quality" value="high"> 
    <param name="allowFullScreen" value="true" /> 
    <embed 
    src="http://www.byedbl.com/static/vcastr22.swf?vcastr_file=http://flv.byedbl.com/1.flv" 
    quality="high" 
    pluginspage="http://www.macromedia.com/go/getflashplayer" 
    type="application/x-shockwave-flash" width="820" height="840"> 
    </embed> 
    </object> 
    

    Yamdi下载地址

    • 正向代理服务器
    server
    {
     listen 80;
     location / {
        #DNS解析服务器的IP地址
        resolver 8.8.8.8;
        proxy_pass http://$host$request_uri;
     }
     access_log /var/log/access_log.log
     
    } 
    
    • 关闭日志
    location = /robots.txt {
        log_not_found off;
    }
    location = /favicon.ico{
        log_not_found off;
    }
    
    • try_files 用法
    # try_files 用法,按照顺序一路找存在的,必须要有个存在,不然会报错
    location / {
        try_files /system/maintenance.html $uri $uri/index.html $uri.html @byedbl_proxy
    }
    
    location @byedbl_proxy {
        proxy_pass http://www.byedbl.com;
    }
            location /api/ {
                    try_files /system/maintenance.html $uri $uri/index.html $uri.html @byedbl_proxy;
                    #proxy_pass http://www.byedbl.com;
                    #root /usr/share/nginx/html/system;
    
            }
    
    • CPU亲和力设置
    worker_processes 2;
    worker_cpu_affinity 01 10;
    
    • 记录请求内容,用于调试的时候用
    #记录客户端发过来的POST请求内容
    client_body_in_file_only on;
    #指定缓存文件的路径,最多3层子目录,1 2 表示第一层为1个数字,第二层为2个数字
    client_body_temp_path /var/cache/path 1 2 ;
    

    例子:

    [root@localhost client_temp]# more 0000000001 
    ----------------------------055840557212412661906914
    Content-Disposition: form-data; name="name"
    
    zzj
    ----------------------------055840557212412661906914
    Content-Disposition: form-data; name="age"
    
    18
    ----------------------------055840557212412661906914--
    
    
    • 限制HTTP方法,白名单
    limit_except GET {
        allow 192.168.1.0/32;
        deny all;
    }
    
    • 监听两个端口,注意Dockerfile和docker-compose文件要放端口出来
        listen      80;
        listen      8080;
        listen       443 default ssl;
    
    • basic认证
            auth_basic "Byedbl";
            auth_basic_user_file conf.d/htpasswd ;
    
    printf "byedbl1:$(openssl passwd -crypt xxxx)\n" >>conf.d/htpasswd
    

    相关文章

      网友评论

          本文标题:实战Nginx

          本文链接:https://www.haomeiwen.com/subject/cymneftx.html