Nginx之反向代理配置(二)
- 2020 年 3 月 6 日
- 筆記
前文我們聊了Nginx的防盜鏈、反向代理以及開啟nginx代理快取,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12417130.html;今天我們繼續說nginx的反向代理,上一篇主要就說了下nginx反向代理http協議的使用,被代理RUL包含和不包含RUI的處理邏輯;我們可以把這種前後端都用同樣的協議理解為同構代理,就是說前端用戶訪問nginx是http或https協議,代理伺服器訪問後端的真正提供服務的伺服器也是基於http協議,這種前後端都是使用同一種協議,我們就說這是同構;同理有同構就有異構,異構就是前後端使用的協議不同,比如前端用戶使用http或https協議,代理和後端伺服器使用fastcgi協議,這種就叫異構;互聯網上絕大部分網站都不是純html靜態網頁,很多網站都是有自己的應用伺服器,比如,我們用戶訪問的數據是需要一段腳本,或者某一程式執行後的數據,那麼我們就把後面需要執行腳本的伺服器叫應用伺服器;nginx作為web伺服器它雖然有很多功能,但是它自己沒有執行某些腳本的能力比如php腳本,通俗的講,nginx只可以處理靜態文本,不能自己執行php腳本(需藉助其他應用伺服器),它和httpd類似,httpd還可以動態的載入php模組,讓其擁有執行php腳本的能力,nginx沒有,為了實現這樣的功能,nginx就支援通過fastcgi協議向後端代理客戶端請求一個自己不能處理的資源;當然類似的協議還有很多比如,scgi、uwsgi等等;像這種異構的架構上,它的原理是這樣的,客戶端請求某一腳本資源,比如,index.php這個文件,如果我們不把用戶的請求代理到後端應用伺服器上,客戶端看到的數據是index.php里的腳本內容,這顯然是不合情理的;那怎麼辦呢?通常情況我們需要在nginx伺服器上配置,用戶訪問某某.php結尾的URL時,我們就讓它幹嘛幹嘛,通過這種匹配用戶的URL去做代理,把用戶的請求代理到後端伺服器,讓後端應用伺服器把腳本執行完,然後把執行後的數據返回給代理,再由代理響應給客戶端;如果是後端應用伺服器需要某些數據,需要到資料庫里去拿數據,很可能應用伺服器此時還會扮演客戶端角色,通過某種協議去資料庫拿數據;我們可以看到最終我們用戶看到的網頁里的內容,它來自很多伺服器,所以說一個動態網站上由很多台伺服器共同完成一個處理請求的結果,我們可以理解成,每個伺服器處理自己擅長的事務,分工合作,最後把處理好的數據由代理響應給客戶端;
ngx_http_fastcgi_module:此模組實現了nginx允許將用戶請求代理至fastcgi 伺服器
1、fastcgi_pass address:設置fastcgi伺服器的地址,此地址可以是IP加埠的形式,也可以是域名或者UNIX域套接字路徑;此選項可用於location 和if in location 配置段中
示例
fastcgi_pass localhost:9000
提示:以上配置意思是,通過fastcgi協議反代本機的9000埠上的服務響應;
fastcgi_pass Unix:/tmp/fastcgi.socket;
提示:以上表示設置fastcgi地址是本機/tmp/fastcgi.socket文件;
2、fastcgi_index name;設置fastcgi的默認主頁資源名稱;此指令可用於http、server、location配置段中
3、fastcgi_param parameter value [if_not_empty]:設置一個參數,用於傳遞給後端fastcgi伺服器,參數的值可以是文本,變數,或者二者的組合。
示例
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
提示:以上配置表示把SCRIPT_FILENAME等於/home/www/scripts/php$fastcgi_script_name傳遞給fastcgi伺服器,$fastcgi_script_name表示用戶請求的腳本名稱;意思是告訴fastcgi伺服器該把那個腳本執行了返回給客戶端(這裡的客戶端通常指代理伺服器)
fastcgi_param QUERY_STRING $query_string;
提示:我們知道一個腳本傳遞不同的參數,執行的結果就會不同;以上配置表示把請求的腳本的參數通過QUERY_STRING變數保存,並傳遞給後端fastcgi伺服器,讓其運行某腳本時,把QUERY_STRING保存的值作為參數傳遞給腳本;當然我們向後端傳遞的東西很多,不便一一寫出來,也不太可能一一寫到配置文件中,在nginx的配置目錄里有一個文件,專門存放nginx上的變數對應後端fastcgi伺服器上的變數的一個配置文件fastcgi.conf 通常我們把這個配置文件用include指令來導入到我們需要定義nginx變數通過fastcgi變數傳遞給fastcgi伺服器;
示例
location ~* .php$ { root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name; include fastcgi_params; }
提示:以上配置表示匹配用戶URI,如果用戶URI是以.php結尾的,就通過fastcgi協議代理至本機的127.0.0.1:9000埠進行處理(執行),fastcgi伺服器默認主頁資源名叫index.php,並告訴fastcgi伺服器到/usr/share/nginx/html/下去找用戶請求的資源腳本,如果還有其他參數和指令要傳遞,就使用/etc/nginx/fastcgi_params中的定義來把nginx的變數保存的值傳遞給後端fastcgi伺服器,以上是反代動態php網頁的配置示例,有了以上配置 nginx就可以作為代理伺服器響應客戶端請求動態腳本php的能力了;
[root@www nginx]# vim /etc/nginx/conf.d/proxy.conf server { server_name www.test.com; proxy_cache proxy_cache; # proxy_cache_key $request_uri; # proxy_cache_methods GET HEAD; proxy_cache_valid 200 302 15m; proxy_cache_valid 404 1m; # proxy_cache_use_stale http_500 http_502; location /en/docs/ { proxy_pass http://nginx.org; } location ~* /(.*).php$ { root /app/php_scripts; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /app/php_scripts$fastcgi_script_name; include /etc/nginx/fastcgi_params; } } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ "conf.d/proxy.conf" 23L, 500C written [root@www nginx]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@www nginx]# mkdir /app/php_scripts -p [root@www nginx]# cat >> /app/php_scripts/test.php <?php phpinfo(); ?> ^C [root@www nginx]# cat /app/php_scripts/test.php <?php phpinfo(); ?> [root@www nginx]# nginx -s reload [root@www nginx]#
提示:在上面配置前需要先安裝好php-fpm,安裝好後需要更改/etc/php-fpm.d/www.conf里的user 和group,通常情況要看前端代理是用那個用戶啟動的,我們後端就用那個用戶啟動即可,我們前端代理商nginx,這裡需要更改成nginx即可,這樣修改後,保存配置,然後啟動php-fpm,然後在本機就可以看到127.0.0.1:9000就處於監聽狀態了;以上配置表示用戶請求.php結尾的資源都反代至127.0.01:9000進行處理;並且明確說明了後端fastcgi主頁資源名稱為index.php,後端應用伺服器的根路徑為/app/php_scripts;fastcgi_param SCRIPT_FILENAME /app/php_scripts$fastcgi_script_name同nginx里的root alias指令的作用相同,指定用戶訪問的URI對應磁碟上的路徑,相當於指定後端fastcgi伺服器的工作目錄吧;
提示:可以看到我們訪問test.php是能夠被php-fpm伺服器執行並返回執行後的結果;
4、fastcgi_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];此指令同proxy_cache_path一樣,作用定義fastcgi的代理快取;其中levels表示定義快取目錄的級別,最多3級,每級最多2個字元;keys_zone=name:size表示k/v映射的記憶體空間的名稱及大小;inactive=time表示非活動時長;max_size=size表示指定磁碟上用於快取路徑的存放快取的空間上限;
5、fastcgi_cache zone |off;調用指定的快取空間來快取數據;可用於http,server,location配置段中
6、fastcgi_cache_key string;定義用作快取項的key的字元串;
7、fastcgi_cache_methods GET|HEAD|POST ……;定義那些請求方法使用快取;默認是GET和HEAD
8、fastcgi_cache_min_uses number;定義快取空間中的快取項在inactive定義的非活動時間內至少要被訪問到此處所指定的次數方可被認為活動的快取項,不被清理;
9、fastcgi_cache_valid[code] tiem;設定不同的響應碼各自快取的時長;
10、fastcgi_keep_conn on | off;:設置是否保持連接,默認情況下,FastCGI伺服器將在發送響應後立即關閉連接。但是,當這個指令被設置為值on時,nginx將指示FastCGI伺服器保持連接打開。
示例
提示:在定義快取空間時,必須要在http配置段定義,以上表示定義一個fastcgi的快取空間,其名稱為php_cache,在記憶體中使用10m的空間,在物理磁碟上的路徑為/cache/proxy/php-fpm/目錄下,最大空間為2g;
提示:以上配置表示使用fastcgi的快取空間php_cache,快取key為$request_uri,就是把用戶請求的uri hash作為快取路由,什麼意思呢,就是nginx查找快取是通過hash什麼來查找快取的,上面的配置就是定義nginx把用戶請求的URI作為hash對象;對用戶請求用的方法是GET 或HEAD方法時,使用快取;快取最小命中次數為3次,也就說在非活動時長內,該快取項命中次數小於3次就會被認為該快取是無效的,在下次檢查快取的有效性,就會被清理;對響應碼是200 或302的資源快取15分鐘,對404響應碼的資源快取1分鐘;開啟和後端的fastcgi伺服器的長連接;
提示:可以看到我們訪問test.php頁面時,在我們定義的快取空間里生成了快取,但是我們訪問了test.php這一個頁面,為什麼會快取三項呢?其實我們可以打開瀏覽器的web開發者模式,查看它請求和響應的情況
提示:可以看到我們訪問test.php這個頁面,其背後是3次請求,所以我們在快取空間里看到有三條快取項,其實快取空間里的快取項每一個快取項就代表一個快取資源,我們是可以通過cat命令查看快取項里的內容的;如下
提示:我們可以看到裡面的快取項紀錄的資訊,其中有一項KEY 就是我們指定的fastcgi_cache_key 說指定變數的值;我們查看快取項里的內容很可能出現亂碼,原因是快取的內容有二進位,或者其他字元編碼的內容;
以上就是nginx作為反向代理伺服器代理動態資源的介紹,總結一點,nginx代理動態資源和代理http資源的思想是類似的,只是使用的指令不一樣;尤其對於快取,兩者的思想幾乎完全一致,只是使用的模組和指令不同而已;對於動態資源我們除了要指定被代理的地址外,還需要指定被代理端資源路徑,導入nginx變數與fastcgi變數對應的配置指令文件;對於快取,兩者沒有什麼區別;