1. 程式人生 > >第十二章LNMP架構下預習筆記

第十二章LNMP架構下預習筆記

12.17 Nginx負載均衡

配置檔案

upstream qq_com
{
    ip_hash;
    server 61.135.157.156:80;
    server 125.39.240.113:80;
}
server
{
    listen 80;
    server_name www.qq.com;
    location /
    {
        proxy_pass      http://qq_com;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
12.18 ssl原理

12.19 生產ssl金鑰對

12.20 Nginx配置ssl

mkdir /data/wwwroot/aming.com

cd /usr/local/src/nginx-1.14.0

./configure --help | grep ssl

./configure --prefix=/usr/local/nginx --with-http_ssl_module

make && make install

12.21 php-fpm的pool

[www]

listen = /tmp/www.sock

listen.mode=666

user = php-fpm

group = php-fpm

pm = dynamic

pm.max_children = 50

pm.start_servers = 20

pm.min_spare_servers = 5

pm.max_spare_servers = 35

pm.max_requests = 500

rlimit_files = 1024

12.22 php-fpm慢執行日誌

vim /usr/local/php-fpm/etc/php-fpm.d/www.conf

request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log

注意:sock

vim /data/wwwroot/test.com/sleep.php

<?php 
echo "test slow log";
sleep(2);
echo "done";
?>
 

12.23 open_basedir

php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

open_basedir 和虛擬主機裡面定義要一致

配置錯誤日誌:

vim /usr/local/php-fpm/etc/php.ini

display_errors = Off

log_errors = On
error_log = /usr/local/php-fpm/var/log/php_errors.log

error_reporting = E_ALL

touch /usr/local/php-fpm/var/log/php_errors.log

chmod 777 /usr/local/php-fpm/var/log/php_errors.log

/etc/init.d/php-fpm restart

把basedir故意改錯

12.24 php-fpm程序管理

課堂串講

一、負載均衡

1、什麼是負載均衡

nginx僅僅作為nginx proxy反向代理使用,因為這個反向代理功能表現的效果就是負載均衡叢集的效果,所以就稱為nginx負載均衡。

反向代理與負載均衡的區別:

普通負載均衡軟體,例如LVS,其實現的功能只是對請求資料包的轉發(也可能會改寫資料包)、傳遞,其中DR模式明顯的特徵是從負載均衡下面的節點服務來看,接收到的請求還是來自訪問負載均衡器的客戶端的真實使用者;而反向代理就不一樣了,反向代理接收訪問使用者的請求後,會代理使用者重新發起請求代理下的節點伺服器,最後把資料返回給客戶端使用者,在節點伺服器看來,訪問的節點伺服器的客戶端使用者就是反向代理伺服器了,而非真實的網站訪問使用者。

總之,負載均衡轉發使用者請求的資料包,而nginx反向代理是接收使用者的請求然後重新發起請求去請求其後面的節點。

實現nginx負載均衡的元件主要有兩個:

ngx_http_proxy_module:proxy代理模組,用於把請求後拋給伺服器節點或upstream伺服器池。

ngx_http_upstream_module:負載均衡模組,可以實現網站的負載均衡功能及節點的健康檢查。

簡單負載均衡示意圖

2、nginx upstream模組

nginx負載均衡功能依賴於ngx_http_upstream_module模組,所支援的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。

upstream test  # upstream是關鍵字,後面的test是upstream叢集組的名稱,可以自己定義,呼叫時使用這個名字
{
   server 192.168.10.203:80  weight=1;#server 關鍵字,後面可以是ip或者域名。如果不指定埠,則預設是80,最後以逗號結束。weight表示權重。
   server 192.168.10.204:80  weight=2;
}

** server標籤引數說明:**

server 192.168.10.203:80 負載均衡後面的RS(Real Server)配置,可以是IP或域名,如果埠不寫,預設是80埠。高併發場景下,IP可以換成域名,通過DNS做負載均衡。

weight=1 代表伺服器權重,預設是1。權重數字越大表示接收的請求比例越大。

max_fails=1 nginx嘗試連線後端主機失敗的次數。這個數值是配合proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream這三個引數來使用的。當nginx接收後端伺服器返回這三個引數定義的狀態碼時,會將這個請求轉發給正常工作的後端伺服器,例如404、502、503。max_fails預設是1,企業場景建議2~3。比如京東1次。

backup 表示熱備配置,備用伺服器。當負載均衡演算法為ip_hash時,後端伺服器在負載均衡中的狀態不能是weight和backup。

fail_timeout=10s 在定義max_fails的失敗次數後,距離下次檢查的間隔時間,預設是10s。如果max_fails=5,就檢查5次,如果5次都是502,那麼等待10s再去檢查一次,如果還是502,在不重新載入nginx配置的情況下,每隔10s再檢查一次。常規業務設定為2~3秒。比如京東3秒。

down 標記這個伺服器不可用。這引數配合ip_hash使用。

3、負載均衡排程演算法

排程演算法一般分為兩類:

第一類:靜態排程演算法,即負載均衡器根據自身設定的規則進行分配,不需要考慮後端節點伺服器的情況,例如:rr、wrr、ip_hash等演算法都屬於靜態排程演算法。

第二類:動態排程演算法,即負載均衡器會根據後端節點的當前狀態來決定是否分發請求,例如:連線數少的優先獲得請求,響應時間短的優先獲得請求。例如:least_conn、fair等都屬於動態排程演算法。

常見演算法介紹:
(1)rr輪詢(預設排程演算法,靜態排程演算法) 按客戶端請求順序把客戶端的請求逐一分配到不同的後端節點伺服器,相當於LVS中的rr演算法,如果後端節點伺服器宕機,宕機的伺服器會被自動從節點伺服器 池中剔除,以使客戶端的使用者訪問不受影響。新的請求會分配給正常的伺服器。
(2)wrr(權重輪詢,靜態排程演算法)
在rr輪詢演算法的基礎上加上權重,即為權重輪詢演算法。當使用該演算法時,權重和使用者訪問成正比,權重值越大,被轉發的請求也就越多。可以根據伺服器的配置和效能指定權重值大小。
(3)ip_hash(ip雜湊,靜態排程演算法)
每個請求按客戶端IP的hash結果分配,當新的請求到達時,先將其客戶端IP通過雜湊演算法算出一個值,在隨後的客戶端請求中,客戶端IP的雜湊值只要相同,就會被分配至同一臺伺服器,該排程演算法可以解決動態網頁的session共享問題,但有時候會導致請求分配不均,即無法保證1:1的負載均衡。
(4)fair(動態排程演算法) 該演算法會根據後端節點伺服器的響應時間來分配請求,響應時間短的優先分配。這是更加智慧的排程演算法。此種演算法可以依據頁面大小和載入時間長短智慧地進行負載均衡,也就是根據後端伺服器的響應時間來分配請求,響應時間短的優先分配。但nginx本身不支援fair演算法,必須下載upstream_fair模組。
(5)least_conn
該演算法會根據後端節點伺服器的連線數來決定分配情況,哪個機子連線數少就分發。 (6)url_hash演算法 與ip_hash演算法類似,這裡是根據訪問URL的hash結果來分配請求,讓每個URL定向到同一個後端伺服器,後端伺服器為快取伺服器時效果顯著。nginx本身bu支援url_hash演算法,必須下載相關包。
(7)一致性hash演算法
一致性hash演算法一般用於代理後端伺服器業務為快取服務(如squid、memcached)的場景,通過將使用者請求的URL或指定字串進行計算,然後排程到後端伺服器上,此後任何使用者查詢同一個URL或指定字串都會被排程到這一臺伺服器上,因此後端的每個節點快取的內容都是不同的,一致性hash演算法可以解決後端某個或某幾個節點宕機後,快取的資料動盪最小。

簡單nginx負載均衡程式碼如下:

upstream test
{
   ip_hash;
   server 192.168.10.203:80;
   server 192.168.10.204:80;
}
server
{
   listen 80;
   server_name test.com
   location /
   {
      proxy_pass http://test;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwared_For $proxy_add_x_forwared_for;
   }
}

4、http_proxy_module模組

1、proxy_pass指令介紹

proxy_pass指令屬於ngx_http_proxy_module模組,此模組可以將請求轉發到另一臺伺服器。在實際的反向代理工作中,會通過location功能匹配指定的URL,然後把接收到的符合匹配URL的請求通過proxy_pass拋給定義好的upstream節點池。

例如:

location  /name/
{
    proxy_pass http://127.0.0.1/haha/;
}
location  /haha/test/
{
    proxy_pass http://127.0.0.1;
}
location  /name/
{
    rewrite /name/([^/]+)  /users?name=$1  break;
    proxy_pass http://127.0.0.1;
}

2、http proxy模組引數

nginx的代理功能通過http proxy模組來實現。該模組相關引數:

proxy_set_header 設定http請求header項傳給後端伺服器節點,例如,可以實現讓後端的伺服器節點獲取訪問客戶端使用者的真實ip。

proxy_next_upstream 設定故障轉移,語法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off ...; 預設值: proxy_next_upstream error timeout;

client_body_buffer_size 用於指定客戶端主題緩衝區大小。

proxy_connect_timeout 表示反向代理與後端節點伺服器連線的超時時間,即發起握手等候響應的超時時間。

proxy_send_timeout 表示代理後端伺服器的資料回傳時間,即在規定時間之內後端伺服器必須傳完所有的資料,否則,nginx將斷開這個連線。

proxy_read_timeout 設定nginx從代理的後端伺服器獲取資訊的時間,表示連線建立後,nginx等待後端伺服器的響應時間,其實是nginx已經進入後端的排隊之中等候處理的時間。

proxy_buffer_size 設定緩衝區大小,預設為proxy_buffers設定的大小。

proxy_buffers 設定緩衝區的數量和大小,nginx從代理的後端伺服器獲取的響應資訊,會放到緩衝區。

proxy_busy_buffers_size 用於設定系統很忙時可以使用的proxy_buffers大小,官方推薦的大小為proxy_buffers*2

proxy_temp_file_write_size 指定proxy快取臨時檔案的大小。

二、SSL

SSL證書可以到各大機構申請,現在基本都是收費的。當然也可以自己製作,自己製作的證書沒有被瀏覽器廠商承認,所以只能自己測試用。

下面演示自己製作證書,配置SSL。

(1)生成私鑰和公鑰

1、生成一個私鑰

假設網站目錄是/htdocs/ssl

[[email protected] ~]# mkdir /htdocs/ssl
[[email protected] ~]# cd /htdocs/ssl/
[[email protected] ssl]# openssl genrsa -des3 -out tmp.key 2048
Generating RSA private key, 2048 bit long modulus
..........................................................................................+++
..................................................................................................................................................................+++
e is 65537 (0x10001)
Enter pass phrase for tmp.key:
Verifying - Enter pass phrase for tmp.key:
[[email protected] ssl]# 

生成私鑰需要設定密碼,假設密碼是:123456

生成的這個私鑰是有密碼的,現在要把這密碼去掉:

[[email protected] ssl]# openssl rsa -in tmp.key -out pri.key
Enter pass phrase for tmp.key:
writing RSA key
[[email protected] ssl]# 

輸入密碼123456後即可,此時的私鑰pri.csr就沒有密碼了。

2、生成請求證書

用剛才的沒有加密的私鑰去生成請求證書。

[[email protected] ssl]# openssl req -new -key pri.key -out pri.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[[email protected] ssl]# 

反正是用來自己測試,所以上面的很多資訊都沒有填寫。

3、生成公鑰

用前面生成的沒有密碼的私鑰(pri.key)和請求檔案(pri.csr)去生成公鑰

[[email protected] ssl]# openssl x509 -req -days 365 -in pri.csr -signkey pri.key -out public.crt
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting Private key
[[email protected] ssl]# 

OK,完成。私鑰是:pri.key,公鑰是:public.crt。

(2)配置ssl

建立虛擬主機,假設配置檔案為:ssl.conf,網站目錄為:/htdocs/ssl/

[[email protected] ssl]# vim /usr/local/nginx/conf.d/ssl.conf
server {
   listen 443;
   server_name ssl.com;
   index index.html index.php;
   root /htdocs/ssl;


   ssl on;
   ssl_certificate  /htdocs/ssl/public.crt;
   ssl_certificate_key /htdocs/ssl/pri.key;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  location ~ \.php$ {
     root /htdocs/ssl;
     fastcgi_pass 127.0.0.1:9000;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
     include fastcgi_params;
  }
}


/usr/local/nginx/conf/fastcgi_params檔案中新增:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

(3)建立測試頁

[[email protected] ssl]# echo "<?php phpinfo(); ?>" > /htdocs/ssl/index.php

重啟nginx服務和清空防火牆。

[[email protected] ssl]# /usr/local/nginx/sbin/nginx -s reload
[[email protected] ssl]# iptables -F

瀏覽器開啟:https:192.168.10.205

提示不安全,因為是自己製作的證書。

點選高階--新增例外即可。

OK顯示成功:

三、php_fpm之pool

每一個pool可以監聽一個埠。預設的pool是[www] 比如自定義一個pool,名字為[haha]

[[email protected] ~]# vim /usr/local/php7/etc/php-fpm.d/www.conf
[haha]
listen = /tmp/haha.sock
listen.mode = 666
user = nginx
group = nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

儲存退出,重新載入

[[email protected] ~]# /usr/local/php7/sbin/php-fpm -t
[03-Jul-2018 21:00:27] NOTICE: configuration file /usr/local/php7/etc/php-fpm.conf test is successful

[[email protected] ~]# /etc/rc.d/init.d/php-fpm reload
Reload service php-fpm  done
[[email protected] ~]# 

檢視一下程序:

[[email protected] ~]# ps aux |grep php-fpm
root       4976  1.0  0.4 224596  7088 ?        Ss   21:00   0:00 php-fpm: master process (/usr/local/php7/etc/php-fpm.conf)
nginx      4977  1.0  0.7 228764 13964 ?        S    21:00   0:00 php-fpm: pool www
nginx      4978  1.3  0.7 228764 13988 ?        S    21:00   0:00 php-fpm: pool www
nginx      4979  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4980  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4981  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4982  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4983  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4984  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4985  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4986  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4987  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4988  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4989  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4990  0.4  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4991  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4992  0.3  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4993  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4994  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4995  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4996  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4997  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4998  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
root       5028  0.0  0.0 112704   968 pts/1    S+   21:01   0:00 grep --color=auto php-fpm
[[email protected] ~]# 

OK,自定義的haha已啟動。

四、php-fpm的慢執行日誌

在[www]pool中新增以下兩行內容

[[email protected] ~]# vim /usr/local/php7/etc/php-fpm.d/www.conf
request_slowlog_timeout = 1
slowlog = /usr/local/php7/var/log/www-slow.log

重啟php-fpm

[[email protected] ~]# systemctl restart php-fpm

測試:

網站目錄為:/htdocs/slow

[[email protected] ~]# mkdir /htdocs/slow
[[email protected] ~]# vim /htdocs/slow/slow.php
<?php

   echo "test slow log";
   sleep(2);
   echo "done";
?>

虛擬主機配置檔案:

[[email protected] ~]# vim /usr/local/nginx/conf.d/slow.conf
server {
    listen       8088;
    server_name  node1;
    location / {
        root   /htdocs/slow;
        index  index.php index.html index.htm;
    }
    location ~ \.php$ {
        root           /htdocs/slow;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME   /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }
 }
 

清空防火牆,關閉selinux,重啟nginx,php-fpm

[[email protected] ~]# iptables -F
[[email protected] ~]# setenforce 0
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload
[[email protected] ~]# /etc/rc.d/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
[[email protected] ~]# 

使用curl命名測試:

[[email protected] ~]# curl -x127.0.0.1:8088 node1/slow.php -I
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 13:25:58 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.5

[[email protected] ~]# 

檢視日誌:

[[email protected] ~]# cat  /usr/local/php7/var/log/www-slow.log 

[03-Jul-2018 21:26:57]  [pool www] pid 5736
script_filename = /htdocs/slow/slow.php
[0x00007fd06581d090] sleep() /htdocs/slow/slow.php:4
[[email protected] ~]# 

日誌顯示/htdocs/slow/slow.php檔案的第4行使用了sleep()

五、php-fpm之open_basedir

可以針對每個虛擬主機設定basedir,也可針對每個pool設定basedir。

[[email protected] ~]# vim /usr/local/php7/etc/php-fpm.d/www.conf
php_admin_value[open_basedir]=/htdocs/test2:/tmp
[[email protected] ~]# /etc/rc.d/init.d/php-fpm restart

測試:

[[email protected] ~]# curl -x127.0.0.1:80 haha1/index.php
No input file specified.
[[email protected] ~]# curl -x127.0.0.1:80 haha1/index.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 14:09:08 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.5

[[email protected] ~]# 

把php_admin_value[open_basedir]改為/htdocs/test1:/tmp 重啟php-fpm,再測試:

[[email protected] ~]# curl -x127.0.0.1:80 haha1/index.php -I
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 14:10:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.5
Set-Cookie: zbx_sessionid=28227a56a4d998b32ef6c00517de0347; HttpOnly
Set-Cookie: PHPSESSID=js5lu9rp93lc8i49paq6qaicdm; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

[[email protected] ~]# 

OK,正常。

六、php-fpm程序管理

配置解釋:

pm = dynamic:動態程序管理,也可以是static

pm.max_children = 50 : 最大子程序數

pm.start_servers = 20 :  啟動服務時會啟動的程序數

pm.min_spare_servers = 5 : 定義在空閒時段,子程序數的最少值,如果達到這個值,php-fpm服務會自動派生新的子程序

pm.max_spare_servers = 35 : 定義在空閒時段,子程序數的最大值,如果高於這個值,php-fpm服務會清理空閒的子程序

pm.max_requests = 500 :定義一個字程序最多可以處理多少個程序,這裡設定成500,也就是說在一個php-fpm的子程序最多可以處理500個,若達到這個數值時,它就會自動退出。

rlimit_files = 1024 :設定檔案開啟描述符的rlimit限制. 預設值: 系統定義值
系統預設可開啟控制代碼是1024,可使用 ulimit -n檢視,ulimit -n 2048修改(臨時修改)。

擴充套件

針對請求的uri來代理 http://ask.apelearn.com/question/1049

根據訪問的目錄來區分後端的web http://ask.apelearn.com/question/920

nginx長連線 http://www.apelearn.com/bbs/thread-6545-1-1.html

nginx演算法分析 http://blog.sina.com.cn/s/blog_72995dcc01016msi.html

nginx中的root和alias區別 http://blog.csdn.net/21aspnet/article/details/6583335

nginx的alias和root配置 http://www.ttlsa.com/nginx/nginx-root_alias-file-path-configuration/

http://www.iigrowing.cn/shi-yan-que-ren-nginx-root-alias-location-zhi-ling-shi-yong-fang-fa.html 這個更詳細

ssl:https://coding.net/u/aminglinux/p/nginx/git/blob/master/ssl/ca.md