1. 程式人生 > >web單機優化

web單機優化

mes 基本知識 喜歡 時間戳 adl pro 提升 傳輸 描述符

又得開始寫博客了,目測又要一周一篇了,當然了這不算python跟前端的,個人喜歡notepad++可惜不能放圖片,word什麽的太討厭了

為什麽要單機優化呢,很簡單,因為不論以後是各類集群也好,物理機虛擬機也好,只有將個人優勢發揮到最大才能提升整體的最低限度,因為木桶原理嘛;再一個,窮啊,玩linux那就是得優化,極盡的壓榨操作系統的性能。集群什麽的都是從單機演化出來的,so,優化好單機是你繼續下一步的初始條件

我們從一個請求連接的總流程來看一下我們可優化的點(運維角度)

其實這中間的每一個步驟速度提升都對我們的性能有提升(此時的性能是指用戶的客觀感受,就是開你網頁快不快),每次網站變卡了,領導就說去趕快加點帶寬去,這句話也是對的,帶寬大了,數據發送的時間就會變少,加帶寬肯定是對性能提升有好處的,so現在知道了你們老大其實也是很專業的了吧~~~

好了,不賣萌了,作為專業的運維,我們肯定是希望花合適的時間金錢在最合適的提升位置,這也就是所謂的 “瓶頸點”,因此做優化,找出“瓶頸點”最為關鍵!但是非常可惜我們只能從自己的服務器這面進行優化的進行,因為找出“瓶頸點”這就是一個很現實的事情了,紙上談兵,毫無意義。

因此,進入今天的主題吧,單機web性能優化!

完全單機的web其實是不容易針對優化的,因為所有的服務都需要安放在一臺機器上,常見的就是我們喜歡的lnmp,一臺電腦上要裝nginx、php、mysql,可能還有一些其他的什麽鬼,so,我萌只能進行一些通用的優化了。

技術分享

一.從系統本身限制考慮

先從我們的服務器本身考慮,我們需要使用ulimit 這個熟悉的命令將每個進程可以打開的文件數目加大到65535(默認值1024)並更改系統可打開的總文件數目,為什麽要改這玩意?because on Linux everything is file,so,we must do it!還是不理解,好吧,每當創建一個連接後,這讓條連接都會打開若幹文件,哪怕至少我們也要打開一個小socket,這樣就會占用一個文件,如果連接過多,而單個任務上有限制只允許一共打開1024個文件,那麽後面的連接就進不來了。同理,如果所有任務打開的文件數超過了系統本身允許的上限也不行,所以file-max也是尤為重要的,兩者缺一不可!

1 [[email protected] ~]# ulimit -n
2 1024
3 [[email protected] ~]# ulimit -n 65535
4 [[email protected] ~]# ulimit -n
5 65535
6 [[email protected] ~]# cat /proc/sys/fs/file-max
7 181795
8 [[email protected] ~]# echo "fs.file-max = 6553560" >>/etc/sysctl.conf

二. 提供的服務類型考慮

我們對外提供web服務,那麽我走的肯定是http/https連接了,對內我自己的業務需要連接自己的數據庫,,so,總的來說我走的就是tcp連接,既然如此我們先回顧下經典的三握四揮吧

技術分享

流程及三次握手相關的就不說了就那麽幾下,直接總結揮手重要的

time_wait出現在客戶端主動斷開連接後

close_wait出現在服務端主動斷開連接後

其實兩個wait都是不太好,而且他們在斷開後還是會留有一個2分鐘的文件,這樣就占用了上面的可打開文件數資源!so,我們從這一點進行相關優化,首先,我們要思考下為什麽連接斷開了,默認還是會保留狀態呢,寫tcp協議這哥們是不是傻,是不是傻,你覺得他是不是傻?其實不是,人家只是基於當時的環境考慮了一些問題:

  1. 防止上一次連接的包在網絡傳輸中迷路了,要把它收回來
  2. TCP不是UDP,要保證可靠性!在主動關閉方發送的最後一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED!
  3. 另外這麽設計TIME_WAIT 會定時的回收資源,並不會占用很大資源的,除非短時間內接受大量請求或者受到攻擊

當然,這是基於當年的網絡環境下的考慮,1981年的網絡狀況大約4分鐘你傳輸一個byte!so不解釋了(我怎麽知道的?因為我會穿越時空啊,我剛才還去買了幾瓶82年的雪碧呢~),但是這不是我們就不優化的理由呀,so,我們有三個內核參數來解決這個問題。

  1. tcp_tw_reuse復用,畢竟每次創建TCP連接是需要消耗資源的,如果TIME-WAIT sockets能復用那真的很不錯,我們可以在任何地方開啟它
  2. tcp_tw_recycle快速銷魂,它在內網環境下會很給力,可以讓你快速回收TIME_WAIT sockets,但是它有一個問題就是不可以在NAT負載均衡器上打開
  3. tcp_timestamps是上面兩個選項的基礎條件,不過默認情況下是已經打開的,它就是在打一個時間戳,我們需要一個標識來確定sockets是否該被回收或是復用

1 [[email protected] ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
2 0
3 [[email protected] ~]# cat /proc/sys/net/ipv4/tcp_timestamps
4 1
5 [[email protected] ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle
6 0
7 [[email protected] ~]# echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
8 [[email protected] ~]# echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

文件限制方面的優化現在貌似這樣就很不錯哦,現在我們不考慮這面單純的就是想提高該web的並發量,怎麽破,我們都知道建立連接後是兩臺機器端口間的互相傷害,so,如果我們可以多開一些端口,有人會問,多開端口那是客戶端的問題,你服務端開個80別人連你不都走這個麽,這就是架構的魅力所在,在你是服務器的同時,你又是客戶端,你提供web就單純是個html麽,不需要交互數據庫嘛,不需要拿靜態資源嘛,靜態資源可能也有個服務器,so,任重而道遠啊,多有一些可打開的端口是一件美好的事情了吧

1 [[email protected] ~]# cat /proc/sys/net/ipv4/ip_local_port_range 
2 32768    60999
3 [[email protected] ~]# echo "10000 65530" > /proc/sys/net/ipv4/ip_local_port_range

三.組件分離

當服務完全都在一臺機器上時,我們肯定會隨著業務量的增多進行分離,一般會先將數據庫分離,然後再將靜態資源分離。

技術分享

一下子整齊了許多,我們有了3臺服務器,在購買服務器的時候我們就可以針對業務挑選性價比更高的服務器,我們的應用服務器不需要存儲什麽東西,so磁盤什麽的就可以從簡,數據庫那必須ssd了,現在已經很便宜了,對io的提升是極其明顯的,而文件服務器,用ssd也好,但是cpu跟內存就不需要太關註了。

當我們的機器分離出來後,已經給我們的並發量帶來了提升,每個服務都是要占文件描述符的,現在分離出來,各自占本機的,沒人跟你搶,還有可使用的端口。

我們先優化數據庫跟文件服務器,他們都需要對磁盤進行大量的io操作,所以我們要對磁盤調度方式進行調整,linuxIO調度大家都知道的,基本知識

Cfq:完全公平,默認選項

Noop:什麽都不做,ssd就用這個

Deadline:有一個最後期限,數據庫常用

So,很明顯我們的文件服務器在使用了ssd盤後就可以將其的盤符的調度改成Noop了,而web服務器可能就是記錄下日誌,所以使用默認的Cfq就好。而數據庫服務器使用Deadline,那麽請問使用了ssd的數據庫改用Deadline還是Noop?答案其實都是可以的,其實這兩者之間性能差別不大,但是由於數據庫的性質,設置一個最後期限還是更加合理。

最後我們優化我們的web服務器,以nginx為例,

高級配置:

worker_processes auto;

Events配置:

use epoll;

worker_connections 65535

HTTP配置:

sendfile on;

tcp_nopush on;

tcp_nodelay on;

前幾個就不說了,tcp_nopush與tcp_nodelay的意義是相對的,但是在開啟sendfile的情況下並不沖突,簡單的說最終的效果就是會將發送的數據一直積累到最大報文長度後再發送,如果是最後的包那麽會直接發送不等待

web單機優化