Nginx高階用法(三)

Nginx反向代理

  反向代理:反向代理也叫reverse proxy,指的是代理外網用戶的請求到內部的指定web服務器,並將數據返回給用戶的一種方式,這是用的比較多的一種方式。
  Nginx除了可以在企業提供高性能的web服務之外,另外還可以將本身不具備的請求通過某種預定義的協議轉發至其它服務器處理,不同的協議就是Nginx服務器與其他服務器進行通信的一種規範,主要在不同的場景使用以下模塊實現不同的功能:

ngx_http_proxy_module: 將客戶端的請求以http協議轉發至指定服務器進行處理。
ngx_stream_proxy_module:將客戶端的請求以tcp協議轉發至指定服務器處理。
ngx_http_fastcgi_module:將客戶端對php的請求以fastcgi協議轉發至指定服務器助理。
ngx_http_uwsgi_module:將客戶端對Python的請求以uwsgi協議轉發至指定服務器處理。

Nginx http的反向代理實現

反向代理配置參數

  1. proxy_pass; 用來設置將客戶端請求轉發給的後端服務器的主機,可以是主機名、IP地址:端口的方式,也可以代理到預先設置的主機羣組,需要模塊gx_http_upstream_module支持。
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    proxy_pass http://192.168.36.110:80;  # 不帶斜線將訪問的/web,等於訪問後端服務器 http://192.168.36.103:80/web/index.html,即後端服務器配置的站點根目錄要有web目錄纔可以被訪問,這是一個追加/web到後端服務器。  帶斜線,等於訪問後端服務器的http://192.168.36.103:80/index.html 內容返回給客戶端  
    index index.html;
  }
}

訪問測試
[root@CentOS7 conf.d]#curl -L -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 08:24:33 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/

HTTP/1.1 200 OK
Date: Sat, 01 Jun 2019 08:24:31 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Sat, 25 May 2019 03:41:28 GMT
ETag: "19-589ae171491d6"
Accept-Ranges: bytes
Content-Length: 25
Content-Type: text/html; charset=UTF-8

<h1>Real Server 110</h1>

Nginx高階用法(三)

  1. proxy_hide_header; 用於nginx作爲反向代理的時候,在返回給客戶端http響應的時候,隱藏後端服務版本相應頭部的信息,可以設置在http/server或location塊
[root@CentOS7 conf.d]#vim a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_hide_header Location;  # 若想隱藏多個head頭部信息需要再次定義proxy_hide_header,不支持在後面接着寫
  }
}

[root@CentOS7 conf.d]#nginx -s reload
[root@CentOS7 conf.d]#curl -L -I http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 08:30:47 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
  1. proxy_pass_request_body on | off; 是否向後端服務器發送HTTP包體部分,可以設置在http/server或location塊,默認即爲開啓
  2. proxy_pass_request_headers on | off; 是否將客戶端的請求頭部轉發給後端服務器,可以設置在http/server或location塊,默認即爲開啓
  3. proxy_set_header; 可以更改或添加客戶端的請求頭部信息內容並轉發至後端服務器,比如在後端服務器想要獲取客戶端的真實IP的時候,就要更改每一個報文的頭部,如下:
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # proxy_set_header HOST $remote_addr;
    # 添加HOST到報文頭部,如果客戶端爲NAT上網那麼其值爲客戶端的共用的公網IP地址。
  4. proxy_hide_header field; 用於隱藏後端服務器特定的響應首部,默認nginx在響應報文中不傳遞後端服務器的首部字段Date, Server, XPad, X-Accel等
  5. proxy_connect_timeout time; 配置nginx服務器與後端服務器嘗試建立連接的超時時間,默認爲60秒
    proxy_connect_timeout 60s;
    # 60s爲自定義nginx與後端服務器建立連接的超時時間
  6. proxy_read_time time; 配置nginx服務器向後端服務器或服務器組發起read請求後,等待的超時時間,默認60s
    proxy_send_time time;
    # 配置nginx項後端服務器或服務器組發起write請求後,等待的超時時間,默認60s
  7. proxy_http_version 1.0; 用於設置nginx提供代理服務的HTTP協議的版本,默認http 1.0
  8. proxy_ignore_client_abort off; 當客戶端網絡中斷請求時,nginx服務器中斷其對後端服務器的請求。即如果此項設置爲on開啓,則服務器會忽略客戶端中斷並一直等着代理服務執行返回,如果設置爲off,則客戶端中斷後Nginx也會中斷客戶端請求並立即記錄499日誌,默認爲off。
  9. proxy_headers_hash_bucket_size 64; 當配置了 proxy_hide_header和proxy_set_header的時候,用於設置nginx保存HTTP報文頭的hash表的上限。

  10. proxy_headers_hash_max_size 512; 設置proxy_headers_hash_bucket_size的最大可用空間
  11. server_names_hash_bucket_size 512; server_name hash表申請空間大小
  12. server_names_hash_max_szie 512; 設置服務器名稱hash表的上限大小

反向代理--緩存功能

  1. proxy_cache zone | off; 默認off 指明調用的緩存,或關閉緩存機制
  2. proxy_cache_key string; 緩存中用於“鍵”的內容,默認值:proxy_cache_key $scheme$proxy_host$request_uri;
  3. proxy_cache_valid [code ...] time; 定義對特定響應碼的響應內容的緩存時長,定義在http{...}中
    示例
    # 調用緩存功能,需要定義在相應的配置段,如server{...};或者location等
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 10m;  # 對200、302類響應碼緩存10分鐘
    proxy_cache_valid 404 1m;   # 對404類響應碼緩存1分鐘
  4. proxy_cache_path; 定義可用於proxy功能的緩存;
    
    使用方法:
    proxy_cache_path path [levels=levels] [use_temp_path=on|off]
    keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number]
    [manager_sleep=time] [manager_threshold=time] [loader_files=number]
    [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number]
    [purger_sleep=time] [purger_threshold=time];

示例:在http配置定義緩存信息
proxy_cache_path /var/cache/nginx/proxy_cache # 定義緩存保存路徑,proxy_cache會自動創

levels=1:2:2; # 定義緩存目錄結構層次,1:2:2可以生成2^4x2^8x2^8=1048576個目錄
keys_zone=proxycache:20m; # 指內存中緩存的大小,主要用於存放key和metadata(如:使用次數)
inactive=120s; # 緩存有效時間
max_size=1g; # 最大磁盤佔用空間,磁盤存入文件內容的緩存空間最大值

5. proxy_cache_use_stale; 在被代理的後端服務器出現哪種情況下,可直接使用過期的緩存響應客戶端
```bash
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默認是off
  1. proxy_cache_methods GET | HEAD | POST ...; 對哪些客戶端請求方法對應的響應進行緩存,GET和HEAD方法總是被緩存
  2. proxy_set_header field value; 設定發往後端主機的請求報文的請求首部的值
    Context: http, server, location
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    請求報文的標準格式如下:
    X-Forwarded-For: client1, proxy1, proxy2

緩存配置

[root@CentOS7 conf.d]#vim ../conf/nginx.conf  # 配置在nginx.conf http配置段
    proxy_cache_path /data/nginx/proxycache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;

[root@CentOS7 conf.d]#cat a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {    # 要緩存的URL或者放在server配置項對所有URL都進行緩存
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_hide_header Location;
    proxy_hide_header Connection;
    proxy_set_header clientip $remote_addr;
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 10m;
    proxy_cache_valid any 1m;
  }
}
[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

訪問驗證

[root@CentOS7 conf.d]#curl -L http://www.a.com/app
[root@CentOS7 conf.d]#ab -n 2000 -c 200 http://www.a.com/app
Total transferred:      822000 bytes
HTML transferred:       468000 bytes
Requests per second:    9413.58 [#/sec] (mean)
Time per request:       21.246 [ms] (mean)
Time per request:       0.106 [ms] (mean, across all concurrent requests)
Transfer rate:          3778.30 [Kbytes/sec] received

# 緩存路徑結構及文件大小
[root@CentOS7 conf.d]#tree /data/nginx/proxycache/
/data/nginx/proxycache/
├── 2
│   └── e
│       └── 8
└── 7
    └── 5
        └── b
            └── 606c5106afffe9fd4f2021504afe7b57

6 directories, 1 file

驗證文件內容
[root@CentOS7 conf.d]#head -n100 /data/nginx/proxycache/7/5/b/606c5106afffe9fd4f2021504afe7b57
HTTP/1.1 200 OK
Date: Sat, 01 Jun 2019 09:51:06 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Sat, 01 Jun 2019 09:50:35 GMT
ETag: "1388-58a4010131b0d"
Accept-Ranges: bytes
Content-Length: 5000
Connection: close
Content-Type: text/html; charset=UTF-8

添加自定義頭部信息

nginx基於模塊ngx_http_headers_module可以實現對頭部報文添加指定的key與值

# 添加自定義首部,如下:
add_header name value [always];
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
add_trailer name value [always];
添加自定義響應信息的尾部, 1.13.2版後支持

Nginx配置

[root@CentOS7 conf.d]#cat a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_set_header clientip $remote_addr;
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 10m;
    proxy_cache_valid any 1m;
    add_header X-Via $server_addr;
    add_header X-Cache $upstream_cache_status;
    add_header X-Accel $server_name;
  }
}
[root@CentOS7 conf.d]#nginx -s reload

[root@CentOS7 conf.d]#curl -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 10:12:16 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/
X-Via: 192.168.36.104
X-Cache: MISS  # 第一次訪問沒有使用緩存,再次進行訪問測試
X-Accel: www.a.com

[root@CentOS7 conf.d]#curl -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 10:12:18 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/
X-Via: 192.168.36.104
X-Cache: HIT   # 第二次訪問命中緩存
X-Accel: www.a.com

自定義頭部
Nginx高階用法(三)

第二次訪問命中緩存
Nginx高階用法(三)

Nginx http反向代理高級應用

Nginx可以基於ngx_http_upstream_module模塊提供服務器分組轉發、權重分配、狀態監測、調度算法等高級功能

http upstream 配置參數

upstream name {

} 
# 自定義一組服務器,配置在http內

server address [parameters];
# 配置一個後端web服務器,配置在upstream內,至少要有一個server服務器配置。
# server支持的parameters如下:
weight=number # 設置權重,默認爲1。
max_conns=number # 給當前server設置最大活動鏈接數,默認爲0表示沒有限制。
max_fails=number # 對後端服務器連續監測失敗多少次就標記爲不可用。
fail_timeout=time # 對後端服務器的單次監測超時時間,默認爲10秒。
backup # 設置爲備份服務器,當所有服務器不可用時將重新啓用次服務器。
down # 標記爲down狀態。
resolve # 當server定義的是主機名的時候,當A記錄發生變化會自動應用新IP而不用重啓Nginx。

hash KEY consistent;
# 基於指定key做hash計算,使用consistent參數,將使用ketama一致性hash算法,適用於後端是Cache服務器(如varnish)時使用,consistent定義使用一致性hash運算,一致性hash基於取模運算。

# 所謂取模運算,就是計算兩個數相除之後的餘數,比如10%7=3, 7%4=3
hash $request_uri consistent; # 基於用戶請求的uri做hash

ip_hash; # 源地址hash調度方法,基於的客戶端的remote_addr(源地址)做hash計算,以實現會話保持

least_conn; # 最少連接調度算法,優先將客戶端請求調度到當前連接最少的後端服務器

多臺web服務器實現反向代理

[root@CentOS7 conf.d]#vim ../conf/nginx.conf
    upstream app1 {
      #hash $request_uri consistent;
      #ip_hash;  # 指定ip_hash算法,根據session調度到同一臺後端主機上,當此臺主機宕機,則強制切換到另一臺存活的主機上
      #least_conn;
      server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3;  # 後端服務器狀態監測:fail_timeout連續檢測多少次失敗,max_fails檢測時長
      server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3;
      server 192.168.36.101:80 weight=1 fail_timeout=5s max_fails=3 backup;  # 備用服務器,當其餘反向代理服務器宕機,啓用備用服務器
    }
[root@CentOS7 conf.d]#vim a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location / {
    index index.html;
    root /data/nginx/html/pc;
  }
  location /app {
    index index.html;
    proxy_pass http://app1;
  }
}
[root@CentOS7 conf.d]#nginx -s reload

訪問測試
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.110
192.168.36.106
192.168.36.110
192.168.36.106

啓用ip_hash算法

[root@CentOS7 conf.d]#vim ../conf/nginx.conf
    upstream app1 {
      #hash $request_uri consistent;
      #least_conn;
      server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3;
      server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3;
      ip_hash;
    }
[root@CentOS7 conf.d]#nginx -s reload

訪問測試:
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106

宕機測試
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.110   # 請求被強制切換到存活主機上
192.168.36.110
....
192.168.36.106  # 當修復好宕機主機重新工作,請求將重新回到原來的主機上
192.168.36.106
192.168.36.106 

Nginx動靜分離

upstream web {
    server  192.168.36.1 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.2 weight=1 max_fails=2  fail_timeout=2;
} 

upstream image  {
    server  192.168.36.3 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.4 weight=1 max_fails=2  fail_timeout=2;
} 

upstream php {
    server  192.168.36.5 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.6 weight=1 max_fails=2  fail_timeout=2;
} 

location  /{
    root html/web;
    index  index.php index.html;
}

location ~* \.php$ {
    fastcgi_proxy  http://php;
}

location ~* "\.(.jpg|png|jpeg|gif)" {
    proxy_pass http://image;
}

Nginx Tcp負載均衡

Nginx在1.9.0版本開始支持tcp模式的負載均衡,在1.9.13版本開始支持udp協議的負載,udp主要用於DNS的域名解析,其配置方式和指令和http 代理類似,其基於ngx_stream_proxy_module模塊實現tcp負載,另外基於模塊ngx_stream_upstream_module實現後端服務器分組轉發、權重分配、狀態監測、調度算法等高級功能。

Tcp負載均衡配置參數

stream { #定義stream
  upstream backend { #定義後端服務器
    hash $remote_addr consistent; #定義調度算法
    server backend1.example.com:12345 weight=5; #定義具體server
    server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
  } 
  upstream dns { #定義後端服務器
    server 192.168.0.1:53535; #定義具體server
    server dns.example.com:53;
  } 
  server { #定義server
    listen 12345; #監聽IP:PORT
    proxy_connect_timeout 1s; #連接超時時間
    proxy_timeout 3s; #轉發超時時間
    proxy_pass backend; #轉發到具體服務器組
  } 
  server {
    listen 127.0.0.1:53 udp reuseport;
    proxy_timeout 20s;
    proxy_pass dns;
  } 
  server {
    listen [::1]:12345;
    proxy_pass unix:/tmp/stream.socket;
  }
}

負載均衡實驗環境

主機名稱 主機IP 運行服務
CentOS7 192.168.36.104 Nginx
CentOS7-1 192.168.36.110 Redis、Mysql

基於Redis的負載均衡實例

安裝並配置Redis服務

[root@CentOS7-1 ~]#yum install -y redis
[root@CentOS7-1 ~]#vim /etc/redis.conf
[root@CentOS7-1 ~]#egrep "^bind" /etc/redis.conf
bind 0.0.0.0
[root@CentOS7-1 ~]#systemctl start redis
[root@CentOS7-1 ~]#systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
[root@CentOS7-1 ~]#ss -ntl | grep 6379   # Redis基於6379端口進行工作
LISTEN     0      128          *:6379                     *:*

Nginx配置

[root@CentOS7 ~]#mkdir /apps/nginx/tcp
[root@CentOS7 ~]#cd /apps/nginx/tcp/
[root@CentOS7 tcp]#vim tcp.conf
stream {
  upstream redis_server {
    server 192.168.36.110:6379 max_fails=3 fail_timeout=30s;
  }
  server {
    listen 192.168.36.104:6379;
    proxy_connect_timeout 3s;
    proxy_timeout 3s;
    proxy_pass redis_server;
  }
}

[root@CentOS7 tcp]#vim ../conf/nginx.conf
include /apps/nginx/tcp/tcp.conf;   # 注意此處的include與http模塊平級,建議寫在http模塊上方

[root@CentOS7 tcp]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 tcp]#nginx -s reload

# 查看6379端口是否開啓
[root@CentOS7 tcp]#ss -ntl | grep 6379
LISTEN     0      128    192.168.36.104:6379                     *:*

# 測試通過Nginx負載連接Redis
[root@CentOS7-1 ~]#redis-cli -h 192.168.36.104
192.168.36.104:6379> set name darius
OK
192.168.36.104:6379> get name
"darius"
192.168.36.104:6379>

基於Mysql的負載均衡實例

服務器安裝Mariadb

[root@CentOS7-1 ~]#yum install -y mariadb mariadb-server
[root@CentOS7-1 ~]#systemctl start mariadb   # 啓動mariadb數據庫服務
[root@CentOS7-1 ~]#systemctl enable mariadb   # 開機自啓動數據庫服務
[root@CentOS7-1 ~]#ss -ntl | grep 3306   # 檢查端口是否啓動
LISTEN     0      50           *:3306                     *:*

Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@CentOS7-1 ~]#mysql_secure_installation   # 對數據庫進行安全加固

# 對數據庫進行授權操作
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.36.%' IDENTIFIED BY 'centos';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Nginx配置

[root@CentOS7 tcp]#vim tcp.conf
stream {
  upstream mysql_server {
    least_conn;
    server 192.168.36.110:3306 max_fails=3 fail_timeout=30s;
  }
  server {
    listen 192.168.36.104:3306;
    proxy_connect_timeout 3s;
    proxy_timeout 3s;
    proxy_pass mysql_server;
  }
}
[root@CentOS7 tcp]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 tcp]#nginx -s reload

# 對負載端口進行檢查
[root@CentOS7 tcp]#ss -ntl | grep 3306
LISTEN     0      128    192.168.36.104:3306                     *:*

####測試通過nginx負載連接Mysql

[root@CentOS7-1 ~]#mysql -uroot -pcentos -h 192.168.36.104
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 16
Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE Darius;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| Darius             |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

MariaDB [(none)]>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章