#user  nobody;

#启动进程,通常设置成和cpu的数量相等
worker_processes  4;

#全局错误日志及PID文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#默认pid的保存位置如下,可更改
#pid        logs/nginx.pid;

#工作模式及连接数上限
events {
    #epoll是多路复用IO(I/O Multiplexing)中的一种方式,
    #仅用于linux2.6以上内核,可以大大提高nginx的性能
    #use   epoll;

    #单个worker process进程的最大并发链接数
    worker_connections  1024;

    # 并发总数是 worker_processes 和 worker_connections 的乘积
    # 即 max_clients = worker_processes * worker_connections
    # 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4  为什么
    # 为什么上面反向代理要除以4,应该说是一个经验值
    # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
    # worker_connections 值的设置跟物理内存大小有关
    # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
    # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
    # 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
    # $ cat /proc/sys/fs/file-max
    # 输出 34336
    # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
    # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
    # 使得并发总数小于操作系统可以打开的最大文件数目
    # 其实质也就是根据主机的物理CPU和内存进行配置
    # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
    # ulimit -SHn 65535
}

http {
    #设定mime类型,类型由mime.type文件定义
    include       mime.types;
    #默认的传输文件方式
    default_type  application/octet-stream;

    #设定名称为main的日志格式取代默认的combined格式,$time_iso8601(标准格式2017-01-19T09:10:52+08:00)。
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access日志位置和格式, 需要增加http_x_forwarded_for的显示,日志需要定时移除或改名,不支持按天分文件
    access_log  logs/access.log  main;
    #缓冲,避免每次都关闭打开日志文件
    open_log_file_cache max=1000 inactive=60s valid=60s min_uses=2;

    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
    #对于普通应用,必须设为 on,
    #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
    #以平衡磁盘与网络I/O处理速度,降低系统的uptime.
    sendfile        on;
    #激活tcp_nopush参数可以允许把httpresponse header和文件的开始放在一个文件里发布,积极的作用是减少网络报文段的数量
    tcp_nopush     on;

    #长连接超时时间,默认是75s
    keepalive_timeout  60s;
    #激活tcp_nodelay,内核会等待将更多的字节组成一个数据包,从而提高I/O性能
    tcp_nodelay on;

    #开启gzip压缩
    gzip  on;
    #IE6及以下版本性能太差,不压缩
    gzip_disable "MSIE [1-6].";
    gzip_min_length 1000;
    gzip_buffers   4 16k;
    gzip_types    text/plain application/x-javascript text/css;

    #设定请求缓冲
    client_header_buffer_size    128k;
    large_client_header_buffers  4 128k;

    #禁止嵌套访问
    add_header X-Frame-Options SAMEORIGIN;
    #设置httponly
    add_header Set-Cookie "HttpOnly=true; max-age=1800";

    #限制每个IP只能访问60次/分钟,以及白名单,同时需在location中开启代码
    limit_req_zone $binary_remote_addr zone=allips:10m rate=60r/m;
    geo $limited{
        default 1;
        #My IPs
        127.0.0.1/32 0;
        192.168.0.0/32 0;
    }
    
    upstream mywebapp {
        #ip_hash负载,如果没加这条指令,nginx会使用默认的round robin负载均衡(指定weight比重)
        #ip_hash;
        #max_fails表示超时重试的最大次数,当在fail_timeout时间段内重试次数达到上限则标记服务器不可用,将在fail_timeout后取消标记并重新尝试计数。此处超时计算依赖请求的超时时间,即nginx到后端server的请求超时时间设置见server的location /部分
        server 127.0.0.1:8888 weight=1 max_fails=1 fail_timeout=30s;
        #server 127.0.0.1:7001 weight=1 max_fails=1 fail_timeout=30s;
    }

    #设定虚拟主机配置,第一个主机为默认主机
    #设置默认server防御host头攻击
    server {
        listen       8100  default_server;
        server_name _;
        location / {
            return 403;
        }
    }
    server {
        #访问端口
        listen       8100;
        server_name  192.168.11.150;    #此处必须是用户浏览器内输入的IP或域名
        #定义服务器的默认网站根目录位置,可相对/绝对地址,指定了静态文件的存放位置,千万不要写成\
        #root  D:/bea12/user_projects/domains/base_domain/autodeploy/DefaultWebApp;
        root  D:/java/tomcat-9.0.10/webapps/root;

        #charset koi8-r;
        
        #禁止Scrapy等工具的抓取,HttpClient仍可用
        if ($http_user_agent ~* (Scrapy|Curl)) {
            return 403;
        }
        #禁止指定UA及UA为空的访问,会导致一些使用接口没法访问了,因此需要仔细分别
        #if ($http_user_agent ~* "WinHttp|WebZIP|FetchURL|node-superagent|java/|FeedDemon|Jullo|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|Java|Feedly|Apache-HttpAsyncClient|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|^$" ) {
        #     return 403;
        #}
        #屏蔽GET|POST|OPTIONS之外的请求方式:delete put trace,貌似trace默认就是返回405
        if ($request_method !~* GET|POST|OPTIONS) {
            return 403;
        }
        
        #location匹配规则:=最先,^~次之,然后按配置出现顺序(建议按请求频率确定顺序),最后是/根通配
        #默认请求策略
        location / {
            #使用限制器,每秒最多30个请求
            limit_req zone=allips burst=30 nodelay;
            proxy_pass http://mywebapp;
            #proxy_redirect  off;   
            proxy_set_header        Host    $http_host;   
            proxy_set_header        X-Real-IP       $remote_addr;   
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

            #proxy_set_header   Cookie $http_cookie;
            #nginx与server的连接超时时间(与server线程是否阻塞无关,不是等待后端返回页面的时间),默认值是60s,不能超过75s
            proxy_connect_timeout       3;
            #nginx发送请求给server的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间,默认值是60s
            #proxy_send_timeout       60s
            #nginx会等待多长时间来获得server的响应,这个时间不是获得整个response的时间,而是两次reading操作的时间
            #(与server线程是否阻塞有关,应根据server是否有大时长运算调整,同时也要增加keepalive_timeout的时间),默认值是60s
            #proxy_read_timeout       60s;

            #设置off避免编码转换出现不对的情况
            chunked_transfer_encoding       off;
            #让cookies写在根目录下,这样才不会丢失,如果出现cookies丢失的话
            #proxy_cookie_path /examples/ /;
        }

        #给icon图标响应空白图片,避免读硬盘并记录日志
        location ~ /(favicon.ico|apple-touch-icon.png|apple-touch-icon-precomposed.png)$ {
            empty_gif;
            access_log off;
        }

        #静态文件缓存,必须设置正确的root,不记录access日志,另外如果静态文件是在其他服务器,应使用反向代理并缓存(见后:location ~ \.php$)
        #如果使用了模板引擎等,不要把html\htm设置为静态缓存,否则可以
        location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|json|css|swf|zip|rar|7z|exe|doc|docx|xls|xlsx|ppt|pptx|cab|eot|otf|fon|font|ttf|ttc|woff|woff2)$ {
            expires    7d;
            access_log off;
        }

        #关闭robots.txt不存在时记录日志
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
        
        # 不允许访问隐藏文件例如 .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
        
        #404页面
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #错误页面
        error_page   500 502 503 504  /50x.html;
        #指定50x页面的响应
        location = /50x.html {
            root   html;
        }

        #指定特定的请求使用反向代理到指定的服务,比如使用验证码
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        #指定特定的请求使用特定服务
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        #指定特定的请求拒绝服务,比如禁止访问/web-info/
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
}