反向代理:反向代理也叫reverse proxy,指的是代理外網用戶的請求到內部的指定web服務器,並將數據返回給用戶的一種方式,這是用的比較多的一種方式。
Nginx除了能夠在企業提供高性能的web服務以外,另外還能夠將自己不具有的請求經過某種預約義的協議轉發至其它服務器處理,不一樣的協議就是Nginx服務器與其餘服務器進行通訊的一種規範,主要在不一樣的場景使用如下模塊實現不一樣的功能:php
ngx_http_proxy_module: 將客戶端的請求以http協議轉發至指定服務器進行處理。 ngx_stream_proxy_module:將客戶端的請求以tcp協議轉發至指定服務器處理。 ngx_http_fastcgi_module:將客戶端對php的請求以fastcgi協議轉發至指定服務器助理。 ngx_http_uwsgi_module:將客戶端對Python的請求以uwsgi協議轉發至指定服務器處理。
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>
[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
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header HOST $remote_addr; # 添加HOST到報文頭部,若是客戶端爲NAT上網那麼其值爲客戶端的共用的公網IP地址。
proxy_connect_timeout 60s; # 60s爲自定義nginx與後端服務器創建鏈接的超時時間
proxy_send_time time; # 配置nginx項後端服務器或服務器組發起write請求後,等待的超時時間,默認60s
proxy_headers_hash_bucket_size 64; 當配置了 proxy_hide_header和proxy_set_header的時候,用於設置nginx保存HTTP報文頭的hash表的上限。html
示例 # 調用緩存功能,須要定義在相應的配置段,如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分鐘
使用方法: 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; # 最大磁盤佔用空間,磁盤存入文件內容的緩存空間最大值mysql
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
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與值nginx
# 添加自定義首部,以下: 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版後支持
[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
自定義頭部web
第二次訪問命中緩存redis
Nginx能夠基於ngx_http_upstream_module模塊提供服務器分組轉發、權重分配、狀態監測、調度算法等高級功能算法
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; # 最少鏈接調度算法,優先將客戶端請求調度到當前鏈接最少的後端服務器
[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
[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
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在1.9.0版本開始支持tcp模式的負載均衡,在1.9.13版本開始支持udp協議的負載,udp主要用於DNS的域名解析,其配置方式和指令和http 代理相似,其基於ngx_stream_proxy_module模塊實現tcp負載,另外基於模塊ngx_stream_upstream_module實現後端服務器分組轉發、權重分配、狀態監測、調度算法等高級功能。sql
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 |
[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 *:*
[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>
[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)
[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)]>