主頁 > 軟體設計 > nginx負載均衡session共享

nginx負載均衡session共享

2021-08-22 07:09:23 軟體設計

文章目錄

  • 一、可道云專案結合redis快取部署
    • redis快取可道云專案資料及會話,加快網站訪問速度
  • 二、Nginx負載均衡會話共享
    • 1.1 什么是會話保持
    • 1.2 為什么需要會話保持
    • 1.3 Cookie機制、Session機制、token機制
    • 1.4 如何實作會話保持
    • 1.5 會話保持場景實踐
  • 三、 后端節點例外容錯機制
    • 3.1 配置語法
    • 3.2 場景示例
  • 四、Nginx負載均衡調度場景
    • 4.1 根據uri進行調度(路由)
    • 4.2 Proxy添加/與不添加/
    • 4.3 根據請求設備進行調度
  • 五、 Nginx多級代理獲取真實IP
    • 5.1 多級代理獲取地址概述
    • 5.2 多級代理獲取地址實踐
    • 5.1 多級代理獲取地址概述
      • 5.2.1.環境準備
      • 5.2.2 配置一級代理
      • 5.2.3 配置二級代理
      • 5.2.4 配置三級代理
      • 5.2.5 配置webserver
      • 5.2.5 瀏覽器訪問ip.bertwu.net,觀察并分析各節點日志
    • 5.3 RealiP模塊獲取真實IP

一、可道云專案結合redis快取部署

redis快取可道云專案資料及會話,加快網站訪問速度

環境準備:

主機名應用環境外網IP(WAN)內網IP(LAN)
web01nginx+php10.0.0.7172.16.1.7
redis01redis172.16.1.41
db01mysql (mariadb)172.16.1.51

1.下載可道云開源代碼,部署在web01服務器上,

可道云官網下載

下載原始碼,解壓到指定目錄,授權,

[root@web01 ~]# wget wget https://static.kodcloud.com/update/download/kodbox.1.22.zip
[root@web01 ~]# mkdir /code/kedaoyun -p
[root@web01 ~]# unzip kodbox.1.22.zip -d /code/kedaoyun
[root@web01 ~]# chmod -R www.www /code/kedaoyun

2.撰寫組態檔

[root@web01 conf.d]# cat kedaoyun.conf 
server {
	listen 80;
	server_name kdy.bertwu.net;
	root /code/kedaoyun;

	location / {
		index index.php;
	}
	location ~ .*\.php$ {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
		
	}

}

3.mysql資料庫授權遠程登錄,確保db01開啟了遠程連接用戶,

MariaDB [(none)]> grant all privileges on *.* to 'app'@'172.16.1.%' identified by '123kod456';

4.db01上創建可道云資料庫

MariaDB [(none)]> create database kodbox;
Query OK, 1 row affected (0.00 sec)

5.配置hosts檔案,瀏覽器訪問 kdy.bertwu.net
在這里插入圖片描述
6. redis服務器上安裝redis并啟用

[root@redis01 ~]# yum install redis -y

7.配置 redis 監聽在本地的內網網卡上

[root@redis01 ~]# sed -i '/^bind/c bind 127.0.0.1 172.16.1.41' /etc/redis.conf

8.啟動redis

[root@redis01 ~]# systemctl start redis
[root@redis01 ~]# systemctl enable redis
[root@redis01 ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 172.16.1.41:6379        0.0.0.0:*               LISTEN      1262/redis-server 1 
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1262/redis-server 1

9.接入redis
在這里插入圖片描述
10.查看redis已經有用戶的資料了

127.0.0.1:6379> keys *
 1) "ac3e2_UserModel_getInfoFull_ID_1"
 2) "43abe268181757bedee0e410ac6c5e4b"
 3) "ac3e2_SystemOption_System.storageList"
 4) "ac3e2_SystemOption_System.sourceAuthList"
 5) "ac3e2_UserModel_getInfoSimple_ID_1"
 6) "ac3e2_SystemOption_System.noticeList"
 7) "ac3e2_UserTagSourceModel_listData_ID_0"

二、Nginx負載均衡會話共享

1.1 什么是會話保持

會話(Session)跟蹤是Web程式中常用的技術,用來跟蹤用戶的整個會話,常用的會話跟蹤技術是Cookie與Session,Cookie通過在客戶端記錄資訊確定用戶身份,Session通過在服務器端記錄資訊確定用戶身份,當用戶登陸一個網站服務器,網站服務器會將用戶的登陸資訊存盤下來(存盤下來的內容叫 Session )以保證我們能夠一直處于 ”登陸在線“ 狀態,

1.2 為什么需要會話保持

由于我們使用的是負載均衡輪詢機制,會導致用戶請求分散在不同的節點,從而造成會話無法保持,假設用戶A,通過負載均衡登陸了網站,此時會話資訊存盤在A節點,那么當它一重繪,負載均衡會將請求分發給B節點,那么B節點沒有用戶A的登陸資訊,就會提示用戶A登陸,當A用戶點擊登陸時又會將請求分發給C節點,從而造成用戶A無法實作會話保持,

1.3 Cookie機制、Session機制、token機制

請參考:
Cookie與Session
徹底理解cookie,session,token的區別
cookie保存在客戶端,但是不安全,session存在服務器端,由服務器保存,但是會增加服務器壓力,而且負載均衡機制會調度在不同節點,token是結合了兩者的優勢,

1.4 如何實作會話保持

  1. 粘性session:指Ngnix每次都將同一用戶的所有請求轉發至同一臺服務器上,及Nginx的 IP_hash,
  2. session復制(幾乎不用):每次session發生變化,就廣播給集群中的服務器,使所有的服務器上的session相同,
  3. session共享:快取session至記憶體資料庫中,使用redis,memcached實作,(可以設定過期時間,過期自動清理)
  4. session持久化:將session存盤至資料庫中,像操作資料一樣操作session,(會導致資料庫大量臟資料,幾乎不用)

1.5 會話保持場景實踐

環境準備:

主機名應用環境外網IP(WAN)內網IP(LAN)
web01nginx+php10.0.0.7172.16.1.7
web02nginx+php10.0.0.8172.16.1.8
db01mysql(mariadb)172.16.1.41
redis01redis172.16.1.41
lb01nginx負載均衡10.0.0.5172.16.1.51

1.下載 下載phpmyadmin專案
官網
2.解壓到指定目錄制作軟連接,授權

[root@web01 ~]# unzip phpMyAdmin-5.1.1-all-languages.zip -d /code # 解壓
[root@web01 ~]# cd /code/
[root@web01 code]# ln -s phpMyAdmin-5.1.1-all-languages/ phpmyadmin # 制作軟連接
[root@web01 code]# ll
lrwxrwxrwx  1 root root   31 Aug 18 19:57 phpmyadmin -> phpMyAdmin-5.1.1-all-languages/
[root@web01 code]# chown -R www.www phpmyadmin/  # 授權

3.修改 phpmyadmin 連接遠程的資料庫

[root@web01 code]# cd phpmyadmin/
[root@web01 phpmyadmin]# cp config.sample.inc.php config.inc.php # 修改樣本名,然后修改內容
[root@web01 phpmyadmin]# vim config.inc.php
$cfg['Servers'][$i]['host'] = '172.16.1.51';

4撰寫nginx組態檔

[root@web01 conf.d]# cat phpmyadmin.conf 
server {
	listen 80;
	server_name phpmyadmin.bertwu.net;
	root /code/phpmyadmin;
	location / {
	index index.php index.htmp;
	
	}
	location ~ .*\.php$ {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
	} 
}

[root@web01 conf.d]# nginx -t
[root@web01 conf.d]# systemctl reload nginx

5.db01端授權遠程用戶登錄

MariaDB [(none)]> grant all privileges on *.* to 'app'@'172.16.1.%' identified by '123guest456';
Query OK, 0 rows affected (0.00 sec)

7.瀏覽器測驗是否連接成功
8.web02節點同樣的部署
9.撰寫負載均衡nginx組態檔
撰寫一份 proxy 負載均衡的組態檔,將請求調度到后端 web 節點

[root@lb01 conf.d]# cat lb_phpmyadmin.conf 
upstream lb_phpmyadmin {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}

server {
	listen 80;
	server_name phpmyadmin.bertwu.net;
	location / {
		proxy_pass http://lb_phpmyadmin;
		include proxy_params;
	}
}


[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# nginx -t

其中proxy_params配置如下

[root@lb01 nginx]# cat proxy_params 
# ip
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# http version
proxy_http_version 1.1;
proxy_set_header Connection "";

# timeout
proxy_connect_timeout 120s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;

# buffer
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
為什么要接入redis,是因為需要共享session ,否則負載均衡時候,客戶第一次請求后端,服務器下發的session與第二次請求攜帶給后端的cookie總是不能在同一主機,所以導致永遠都登錄不上,解決方案有多種,可以用ip_hash、 url_hash、(缺點是只能調度到某一個節點,請求資料傾斜),如果想調度到任意節點都不影想會話不掉線,建議使用 redis的session共享方案,

10.redis01服務器上安裝redis并啟用

[root@redis01 ~]# yum install redis -y

11.配置 redis 監聽在本地的內網網卡上

[root@redis01 ~]# sed -i '/^bind/c bind 127.0.0.1 172.16.1.41' /etc/redis.conf

12.啟動redis

[root@redis01 ~]# systemctl start redis
[root@redis01 ~]# systemctl enable redis
[root@redis01 ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 172.16.1.41:6379        0.0.0.0:*               LISTEN      1262/redis-server 1 
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1262/redis-server 1

13.配置php連接Redis
1.修改 /etc/php.ini 檔案,[所有節點都需要操作]

[root@web01 conf.d]# vim /etc/php.ini
session.save_handler = redis
session.save_path = "tcp://172.16.1.41:6379"
;session.save_path = "tcp://172.16.1.41:6379?auth=123456" #如果redis存在密碼,則使用該方式

2.注釋 php-fpm.d/www.conf 里面的兩條內容,否則 session 內容會一直寫入 /var/lib/php/session 目錄中,從而造成會話共享失敗,(所有節點都需要操作)

[root@web01 conf.d]# vim /etc/php-fpm.d/www.conf 
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session

3.重啟 php-fpm 服務,(所有節點都需要操作)

[root@web01 conf.d]# php-fpm -t
[root@web01 conf.d]# systemctl restart nginx

14.測驗集群會話共享
1.瀏覽器查看請求回應的cookie資訊

在這里插入圖片描述
2檢查 redis 中是否存在 cookie 對應的 session 資訊

[root@redis01 ~]# redis-cli
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "PHPREDIS_SESSION:b7681e67c147e7ce1e296a5b650b9b4d"
127.0.0.1:6379> 

3.此時用戶的 cookie 始終都不會發生任何變化,無論請求被負載調度到那一臺后端web 節點服務器都不會出現沒有登陸情況,

三、 后端節點例外容錯機制

使用nginx負載均衡時,如何將后端請求超時的服務器流量平滑的切換到另一臺上?如果后臺服務連接超時,Nginx是本身是有機制的,如果出現一個節點down掉的時候,Nginx會更據你具體負載均衡的設定,將請求轉移到其他的節點上,但是,如果后臺服務連接沒有down掉,而是回傳了錯誤例外碼 如:504、502、500,該怎么辦?

3.1 配置語法

# 當其中一臺回傳錯誤碼 404,500 等錯誤時,可以分配到下一臺服務器程式繼續處理,提高平臺訪問成功率,
proxy_next_upstream  error | timeout | http_500 | http_502 | http_503 | http_504 |http_404;

3.2 場景示例

blog專案為例,如果有一個節點php-fpm服務例外停止,這樣前端用戶請求頁面就會時而502時而正常,用戶體驗度極差,
在這里插入圖片描述
解決方案:

[root@lb01 conf.d]# cat proxy_blog.conf 
upstream blog {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name blog.bertwu.net;
	location / {
		proxy_pass http://blog;
		proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
		proxy_next_upstream_tries 2; # 嘗試的次數
		proxy_next_upstream_timeout 3s; # 嘗試的超時時間
		include /etc/nginx/proxy_params;
	}
}

四、Nginx負載均衡調度場景

4.1 根據uri進行調度(路由)

在這里插入圖片描述
由于資源有限,每個集群其實是一臺主機,基于開放多埠模擬集群中的多臺主機,

主機名應用環境外網IP(WAN)內網IP(LAN)開放埠
web01nginx10.0.0.7172.16.1.78081, 8082
web02nginx10.0.0.8172.16.1.88081, 8082
lb01nginx10.0.0.5172.16.1.580

web01配置如下:

[root@web01 conf.d]# cat uri.conf 
server {
	listen 8081;
	server_name uri.bertwu.net;
	root /code/user1;
	location / {
		index index.html;
	}
}

server {
	listen 8082;
	server_name uri.bertwu.net;
	root /code/user2;
	location / {
		index index.html;
	}
}


[root@web01 conf.d]# mkdir /code/user1
[root@web01 conf.d]# mkdir /code/user2
[root@web01 conf.d]# echo 'user-8081' > /code/user1/index.html
[root@web01 conf.d]# echo 'user-8082' > /code/user2/index.html
[root@web01 conf.d]# nginx -t
[root@web01 conf.d]# systemctl reload nginx

web02配置如下:

[root@web02 conf.d]# cat uri.conf 
server {
	listen 8081;
	server_name uri.bertwu.net;
	root /code/pass1;
	location / {
		index index.html;
	}
}

server {
	listen 8082;
	server_name uri.bertwu.net;
	root /code/pass2;
	location / {
		index index.html;
	}
}


[root@web02 conf.d]# mkdir /code/pass1
[root@web02 conf.d]# mkdir /code/pass2
[root@web02 conf.d]# echo 'pass-8081' > /code/pass1/index.html
[root@web02 conf.d]# echo 'pass-8082' > /code/pass2/index.html
[root@web02 conf.d]# nginx -t
[root@web02 conf.d]# systemctl reload nginx

lb01負載均衡配置如下:

[root@lb01 conf.d]# cat lb_uri.conf 
upstream user {
	server 172.16.1.7:8081;
	server 172.16.1.7:8082;
}

upstream pass {
	server 172.16.1.8:8081;
	server 172.16.1.8:8082;
}


server {
	listen 80;
	server_name uri.bertwu.net;
	
	location /user {
		proxy_pass http://user;
		include proxy_params;
	}
	
	location /pass {
		proxy_pass http://pass;
		include proxy_params;
	}
}
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl reload nginx

前端修改完hosts檔案后訪問http://uri.bertwu.net/user 或http://uri.bertwu.net/pass,都會報404錯誤,打開任意一個節點的錯誤日志發現:

2021/08/19 00:22:01 [error] 2804#2804: *198 open() "/code/user1/user" failed (2: No such file or directory), client: 172.16.1.5, server: uri.bertwu.net, request: "GET /user HTTP/1.1", host: "uri.bertwu.net"

TMD 竟然路徑成了 /code/user1/user ,這是為什么?

4.2 Proxy添加/與不添加/

在使用proxy_pass反向代理時,最后結尾添加/和不添加/有什么區別?

proxy_pass http://localhost:8080;
proxy_pass http://localhost:8080/;
不添加時
#用戶請求URL: /user/index.html
#請求到達Nginx負載均衡: /user/index.html
#Nginx負載均衡到后端節點: /user/index.html

添加/時
#用戶請求URL: /user/index.html
#請求到達Nginx負載均衡: /user/index.html
#Nginx負載均衡到后端節點: /index.html

1.帶 / 意味著Nginx代理會修改用戶請求的URL,將location匹配的URL進行洗掉,
2.不帶 / 意味著Nginx代理不會修改用戶請求的URL,而是直接代理到后端應用服務器

上述問題只需要在prox_pass后面加/,代碼如下:

[root@lb01 conf.d]# cat lb_uri.conf 
upstream user {
	server 172.16.1.7:8081;
	server 172.16.1.7:8082;
}

upstream pass {
	server 172.16.1.8:8081;
	server 172.16.1.8:8082;
}


server {
	listen 80;
	server_name uri.bertwu.net;
	
	location /user {
		proxy_pass http://user/;
		include proxy_params;
	}
	
	location /pass {
		proxy_pass http://pass/;
		include proxy_params;
	}
}

方案二,創建/code/user1/user 目錄,將/code/user1/index.htm 移動到code/user1/user/index.html ,其他節點同理,

4.3 根據請求設備進行調度

在這里插入圖片描述

[root@lb01 conf.d]# cat agent.conf 
upstream phone {
	server 172.16.1.7:80;
	
}

upstream pc {
	server 172.16.1.8:80;
}



server {
	listen 80;
	charset utf-8;
	include proxy_params;
	default_type text/html;
	server_name agent.bertwu.net;
	location / {
		if ($http_user_agent ~* 'android|iphone|ipad') {
			proxy_pass http://phone;
		}
	
		if ($http_user_agent ~* 'MSIE|Trident') {
			return 200 "瀏覽器真棒!";
		}
		proxy_pass http://pc;
	}
	
}

[root@web02 conf.d]# cat pc.conf 
server {
	listen 80;
	server_name agent.bertwu.net;
	root /code/pc;
	location / {

		index index.html;
	}
}
server {
	listen 80;
	server_name agent.bertwu.net;
	root /code/phone;
	location / {
		index index.html;
	}
}

在這里插入圖片描述
在這里插入圖片描述

五、 Nginx多級代理獲取真實IP

5.1 多級代理獲取地址概述

用戶發起請求,沿途可能會經過多級代理,最終抵達應用節點,那應用節點如何獲取客戶端真實IP地址
1:通過X-Forwarded-For透傳客戶端的真實IP實作方式
2:使用Nginx RealIP模塊實作客戶端地址透傳
在這里插入圖片描述

5.2 多級代理獲取地址實踐

5.1 多級代理獲取地址概述

用戶發起請求,經過多級代理之后, web服務器無法直接獲取到客戶端真實的IP地址,
$remote_addr獲取的是上級反反向代理的IP地址, 反向代理服務器在轉發請求的http頭資訊中,
增加http_x_forwarded_for資訊,用來記錄客戶端IP地址和客戶端請求的服務器地址的詳細程序,

5.2.1.環境準備

一級代理 10.0.0.5 proxy_node1
二級代理 10.0.0.7 proxy_node2
三級代理 10.0.0.9 proxy_node3
真實節點 10.0.0.8 webserver
路徑:
10.0.0.1--->10.0.0.5----->10.0.0.9------>10.0.0.8

5.2.2 配置一級代理

[root@lproxy_node1 conf.d]# cat proxy_node1.conf 
server {
	listen 80;
	server_name ip.bertwu.net;
	location / {
		proxy_pass http://10.0.0.7:80;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		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;
	}
}

5.2.3 配置二級代理

[root@proxy_node2 conf.d]# cat proxy_node2.conf 
server {
	listen 80;
	server_name ip.bertwu.net;
	location / {
		proxy_pass http://10.0.0.9:80;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		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;
	}
}

5.2.4 配置三級代理

[root@proxy_node3 conf.d]# cat proxy_node3.conf 
server {
	listen 80;
	server_name ip.bertwu.net;
	location / {
		proxy_pass http://10.0.0.8:80;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		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;
	}
}

5.2.5 配置webserver

web02.conf  web.conf    
[root@weberver conf.d]# cat web.conf 
server {
	listen 80;
	server_name ip.bertwu.net;
	root /code/ip;
	location / {
		index index.html;
	}
}

5.2.5 瀏覽器訪問ip.bertwu.net,觀察并分析各節點日志

以下是各級代理的訪問日志資訊,請注意觀察第一段$remote_addr 和最后一段$http_x_forwarded_for的資訊,

# 一級代理日志
10.0.0.1 - - [20/Aug/2021:00:24:12 +0800] "GET / HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "-"
# 二級代理日志
10.0.0.5 - - [20/Aug/2021:00:24:12 +0800] "GET / HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1"
# 三級代理日志
172.16.1.7 - - [20/Aug/2021:00:24:12 +0800] "GET / HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1, 10.0.0.5"
# webserver日志
10.0.0.9 - - [20/Aug/2021:00:24:12 +0800] "GET / HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1, 10.0.0.5, 10.0.0.7"

5.3 RealiP模塊獲取真實IP

使用nginx Realip_module獲取多級代理下的客戶端真實IP地址,在后端Web節點上添加如下配置即可(Realip需要知道所有沿途經過的代理節點的IP地址或IP段);

[root@web02 conf.d]# cat web.conf 
server {
	listen 80;
	server_name ip.bertwu.net;
	set_real_ip_from 10.0.0.5;
	set_real_ip_from 10.0.0.7;
	set_real_ip_from 10.0.0.9;
	real_ip_header X-Forwarded-For;
	real_ip_recursive on;
	root /code/ip;
	location / {
		index index.html;
	}
}


#set_real_ip_from:真實服務器上一級代理的IP地址或者IP段,可以寫多行   
#real_ip_header:從哪個header頭檢索出需要的IP地址    
#real_ip_recursive:遞回排除set_real_ip_from里面出現的IP,其余沒有出現的認為是用戶真實IP

再次查看日志:

# 一級代理日志
10.0.0.1 - - [20/Aug/2021:01:06:39 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "-"
# 二級代理日志
10.0.0.5 - - [20/Aug/2021:01:06:39 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1"
# 三級代理日志
10.0.0.7 - - [20/Aug/2021:01:06:39 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1, 10.0.0.5"
# webserver日志
10.0.0.1 - - [20/Aug/2021:01:06:39 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1, 10.0.0.5, 10.0.0.7"

可以看到,最終結果是

10.0.0.1 - - [20/Aug/2021:01:06:39 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" "10.0.0.1, 10.0.0.5, 10.0.0.7"

10.0.0.5、10.0.0.7、10.0.0.9都出現在出現在set_real_ip_from中,僅僅10.0.0.1沒出現,那么他就被認為是用戶真實的ip地址,同時會被賦值到 $remote_addr變數中,這樣我們的程式無需做任何修改,直接使用$remote_addr變數即可獲取真實IP地址,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/295378.html

標籤:其他

上一篇:分布式框架之(二)分布式RPC框架Dubbo入門

下一篇:LeetCode通關:堆疊和佇列六連,匹配問題有絕招

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more