ngx_http_proxy_module, ngx_http_upstream_module
ngx_http_proxy_module:實現反向代理及緩存功能
proxy_pass http://{SERVER_IP|UPSTREAM_NAME}/uri
proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size];
proxy_cache zone_name; //緩存名稱
proxy_cache_valid [code] time; //指明不同響應碼內容的緩存時長
proxy_cache_method //只對哪些方法獲取的資源進行緩存,一般使用get
proxy_cache_use_stale error timeout ... //是否使用過期的緩存進行響應
proxy_cache_min_uses //某資源至少響應請求多少次后才被緩存下來
proxy_cache_bypass string: 設置在何種情形下nginx將不從cache取數據的;比如郵件
例如:$cookie_nocache、$arg_nocache 、$http_authorization
proxy_set_header
ngx_http_upstream_module:定義服務器組 http://nginx.org/en/docs/http/ngx_http_upstream_module.html
可以調用服務器組反向代理有:proxy_pass, fastcgi_pass, uwsgi_pass,
upstream name {
server address [parameters];
ip_hash; //基於源地址綁定,比ip_hash更精確的是session綁定機制是cookie記錄,但LVS是沒辦法識別cookie的,因為cookie是應用層數據
}
nginx(2)
1、SNAT模式的大量Client
基於sticky實現session綁定:對應於工作在應用層的程序才擁有的功能
(1)cookie:基於cookie的綁定
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
(2)route:基於路由的綁定
map $cookie_jsessionid $route_cookie {
~.+\.(?P<route>\w+)$ $route;
}
map $request_uri $route_uri {
~jsessionid=.+\.(?P<route>\w+)$ $route;
}
upstream backend {
server backend1.example.com route=a;
server backend2.example.com route=b;
sticky route $route_cookie $route_uri;
}
(3)learn () :基於學習的綁定
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8081;
sticky learn
create=$upstream_cookie_examplecookie
lookup=$cookie_examplecookie
zone=client_sessions:1m;
}
2、least_conn: 調度方法,最少連接(相當於LVS中的wlc算法);
3、keeplive: 激活代理服務器nginx和后端服務器之間的持久連接功能的,專用在upstream,
Syntax: | keepalive |
---|---|
Default: | — |
Context: | upstream |
例子:keepalive一般用在上游服務器是非http服務器時才使用,因為keepalive會損壞http的並發性能,如果后端是專用存儲時(比如基於鍵值存儲的memcache),基於keepalive指令可以使鏈接處於一段時間的長連接,提高查詢性能。
upstream memcached_backend {
server 127.0.0.1:11211;
server 10.0.0.2:11211;
keepalive 32;
}
health_check:只能同在location
使用health_check時建議關閉訪問日志,因為后端服務器不能檢測health_check的檢測是正常請求還是只是用來檢測的

自定義響應首部:
add_header X-Via $server_addr; 自定義響應首部通知客戶端是由誰響應的
add_header X-Cache $upstream_cache_status; 告訴客戶端響應是否命中
首先編輯代理服務器的server配置文件
# vim /etc/nginx/conf.d/default.conf
server { listen 80; server_name localhost; add_header X-Via $server_addr; add_header X-Cache $upstream_cache_status; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } location /forum/ { proxy_cache mycache; proxy_cache_valid 200 1d; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://upservers/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; add_header X-Via $server_addr; //啟用添加自定義頭部 add_header X-Cache $upstream_cache_status; }
Module ngx_http_fastcgi_module模塊介紹
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
proxy_pass http://{SERVER_IP|UPSTREAM_NAME}/uri //proxy_pass指令是把用戶的請求反向代理至上有的web服務器,所以這里的協議是http協議,如果上有的協議不是http協議而是fastcgi協議,就必須使用fastcgi模塊來實現。
fastcgi模塊的意義是:
nginx作為代理服務器,當客戶端發起對nginx代理服務器的php類型資源的請求,比如是index.php,此時nginx代理服務器只是一個靜態內容服務器,所以nginx就會把index.php的文件內容拿過來包裝成響應報文后直接返回給客戶端,但此時響應報文是源代碼,客戶端是看不懂的。
所以應該讓nginx自持php應用代碼的運行,但是nginx自己不支持,所以需要做一個php的服務器。此后nginx在接收到報文時就可以根據請求資源的后綴名進行判斷,一旦是php,nginx就會使用特定協議將請求報文反向代理至php的server上,php服務器將會執行index.php上的代碼並將執行后的結果返回值nginx代理服務器上,然后nginx就會把響應報文進行封裝並返回給客戶端。這又是一種反向代理,但是使用的協議是fastcgi協議而不是http協議。
如何讓nginx支持LNMP:
php是無法作為nginx的模塊的,所以php只能工作於fpm模式
# yum list all *fpm* //查找是否有fpm模塊
Loaded plugins: fastestmirror
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Determining fastest mirrors
* base: mirrors.nwsuaf.edu.cn
* extras: mirrors.neusoft.edu.cn
* updates: mirrors.neusoft.edu.cn
Available Packages
php-fpm.x86_64 5.4.16-45.el7 base
# yum info php-fpm //查看此模塊的詳細信息
# yum install php-fpm //安裝php-fpm模塊
# rpm -ql php-fpm //查看php-fpm安裝信息
/etc/logrotate.d/php-fpm
/etc/php-fpm.conf //主配置文件
/etc/php-fpm.d
/etc/php-fpm.d/www.conf //這里可以查看php監聽的地址,如果php和nginx不在同一主機的話,就需要修改php監聽的地址了
/etc/sysconfig/php-fpm //服務腳本
/run/php-fpm
/usr/lib/systemd/system/php-fpm.service
/usr/lib/tmpfiles.d/php-fpm.conf
/usr/sbin/php-fpm //可執行程序
/usr/share/doc/php-fpm-5.4.16
/usr/share/doc/php-fpm-5.4.16/fpm_LICENSE
/usr/share/doc/php-fpm-5.4.16/php-fpm.conf.default
/usr/share/fpm
/usr/share/fpm/status.html
/usr/share/man/man8/php-fpm.8.gz
/var/log/php-fpm
# systemctl start php-fpm //啟動
# ss -tunl //查看端口
下面讓nginx將用戶的請求基於fastcgi協議發送給php
# vim /etc/nginx/conf.d/default.conf //編輯此文件,啟用php配置段
location ~ \.php$ { root html; //這里的頁面要和上面nginx的web頁面保持一致,修改如下
root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; //向后端傳遞的參數
//SCRIPT_FILENAME是變量名指令,用戶請求的文件名(即變量名$fastcgi_script_name),
通過uri(~ \.php$)的方式傳遞給后端的服務器(127.0.0.1:9000)
include fastcgi_params; //包含另外一個文件
}
# cd /usr/share/nginx/html/ //對主頁面進行修改
# vim index.php
<?php
phpinfo();
?>
# vim /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm; //並在根這里添加index.php
要對/etc/nginx/fastcgi_params做修改
/etc/nginx //在這個文件目錄下有一個fastcgi_params配置文件
fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200;
編輯/etc/nginx/fastcgi_params,將其內容更改為如下內容:
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
此時nginx已經可以和php結合工作了,下面就要解決php和mysql/mariadb結合
# yum install php-mysql
# rpm -ql php-mysql
/etc/php.d/mysql.ini
/etc/php.d/mysqli.ini
/etc/php.d/pdo_mysql.ini
/usr/lib64/php/modules/mysql.so
/usr/lib64/php/modules/mysqli.so
/usr/lib64/php/modules/pdo_mysql.so
# systemctl reload php-fpm
# yum install mariadb-server //安裝mariadb
安裝好mariadb后,驗證php和mariadb是否可以結合工作
# vim /usr/share/nginx/html/index.php
<?php $conn = mysql_connect('127.0.0.1','root',''); if ($conn) echo succ; else echo fail; mysql_close(); ?>
# systemctl stop mariadb //關閉mariadb后在測試
LNAMP :以nginx做代理服務器進行負載均衡,后端的服務器平台是多個LAMP,在這種場景中nginx和后端的LAMP交互時是兩個web服務器之間的交互(http協議),LAMP中的php可以以 apache的模塊進行工作。
動態內容和靜態內容分離:php服務器和MySQL服務器與后端負載均衡的服務器不在同一個服務器上
LNMP, fastcgi_cache fastcgi協議的緩存服務器
Syntax: |
[ |
---|---|
Default: | — |
Context: | http //需要定義在http上下文 |
fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
以上是定義位置以及定義方法,定義完成后需要使用fastvgi_cache進行調用
Syntax: | fastcgi_cache |
---|---|
Default: | fastcgi_cache off; |
Context: | http , server , location 使用上下文 |
# vim /etc/nginx/nginx.conf //首先編輯nginx的主配置文件http上下文
fastcgi_cache_path /cache/fastcgi/ levels=1:1 keys_zone=fcgicache:10m inactive=3m max_size=1g;
# vim /etc/nginx/conf.d/default.conf //在對應的location中進行調用
location ~ \.php$ { //對應的php的location中進行調用 fastcgi_cache fcgicache; root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }
# systemctl reload nginx
# mkdir /cache/fastcgi -pv
# ll /cache
total 0
drwx------ 2 nginx root 6 Nov 29 05:02 fastcgi
drwxr-xr-x 4 nginx nginx 24 Nov 28 23:41 nginx
#vim /usr/share/nginx/html/test.php
<?php
phpinfo();
?>

再次刷新時發現X-Cache仍然是MISS,即無法緩存
#vim /etc/nginx/conf.d/default.conf //在php配置段中指明緩存響應碼,如果不指明,就不緩存
fastcgi_cache_valid 200 10m;
fastcgi_cache_valid 302 3m;
fastcgi_cache_valid any 1m;
下面利用ab命令對開啟緩存和不開啟緩存進行性能對比
1、首先關閉fastcgi_cache
# /etc/nginx/conf.d/default.conf
#fastcgi_cache fcgicache;
fastcgi_cache off; //暫時關閉fastcgi_cache
# systemctl reload nginx
# yum install httpd-tools
# ab -n 10000 -c 100 http://192.168.184.142/test.php -n是請求數量,-c是並發量
This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.184.142 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: nginx/1.14.1 Server Hostname: 192.168.184.142 Server Port: 80 Document Path: /test.php Document Length: 43330 bytes Concurrency Level: 100 Time taken for tests: 4.891 seconds Complete requests: 10000 Failed requests: 996 (Connect: 0, Receive: 0, Length: 996, Exceptions: 0) Write errors: 0 Total transferred: 435018878 bytes HTML transferred: 433298878 bytes Requests per second: 2044.69 [#/sec] (mean) Time per request: 48.907 [ms] (mean) Time per request: 0.489 [ms] (mean, across all concurrent requests) Transfer rate: 86863.18 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.5 1 4 Processing: 3 48 13.7 47 114 Waiting: 2 47 13.6 46 113 Total: 5 49 13.6 48 114 Percentage of the requests served within a certain time (ms) 50% 48 66% 53 75% 57 80% 59 90% 67 95% 73 98% 81 99% 84 100% 114 (longest request)
2、開啟fastcgi_cache
# vim /etc/nginx/conf.d/default.conf
fastcgi_cache fcgicache;
#fastcgi_cache off;
#systemctl reload nginx
# ab -n 10000 -c 100 http://192.168.184.142/test.php
This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.184.142 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: nginx/1.14.1 Server Hostname: 192.168.184.142 Server Port: 80 Document Path: /test.php Document Length: 43330 bytes Concurrency Level: 100 Time taken for tests: 0.527 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 435160000 bytes HTML transferred: 433300000 bytes Requests per second: 18986.36 [#/sec] (mean) //與上面的對比差距是非常大的 Time per request: 5.267 [ms] (mean) Time per request: 0.053 [ms] (mean, across all concurrent requests) Transfer rate: 806845.98 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.3 0 4 Processing: 1 5 0.9 5 8 Waiting: 0 5 0.9 5 8 Total: 4 5 0.9 5 8 Percentage of the requests served within a certain time (ms) 50% 5 66% 5 75% 6 80% 6 90% 6 95% 7 98% 7 99% 7 100% 8 (longest request)
練習:
(1) root為同一路徑;
(2) root為不同的路徑;
location \.php$ {
root /web/app/wp;
}
location / {
root /web/htdocs;
}
如何解決root路徑不同的問題?
(3) fpm server為另一主機;
location \.php$ {
fastcgi_pass fastcgi://192.168.184.142:9000;
}
location / {
root /web/htdocs;
}
總結:
cache:
proxy_cache
fastcgi_cache