Glance源碼架構探祕(四)

Glance源碼架構探祕(一)

Glance源碼架構探祕(二)

Glance源碼架構探祕(三)

Glance源碼架構探祕(四)


最近感情生活頗不順利,耽擱了很長時間。今天抽出時間來給大家繼續分享Glance源碼架構探祕,詳細闡述glance鏡像操作部分。


前幾章,我們花了很大的篇幅,討論了Glance服務的WSGI框架部分,包括網絡編程eventlet庫,綠化的webserver,WSGI,URL的Routes分發,分析請求拼接響應及控制器controller的機構等。瞭解及掌握這些技術內幕,對於我們今後研究Nova的代碼架構是十分有幫助的。

首先,我們先研究一下Glance的代碼目錄,我們一直以來還沒有研究過目錄,這對本章的理解十分重要

api —— API對外接口的包,glance服務的對外接口都在這裏

    middleware —— 中間件

    V1 —— 第一版API

    V2 —— 第二版API

    authorization.py —— 提供用戶驗證管理的功能

    policy.py —— 提供policy管理的功能(policy不是本章的重點,可自行進行引申閱讀)

common —— glance一些共用的模塊

db —— 數據庫操作模塊

openstack —— openstack的一些共用模塊

notifier —— 通知系統的模塊(目前主要做log用)

store —— 後端存儲管理模塊

當用戶的glance操作的請求通過WSGI,通過分發dispatch終於進入到控制器Controller之後,我們也最終要開始glance鏡像的具體操作了。大家研讀Controller內的代碼會發現,不管什麼操作,如上傳鏡像,修改鏡像元數據等,開始都會有上述兩條語句

image_factory = self.gateway.get_image_factory(req.context)
image_repo = self.gateway.get_repo(req.context)
會生成一個image_factory對象和一個image_repo對象,其中image_factory對應後端store進行鏡像的存儲等操作,image_repo對應glance的鏡像數據庫的管理等操作。

我們看一下gateway中的代碼

class Gateway(object):
    def __init__(self, db_api=None, store_api=None, notifier=None,
                 policy_enforcer=None):
        self.db_api = db_api or glance.db.get_api()
        self.db_api.configure_db()
        self.store_api = store_api or glance.store
        self.notifier = notifier or glance.notifier.Notifier()
        self.policy = policy_enforcer or policy.Enforcer()

    def get_image_factory(self, context):
        image_factory = glance.domain.ImageFactory()
        policy_image_factory = policy.ImageFactoryProxy(
                image_factory, context, self.policy)
        authorized_image_factory = authorization.ImageFactoryProxy(
                policy_image_factory, context)
        return authorized_image_factory

    def get_repo(self, context):
        image_repo = glance.db.ImageRepo(context, self.db_api)
        store_image_repo = glance.store.ImageRepoProxy(
                context, self.store_api, image_repo)
        policy_image_repo = policy.ImageRepoProxy(
                context, self.policy, store_image_repo)
        notifier_image_repo = glance.notifier.ImageRepoProxy(
                policy_image_repo, self.notifier)
        authorized_image_repo = authorization.ImageRepoProxy(
                notifier_image_repo, context)
        return authorized_image_repo
下面是我畫的所涉及到類的UML圖


熟悉涉及模式的同學可以看出,這是一個經典的責任鏈模式(Chain of Responsibility)。責任鏈模式是一種對象的行爲模式【GOF95】。在責任鏈模式裏,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織鏈和分配責任。

正如上面對於責任鏈模式的描述,我們進行一個操作比如add(),這個操作會在我們的ImageRepoProxy責任鏈上傳遞下去(authorization -> notifier -> policy -> store -> db),如果這個操作在鏈上某個類中有對應的同名方法,則調用這個方法然後傳遞下一級類,否則直接傳遞至下一級。通過這種方式,將驗證,通知,policy,後端存儲,數據庫等操作有機的結合起來,代碼結構也非常優美,便於理解。

OpenStack代碼可以發現許多非常棒的設計模式的應用,大家不妨多多留心。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章