Python 版 APM 服務(wù)使用測試
后端開發(fā)與云服務(wù)
云服務(wù)這個詞,大概最早是從云盤開始的,那時候概念也特別簡單,無非就是把一些數(shù)據(jù)存在別人的服務(wù)器上,在”云存儲”這個名詞火起來之前,QQ 也有提供網(wǎng)站的功能用來存一些小東西(05年06年的樣子,那時候大概只有幾十 M 的空間),其實剛聽到這個概念的時候我就很不理解,光存存東西不至于吹得這么玄乎吧。畢業(yè)后入行,云服務(wù)器才慢慢真真的豐富起來,從最開始的 VPS 變成云服務(wù)器、存儲變成資源服務(wù)器、遠程數(shù)據(jù)庫等等,現(xiàn)在甚至有幫你防 DDOS 的服務(wù)(去年和今年貌似 DDOS 變得越來越?jīng)]有節(jié)操了)。確實節(jié)省了很多精力,也省錢。
除了云,最近幾年還有另外一個比較火的詞:"大數(shù)據(jù)”。我沒接觸過那么大的數(shù)據(jù),作為一個半吊子運維,接觸的***的數(shù)據(jù)應(yīng)該就是服務(wù)器 log 了。所以大數(shù)據(jù)的東西以后有機會接觸再說,對我來說更重要的是 — 數(shù)據(jù)統(tǒng)計。
服務(wù)端的各種 log 不僅是分析服務(wù)器的狀態(tài)的重要參數(shù),也是從后臺代碼里抓 bug 抓異常檢查 SQL 性能等各種工作的參考。log 數(shù)據(jù)一般都是單調(diào)而且重復的居多,要發(fā)現(xiàn)它的價值,往往需要大量的分析和統(tǒng)計工作。各種監(jiān)控服務(wù)、分析工具也是層出不窮。不過到今年我才知道有個詞叫 "APM"。
APM (Application Performance Management/Monitoring) 簡單翻譯過來就是"應(yīng)用性能管理/監(jiān)控”(也許說監(jiān)控更準確一些)。大概就是服務(wù)器上部署的 awstats、nagios、zabbix 等一堆東西的集合。有服務(wù)器的地方就有云,既然這個事情這么麻煩,那就自然也可以交給別人來做了。
前幾天找到了一個 Python 的小 web 框架:bottle,只 有一個文件,簡潔好用,覺得很不錯,先是用它來做了一個簡單的小應(yīng)用(APP 下載,公司內(nèi)部使用),準備這段時間嘗試用它來自己寫一個簡單的博客系統(tǒng),改造一下自己的博客,所以業(yè)務(wù)時間花在搞 Python 上的比較多一點。恰好看到了在測 Python 版本的探針,于是部署來測試一下。部署之前先在本地做了一些測試,不過聽云目前僅支持基于 django 開發(fā)的程序(文檔上寫的目標是支持所有以 wsgi 協(xié)議部署的 Python Web 服務(wù),包括 flask、tornado 等等,不過這個應(yīng)該還要等后續(xù)開發(fā)支持了),所以我就先在本地用 django 測了一下。
聽云探針(Python版)的使用
探針部署過程十分簡單,在聽云后臺復制自己賬戶的 license key,生成配置文件,將配置文件地址加載到環(huán)境變量中,就可以啟動程序開始使用了。以下是測試環(huán)境部署步驟的介紹。
先用 virtualenv 開辟一個環(huán)境并 active 之:
virtualenv tingyun cd tingyun source bin/active
聽云探針在 pypi 的倉庫里有,所以可以直接安裝了,同時也安裝 django , 探針支持 MySQL 的 log 記錄,所以我也安裝了 MySQL 的組件并將 django 的數(shù)據(jù)庫從 sqlite 改成 MySQL:
# 安裝組件 pip install tingyun django MySQL-python # 創(chuàng)建一個 django 工程 django-admin startproject www
接著需要修改一下 django 的數(shù)據(jù)庫選項,進入到 www/www 目錄,打開 settings.py,找到 DATABASE 的字典,注釋掉原有的 sqlite 選項并改為 MySQL:
# 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django', 'USER': 'root', 'PASSWORD': '', 'HOST': '', 'PORT': '', }
在 MySQL 中創(chuàng)建 django 的庫,然后安裝 django 的 admin 后臺需要的數(shù)據(jù)表(注意回到 manage.py 所在的目錄):
python manage.py syncdb
接下來設(shè)置聽云的服務(wù),按照聽云后臺的提示和文檔說明進行就可以了:
# YourLicenseKey 是你的聽云后臺里顯示的 key # 聽云后臺里將 tingyun.ini 放置在 tmp 目錄,我建議你放在當前工作目錄,免得丟失 # 一些配置參數(shù)可以打開 tingyun.ini 進行修改 tingyun-admin generate-config YourLicenseKey tingyun.ini # # 這里的 TING_YUN_CONFIG_FILE 寫絕對路徑比較保險,以下是我本地的目錄 # 如果是在服務(wù)器上,可以寫入到 .bashrc 或者 .bash_profile 中去,需要重啟服務(wù)時不用重新設(shè)置 export TING_YUN_CONFIG_FILE=/Users/Scholer/Work/Personal/tingyun/tingyun.ini # # 聽云的服務(wù)會讀取當前環(huán)境變量的參數(shù) TING_YUN_CONFIG_FILE 來獲取配置文件 # 我們可以先檢查一下,如果看到 success 字樣就 OK tingyun-admin check-config
萬事具備,可以啟動服務(wù)了:
tingyun-admin run-program python www/manage.py runserver
接下來我們就可以瀏覽一下頁面,登錄一下后臺等等生成一些訪問記錄來看看效果了(或者可以比較殘暴一點用測試工具,我用 ab 發(fā)了一些的測試請求)。
一切順利的話,過一會兒刷新一下聽云的后臺,就能看到一些數(shù)據(jù)了。
有一些事情需要注意一下:
- 聽云的多個應(yīng)用是同一個 key,通過應(yīng)用名稱來區(qū)分應(yīng)用;
- 不同于一些其他服務(wù)、聽云沒有新建一個 應(yīng)用的過程,有部署、上報的數(shù)據(jù)就能看到數(shù)據(jù)了;
- 如果使用 uwsgi 的方式不是,需要開啟
enable-threads
和single-interpreter
的選項。
上報數(shù)據(jù)觀察
登錄到聽云的后臺管理面板就能查看到一些監(jiān)控日志分析了(圖表是用 highcharts 做的,體驗相當不錯)。
圖中可以看到一些基本的數(shù)據(jù)圖表,包括應(yīng)用的響應(yīng)時間、Apdex(應(yīng)用程序性能指數(shù)),應(yīng)用響應(yīng)耗時和吞吐率等等。
此外面板上也會有硬件的基本信息,包括 CPU 的占用時間、內(nèi)存占用等參數(shù)。
各項參數(shù)指標的統(tǒng)計最終目的都是為了分析服務(wù)器本身的承載能力和性能。當以上參數(shù)出現(xiàn)異常情況,比如響應(yīng)時間過長、CPU負載過高或者內(nèi)存剩余不多時,就要考慮升級硬件資源或者對程序進行優(yōu)化了。
Apdex (Application Performance Index) ,應(yīng)用性能指數(shù)。這是一個近幾年成立的聯(lián)盟組織,大概是在 2010 年發(fā)起的,12 年之后沉寂了兩年,去年又開始活躍了。這個聯(lián)盟意在通過一個統(tǒng)一的標準來計算和衡量應(yīng)用程序的的性能,在它的 官網(wǎng) 中有一些專門的文章來介紹自己。
"Apdex is a way to study measurements of any experience that can be interpreted on a scale ranging from excellent to unacceptable. " (Apdex 用以學習解釋從好到壞的評級標準的相關(guān)經(jīng)驗。)
Apdex 的計算在下面這篇文章用也有介紹:
Apdex = (正常樣本 + 0.5 x 低質(zhì)樣本 + 0 x 高質(zhì)樣本) / 樣本總量
我們可以這樣把正常樣本理解成正常的時間,低質(zhì)和高質(zhì)就分別表示響應(yīng)的慢和快。顯然計算結(jié)果從 1 到 0 就表示從好到壞。
詳細介紹:http://www.apdex.org/index.php/2014/05/apdex-is-not-just-for-application-performance/
以上兩張統(tǒng)計圖分別展示了應(yīng)用層的處理時間與數(shù)據(jù)庫調(diào)用時間。這兩個參數(shù)是對程序和 SQL 語句進行優(yōu)化的重要參考。這里應(yīng)該是計算的平均時間。
在實際的分析過程中,我們也同樣需要對于所有耗時過長的處理或者 SQL 慢查詢進行分析和優(yōu)化。聽云也提供了對于耗時應(yīng)用和 SQL 的統(tǒng)計。
在上面的"最耗時的應(yīng)用過程"中,有一個墻鐘時間比的概念。墻鐘時間(Wall-clock time / wall time)指的是程序從開始執(zhí)行到結(jié)束的過程中人的時間感知(這個時間是大于 CPU 時間的,由系統(tǒng)提供)。墻鐘時間比就表示當前時間點下某個程序占總墻鐘時間的百分比。
除了常見關(guān)系型數(shù)據(jù)庫的監(jiān)控,聽云也提供了對 memcached、Redis、MongoDB 等非關(guān)系型數(shù)據(jù)庫的監(jiān)控和統(tǒng)計。
響應(yīng)率和吞吐率參數(shù)參數(shù)。吞吐率指的是單位時間內(nèi)響應(yīng)的數(shù)量。這兩個參數(shù)是對網(wǎng)站總體的響應(yīng)速度和承載能力的評估。
吞吐量、響應(yīng)時間、Apdex和錯誤率的概覽。
聽云后臺的參數(shù)記錄十分全面,從硬件基礎(chǔ)到程序響應(yīng)到數(shù)據(jù)庫執(zhí)行耗時都有完整的分析和記錄。不過遺憾的是在后臺沒有看到 HTTP 狀態(tài)碼的記錄,類似 awstats 提供的記錄和統(tǒng)計功能。不過相對于一個需要自己做復雜的配置的開源組件,優(yōu)勢還是十分明顯的。我也相信隨著時間的推移,服務(wù)會越來越豐富,這些信息都會被 記錄并分析出來。
簡析
部署和數(shù)據(jù)分析都說了,現(xiàn)在也可以簡單的來分析下聽云是如何運作的。我無意去弄清楚探針工作的每一個步驟,但卻可以了解一下大致的流程。
Python 作為一門膠水語言,已經(jīng)積淀了豐富的優(yōu)秀模塊,歷來都是被公認為作為服務(wù)端運維***力的腳本語言,對于這類問題的處理上,具有天然的優(yōu)勢。聽云在語言上也做了處理,能夠同時支持 Python 2 和 Python 3。
在聽云的配置文件 tingyun.ini 中,除了有 license_key
以外,還有 app_name
、 log_file
、 log_level
等參數(shù)配置。其中 action_tracer.log_sql
可以選擇是否將 SQL 日志只保存在本地文件中(這應(yīng)該是出于安全考慮,畢竟把所有的 SQL 日志都暴漏給服務(wù)平臺,有些人可能會有些顧慮。但是考慮到現(xiàn)在服務(wù)器一般都是云服務(wù)器,所以這其實問題也并不大,選擇了服務(wù),就應(yīng)該相信服務(wù)),這點聽云考慮的很周到。
log 文件中記錄了一些 trace 的log,包括程序耗時等。
回到程序本身中去,在啟動探針的時,我們執(zhí)行的是 tingyun run-program
,最終執(zhí)行的是聽云的 package 中 admin 目錄下的 run_program
的函數(shù),check_config
、generate_config
也位于 admin 目錄下。整個程序目錄還包括 bootstrap 、hook 和 api 目錄。
root_directory = os.path.dirname(root_directory) boot_directory = os.path.join(root_directory, 'bootstrap') python_path = boot_directory
run_program
將 bootstrap 目錄加入系統(tǒng) path 中。通過 Python 提供的兩個 hook(sitecustomize 和 usercustomize 之中的 sitecustomize,聽云探針正式被加載到運行環(huán)境中:
if config_file is not None: # When installed as an egg with buildout, the root directory for # packages is not listed in sys.path and scripts instead set it # after Python has started up. This will cause importing of # 'tingyun' module to fail. if root_directory not in sys.path: sys.path.insert(0, root_directory) import tingyun.agent # Finally initialize the agent. tingyun.agent.initialize(config_file=config_file)
在 tingyun.api.initial.config
中,initialize
函數(shù)被執(zhí)行,調(diào)用 _process_module_builtin
函數(shù),探針開始工作 :
_load_configuration(config_file=config_file) if not _detect_done: _detect_done = True _process_module_builtin()
MySQL、Redis 等監(jiān)控模塊都位于 hook 目錄下,通過 _process_module_definition_wrapper
函數(shù)將進程與監(jiān)控模塊進行綁定,包括 django 的主要模塊以及常用的數(shù)據(jù)庫等。在核心模塊執(zhí)行的時候觸發(fā)監(jiān)控,將數(shù)據(jù)回傳到 api.tracert
模塊進行處理。
而對于硬件信息的檢測則由 api.platform.system_info
進行。
應(yīng)用監(jiān)控數(shù)據(jù)最終會由 api.tracert.uploader
上傳到聽云的服務(wù)器(host 的設(shè)置位于 api.settings
中,host 地址是 redirect.networkbench.com,所以看到你的服務(wù)器往這個域名發(fā)送請求時,不要覺得奇怪),通過聽云的處理,我們就能看到應(yīng)用程序的各種監(jiān)控數(shù)據(jù)了。
對聽云探針的簡單分析就到這里,有興趣的讀者可以進一步深入研究。其實對于這類云服務(wù),程序的本身都是透明的,不用有太大的安全顧慮,對于服務(wù)提供方而言,更重要的是數(shù)據(jù)的分析工作。
聽云本身提供的服務(wù)器是非常優(yōu)秀的,雖然目前還并非***。我也期待服務(wù)能更加完善,提供更完善的數(shù)據(jù)分析。另外一方面,通過 tingyun-admin run-program
的方式啟動程序,對開發(fā)者和服務(wù)器管理員來說可能有些侵入感。如果能用模塊加載的方式調(diào)用,或許更符合某些開發(fā)者的習慣。