服務器性能測試

淺談服務器性能測試的全生命周期——從測試、結果分析到優化策略

?2016-06-16?Micheal?騰訊WeTest
測試開發者的共同關注!
作者:Micheal,騰訊資深后臺開發工程師。WeTest導讀

服務器性能測試是一項非常重要而且必要的工作,本文是作者Micheal在對服務器進行性能測試的過程中不斷摸索出來的一些實用策略,通過定位問題,分析原因以及解決問題,實現對服務器進行更有針對性的優化,提升服務器的性能。

1.服務器性能測試小結講到服務器性能大部分人會想到這個服務器的架構是什么樣子的,用的什么epoll,select,spring,tornado之類的。其實從本質上來看的話目前大部分的服務器主要包括邏輯層以及DB層,我們采用的各種框架組件處于邏輯服務器中,如下圖所示。


服務器架構本質

服務器性能測試是一項比較繁瑣的事情,作為沒有做過性能測試的同學可能需要理清楚以下幾個事情。

?

1.1.??協議分析

首先是協議分析,性能測試本質上是我們用代碼來模擬真實的用戶請求,所以我們必須要知道發送出去的請求內容才能模擬。在典型的CS服務器中很多使用了protobuf,thrift,tdr(騰訊自研)來序列化以及反序列號請求內容。

序列化之后一方面可以對數據進行壓縮處理,另一方面也避免請求內容明文傳輸造成被抓包·泄漏數據的危險。之前有過服務器傳輸數據的時候使用的是明文直接發送,而且這個數據是一些敏感的sql語句,這樣首先暴露了數據庫的表結構,同時不法分子可以通過模擬發包造成“脫褲”甚至是數據被清空。

?

1.1.1.???Protobuf

谷歌出品,必屬精品。Protobuf使用起來很方便,學習成本非常低,而且序列化和反序列號的接口很容易使用。同時它相對于xml以及json,極大的的減小了數據占用的空間,減少了傳輸成本。目前支持包括C++,java以及python等多個語言。Protobuf目前用的比較多,打解包也很方便,比較推薦使用。

?

1.1.2.???Thrift

Thrift是一個跨語言的輕量級rpc消息和數據交換框架。Thrift支持幾乎絕大部分主流的語言,包括C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml,雖然大部分我都沒有用過。相對于protobuf,thrift提供了全套RPC解決方案,包括序列化機制、傳輸層、并發處理框架等,也因為如此thrift的學習成本比較高。

?

1.1.3.???騰訊自研協議tdrTdr是騰訊自研跨平臺多語言數據表示組件,主要用于基于數據的序列化反序列化(支持二進制方式和XML文本方式)以及ORM數據存儲。廣泛用于互娛自研游戲和部分代理游戲。在性能上基本和protobuf差不多,主要應用在C++程序中。

在做服務器性能測試之前,我們需要了解它的協議是怎么定義的。

?

1.2.??機器人管理

本質上機器人管理就是一個調度控制器,在獲取需要發送的請求協議之后,需要有一個框架來管理所有的機器人,控制機器人的啟動,發送請求以及停止的動作。框架的選擇需要根據服務器的實際情況來,不同的業務場景,使用不同的框架產生的壓力上限也會不一樣。


機器人管理框架

以一個簡單的多線程框架為例,主線程負責控制邏輯,管理所有的機器人狀態信息。子線程執行每個機器人的任務,包括連接服務器,發送數據,接收數據,斷開連接等。

?

1.3.??結果統計

機器人發送請求包之后,一般是要等待服務器的響應回包。服務器那邊可以計算本次壓測過程中各項業務數據,包括TPS,總的收發包量等。

不可能在測試過程中一直盯著各個數據看,我們需要把每項數據記錄下來,后續綜合各項結果進行分析。

這里的結果統計除了需要統計每個機器人收到回包的結果,還需要統計服務器在壓測過程中的各項性能數據變化。一旦客戶端的壓力上到一定值時,服務器某項資源支撐不了的話,說明這個資源可能存在短板,存在可以優化的空間。

?

2.?性能結果分析

性能結果分析是一個比較復雜的過程。需要綜合硬件、操作系統、應用程序等多方面來定位。

?

2.1.??硬件的影響

硬件對服務器性能影響還是蠻大的,如果是土豪的話,可以直接買最好的。我們分析硬件主要是希望選擇合適的配置,節約資源,避免出現高射炮打蚊子的情況。

?

2.1.1.???CPU在資金的充足下,一般來說CPU的數量越多,主頻越高,那么服務器的性能也就會越好。在實際測試過程中,如果在大壓力下持續觀察CPU的使用率很低,那么CPU的資源基本上是可以滿足服務器要求的。這樣的情況其實是有點浪費CPU資源的,比較理想的情況是壓力不大的時候CPU利用率比較低,壓力上來之后CPU利用率保持在60%-70%。

大部分的CPU在同一時間內只能運行一個線程,但是超線程的處理器可以在同一個時間運行多個線程,我們可以利用處理前超線程特性提高系統性能。雖然采用超線程技術能同時執行兩個線程,但它并不象兩個真正的CPU那樣,每個CPU都具有獨立的資源。當兩個線程都同時需要某一個資源時,其中一個要暫時停止,并讓出資源,直到這些資源閑置后才能繼續。因此超線程的性能并不等于兩顆CPU的性能。

?

2.1.2.???內存

內存的大小也是影響服務器性能的一個重要因素。內存太小,系統進程要被阻塞,應用程序會變得緩慢,甚至是失去響應;如果太大的話,也是造成一種浪費。Linux系統中采用物理內存和虛擬內存兩種方式,使用虛擬內存可以緩解物理內存的不足,但是如果占用過多的虛擬內存的話,應用程序的性能會明顯的下降。

?

2.1.3.???網絡帶寬

網絡帶寬的大小限制了客戶端與服務器交互的流量,相對其他硬件資源,網絡帶寬在價格上更貴。這需要我們合理預估服務器的可服務器能力,需要占用的帶寬資源。

?

2.1.4.???磁盤IO

目前磁盤都是機械方式運作的,主要體現在磁盤讀寫前尋找磁道的過程。磁盤自帶的讀寫緩存大小,對于磁盤讀寫速度至關重要。讀寫速度快的磁盤,通常都帶有較大的讀寫緩存。磁盤的尋道過程是機械方式,決定了其隨機讀寫速度將明顯低于順序讀寫。在我們做系統設計和實現時,需要考慮到磁盤的這一特性。

?

2.2.??操作系統及軟件

2.2.1.???版本

不同的操作系統在內核實現上可能各不相同,因而對運行在上面的應用程序來說可能影響比較大。

筆者并沒有做過分析不同操作系統對服務器性能的影響,因為只用過Linux開發服務器程序。Linux操作系統在這十幾年發展的異常迅猛,目前大部分的服務器都是運行在Linux操作系統上的。Linux目前具有最好的生態系統,服務器端的各種軟件都為它而設計,默認都認為你是在?Linux?上跑,你要是整一個非?Linux?的服務器,你得有足夠的心理準備,因為出現任何問題,你可能未必能找到能幫你解決問題的人。

?

2.2.2.???參數配置先說一個小故事。福特公司一套重要設備出現故障,找了很多人來維修,結果都沒有維修好,沒辦法了,就在購買設備的英國公司高價聘請一位工程師過來維修,工程師來到之后,反復查找原因,最后在一個小零件上劃了一條線,然后對旁邊福特公司的人說,在劃線的地方切掉就好了,果不其然,切掉之后故障真的解除了,按照合約,福特公司應支付公司一萬美元,周圍的人都唏噓不已,感嘆一條線就可以價值一萬美元,工程師回答到:那條線只值一美元,而怎樣找到那條線值9999美元。我們在測試服務器的過程中,經常會遇到性能上不去。查看CPU,網絡,IO消耗都挺低的,就是定位不到問題的原因。有經驗的程序員可能會告訴你你把某個參數修改一下,立馬性能噌噌噌上去了。比如mysql相關設置,系統文件描述符,緩沖區大小,time_wait快速回收設置等,甚至是線程池配置的線程個數也會對服務器的性能產生較大的影響。

關于數據庫參數的設置,比如mysql的配置文件my.cnf文件中,修改不同的配置(比如innodb_flush_log_at_trx_commit?設置為0,1還是2?)可能會對數據庫的讀寫性能影響很大。

?

2.2.3.???應用程序本身實現比如程序中需要頻繁申請內存,使用bzero和memset對服務器性能影響差距可能會很大。

另外程序中的一些查詢操作,采用不同的數據結構,可以實現時間和空間上的相互轉化,從而影響服務器的性能。

?

3.?Linux下的數據監控工具

3.1.??Vmstat

Vmstat,virtual memmory statistics(虛擬內存統計),主要是對操作系統的內存信息、進程狀態、cpu活動等進行監視,但是它不能對某個進程進行深入的分析。

Procs中r列表示運行和等待CPU時間片的進程數,如果r值長期大于CPU個數,說明CPU資源不夠用啦,可以適當增加CPU數量。
Procs中b列表示當前等待資源的進程數,包括等待I/O,內存等。Swpd列表示切換到內存交換區的KB數,一般si,so為0的話基本不影響系統的性能。Cache是page cache的內存數量,Linux會把空閑的物理內存的一部分拿來做文件和目錄的緩存,以便提高程序執行的性能。如果cache的值較大的話,說明緩存了太多的文件,如果bi值小的話,說明文件系統效率比較高。Si是每秒從磁盤讀入虛擬內存的大小,如果這個值一直大于0,表示物理內存不夠用或者內存泄露了,需要查找耗內存進程解決掉。Bi,bo是表示從塊設備讀入數據的總量以及寫到塊設備的數據總量。如果bi+bo值比較大,而且wa值也比較大的話,說明系統磁盤I/O可能有問題,性能不高。

In和cs是每秒鐘的設備中斷數以及上下文切換數。它們很大的話,表面內核消耗的CPU時間較多。

?

3.2.??Top

Top是一個動態顯示過程,即可以通過用戶按鍵來不斷刷新當前狀態。它可以按照系統中當前進程的CPU利用率以及占用的內存大小進行排序,可以比較快速定位出系統響應遲鈍的原因。如果在前臺執行該命令,它將獨占前臺,直到用戶終止該程序為止。

top是一個顯示數據較多的工具,第一行顯示的是系統的開機運行時間,機器的CPU負載信息;第二行顯示當前系統任務的總數,以及各個狀態的進程數;第三行顯示的是CPU資源的使用情況總覽;第四行顯示內存的使用情況總覽;第五行顯示的是內存交換區的使用情況總覽;后面開始是每個進程對資源使用的情況。

?

3.3.??Nmon

Nmon提供對CPU、內存、網絡、磁盤等系統資源占用情況分析,相比其他Linux命令獲取到的數據,nmon的功能更為集中、配置性更強。通過nmon采集到數據之后可以在windows系統中使用nmon_analyser做數據的展示以及分析工作,可視化效果比較好。

由于一般Linux系統都不自帶nmon,使用之前需要下載安裝。

?

3.4.??Uptime

Uptime命令顯示系統已經運行了多長時間,它依次顯示當前時間、系統已經運行了多長時間、目前有多少登陸用戶、系統在過去的1分鐘、5分鐘和15分鐘內的平均負載。

關于系統平均負載,它表示在特定時間間隔內運行隊列中的平均進程數。如果一個進程滿足以下條件則其就會位于運行隊列中:沒有在等待I/O操作的結果;沒有主動進入等待狀態;沒有被停止。

?

3.5.??Netstat

Netstat命令可以顯示本機的網絡連接情況,監聽端口以及路由表等各種網絡相關信息。Netstat用于顯示與IP、TCP、UDP和ICMP協議相關的統計數據,一般用于檢驗本機各端口的網絡連接情況。

比較常用的可以用次命令查看當前開啟監聽的服務器進程信息以及端口信息。

?

3.6.??Free

Free是監控Linux使用情況最常用的命令。“Free -m”可以查看以M為單位的使用情況,這里主要觀察free和cached兩列。

一般來說,如果應用程序可用內存/系統物理內存>70%時,表明目前系統內存資源比較充足,不影響系統性能;如果應用程序可用內存/系統物理內存<20%時,表明目前系統內存資源比較緊缺,需要釋放其他程序內存或者增加內存;如果應用程序可用內存/系統物理內存在20%-70%之間,表明目前系統的內存資源基本滿足應用需求,暫時不影響系統的性能。

?

3.7.??Sar

Sar也是一個強大的分析系統性能的工具,它可以比較全面的獲取系統的CPU,運行隊列,磁盤IO,分頁,內存,CPU中斷,網絡等多項數據。

上圖是使用sar獲取系統CPU的整體負責情況,每隔1秒統計一次,統計3次,最后會給出3次的平均值。需要查看其他的數據可以查看手冊使用。

?

3.8.??Iostat

Iostat是I/O statistics的縮寫,主要功能是對系統的磁盤I/O操作進行監控。它的輸出主要顯示磁盤讀寫操作的統計信息,同時也會給出CPU的使用情況。

這里顯示的是查看CPU和磁盤的信息,統計間隔2秒,共3次。

?

3.9.??Valgrind

Valgrind是一款廣泛用于監控程序運行過程進行內存調試、內存泄漏檢測以及性能分析的工具。它會給出內存泄漏的統計,包括definitely lost,indirectly lost,possibly lost,still reachable ,suppressed等,我們可以使用valgrind來測試程序中內存不規范使用的部分。同時對于地址越界問題也可以通過valgrind掃出來,它會統計invalid write的情況。

?

4.?服務器的性能優化

在優化之前,先要搞清楚服務器的具體業務需求是什么,據此來優化其中的短板。

?

4.1.??存儲的優化

IO相對來說比較耗時,我們都知道越靠近CPU的存儲,其訪問速度越快,但是其價格越貴。下圖來展示了不同存儲的容量以及訪問時間。

目前很多同學在優化服務器性能的時候都會從存儲這方面入手。

儲存的容量以及訪問時間

?

4.1.1.???用內存換時間

4.1.1.1.?增加緩存

很多web應用是有大量的靜態內容,這些靜態內容主要都是一些小文件,并且會被頻繁的讀,采用Apache以及nginx作為web服務器。在web訪問量不大的時候,這兩個http服務器可以說是非常的迅速和高效,如果負載量很大的時候,我們可以采用在前端搭建cache服務器,將服務器中的靜態資源文件緩存到操作系統內存中直接進行讀操作,因為直接從內存讀取數據的速度要遠大于從硬盤讀取。這個其實也是增加內存的成本來降低訪問磁盤帶來的時間消耗。

?

4.1.1.2.?內存數據庫內存數據庫,其實就是將數據放在內存中直接操作的數據庫。相對于磁盤,內存的數據讀寫速度要高出幾個數量級,將數據保存在內存中相比從磁盤上訪問能夠極大地提高應用的性能。內存數據庫拋棄了磁盤數據管理的傳統方式,基于全部數據都在內存中重新設計了體系結構,并且在數據緩存、快速算法、并行操作方面也進行了相應的改進,所以數據處理速度比傳統數據庫的數據處理速度要快很多。但是安全性的問題可以說是內存數據庫最大的硬傷。因為內存本身有掉電丟失的天然缺陷,因此我們在使用內存數據庫的時候,通常需要,提前對內存上的數據采取一些保護機制,比如備份,記錄日志,熱備或集群,與磁盤數據庫同步等方式。

對于一些重要性不高但是又想要快速響應用戶請求的部分數據可以考慮內存數據庫來存儲,同時可以定期把數據固化到磁盤。

?

4.1.1.3.?RDD

這里圖個新鮮,說說內存換時間在大數據云計算相關領域的一些應用。Spark最近很火,它的核心要數RDD了,RDD最早來源與Berkeley實驗室的一篇論文《Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing》。現有的數據流系統對兩種應用的處理并不高效:一是迭代式算法,這在圖應用和機器學習領域很常見;二是交互式數據挖掘工具。這兩種情況下,將數據保存在內存中能夠極大地提高性能。這里不詳細說RDD了,只是想說程序員一直是覬覦內存的讀取速度的。

?

4.1.2.???使用SSD等

除了對內存方面的優化,還可以對磁盤這邊進行優化。跟傳統機械硬盤相比,固態硬盤具有快速讀寫、質量輕、能耗低以及體積小等特點。但是ssd的價格相比傳統機械硬盤要貴,有條件的可以使用ssd來代替機械硬盤。

?

4.2.??數據庫優化大部分的服務器請求最終都是要落到數據庫中,隨著數據量的增加,數據庫的訪問速度也會越來越慢。想要提升請求處理速度,必須要對原來的單表進行動刀了。目前主流的Linux服務器使用的數據庫要屬mysql了,如果我們使用mysql存儲的數據單個表的記錄達到千萬級別的話,查詢速度會很慢的。根據業務上合適的規則對數據庫進行分區分表,可以有效提高數據庫的訪問速度,提升服務器的整體性能。

另外對于業務上查詢請求,在建表的時候可以根據相關需求設置索引等,以提高查詢速度。

?

4.3.??利用多核優勢

現在運行服務器的主流機器配置都是多核CPU的,我們在設計服務器的時候可以利用多核心的特點,采用多進程或者多線程的框架。

關于選擇多線程還是多進程可以根據實際的需求,結合各自的優缺點進行選擇。

對于多線程的使用,特別是使用線程池的時候可以通過測試不同線程池服務器的性能來設置合適的線程池。

?

4.4.??選擇合適的IO模型

《UNIX網絡編程卷1:套接字聯網API》中有一幅圖比較經典。


IO模型

阻塞I/O模型:數據沒到達之前,I/O一直阻塞,如果數據到達,則會返回。典型的是recvfrom,一般的默認都是阻塞的。
非阻塞的I/O模型:和阻塞相反,只要不能得到結果的時候,I/O立刻返回。不會阻塞當前線程。
IO復用模型:也就是自己要學習的部分。多路復用的意思是,將多路信號合并到一路上進行處理,類似多個管道匯集到一個管道,與之相反的是多路分解。IO復用模型主要是select,poll,epoll;對一個IO端口,兩次調用,兩次返回,比阻塞IO并沒有什么優越性;關鍵是能實現同時對多個IO端口進行監聽;函數也會使進程阻塞,但是和阻塞I/O所不同的的,這兩個函數可以同時阻塞多個I/O操作。而且可以同時對多個讀操作,多個寫操作的I/O函數進行檢測,直到有數據可讀或可寫時,才真正調用I/O操作函數。信號驅動:首先開啟套接口信號驅動I/O功能,并通過系統調用sigaction安裝一個信號處理函數。當數據報準備好被讀時,就為該進程生成一個SIGIO信號。隨即可以在信號處理程序中調用recvfrom來讀數據報,井通知主循環數據已準備好被處理中。也可以通知主循環,讓它來讀數據報。異步的IO模型:告知內核啟動某個操作,并讓內核在整個操作完成后(包括將數據從內核拷貝到用戶自己的緩沖區)通知我們。

這里并不是說一定要用某個模型,epoll也并不是在所有情況下都比select性能要好的,在選擇的時候還是要結合業務需求來。

?

4.5.??分布式部署程序

當單機服務器已經找不到合適的優化點時,我們可以通過分布式部署來提高服務器的響應能力。優秀的服務器開發都會為自己的服務器的擴容,容災提出一些解決方案。個人覺得服務器設計的時候簡單點比較好,這樣后期擴容的時候會很方便。

?

淺談服務器性能測試的全生命周期——從測試、結果分析到優化策略

原創?2016-06-16?Micheal?騰訊WeTest
測試開發者的共同關注!
作者:Micheal,騰訊資深后臺開發工程師。WeTest導讀

服務器性能測試是一項非常重要而且必要的工作,本文是作者Micheal在對服務器進行性能測試的過程中不斷摸索出來的一些實用策略,通過定位問題,分析原因以及解決問題,實現對服務器進行更有針對性的優化,提升服務器的性能。

1.服務器性能測試小結講到服務器性能大部分人會想到這個服務器的架構是什么樣子的,用的什么epoll,select,spring,tornado之類的。其實從本質上來看的話目前大部分的服務器主要包括邏輯層以及DB層,我們采用的各種框架組件處于邏輯服務器中,如下圖所示。


服務器架構本質

服務器性能測試是一項比較繁瑣的事情,作為沒有做過性能測試的同學可能需要理清楚以下幾個事情。

?

1.1.??協議分析

首先是協議分析,性能測試本質上是我們用代碼來模擬真實的用戶請求,所以我們必須要知道發送出去的請求內容才能模擬。在典型的CS服務器中很多使用了protobuf,thrift,tdr(騰訊自研)來序列化以及反序列號請求內容。

序列化之后一方面可以對數據進行壓縮處理,另一方面也避免請求內容明文傳輸造成被抓包·泄漏數據的危險。之前有過服務器傳輸數據的時候使用的是明文直接發送,而且這個數據是一些敏感的sql語句,這樣首先暴露了數據庫的表結構,同時不法分子可以通過模擬發包造成“脫褲”甚至是數據被清空。

?

1.1.1.???Protobuf

谷歌出品,必屬精品。Protobuf使用起來很方便,學習成本非常低,而且序列化和反序列號的接口很容易使用。同時它相對于xml以及json,極大的的減小了數據占用的空間,減少了傳輸成本。目前支持包括C++,java以及python等多個語言。Protobuf目前用的比較多,打解包也很方便,比較推薦使用。

?

1.1.2.???Thrift

Thrift是一個跨語言的輕量級rpc消息和數據交換框架。Thrift支持幾乎絕大部分主流的語言,包括C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml,雖然大部分我都沒有用過。相對于protobuf,thrift提供了全套RPC解決方案,包括序列化機制、傳輸層、并發處理框架等,也因為如此thrift的學習成本比較高。

?

1.1.3.???騰訊自研協議tdrTdr是騰訊自研跨平臺多語言數據表示組件,主要用于基于數據的序列化反序列化(支持二進制方式和XML文本方式)以及ORM數據存儲。廣泛用于互娛自研游戲和部分代理游戲。在性能上基本和protobuf差不多,主要應用在C++程序中。

在做服務器性能測試之前,我們需要了解它的協議是怎么定義的。

?

1.2.??機器人管理

本質上機器人管理就是一個調度控制器,在獲取需要發送的請求協議之后,需要有一個框架來管理所有的機器人,控制機器人的啟動,發送請求以及停止的動作。框架的選擇需要根據服務器的實際情況來,不同的業務場景,使用不同的框架產生的壓力上限也會不一樣。


機器人管理框架

以一個簡單的多線程框架為例,主線程負責控制邏輯,管理所有的機器人狀態信息。子線程執行每個機器人的任務,包括連接服務器,發送數據,接收數據,斷開連接等。

?

1.3.??結果統計

機器人發送請求包之后,一般是要等待服務器的響應回包。服務器那邊可以計算本次壓測過程中各項業務數據,包括TPS,總的收發包量等。

不可能在測試過程中一直盯著各個數據看,我們需要把每項數據記錄下來,后續綜合各項結果進行分析。

這里的結果統計除了需要統計每個機器人收到回包的結果,還需要統計服務器在壓測過程中的各項性能數據變化。一旦客戶端的壓力上到一定值時,服務器某項資源支撐不了的話,說明這個資源可能存在短板,存在可以優化的空間。

?

2.?性能結果分析

性能結果分析是一個比較復雜的過程。需要綜合硬件、操作系統、應用程序等多方面來定位。

?

2.1.??硬件的影響

硬件對服務器性能影響還是蠻大的,如果是土豪的話,可以直接買最好的。我們分析硬件主要是希望選擇合適的配置,節約資源,避免出現高射炮打蚊子的情況。

?

2.1.1.???CPU在資金的充足下,一般來說CPU的數量越多,主頻越高,那么服務器的性能也就會越好。在實際測試過程中,如果在大壓力下持續觀察CPU的使用率很低,那么CPU的資源基本上是可以滿足服務器要求的。這樣的情況其實是有點浪費CPU資源的,比較理想的情況是壓力不大的時候CPU利用率比較低,壓力上來之后CPU利用率保持在60%-70%。

大部分的CPU在同一時間內只能運行一個線程,但是超線程的處理器可以在同一個時間運行多個線程,我們可以利用處理前超線程特性提高系統性能。雖然采用超線程技術能同時執行兩個線程,但它并不象兩個真正的CPU那樣,每個CPU都具有獨立的資源。當兩個線程都同時需要某一個資源時,其中一個要暫時停止,并讓出資源,直到這些資源閑置后才能繼續。因此超線程的性能并不等于兩顆CPU的性能。

?

2.1.2.???內存

內存的大小也是影響服務器性能的一個重要因素。內存太小,系統進程要被阻塞,應用程序會變得緩慢,甚至是失去響應;如果太大的話,也是造成一種浪費。Linux系統中采用物理內存和虛擬內存兩種方式,使用虛擬內存可以緩解物理內存的不足,但是如果占用過多的虛擬內存的話,應用程序的性能會明顯的下降。

?

2.1.3.???網絡帶寬

網絡帶寬的大小限制了客戶端與服務器交互的流量,相對其他硬件資源,網絡帶寬在價格上更貴。這需要我們合理預估服務器的可服務器能力,需要占用的帶寬資源。

?

2.1.4.???磁盤IO

目前磁盤都是機械方式運作的,主要體現在磁盤讀寫前尋找磁道的過程。磁盤自帶的讀寫緩存大小,對于磁盤讀寫速度至關重要。讀寫速度快的磁盤,通常都帶有較大的讀寫緩存。磁盤的尋道過程是機械方式,決定了其隨機讀寫速度將明顯低于順序讀寫。在我們做系統設計和實現時,需要考慮到磁盤的這一特性。

?

2.2.??操作系統及軟件

2.2.1.???版本

不同的操作系統在內核實現上可能各不相同,因而對運行在上面的應用程序來說可能影響比較大。

筆者并沒有做過分析不同操作系統對服務器性能的影響,因為只用過Linux開發服務器程序。Linux操作系統在這十幾年發展的異常迅猛,目前大部分的服務器都是運行在Linux操作系統上的。Linux目前具有最好的生態系統,服務器端的各種軟件都為它而設計,默認都認為你是在?Linux?上跑,你要是整一個非?Linux?的服務器,你得有足夠的心理準備,因為出現任何問題,你可能未必能找到能幫你解決問題的人。

?

2.2.2.???參數配置先說一個小故事。福特公司一套重要設備出現故障,找了很多人來維修,結果都沒有維修好,沒辦法了,就在購買設備的英國公司高價聘請一位工程師過來維修,工程師來到之后,反復查找原因,最后在一個小零件上劃了一條線,然后對旁邊福特公司的人說,在劃線的地方切掉就好了,果不其然,切掉之后故障真的解除了,按照合約,福特公司應支付公司一萬美元,周圍的人都唏噓不已,感嘆一條線就可以價值一萬美元,工程師回答到:那條線只值一美元,而怎樣找到那條線值9999美元。我們在測試服務器的過程中,經常會遇到性能上不去。查看CPU,網絡,IO消耗都挺低的,就是定位不到問題的原因。有經驗的程序員可能會告訴你你把某個參數修改一下,立馬性能噌噌噌上去了。比如mysql相關設置,系統文件描述符,緩沖區大小,time_wait快速回收設置等,甚至是線程池配置的線程個數也會對服務器的性能產生較大的影響。

關于數據庫參數的設置,比如mysql的配置文件my.cnf文件中,修改不同的配置(比如innodb_flush_log_at_trx_commit?設置為0,1還是2?)可能會對數據庫的讀寫性能影響很大。

?

2.2.3.???應用程序本身實現比如程序中需要頻繁申請內存,使用bzero和memset對服務器性能影響差距可能會很大。

另外程序中的一些查詢操作,采用不同的數據結構,可以實現時間和空間上的相互轉化,從而影響服務器的性能。

?

3.?Linux下的數據監控工具

3.1.??Vmstat

Vmstat,virtual memmory statistics(虛擬內存統計),主要是對操作系統的內存信息、進程狀態、cpu活動等進行監視,但是它不能對某個進程進行深入的分析。

Procs中r列表示運行和等待CPU時間片的進程數,如果r值長期大于CPU個數,說明CPU資源不夠用啦,可以適當增加CPU數量。
Procs中b列表示當前等待資源的進程數,包括等待I/O,內存等。Swpd列表示切換到內存交換區的KB數,一般si,so為0的話基本不影響系統的性能。Cache是page cache的內存數量,Linux會把空閑的物理內存的一部分拿來做文件和目錄的緩存,以便提高程序執行的性能。如果cache的值較大的話,說明緩存了太多的文件,如果bi值小的話,說明文件系統效率比較高。Si是每秒從磁盤讀入虛擬內存的大小,如果這個值一直大于0,表示物理內存不夠用或者內存泄露了,需要查找耗內存進程解決掉。Bi,bo是表示從塊設備讀入數據的總量以及寫到塊設備的數據總量。如果bi+bo值比較大,而且wa值也比較大的話,說明系統磁盤I/O可能有問題,性能不高。

In和cs是每秒鐘的設備中斷數以及上下文切換數。它們很大的話,表面內核消耗的CPU時間較多。

?

3.2.??Top

Top是一個動態顯示過程,即可以通過用戶按鍵來不斷刷新當前狀態。它可以按照系統中當前進程的CPU利用率以及占用的內存大小進行排序,可以比較快速定位出系統響應遲鈍的原因。如果在前臺執行該命令,它將獨占前臺,直到用戶終止該程序為止。

top是一個顯示數據較多的工具,第一行顯示的是系統的開機運行時間,機器的CPU負載信息;第二行顯示當前系統任務的總數,以及各個狀態的進程數;第三行顯示的是CPU資源的使用情況總覽;第四行顯示內存的使用情況總覽;第五行顯示的是內存交換區的使用情況總覽;后面開始是每個進程對資源使用的情況。

?

3.3.??Nmon

Nmon提供對CPU、內存、網絡、磁盤等系統資源占用情況分析,相比其他Linux命令獲取到的數據,nmon的功能更為集中、配置性更強。通過nmon采集到數據之后可以在windows系統中使用nmon_analyser做數據的展示以及分析工作,可視化效果比較好。

由于一般Linux系統都不自帶nmon,使用之前需要下載安裝。

?

3.4.??Uptime

Uptime命令顯示系統已經運行了多長時間,它依次顯示當前時間、系統已經運行了多長時間、目前有多少登陸用戶、系統在過去的1分鐘、5分鐘和15分鐘內的平均負載。

關于系統平均負載,它表示在特定時間間隔內運行隊列中的平均進程數。如果一個進程滿足以下條件則其就會位于運行隊列中:沒有在等待I/O操作的結果;沒有主動進入等待狀態;沒有被停止。

?

3.5.??Netstat

Netstat命令可以顯示本機的網絡連接情況,監聽端口以及路由表等各種網絡相關信息。Netstat用于顯示與IP、TCP、UDP和ICMP協議相關的統計數據,一般用于檢驗本機各端口的網絡連接情況。

比較常用的可以用次命令查看當前開啟監聽的服務器進程信息以及端口信息。

?

3.6.??Free

Free是監控Linux使用情況最常用的命令。“Free -m”可以查看以M為單位的使用情況,這里主要觀察free和cached兩列。

一般來說,如果應用程序可用內存/系統物理內存>70%時,表明目前系統內存資源比較充足,不影響系統性能;如果應用程序可用內存/系統物理內存<20%時,表明目前系統內存資源比較緊缺,需要釋放其他程序內存或者增加內存;如果應用程序可用內存/系統物理內存在20%-70%之間,表明目前系統的內存資源基本滿足應用需求,暫時不影響系統的性能。

?

3.7.??Sar

Sar也是一個強大的分析系統性能的工具,它可以比較全面的獲取系統的CPU,運行隊列,磁盤IO,分頁,內存,CPU中斷,網絡等多項數據。

上圖是使用sar獲取系統CPU的整體負責情況,每隔1秒統計一次,統計3次,最后會給出3次的平均值。需要查看其他的數據可以查看手冊使用。

?

3.8.??Iostat

Iostat是I/O statistics的縮寫,主要功能是對系統的磁盤I/O操作進行監控。它的輸出主要顯示磁盤讀寫操作的統計信息,同時也會給出CPU的使用情況。

這里顯示的是查看CPU和磁盤的信息,統計間隔2秒,共3次。

?

3.9.??Valgrind

Valgrind是一款廣泛用于監控程序運行過程進行內存調試、內存泄漏檢測以及性能分析的工具。它會給出內存泄漏的統計,包括definitely lost,indirectly lost,possibly lost,still reachable ,suppressed等,我們可以使用valgrind來測試程序中內存不規范使用的部分。同時對于地址越界問題也可以通過valgrind掃出來,它會統計invalid write的情況。

?

4.?服務器的性能優化

在優化之前,先要搞清楚服務器的具體業務需求是什么,據此來優化其中的短板。

?

4.1.??存儲的優化

IO相對來說比較耗時,我們都知道越靠近CPU的存儲,其訪問速度越快,但是其價格越貴。下圖來展示了不同存儲的容量以及訪問時間。

目前很多同學在優化服務器性能的時候都會從存儲這方面入手。

儲存的容量以及訪問時間

?

4.1.1.???用內存換時間

4.1.1.1.?增加緩存

很多web應用是有大量的靜態內容,這些靜態內容主要都是一些小文件,并且會被頻繁的讀,采用Apache以及nginx作為web服務器。在web訪問量不大的時候,這兩個http服務器可以說是非常的迅速和高效,如果負載量很大的時候,我們可以采用在前端搭建cache服務器,將服務器中的靜態資源文件緩存到操作系統內存中直接進行讀操作,因為直接從內存讀取數據的速度要遠大于從硬盤讀取。這個其實也是增加內存的成本來降低訪問磁盤帶來的時間消耗。

?

4.1.1.2.?內存數據庫內存數據庫,其實就是將數據放在內存中直接操作的數據庫。相對于磁盤,內存的數據讀寫速度要高出幾個數量級,將數據保存在內存中相比從磁盤上訪問能夠極大地提高應用的性能。內存數據庫拋棄了磁盤數據管理的傳統方式,基于全部數據都在內存中重新設計了體系結構,并且在數據緩存、快速算法、并行操作方面也進行了相應的改進,所以數據處理速度比傳統數據庫的數據處理速度要快很多。但是安全性的問題可以說是內存數據庫最大的硬傷。因為內存本身有掉電丟失的天然缺陷,因此我們在使用內存數據庫的時候,通常需要,提前對內存上的數據采取一些保護機制,比如備份,記錄日志,熱備或集群,與磁盤數據庫同步等方式。

對于一些重要性不高但是又想要快速響應用戶請求的部分數據可以考慮內存數據庫來存儲,同時可以定期把數據固化到磁盤。

?

4.1.1.3.?RDD

這里圖個新鮮,說說內存換時間在大數據云計算相關領域的一些應用。Spark最近很火,它的核心要數RDD了,RDD最早來源與Berkeley實驗室的一篇論文《Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing》。現有的數據流系統對兩種應用的處理并不高效:一是迭代式算法,這在圖應用和機器學習領域很常見;二是交互式數據挖掘工具。這兩種情況下,將數據保存在內存中能夠極大地提高性能。這里不詳細說RDD了,只是想說程序員一直是覬覦內存的讀取速度的。

?

4.1.2.???使用SSD等

除了對內存方面的優化,還可以對磁盤這邊進行優化。跟傳統機械硬盤相比,固態硬盤具有快速讀寫、質量輕、能耗低以及體積小等特點。但是ssd的價格相比傳統機械硬盤要貴,有條件的可以使用ssd來代替機械硬盤。

?

4.2.??數據庫優化大部分的服務器請求最終都是要落到數據庫中,隨著數據量的增加,數據庫的訪問速度也會越來越慢。想要提升請求處理速度,必須要對原來的單表進行動刀了。目前主流的Linux服務器使用的數據庫要屬mysql了,如果我們使用mysql存儲的數據單個表的記錄達到千萬級別的話,查詢速度會很慢的。根據業務上合適的規則對數據庫進行分區分表,可以有效提高數據庫的訪問速度,提升服務器的整體性能。

另外對于業務上查詢請求,在建表的時候可以根據相關需求設置索引等,以提高查詢速度。

?

4.3.??利用多核優勢

現在運行服務器的主流機器配置都是多核CPU的,我們在設計服務器的時候可以利用多核心的特點,采用多進程或者多線程的框架。

關于選擇多線程還是多進程可以根據實際的需求,結合各自的優缺點進行選擇。

對于多線程的使用,特別是使用線程池的時候可以通過測試不同線程池服務器的性能來設置合適的線程池。

?

4.4.??選擇合適的IO模型

《UNIX網絡編程卷1:套接字聯網API》中有一幅圖比較經典。


IO模型

阻塞I/O模型:數據沒到達之前,I/O一直阻塞,如果數據到達,則會返回。典型的是recvfrom,一般的默認都是阻塞的。
非阻塞的I/O模型:和阻塞相反,只要不能得到結果的時候,I/O立刻返回。不會阻塞當前線程。
IO復用模型:也就是自己要學習的部分。多路復用的意思是,將多路信號合并到一路上進行處理,類似多個管道匯集到一個管道,與之相反的是多路分解。IO復用模型主要是select,poll,epoll;對一個IO端口,兩次調用,兩次返回,比阻塞IO并沒有什么優越性;關鍵是能實現同時對多個IO端口進行監聽;函數也會使進程阻塞,但是和阻塞I/O所不同的的,這兩個函數可以同時阻塞多個I/O操作。而且可以同時對多個讀操作,多個寫操作的I/O函數進行檢測,直到有數據可讀或可寫時,才真正調用I/O操作函數。信號驅動:首先開啟套接口信號驅動I/O功能,并通過系統調用sigaction安裝一個信號處理函數。當數據報準備好被讀時,就為該進程生成一個SIGIO信號。隨即可以在信號處理程序中調用recvfrom來讀數據報,井通知主循環數據已準備好被處理中。也可以通知主循環,讓它來讀數據報。異步的IO模型:告知內核啟動某個操作,并讓內核在整個操作完成后(包括將數據從內核拷貝到用戶自己的緩沖區)通知我們。

這里并不是說一定要用某個模型,epoll也并不是在所有情況下都比select性能要好的,在選擇的時候還是要結合業務需求來。

?

4.5.??分布式部署程序

當單機服務器已經找不到合適的優化點時,我們可以通過分布式部署來提高服務器的響應能力。優秀的服務器開發都會為自己的服務器的擴容,容災提出一些解決方案。個人覺得服務器設計的時候簡單點比較好,這樣后期擴容的時候會很方便。

?

轉載于:https://www.cnblogs.com/da-guang/p/5591978.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255076.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

庖丁解牛TLD(二)——初始化工作(為算法的準備)

我說的初始化&#xff0c;還不是算法的初始化工作&#xff0c;而是讀入圖像&#xff0c;響應鍵盤鼠標之類的工作。作者提供的代碼中的工作包含了從攝像頭讀取和從文件中讀取兩種輸入方案。這里介紹一下從文件輸入的辦法。因為OpenCV從視頻讀取圖像序列的辦法有很好的demo&#…

(轉載)Qt中MOC的一些限制

無意中發現在Qt的文檔里有一篇關于moc工具的limitation的文章&#xff0c;里頭的東西值得學習一下。 Qt一個鏈接的錯誤&#xff0c; 程序結構很簡單&#xff0c; 就是designer設計主界面&#xff0c;在代碼里用多重繼承方式使用&#xff0c; 奇怪的錯誤信息如下&#xff1a; mo…

庖丁解牛TLD(三)——算法初始化

上一講我提到對于算法的初始化工作主要是在tldInit這個函數里實現的。主要分為如下幾大步驟&#xff0c;1&#xff09;初始化Detector。2&#xff09;初始化Trajectory。3&#xff09;訓練Detector 1)初始化Detector 其中bb_scan為掃描grid區域&#xff0c;該函數輸入為boundin…

Web測試容易忽略的地方

1.瀏覽器的后退按鈕 提交表單一條已經成功提交的記錄&#xff0c;back后再提交&#xff0c;看系統會如何處理。檢查多次使用back健的情況在有back的地方&#xff0c;back&#xff0c;回到原來的頁面&#xff0c;再back&#xff0c;重復幾次&#xff0c;看是否會報錯。 2.通過修…

[Android]你不知道的Android進程化(4)--進程通信AIDL框架

大家好&#xff0c;我系蒼王。以下是我這個系列的相關文章&#xff0c;有興趣可以參考一下&#xff0c;可以給個喜歡或者關注我的文章。[Android]如何做一個崩潰率少于千分之三噶應用app--章節列表Google爸爸&#xff0c;聽說要將一些插件化hook系統的變量屬性禁用&#xff0c;…

在未啟動程序情況 點擊視圖設計器 彈出未將對象引用窗體的解決方案

請問下 在未運行程序情況 點擊視圖設計器 彈出未將對象引用窗體 解決方案&#xff1a;1.看后臺進程是不是相關的進程在啟動&#xff0c;如果有關閉進程&#xff1b;重啟vs,即可2.重啟電腦轉載于:https://www.cnblogs.com/yang12311/p/5593838.html

圖像配準的步驟

目前&#xff0c;很難找到一種普適的方法能夠應對所有的配準情況&#xff0c;任何一種配準算法都必須考慮圖像的成像原理、幾何變形、噪聲影響、配準精度等因素。不過&#xff0c;從原理上將&#xff0c;配準算法可以大致分為以下四個步驟&#xff1a; &#xff08;1&#xff0…

Jm86中的encode_one_macroblock注釋

Jm86中的encode_one_macroblock注釋 /*! ************************************************************************************** /brief* Mode Decision for a macroblock* //該函數的作用是編碼一個宏塊&#xff08;包括幀間、幀內、幀內預測的方式&#xff09;。*…

Python之路【第十七篇】:裝飾器

寫代碼的時候有一個原則&#xff0c;開放封閉原則(面向對象)&#xff1a;對某些東西開放&#xff0c;對某些封閉&#xff0c;在裝飾器這里&#xff0c;函數內部是封閉的&#xff0c;不允許改變函數的內部。 裝飾器用來裝飾函數&#xff0c;可以讓函數在執行之前或者執行之后&am…

HALCON示例程序measure_chip.hdev芯片封裝檢測

HALCON示例程序measure_chip.hdev芯片封裝檢測 示例程序源碼&#xff08;加注釋&#xff09; 關于顯示類函數解釋 dev_update_off () read_image (Image, ‘die_on_chip’) get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width * 2, He…

工業機器人智能發展:視覺和觸覺感應簡化

機器人工業協會&#xff08;Robotic Industries Association&#xff09;指出&#xff0c;從2003到2005年間&#xff0c;北美機器人工業以20%的平均年增長率發展。在汽車市場需求疲軟以及外國廠商的壓力不斷增加的背景下&#xff0c;這一成就是如何取得的&#xff1f;成本的普遍…

ASP站點無法訪問怎么辦

確保啟用了目錄瀏覽功能 轉載于:https://www.cnblogs.com/acetaohai123/p/6571257.html

五、案例-指令參考-freemarker指令、表達式

案例-指令參考描述&#xff1a;本人自己測試寫了一遍&#xff0c;如有錯的地方&#xff0c;懂freemarker的朋友望指點指點&#xff01; 案例-指令參考 表達式 一、 Assign 1、<#assign name1"北京" name2"上海" name3"廣東"> 調用&#xf…

PartitionMotionSearch()函數

encode_one_macroblock()函數中的運動估計分為兩大塊&#xff0c;對于宏塊級的三種模式&#xff0c;分塊后直接對patition依次調用PartitionMotionSearch()函數&#xff1b;而對于亞宏塊級的&#xff08;含8x8, 8x4,4x8,4x4&#xff09;模式&#xff0c;首先將宏塊拆分為4個88子…

201521123017 《Java程序設計》第4周學習總結

1. 本周學習總結 2. 書面作業 Q1.注釋的應用 使用類的注釋與方法的注釋為前面編寫的類與方法進行注釋&#xff0c;并在Eclipse中查看。(截圖) Q2.面向對象設計(大作業1&#xff0c;非常重要) 2.1 將在網上商城購物或者在班級博客進行學習這一過程&#xff0c;描述成一個故事。…

完整的VAL3程序

start() begin//延時10秒 delay(5)//初始化變量call init()//清空原有運動堆棧resetMotion()//建立上電任務taskCreate "robotpower",100,robotpower()wait(isPowered())//建立生產任務taskCreate "ProductionCycle",10,ProductionCycle()//建立安全區域…

iOS WebView 加載本地資源(圖片,文件等)

NSString *path [[NSBundle mainBundle] pathForResource:"關于.docx" ofType:nil]; NSURL *url [NSURL fileURLWithPath:path]; NSLog("%", [self mimeType:url]); //webview加載本地文件&#xff0c;可以使用加載數據的方式 //第一個誒參數是一個N…

本文以H264視頻流為例,講解解碼流數據的步驟。

本文以H264視頻流為例&#xff0c;講解解碼流數據的步驟。 為突出重點&#xff0c;本文只專注于討論解碼視頻流數據&#xff0c;不涉及其它&#xff08;如開發環境的配置等&#xff09;。如果您需要這方面的信息&#xff0c;請和我聯系。 準備變量 定義AVCodecContext。如…

2008-2021年商業銀行數據(農商行、城商行、國有行、股份制銀行)

2008-2021年商業銀行數據&#xff08;農商行、城商行、國有行、股份制銀行&#xff09; 1、時間&#xff1a;2008-2021年 2、范圍&#xff1a;1700銀行 3 、指標&#xff1a;證券簡稱、year、證券代碼、資產總計、負債合計、所有者權益合計、利潤總額、凈利潤、貸款總額、存…

EPSON 任務同步 改寫

有時需要在多個任務執行之前來使它們同步。如果預先知道執行每項任務所需要的時間&#xff0c;它們就可以通過簡單地等待由最慢的任務產生的信號來實現同步。然而&#xff0c;如果不知道那個任務是最慢的&#xff0c;就需要使用一個更復雜的同步化機制&#xff0c;如下所示VAL …