配置服務
如果要在 OpenStack 專案中使用 OSprofiler 進行效能跟蹤,大部分專案已經幫我們
初始化了 OSprofiler, 只需要在配置檔案中新增 [profiler]
配置項即可。
OSprofiler 支援使用多種 collector 儲存資料,預設使用訊息佇列+Ceilometer(由oslo.messaging提供驅動)。
我這裡使用 mongodb 作為 collection,原因只是我不喜歡 Ceilometer 和 Mongodb 更方便查詢的GUI。
使用 mongodb 前需先安裝 python mongodb 驅動 pip install pymongo
。
建立 mongodb 資料庫,假設資料庫 Host IP 為 172.16.140.116。
mkdir osprofiler_db && cd osprofiler_db
docker run \
-p 27017:27017 \
-v $pwd/data/db \
--name osprofiler_db \
-d mongo:latest
[profiler]
enabled = True
connection_string = mongodb://172.16.40.116:27017
# hmac_keys 將會被用作 `--osprofiler` 的引數,可以任意指定一串字元
hmac_keys = 123
# 控制跟蹤的內容
trace_wsgi_transport = True
trace_message_store = True
trace_management_store = True
如果使用訊息佇列+Ceilometer,還需要配置Ceilometer,使其不會丟棄OSprofiler傳送的訊息。
[oslo_messaging_notifications]
topics = notifications, profiler
關於應該在哪些點進行跟蹤,OSprofiler 的文件中建議:
-
所有的 HTTP 請求 - 發出了什麼 HTTP 請求,請求時長(服務延遲),請求涉及專案
-
所有 RPC 請求 - 有助於理解某專案中不同服務請求時長,這對於發現專案效能瓶頸非常有用
-
所有 DB API 請求 - 某些情況下慢 DB 查詢是效能瓶頸。DB 查詢耗時是非常有用的資料。
-
所有驅動呼叫 - 在有 Nova, Cinder 或其他三方驅動情況下,跟蹤驅動效能
-
所有 SQL 請求(預設關閉,因為會產生很多訊息)
使用
假設想跟蹤某個 API 請求,只需要在 openstack
命令新增 --osprofile hmac_key
,假設 Glance 已經配置好了
openstack image list --osprofile 123
命令執行完成後會在終端列印如下內容
Trace ID: 2902c7a3-ee18-4b08-aae7-4e34388f9352
Display trace with command:
osprofiler trace show --html 2902c7a3-ee18-4b08-aae7-4e34388f9352
接著使用 osprofiler
命令將報告以 html 格式列印出來。
# 記得指定後端
osprofiler trace show --html 2902c7a3-ee18-4b08-aae7-4e34388f9352 \
--connection-string "mongodb://172.16.140.116:27017" \
-o "report.html"
# 也可以輸出 json 格式報告
osprofiler trace show --json 2902c7a3-ee18-4b08-aae7-4e34388f9352 \
--connection-string "mongodb://172.16.140.116:27017" \
-o "report.json"
使用瀏覽器開啟 report.html 即可看到報告
新增自定義跟蹤點
如果沒有初始化 osprofiler,即使程式碼上打上跟蹤點,osprofiler 也不會傳送任何訊息。如果在使用的專案中沒有進行初始化,可以參考下面的方法進行初始化。
if CONF.profiler.enabled:
osprofiler_initializer.init_from_conf(
conf=CONF,
contex={},
project="cinder",
service=binary,
host=host
)
有 5 種方法在程式碼中打跟蹤點
from osprofiler import profiler
# 手動設定開啟和關閉
def some_func():
profiler.start("point_name", {"any_key": "with_any_value"})
# your code
profiler.stop({"any_info_about_point": "in_this_dict"})
# 使用裝飾器
@profiler.trace("point_name",
info={"any_info_about_point": "in_this_dict"},
hide_args=False)
def some_func2(*args, **kwargs):
# 如果需要隱藏 profile 資訊中的 args, 使用 hide_args=True
pass
# 使用上下文管理器
def some_func3():
with profiler.Trace("point_name", info={"any_key": "with_any_value"}):
# some code here
# 跟蹤某個類方法
@profiler.trace_cls("point_name", info={}, hide_args=False,
trace_private=False)
class TracedClass(object):
def traced_method(self):
pass
# 對於 "_" 開頭的方法,預設不會跟蹤,若有必要可以使用 trace_private=True
def _traced_only_if_trace_private_true(self):
pass
# 新增元類
@six.add_metaclass(profiler.TracedMeta)
class RpcManagerClass(object):
__trace_args__ = {'name': 'rpc', 'info': None, 'hide_args': False, 'trace_private': False}
def my_method(self, some_args):
pass
def my_method2(self, some_arg1, some_arg2, kw=None, kw2=None):
pass
本作品採用《CC 協議》,轉載必須註明作者和本文連結