使用 OSProfiler 對 OpenStack 進行效能測量

PrivateRookie發表於2019-07-25

配置服務

如果要在 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 的文件中建議:

  1. 所有的 HTTP 請求 - 發出了什麼 HTTP 請求,請求時長(服務延遲),請求涉及專案

  2. 所有 RPC 請求 - 有助於理解某專案中不同服務請求時長,這對於發現專案效能瓶頸非常有用

  3. 所有 DB API 請求 - 某些情況下慢 DB 查詢是效能瓶頸。DB 查詢耗時是非常有用的資料。

  4. 所有驅動呼叫 - 在有 Nova, Cinder 或其他三方驅動情況下,跟蹤驅動效能

  5. 所有 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 協議》,轉載必須註明作者和本文連結
多少事,從來急。天地轉,光陰迫。

相關文章