高性能的服務器的架設php
對於高性能網站 ,請求量大,如何支撐?css
1方面,要減小請求html
對於開發人員----合併css, 背景圖片, 減小mysql查詢等.mysql
2: 對於運維 nginx的expires ,利用瀏覽器緩存等,減小查詢.linux
3: 利用cdn來響應請求nginx
4: 最終剩下的,不可避免的請求----服務器集羣+負載均衡來支撐.sql
因此,來到第4步後,就不要再考慮減小請求這個方向了.apache
而是思考如何更好的響應高併發請求.瀏覽器
大的認識-------既然響應是不可避免的,咱們要作的是把工做內容」平均」分給每臺服務器.緩存
最理想的狀態 每臺服務器的性能都被充分利用.
服務器介紹:
服務器IP:
A 192.168.1.201
B 192.168.1.202
C 203
D204
Root: zixue.it
1臺 A
RAM: 2G
HD: 500G
3臺 B, C, D
RAM: 8G
Hd : 200G
1500萬的企業數據在A號服務器的Mysql上。因此咱們就讓A號服務器做爲mysql服務器
實際生產環境中,服務器之間是有區別的,有的服務器cpu很是強(好比有8個cpu,每一個cpu還8個核心,計算浮點數很是厲害,優酷土豆作視頻壓縮,用這個沒錯),有的用來作存儲cpu不必定強,可是硬盤必定要強,有的計算不復雜,可是進程多,好比跑100個php-fpm進程,內存要大。因此要搞清楚服務器當前的業務是計算密集,仍是io密集,仍是進程密集。
靜態內容,html,緩存,在B
memcached,
步驟:
1:A號服務器
1.1安裝 mysql
1.2並導入數據.
注意:先把表中的索引去掉,加快導入速度
2: C號服務器:
2.1: 編譯PHP
注意: enbale-fpm , with-mysql=mysqlnd (編譯成獨立fpm進程,支持mysql,)
2.2: 下載第3方的memcached擴展 編譯進來
3: D號服:
3.1 編譯 memcached
4: B號服:
編譯nginx ,並配置
Cd /app/pcre-8.12
./configure
Make && make install
Cd nginx-1.2.7
./configure --prefix=/usr/local/nginx --add-module=/app/ngx_http_consistent_hash-master
注:紅線部分是nginx的第3方模塊,須要本身下載.
安裝統計模塊,便於觀察nginx的狀態
./configure --prefix=/usr/local/nginx/ --add-module=/app/ngx_http_consistent_hash-master --with-http_stub_status_module
注:stub_status_module是一個內建的模塊,編譯的時候,直接加進去就好了
裝完以後,去配置文件配置一下該模塊
配置完以後在192.168.1.100機器上訪問192.168.1.202/status就能看到統計信息了,統計信息格式以下圖。
壓力測試:
安裝apache的時候,會有一個小工具ab,位置爲:/usr/local/apache/bin/ab
咱們執行上述命令對nginx服務器進行壓力測試,1000併發,50000次請求:結果爲下圖。
失敗數量達到3721,很很差。
再進行2000併發 80000請求的壓力測試:直接報出Too many open files的錯誤。
緣由:linux系統,以簡潔爲美。一切皆文件,咱們打開socket鏈接,也被視爲文件,咱們一會兒打開2000個鏈接,系統以爲打開的太多了,不容許。
咱們經過以下命令查看:默認只容許打開1024個,果真如此
用以下命令修改一下,讓他一會兒能打開20000個
使用status查看,併發最多才800多,咱們的併發設置是2000,問題很大
又測試了併發 請求
nginx相應請求:
那麼高併發,無非就是要考慮系統可否讓我同時創建如此多的socket鏈接,和系統是否容許我同時打開那麼多的文件(萬兆網卡,那時硬件的問題,不考慮。)
因此排查問題也要注意這兩點
主要從系統的dmesg和nginx的error.log錯誤日誌來觀察
下面咱們對於上面高併發出現的問題進行排查,
首先看錯誤日誌
下面的錯誤日誌:報出,open() 「index.html」 failed ,估計就是因爲操做系統是否容許你一個進程打開那麼多的html文件形成的
使用 ulimit –n命令查看,果真如此。那麼進行修改。
修改完畢後,又有洪水攻擊
下面圖片 顯示 洪水攻擊,每次請求帶一個cookie、過去,防止洪水攻擊
這不是一個文件,是一個系統運行狀態值
咱們把上面的配置作成一個腳本,方便咱們之後使用
一個工做進程容許打開幾個文件 worker_rlimit_nofile 10000,放到全局區
此時再進行壓力測試:輕鬆達到
查看status也是如此
1w併發
再壓力測試
高併發網站 keepalive 2s之內 最好不用
keepalive沒了
Php 安裝配置
1 tar -xzvf /path/’
2 cd /path/
3 .configure --prefix=/usr/local/php –
實際生產中,公司都是用多臺服務器專門跑php,每臺服務器的9000端口來跑php,可是咱們這裏沒有那麼多臺服務器,咱們只有一臺,那麼咱們就多開幾個端口來跑php,9000,9001,9002,9003,9004
php-fpm是獨立的進程,是由父進程管理着子進程子進程也監聽者對應的端口。每來一個請求,就會起一個子進程,可是若是長時間沒有請求,那麼這個子進程可能就消失(回收)了。可是對於高併發的網站,基本沒有停歇的時候,因此咱們就不必讓子進程進行回收了
讓每個主進程地下都存活8個子進程,
5*8=40個子進程,一個進程站30多兆內存,加起來也就1-2G
作這麼多不一樣的配置文件,目的就是讓他監聽不一樣的端口。咱們能夠看到php-fpm.conf監聽的是9000端口-以下圖。在php-fpm9001.conf裏面應該監聽的就是9001端口,其餘同理。
啓動的時候咱們寫一個腳本,-y表明,選擇使用什麼配置文件啓動php
執行該腳本以後,執行ps aux |grep php會發現有80個進程嚴陣以待,等待着請求呢
修改nginx的配置文件,添加以下
test.php在 203上,位置爲/var/www
關防火牆
服務器集羣與負載均衡搭建完畢
1:問題 C-->A 的mysql鏈接很慢
解決: my.cnf中的[mysqld]節點中,添加
skip-name-resolve // 這句話使mysql鏈接時忽略解析域名,在制定Mysql權限時,只能根據IP限制,不能根據域名限制.
2: 問題 當memcache中沒有相應的數據,從後臺回調數據時,
http的狀態碼是404,(雖然內容正常),這樣不利於SEO
解決: nginx/conf/nginx.conf
error_page 404 =200 /callback.php; // 這樣 404被改寫成200來響應中
壓力測試:
模擬 前0-10萬是熱數據,
10-20萬是冷門數據
請求熱數據 0-10,請求9次
請求准予數據 請求1次, -----100萬次的請求.
優化思路:
nginx響應請求
1:創建socket鏈接
2: 打開文件,並沿socket返回.
排查問題,也要注意觀察這兩點,
主要從系統的dmesg ,和nginx的error.log來觀察
優化過程
1:判斷nginx的瓶頸
1.1: 首先把ab測試端的性能提升,使之能高併發的請求.
易出問題: too many open files
緣由 : ab在壓力測試時,打開的socket過多
解決: ulimit -n 30000 (重啓失效)
觀察結果: nginx 不須要特殊優化的狀況下, 5000個鏈接,1秒內響應.
知足要求,但 wating狀態的鏈接過多.
1.2: 解決waiting進程過多的問題.
解決辦法: keepalive_timeout = 0;
即: 請求結果後,不保留tcp鏈接.
在高併發的狀況下, keepalive會佔據大量的socket鏈接.
結果: waiting狀態的鏈接明顯減小.
1.3: 解決服務端 too many open files
分析: nginx要響應,
1是要創建socket鏈接,
2 是要讀本地文件
這兩個者限制.
由上圖可看出,nginx的問題容易出在2點上:
1: nginx接受的tcp鏈接多,可否創建起來?
2: nginx響應過程,要打開許多文件 ,可否打開?
第1個問題: 在內核層面(見下)
第2個問題 (見下)
系統內核層面:
net.core.somaxconn = 4096 容許等待中的監聽
net.ipv4.tcp_tw_recycle = 1 tcp鏈接快速回收
net.ipv4.tcp_tw_reuse = 1 tcp鏈接重用
net.ipv4.tcp_syncookies = 0 不抵禦洪水攻擊
ulimit -n 30000
Nginx層面:
解決: nginx.conf 下面: work_connection 加大
worker_connections 10240;
Worker_rlimit_nofiles 10000;
Keepalive_timeout 0;
Nginx---->php-fpm之間的優化
n
如上圖,在不少個nginx來訪問fpm時, fpm的進程要是不夠用, 會生成子進程.
生成子進程須要內核來調度,比較耗時,
若是網站併發比較大,
咱們能夠用靜態方式一次性生成若干子進程,保持在內存中.
方法 -- 修改php-fpm.conf
Pm = static 讓fpm進程始終保持,不要動態生成
Pm.max_children= 32 始終保持的子進程數量
Php-mysql的優化
Linux機器下 ,php 經過IP鏈接其餘mysql服務器時,容易出的問題
能ping能,但connect不到.
通常是由:mysql服務器的防火牆影響的.
併發1萬鏈接,響應時間過長.
優化思路: 同上的nginx
1: 內核層面,加大鏈接數,並加快tcp回收
2: mysql層面,增大鏈接數
3: php層面,用長鏈接,節省鏈接數
4: 用memcached緩存,減輕mysql負擔
具體:
1.1 , PHP服務器增大 ulimint -n選項
1.2 mysql服務器內核配置
添加或修改以下選項
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 0
# syscttl -p 使修改當即生效
2.1 修改mysql.cnf
Vi /etc/my.conf
# service mysqld restart 重啓mysql
3.1 PHP層面 ,用長鏈接
Mysql_connect ---> mysql_pconnect
注: pconnect 在PHP以apache模塊的形式存在時,無效果.
Nginx+phjp+mysql+nginx
在引入memcached後,性能提高不明顯,甚至還略有降低
memcached使50%的請求變快了,可是一部分,反倒慢了.
緣由在於--PHP->memcached也要創建tcp鏈接,代價挺高,
但緩存了數據以後,就省去了mysql的查詢時間.
總結: memcached適合存複雜的sql,尤爲是鏈接查詢/模糊查詢的sql結果
Memcached服務器的優化(集中在內核的ipv4設置上,再也不重複)
d號服務器
4臺機器防火牆所有關掉