Nginx 學習歸整

Nginx 的安裝和配置

安裝

Nginx 是 C 語言編寫的,不跨平臺,不一樣操做系統須要下載不一樣的 Nginx。html

Windows

到官網下載到編譯好的版本便可。前端

Linux

下載源碼以後本身編譯,或者使用 wget / apt 安裝官方編譯好的版本。java

sudo apt install nginx

若是沒有特殊配置的話,Ubuntu 18.04 使用 apt 命令安裝以後的配置文件在 /etc/nginx 目錄下。node

MacOS

筆者很窮,沒錢買 mac。nginx

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 設置跨域容許:c++

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 做爲靜態資源服務器,則會遇到一系列問題須要調整配置。git

Nginx 的運做流程:web

(服務端階段)      (反向代理階段)
瀏覽器    -->     Nginx     -->     java project

當有瀏覽器訪問 Nginx 的時候,Nginx 做爲服務器存在,此時在 Nginx 的配置文件中,對於這一階段的配置均使用 client_xxxx 進行配置。
而當 Nginx 去訪問後端的 java 項目的時候,Nginx 是做爲客戶端存在,此時在配置文件中均爲 proxy_xxxx 去做爲配置。spring

對應到 Nginx 中的 nginx.conf 文件中,則是在 http 模塊中進行相關調控:json

# 主要用於傳輸附件的時候,前端日後端傳輸的最大數額
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;

            # 若是負載的後端服務中的一臺存在 50二、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;
}
相關文章
相關標籤/搜索