1

Nginx 的安装和配置

安装

Nginx 是 C 语言编写的,不跨平台,不同操作系统需要下载不同的 Nginx。

Windows

到官网下载到编译好的版本即可。

Linux

下载源码之后自己编译,或者使用 wget / apt 安装官方编译好的版本。

sudo apt install nginx

如果没有特殊配置的话,Ubuntu 18.04 使用 apt 命令安装之后的配置文件在 /etc/nginx 目录下。

MacOS

笔者很穷,没钱买 mac。

Windows 下的 Nginx 基本命令

启动
start nginx

关闭
./nginx -s quit
./nginx -s stop

查看信息
./nginx -V

重启
./nginx -s reload

Linxu 下的 Nginx 基本命令

启动
./sbin/nginx

关闭
./sbin/nginx -s quit
./sbin/nginx -s stop

查看信息
./sbin/nginx -V
./sbin/nginx -v

重新读取配置
./sbin/nginx -s reload

Nginx 在 CentOS 7 下的安装

Nginx 的 Linux 版本和 Windows 版本有一些不同,即在于其只提供源码,编译的步骤需要使用者自己去做。

step 1 - 使用 CentOS 的 yum 功能下载编译环境
    yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel
step 2 - 进入到 Nginx 的目录下,输入 ./configure 进行配置
    No 1 - 如果出现权限问题,就改用 bash ./configure
    No 2 - 想要安装到特定目录,就使用 ./configure --prefix=[路径]
step 3 - 输入 make
step 4 - 输入 make install
step 5 - 默认情况下,此时默认在 /usr/local 目录下会出现一个 nginx 目录(如果 configure 的时候修改过路径那就不会在这里了)
step 6 - 进入此目录下的 sbin 目录,使用相关命令操作 Nginx
step 7 - 注意对于 Nginx 要用到的端口,需要放开防火墙
    No 1 - 如果是阿里云的服务器,可以配置端口规则
    No 2 - 如果是自己的虚拟机或者实体服务器,需要自己开放防火墙端口
        [1] firewall-cmd --zone=public --add-port=80/tcp --permanent
        [2] firewall-cmd --reload

跨域的后端配套代码

如果是使用 Nginx 做静态资源服务器去做前后端分离,那么就涉及到前端页面的跨域问题。java 基于 Spring 设置跨域允许:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * 解决跨域问题的配置类
 * 让 Spring 扫描到该类即可
 */
@Configuration
public class CorsConfig {
    //允许的 Http 连接类型
    static final String ORIGINS[] = new String[] { "GET", "POST", "PUT", "DELETE" };

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                //设置所有的路径均允许跨域请求
                registry.addMapping("/**").allowedOrigins("*").allowCredentials(true)
                        .allowedMethods(ORIGINS).maxAge(3600).allowCredentials(true);
            }
        };
    }
}

Nginx 的一些概念思考

Nginx 是什么

Nginx 是一个主要用于作为 Http、Https 的事件驱动的 Web 服务器。
Nginx 有两大功能 —— 反向代理和负载均衡。
另外它的扩展性良好,支持很多第三方库。
与 Apache 相比更加轻巧,且支持热更新。

Nginx 如何实现高性能

Nginx 在工作时有一条主线程和多条 Worker 线程;主线程用于维持进程存在和读取配置, Worker 线程用于处理 Request。
当有 Request 进来的时候,会有一条 Worker 线程去进行处理,而如果 Request 进入了阻塞状态,Worker 线程会被暂时调用去处理其它 Request。
也就是说,可以认为 Nginx 是异步处理请求的,一个线程对应了多个 Requst,这使得 Nginx 对 io 密集型工作非常擅长。

Nginx 阻止请求

server { 
     listen 80; 
     server_name  ""; 
     return 444;
 }

Nginx 解决惊群现象

惊群现象意为多个子线程去争抢同一个资源,导致了资源的浪费。在 Nginx 中则是多个线程共同监听一个端口引起的。
Nginx 在端口处加了锁,每次只有一个 Worker 线程会监控该端口。

Nginx 大文件上传

在实际的网站开发过程中,可能会遇到要上传较大文件的需求。在这种情况下,如果使用 Nginx 作为静态资源服务器,则会遇到一系列问题需要调整配置。

Nginx 的运作流程:

      (服务端阶段)      (反向代理阶段)
浏览器    -->     Nginx     -->     java project

当有浏览器访问 Nginx 的时候,Nginx 作为服务器存在,此时在 Nginx 的配置文件中,对于这一阶段的配置均使用 client_xxxx 进行配置。
而当 Nginx 去访问后端的 java 项目的时候,Nginx 是作为客户端存在,此时在配置文件中均为 proxy_xxxx 去作为配置。

对应到 Nginx 中的 nginx.conf 文件中,则是在 http 模块中进行相关调控:

# 主要用于传输附件的时候,前端往后端传输的最大数额
client_max_body_size  500m;
# 浏览器端传过来的 body 的缓冲区大小,会直接影响文件传输的速度
client_body_buffer_size 100m;
# 请求头的缓冲区大小,如果在这个数字以内,就会使用该配置项去读取请求头
client_header_buffer_size 16k;
# 如果请求头超过 client_header_buffer_size 的配置数,就会使用 large_client_header_buffers 去读取
large_client_header_buffers 4 32k;


# 与 Nginx 建立连接的超时时间,单位是秒
proxy_connect_timeout 60s;
# Nginx 连接 upstream 服务器的超时时间,单位是秒
proxy_send_timeout 60s;
# Http请求被后端项目处理后,返回给 Nginx 的响应时间,单位是秒
proxy_read_timeout 60s;

# 在 proxy_buffering 开启的时候,proxy_buffers 和 proxy_busy_buffers_size 才会起作用
proxy_buffering on;
# Nginx 往后端项目发送的 Request 的数量和值
proxy_buffers 4 8k;

如果后端使用的是 SpringBoot 2.0,还需要在 application.properties 中添加如下配置:

spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB

Nginx 使用 ssl 证书

产生证书

生成 key,需要给 key 设置密码:

openssl genrsa -des3 -out cakey.key 1024

生成证书:

openssl req -new -x509 -days 365 -key ./cakey.key -out ./cacert.pem  

证书信息录入:

Enter pass phrase for root.key: --- 输入前面创建的密码 
Country Name (2 letter code) [AU]:CN --- 国家代号,中国输入 CN 
State or Province Name (full name) [Some-State]:BeiJing --- 省的全名,拼音 
Locality Name (eg, city) []:BeiJing --- 市的全名,拼音 
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany Corp. --- 公司英文名 
Organizational Unit Name (eg, section) []: --- 可以不输入 
Common Name (eg, YOUR name) []: --- 此时不输入 
Email Address []:admin@mycompany.com --- 电子邮箱,可随意填

去除密码:

cp cakey.key cakey.key.copy   --- 拷贝 key 文件
openssl rsa -in cakey.key.copy -out cakey.key  --- 去掉密码

Nginx 配置

# https 服务配置
server {
    listen 443 default ssl;  # 如果一台 Nginx 上有多个 https 服务,那么必须要一个要在监听的时候加 default
    server_name  mikylin.cn;
    ssl_certificate   cacert.pem;
    ssl_certificate_key  cakey.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    location / {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        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://my_server/;
    }
}

# 让 http 跳转到 https
server {
    listen 80;
    server_name  mikylin.cn;
    location / {
        rewrite ^(.*)$  https://$host$1 permanent;
    }
}

Nginx 限流

Nginx 能够根据令牌桶原理,对具有某种具有特征的访问进行的限流,比如同一个 ua 或者同一个 ip(同一个 ip 一般就是同一个客户端了)。

# Nginx 可以通过令牌桶的方式对服务进行限流,一般会配合服务代理使用

# 在 http 模块下先配置一个 limit_req_zone,根据访问速度限流
# 第一个参数代表了限流依据,$binary_remote_addr 是用来限制同一个 ip 下的访问流速
# zone 的值是名称和大小,名称是 my_limit_req_zone,大小 10m,都是可以自由设置的
# 第三个参数是令牌桶生成速度,这里设置为 1 秒钟 1 个,那样的话每秒同个 ip 最多访问一次
limit_req_zone $binary_remote_addr zone=my_limit_req_zone:10m rate=1r/s;

# 使用 $http_user_agent 可以用来拦截特定 ua 的请求,比如爬虫和搜索引擎
# limit_req_zone $http_user_agent zone=my_limit_req_zone:10m rate=1r/s;  


# 在 http 模块下先配置一个 limit_conn_zone,根据访问量限流
# 第一个参数代表了限流依据,$binary_remote_addr 是用来限制同一个 ip 下的访问量
# zone 的值是名称和大小,名称是 my_limit_conn_zone,大小 10m,都是可以自由设置的
limit_conn_zone $binary_remote_addr zone=my_limit_conn_zone:10m;

# 使用 $server_name 可以用来限制连接到虚拟服务器的总数
# limit_conn_zone $server_name zone=my_limit_conn_zone:10m;

server {

    listen 10000; 
    server_name limit.mikylin.cn;
    
    location / {

        # 此处配置使用上述 limit_req_zone,zone 的值是上面配置的 limit_req_zone 的名称
        # burst 代表缓冲区,如果 ip 的访问速度超过了令牌的生成速度,会先被放在缓冲区里,这里设置了缓冲 5 次
        # 第三个参数代表了,如果 ip 访问已经超过了令牌生产速度和缓冲区,就会直接返回 503
        limit_req zone=my_limit_req_zone burst=5 nodelay;
        # 记录限流日志 error / warn / debug 等
        limit_req_log_level error;
        # 限流返回的 http code
        limit_req_status 503;


        # 每个 ip 同一时刻只能有一条连接连到服务商
        limit_conn my_limit_conn_zone 1;
        # 记录限流日志 error / warn / debug 等
        limit_conn_log_level error;
        # 限流返回的 http code
        limit_conn_status 503;


        proxy_pass http://www.baidu.com/;
    }
}

Nginx 中的通配符

$arg_xxxx - GET 请求中的任一参数,例如 $arg_userid,意义为 http://xxxx?userid=1,值即为 1
$args - GET 请求中的所有参数,上述参数的超集
$request_uri - 请求的 uri
$scheme - http / https 等
$request_method - get / post / delete 等
$host - 请求的 request header 中的 host
$proxy_add_x_forwarded_for - 重定向地址

$cookie_xxxx - 基本逻辑同 $arg_xxxx,代表 cookie 中的任一参数
$http_cookie - 客户端 cookie 信息
$http_user_agent - 客户端 agent 信息
$remote_port - 客户端端口
$remote_addr - 客户端地址
$binary_remote_addr - 二进制的客户端地址

$server_port - 请求服务器的端口
$server_name - 请求服务器的名称
$server_addr - 服务器地址
$server_protocol - 请求协议,http 1.0 / http 1.1 等

Nginx 的配置文件整合

在 Nginx 目录下的 conf 文件夹下有一个 nginx.conf。内容如下:

# 设置登录用户
# 在 Linux 下如果不设置登录用户,可能会没有权限去访问静态资源
# user root;

# Nginx 进程,一般设置为和 cpu 核数一样
# worker_processes  auto;  # 默认自动
worker_processes  4;

# worker 权重,权重越大则被调用的频率越大
# 一般设置在 -20 - 20 之间,默认 0
worker_priority 0;

# 将 worker 进程分配到不同的 cpu 上
# 需要注意的是,进程数和 cpu 核数需要对应
# 1000 代表了四个核心,其中 1 代表了该 worker 进程真实执行的核心
# 如果上述 worker_processes 配置的数量更多,那么此处需要列举更多的进程编排信息
# worker_cpu_affinity 0001 0001 0010 0100 1000 1000; # 将 6 个 worker 编排进 4 个核心中
work_cpu_affinity 0001 0010 0100 1000;


# 单个进程打开的最多文件描述符数目
# 最好与 Linux 的文件描述符数量相同
# Linux 上查看文件描述符数量 (ulimit -n)
worker_rlimit_nofile 65535;

#错误日志存放目录 
error_log  logs/error.log;

# pid 的存储文件
# 如果不设置的话默认在 /log 下
pid nginx.pid;


# 用来指定 Nginx 的工作模式和最大连接数
events {

    # 工作模式有 select、poll、epoll、kqueue 等,其中前两者是标准模式,后两者是高效模式
    # 在 Linux 上,工作模式一般选择使用 epoll
    # 在 Windows 上,可以选择 poll
    use epoll; 

    # 单个进程的最大连接数,在 Linux 上受到最大句柄数的限制
    # 注意,Nginx 是多进程的
    worker_connections  1024; 

    # 设置网路连接序列化,防止惊群现象发生
    # on 为开启,off 为关闭,默认 on
    accept_mutex on;

    # 设置一个进程是否同时接受多个网络连接
    # on 为开启,off 为关闭,默认 off
    multi_accept on;
}

# 核心的配置模块
http {

    # 文件扩展名与文件类型映射表
    include       mime.types;

    # 默认文件类型,默认为 text/plain
    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;

    # 编码格式
    charset  utf-8;
    
    # 开启 tcp_nopush 可以把 HttpResponse Header 和文件的开始放在一个文件里发布,减少网络报文段的数量
    tcp_nopush  on;

    # 开启 tcp_nodelay,内核会等待将更多的字节组成一个数据包,从而提高 IO 性能
    tcp_nodelay on;

    # 是否使用 sendfile 系统调用来传输文件
    # sendfile 是 Linux 2.0 中新增的 IO 系统(零拷贝 IO 系统)
    sendfile  on;

    # Nginx 工作进程每次调用 sendfile() 传输数据的大小上限
    # 默认值为 0 (表示无限制),可以设置在 http/server/location 模块中
    sendfile_max_chunk  1024k;

    # 连接超时时间,单位是秒
    keepalive_timeout  65s;

    # 单个长连接的最大请求数,默认 100
    keepalive_requests 100;

    # 开启 gzip 压缩功能
    gzip  on;

    # 主要用于传输附件的时候,前端往后端传输的最大数额
    client_max_body_size  500m;

    # 浏览器端传过来的 body 的缓冲区大小,会直接影响文件传输的速度
    client_body_buffer_size 100m;

    # 请求头的缓冲区大小,如果在这个数字以内,就会使用该配置项去读取请求头
    client_header_buffer_size 16k;

    # 如果请求头超过 client_header_buffer_size 的配置数,就会使用 large_client_header_buffers 去读取
    large_client_header_buffers 4 32k;

    # 后端服务器与 Nginx 建立连接的超时时间,单位是秒
    proxy_connect_timeout 60s;

    # Nginx 连接 upstream 服务器的超时时间,单位是秒
    proxy_send_timeout 60s;

    # Http 请求被后端服务器处理后,返回给 Nginx 的响应时间,单位是秒
    proxy_read_timeout 60s;

    # 在 proxy_buffering 开启的时候,proxy_buffers 和 proxy_busy_buffers_size 才会起作用
    proxy_buffering on;

    # Nginx 往后端项目发送的 Request 的数量和值
    proxy_buffers 4 8k;

    # 指定使用缓存
    # cache 为缓存文件的存放目录,在 Nginx 根目录下的 cache 文件夹下
    # keys_zone=test_cache:10m 代表了缓存文件名称为 test_cache,该缓存占用的内存不超过 10m
    # max_size=10g 代表了该缓存文件占用磁盘不超过 10g
    # inactive=60m 代表了该缓存如果 60 分钟没有被访问就会被清理
    # use_temp_path=off 代表了该目录不存放临时文件
    proxy_cache_path  cache  keys_zone=test_cache:10m  max_size=10g  inactive=60m  use_temp_path=off;


    # Nginx 主要功能之一 —— 作为网关进行服务分发
    # 首先需要在 server 模块中配置监听的端口和 url
    server {

        # 监听端口
        listen  8090;

        # 服务的名称
        server_name  hello_world;

        # 编码格式
        #charset gkb;
        charset utf-8;

        # 设置单个连接上能够使用的带宽,单位:k - kb,m - mb
        limit_rate 500k;


        # 对不同的错误编码设置错误的页面
        # error_page  404              /404.html;
        error_page   500 502 503 504  /50x.html;

        # 此处如果有客户端访问 http://ip:8090/,就等同于访问 http://ip:8091/
        location / {
            proxy_pass http://localhost:8091/;
        }

        # 此处如果有客户端访问 http://ip:8090/api,就等同于访问 http://ip:8092/
        location /api {
            proxy_pass http://localhost:8092/;
        }

        # 需要负载均衡的情况
        location /api2 {

            # 如果客户端在指定时间内没有发送一个完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)
            client_header_timeout 60s;

            # 如果客户端在指定时间内没有发送任何 request body 内容,Nginx 返回 HTTP 408(Request Timed Out)
            client_body_timeout 60s;

            # 服务端向客户端传输数据的超时时间
            send_timeout 60s;

            # 重试次数
            proxy_next_upstream_tries 3;

            # Nginx 与 后端业务服务器连接的超时时间
            proxy_connect_timeout 60s;

            # Nginx 与 后端业务服务器连接的读取超时时间
            proxy_read_timeout 60s;

            # Nginx 与 后端业务服务器连接的存入超时时间
            proxy_send_timeout 60s;

            # 如果负载的后端服务中的一台存在 502、504 等问题,则重试到下一台
            proxy_next_upstream http_500 http_501 http_502 http_503 http_504 error timeout invalid_header;
             
             # 重试次数,默认为 0,代表不限制次数
            proxy_next_upstream_tries 3;

            # 是否开启 aio,默认关闭
            aio on;


            # 指定该 server 使用的 Nginx 缓存文件
            # proxy_cache  off;  # 默认为 off,即为不使用缓存
            proxy_cache  test_cache;
            
            # 设置缓存的 key,只有当请求符合 key 的时候才会触发缓存
            # 默认值是请求的 http header 的组合,一般无需设置            
            proxy_cache_key  $host$request_uri$cookie_user;
            
            # 设置使用缓存的 http 协议类型
            # 默认 get 和 head
            proxy_cache_methods GET POST HEAD DELETE;

            # 指定请求至少被发送了多少次以上时才触发缓存
            # 降低低频请求被缓存的情况发生
            proxy_cache_min_users  5;

            # 默认情况下缓存长期有效,除非超出总量限制
            # 也可以根据状态码设置缓存的有效时间
            proxy_cache_valid  200 10m; # 设置 200 状态码的缓存 10 分钟有效
            proxy_cache_valid  any 5m; # 除了 200 之外的缓存 5 分钟有效

            # 设置某些请求不进行缓存,而是全部走服务器
            # 如果 url 中包含该配置的值,则请求不从缓存中获取数据
            # 此处举例,如果 url 中存在参数 nocache,则不走缓存
            proxy_cache_bypass  $arg_nocache;

            # 缓存的并发锁,开启此选项后如果 Nginx 缓存没有命中,只有一个请求会往后端请求数据
            # 其它请求等待其返回结果,然后再度尝试缓存
            # 容易造成性能问题,建议不开启
            proxy_cache_lock off;

            # 拖底配置,如果后端服务器返回出错,Nginx 会选择缓存中的旧数据返回给客户端
            proxy_cache_use_stale error timeout updating http_500 http_501 http_502 http_503 http_504 http_404;

            

            # 在转发的时候把原 http 请求的 Header 中的信息放到转发的请求里
            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_set_body $request_body;
            # default_type application/json;
            # proxy_method POST;


            set $test "test";  # set 语句,存入变量
            set $test_string "${test}_string";  # set 语句,存入变量

            # 使用 nginx 的表达式来完成分支操作
            if ( $host != 'mikylin.cn' ) {
                # return 404;  # 直接返回
                echo "www.baidu.com";
            }



            # 黑名单 ip 设置
            # deny 192.168.1.0/24;
            # deny all; # 全部设置为黑名单
          
            # 白名单设置
            # allow 192.168.1.0/24;
            # allow all; # 全部设置为白名单




            # 设置转发地址,到路由接口为止
            proxy_pass http://hello_word_service/;
        }
    }

    # 配置多个服务达到负载均衡的目的
    upstream hello_word_service {
        # 负载均衡方案一 按照权重分配
        server  localhost:8091 weight=5;
        server  localhost:8092 weight=5;

        # 负载均衡方案二 按照响应时间分配
        # server  localhost:8091;
        # server  localhost:8092;
        # fair;

        # 负载均衡方案三 按照 ip 的 hash 值来分配
        # 注意,同一 ip 的 Hash 值是一定的,所以此处必然分配到同一台服务器上
        # server  localhost:8091;
        # server  localhost:8092;
        # ip_hash;

        # 其它方案不一一列举
    }




    # Nginx 主要功能之二 —— 作为静态资源服务器去调用后端接口
    # 首先需要在 server 模块中配置静态的资源
    server {

        # 监听端口
        listen  8100;

        # 服务的名称
        server_name  demo_web;

        # 编码格式
        charset utf-8;

        # 首页配置,注意读取路径必须要有配置的 index.html 或者 index.htm
        # 如果首页是其它的,就要在这里配置
        # 如果客户端访问 http://ip:8100,就会显示首页
        index index.html index.htm;

        # 静态资源的读取路径,首先会去读取路径下的首页
        root D:\\demo_web;

        # 如果客户端或者页面资源需要访问到 http://ip:8100/api,就等同于访问 http://ip:8080/
        location /api {
            proxy_pass http://localhost:8080/;
        }
        
        # 需要负载均衡的情况
        location /api2 {

            proxy_next_upstream http_500 http_501 http_502 http_503 http_504 error timeout invalid_header;
            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://demo_web_service/;
        }
    }

    # 配置服务地址
    upstream demo_web_service {
        server  localhost:8080;
    }






    # Nginx 主要功能之三 —— 正向代理
    # 正向代理的 Nginx 直接作为转发到外网 url 的转发器使用
    server {

        # 监听端口
        listen  80;

        # 服务的名称
        server_name  base_proxy;

        # 编码格式
        charset utf-8;

        location / {
            proxy_pass http://baidu.com;
        }
    }








    # Nginx 主要功能之四 —— https 代理
    # 需要注意的是,自己生成的证书会被浏览器标识为 不安全的,被认证的证书需要阿里云等资质机构
    server {
    
        # 如果一台 Nginx 上有多个 https 服务,那么必须要一个要在监听的时候加 default
        listen 443 default ssl;  
        
        # 服务的名称
        server_name  mikylin.cn;
        
        # 配置证书
        ssl_certificate   cacert.pem; 
        
        # 配置证书 key
        ssl_certificate_key  cakey.key; 
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        
        # 代理
        location / {
            proxy_next_upstream http_502 http_504 error timeout invalid_header;
            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://my_server/;
        }
    }

    # 让 http 跳转到 https
    server {
        listen 80;
        server_name  mikylin.cn;
        location / {
            rewrite ^(.*)$  https://$host$1 permanent;
        }
    }



    # Nginx 主要功能点补充 —— 限流
    # Nginx 可以通过令牌桶的方式对服务进行限流,一般会配合服务代理使用

    # 在 http 模块下先配置一个 limit_req_zone,根据访问速度限流
    # 第一个参数代表了限流依据,$binary_remote_addr 是用来限制同一个 ip 下的访问流速
    # zone 的值是名称和大小,名称是 my_limit_req_zone,大小 10m,都是可以自由设置的
    # 第三个参数是令牌桶生成速度,这里设置为 1 秒钟 1 个,那样的话每秒同个 ip 最多访问一次
    limit_req_zone $binary_remote_addr zone=my_limit_req_zone:10m rate=1r/s;

    # 使用 $http_user_agent 可以用来拦截特定 ua 的请求,比如爬虫和搜索引擎
    # limit_req_zone $http_user_agent zone=my_limit_req_zone:10m rate=1r/s;  


    # 在 http 模块下先配置一个 limit_conn_zone,根据访问量限流
    # 第一个参数代表了限流依据,$binary_remote_addr 是用来限制同一个 ip 下的访问量
    # zone 的值是名称和大小,名称是 my_limit_conn_zone,大小 10m,都是可以自由设置的
    limit_conn_zone $binary_remote_addr zone=my_limit_conn_zone:10m;

    # 使用 $server_name 可以用来限制连接到虚拟服务器的总数
    # limit_conn_zone $server_name zone=my_limit_conn_zone:10m;

    server {
    
        listen 10000; 
        server_name limit.mikylin.cn;
        
        location / {

            # 此处配置使用上述 limit_req_zone,zone 的值是上面配置的 limit_req_zone 的名称
            # burst 代表缓冲区,如果 ip 的访问速度超过了令牌的生成速度,会先被放在缓冲区里,这里设置了缓冲 5 次
            # 第三个参数代表了,如果 ip 访问已经超过了令牌生产速度和缓冲区,就会直接返回 503
            limit_req zone=my_limit_req_zone burst=5 nodelay;
            # 记录限流日志 error / warn / debug 等
            limit_req_log_level error;
            # 限流返回的 http code
            limit_req_status 503;


            # 每个 ip 同一时刻只能有一条连接连到服务商
            limit_conn my_limit_conn_zone 1;
            # 记录限流日志 error / warn / debug 等
            limit_conn_log_level error;
            # 限流返回的 http code
            limit_conn_status 503;


            proxy_pass http://my_server/;
        }
    }



    # 如果觉得配置文件太长了,可以用 include 去引入其它的配置文件
    # include servers.conf;
}

三流
57 声望16 粉丝

三流程序员一枚,立志做保姆级教程。