Nginx負載均衡
負載均衡 建立在現有網絡結構之上,它提供了一種廉價有效透明的方法擴展網絡設備和服務器的帶寬、增加吞吐量、加強網絡數據處理能力、提高網絡的靈活性和可用性。負載均衡,英文名稱爲Load Balance,其意思就是分攤到多個操作單元上進行執行,例如Web服務器、FTP服務器、企業關鍵應用服務器和其它關鍵任務服務器等,從而共同完成工作任務。
如何配置負載均衡呢?藉助一個模塊叫做upstream,可以在該模塊下可以定義多個IP和端口。
現在藉助qq.com來做個演示,如何知道qq.com的IP呢?可以用命令dig,沒找到命令安裝bind-utils包。
[root@zyshanlinux-001 ~]# yum install -y bind-utils
獲取qq.com的IP,其實就是域名解析。
[root@zyshanlinux-001 ~]# dig qq.com ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> qq.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31325 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;qq.com. IN A ;; ANSWER SECTION: qq.com. 394 IN A 111.161.64.48 qq.com. 394 IN A 111.161.64.40 ;; Query time: 53 msec ;; SERVER: 119.29.29.29#53(119.29.29.29) ;; WHEN: 日 7月 08 20:26:44 CST 2018 ;; MSG SIZE rcvd: 67
拿這2個IP來做負載均衡,配置文件
[root@zyshanlinux-001 ~]# vim /usr/local/nginx/conf/vhost/load.conf
配置內容
upstream qq ##upstream模塊,qq可以是任何名字 { ip_hash; ##在多臺服務器提供同一個服務的時候,支持用戶始終登錄到A服務器上,避免登錄到B機器上導致沒有在B機器上輸入過密碼登錄不成功。 server 111.161.64.48:80; ##如果是80,那麼:80可以省略掉。 server 111.161.64.40:80; } server { listen 80; server_name www.qq.com; location / { proxy_pass http://qq; ##http://後面跟上面起的名字qq。 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
保存退出,在未加載配置前
[root@zyshanlinux-001 vhost]# curl -x127.0.0.1:80 www.qq.com
會訪問到默認虛擬主機默認頁
加載配置後,就會訪問到QQ的真正主頁去。
[root@zyshanlinux-001 vhost]# /usr/local/nginx/sbin/nginx -t [root@zyshanlinux-001 vhost]# /usr/local/nginx/sbin/nginx -s reload [root@zyshanlinux-001 vhost]# curl -x127.0.0.1:80 www.qq.com
注意:Nginx不支持代理https,即是443端口;如果用戶要登錄https,只能通過代理服務器(https)訪問web服務器的http(即80端口),間接達到訪問443(https)。
ssl原理
瀏覽器發送一個https的請求給服務器;
服務器要有一套數字證書,可以自己製作(後面的操作就是阿銘自己製作的證書),也可以向組織申請,區別就是自己頒發的證書需要客戶端驗證通過,纔可以繼續訪問,而使用受信任的公司申請的證書則不會彈出>提示頁面,這套證書其實就是一對公鑰和私鑰;
服務器會把公鑰傳輸給客戶端;
客戶端(瀏覽器)收到公鑰後,會驗證其是否合法有效,無效會有警告提醒,有效則會生成一串隨機數,並用收到的公鑰加密;
客戶端把加密後的隨機字符串傳輸給服務器;
服務器收到加密隨機字符串後,先用私鑰解密(公鑰加密,私鑰解密),獲取到這一串隨機數後,再用這串隨機字符串加密傳輸的數據(該加密爲對稱加密,所謂對稱加密,就是將數據和私鑰也就是這個隨機字符串>通過某種算法混合在一起,這樣除非知道私鑰,否則無法獲取數據內容);
服務器把加密後的數據傳輸給客戶端;
客戶端收到數據後,再用自己的私鑰也就是那個隨機字符串解密;
生成ssl密鑰對
生成密鑰需要工具,生成的密鑰放到/usr/local/nginx/conf路徑下
[root@zyshanlinux-001 vhost]# cd /usr/local/nginx/conf
生成私鑰key文件,還要輸入私鑰密碼
[root@zyshanlinux-001 conf]# 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:
轉換key,取消密碼,否則每次訪問網頁都要輸入私鑰密碼;轉換Key後,tmp.key是以後密碼的,zyshan.key是沒密碼的,可以把tmp.key刪除。
[root@zyshanlinux-001 conf]# openssl rsa -in tmp.key -out zyshan.key Enter pass phrase for tmp.key: writing RSA key [root@zyshanlinux-001 conf]# rm -f tmp.key
生成證書請求文件;需要填入一些信息,因爲測試用可以隨便填。
[root@zyshanlinux-001 conf]# openssl req -new -key zyshan.key -out zyshan.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]:11 State or Province Name (full name) []:bei^H^H^H^H^H^H Locality Name (eg, city) [Default City]:guangzhou Organization Name (eg, company) [Default Company Ltd]:guangzhou Organizational Unit Name (eg, section) []:zysyhan^H^H Common Name (eg, your name or your server's hostname) []:zyshan Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:zyshan An optional company name []:zyshan
需要拿這個文件和之前生成的私鑰一起生產公鑰文件。
[root@zyshanlinux-001 conf]# openssl x509 -req -days 365 -in zyshan.csr -signkey zyshan.key -out zyshan.crt Signature ok subject=/C=11/ST=bei\x08\x08\x08\x08\x08\x08/L=guangzhou/O=guangzhou/OU=zysyhan\x08\x08/CN=zyshan/[email protected] Getting Private key
這樣就有三個文件了。crt公鑰、csr請求文件、key私鑰。
[root@zyshanlinux-001 conf]# ls zyshan. zyshan.crt zyshan.csr zyshan.key
Nginx配置ssl
配置文件
vim /usr/local/nginx/conf/vhost/ssl.conf
配置文件內容
server { listen 443; server_name zyshan.com; index index.html index.php; root /data/wwwroot/zyshan.com; ssl on; ssl_certificate zyshan.crt; ssl_certificate_key zyshan.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; }
創建測試目錄
[root@zyshanlinux-001 vhost]# mkdir /data/wwwroot/zyshan.com
-t檢查語法,unknown directive “ssl” 報錯是因爲之前安裝nginx時的時候配置參數沒有把ssl配置上去,需要到nginx目錄去重新編譯。
[root@zyshanlinux-001 nginx-1.12.1]# cd /usr/local/src/nginx-1.12.1/ [root@zyshanlinux-001 nginx-1.12.1]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module [root@zyshanlinux-001 nginx-1.12.1]# make&&make install
檢查,多了一個參數:--with-http_ssl_module
[root@zyshanlinux-001 nginx-1.12.1]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.12.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module
檢查語法,重啓Nginx,查看端口多了一個443端口。
[root@zyshanlinux-001 nginx-1.12.1]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@zyshanlinux-001 nginx-1.12.1]# /etc/init.d/nginx restart Restarting nginx (via systemctl): [ 確定 ] [root@zyshanlinux-001 nginx-1.12.1]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4672/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1088/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1447/master tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 4672/nginx: master tcp6 0 0 :::22 :::* LISTEN 1088/sshd tcp6 0 0 ::1:25 :::* LISTEN 1447/master tcp6 0 0 :::3306 :::* LISTEN 1405/mysqld
創建測試/data/wwwroot/zyshan.com/index.html文件
[root@zyshanlinux-001 nginx-1.12.1]# cd /data/wwwroot/zyshan.com/ [root@zyshanlinux-001 zyshan.com]# ls index.html index.php
把zyshan.com配置到hosts去
[root@zyshanlinux-001 zyshan.com]# vi /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.106.150 www.qq123.com www.19.com www.zyshan.com 127.0.0.1 www.19.com zyshan.com
測試成功,只是證書是自己頒發的,瀏覽器認爲不安全,報錯而已。
[root@zyshanlinux-001 zyshan.com]# curl https://zyshan.com curl: (60) Peer's certificate issuer has been marked as not trusted by the user. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
php-fpm的pool
vim /usr/local/php/etc/php-fpm.conf//在[global]部分增加 include = etc/php-fpm.d/*.conf mkdir /usr/local/php/etc/php-fpm.d/ cd /usr/local/php/etc/php-fpm.d/ vim www.conf //內容如下 [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 繼續編輯配置文件 vim aming.conf //內容如下 [aming] listen = /tmp/aming.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 /usr/local/php/sbin/php-fpm –t /etc/init.d/php-fpm restart
php-fpm慢執行日誌
配置文件
vim /usr/local/php-fpm/etc/php-fpm.d/www.conf//加入如下內容 request_slowlog_timeout = 1 ##超過1秒的錄入日誌 slowlog = /usr/local/php-fpm/var/log/www-slow.log ##錄入的日誌路徑
測試,寫入一個休眠2秒的php,慢日誌就會把這個慢了2秒的日誌記錄下來,標記出是這句休眠語句導致的慢。
配置nginx的虛擬主機test.com.conf,把unix:/tmp/php-fcgi.sock改爲unix:/tmp/www.sock 重新加載nginx服務 vim /data/wwwroot/test.com/sleep.php//寫入如下內容 <?php echo “test slow log”;sleep(2);echo “done”;?> curl -x127.0.0.1:80 test.com/sleep.php cat /usr/local/php-fpm/var/log/www-slow.log
php-fpm定義open_basedir
vim /usr/local/php-fpm/etc/php-fpm.d/aming.conf//加入如下內容 php_admin_value[open_basedir]=/data/wwwroot/aming.com:/tmp/ 創建測試php腳本,進行測試 再次更改aming.conf,修改路徑,再次測試 配置錯誤日誌 再次測試 查看錯誤日誌
php-fpm進程管理
配置文件中,pm = dynamic動態進程管理;動態的時候後面的所有參數都生效。這裏配置註釋不用“#”而是用“;”
[root@zyshanlinux-001 etc]# cat php-fpm.conf [global] pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] listen = /tmp/php-fcgi.sock ;listen = 127.0.0.1:9000 listen.mode = 666 user = php-fpm group = php-fpm pm = dynamic ;pm = static 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
測試,一開始默認啓動20個子進程
[root@zyshanlinux-001 etc]# ps aux |grep www php-fpm 1486 0.0 0.2 227244 4712 ? S 20:13 0:00 php-fpm: pool www php-fpm 1487 0.0 0.2 227244 4712 ? S 20:13 0:00 php-fpm: pool www php-fpm 1488 0.0 0.2 227244 4712 ? S 20:13 0:00 php-fpm: pool www php-fpm 1489 0.0 0.2 227244 4712 ? S 20:13 0:00 php-fpm: pool www php-fpm 1490 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1491 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1492 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1493 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1494 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1495 0.0 0.2 227244 4716 ? S 20:13 0:00 php-fpm: pool www php-fpm 1496 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1497 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1498 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1499 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1500 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1501 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1502 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1504 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1505 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www php-fpm 1506 0.0 0.2 227244 4720 ? S 20:13 0:00 php-fpm: pool www root 5029 0.0 0.0 112720 972 pts/0 R+ 22:50 0:00 grep --color=auto www
配置pm = static靜態,只有後面跟着的那一行生效,一開始就運行50個子進程,後面的參數都不生效了。
pm = static pm.max_children = 50
檢查語法,重啓服務,測試,確實是默認啓動50個子進程
[root@zyshanlinux-001 etc]# /usr/local/php-fpm/sbin/php-fpm -t [08-Jul-2018 22:57:13] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful [root@zyshanlinux-001 etc]# /etc/init.d/php-fpm restart Gracefully shutting down php-fpm . done Starting php-fpm done [root@zyshanlinux-001 etc]# ps aux |grep www php-fpm 5088 0.0 0.2 227244 4716 ? S 22:57 0:00 php-fpm: pool www php-fpm 5089 0.0 0.2 227244 4716 ? S 22:57 0:00 php-fpm: pool www php-fpm 5090 0.0 0.2 227244 4720 ? S 22:57 0:00 php-fpm: pool www php-fpm 5091 0.0 0.2 227244 4720 ? S 22:57 0:00 php-fpm: pool www php-fpm 5092 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5093 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5094 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5095 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5096 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5097 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5098 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5099 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5100 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5101 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5102 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5103 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5104 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5105 0.0 0.2 227244 4724 ? S 22:57 0:00 php-fpm: pool www php-fpm 5106 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5107 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5108 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5109 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5110 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5111 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5112 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5113 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5114 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5115 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5116 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5117 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5118 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5119 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5120 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5121 0.0 0.2 227244 4728 ? S 22:57 0:00 php-fpm: pool www php-fpm 5122 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5123 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5124 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5125 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5126 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5127 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5128 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5129 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5130 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5131 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5132 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5133 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5134 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5135 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5136 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www php-fpm 5137 0.0 0.2 227244 4732 ? S 22:57 0:00 php-fpm: pool www
pm.max_children = 50 //最大子進程數,ps aux可以查看pm.start_servers = 20 //啓動服務時會啓動的進程數pm.min_spare_servers = 5 //定義在空閒時段,子進程數的最少數量,如果達到這個數值時,php-fpm服務會自動派生新的子進程。pm.max_spare_servers = 35 //定義在空閒時段,子進程數的最大值,如果高於這個數值就開始清理空閒的子進程。pm.max_requests = 500 //定義一個子進程最多處理的請求數,也就是說在一個php-fpm的子進程最多可以處理這麼多請求,當達到這個數值時,它會自動退出
拓展:
針對請求的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 這個更詳細
直播拓展:
證書 https://coding.net/u/aminglinux/p/nginx/git/blob/master/ssl/ca.md Nginx幾種負載均衡算法及配置實例 https://blog.whsir.com/post-1482.html Nginx正向代理配置 https://coding.net/u/aminglinux/p/nginx/git/blob/master/proxy/z_proxy.md