最近在做一個線上平台,架構思路如下
架構演化:1、MVC 2、服務拆分 3、微服務架構 4、領域驅動設計
1、MVC
這個階段主要是快速實現產品,沒考慮其他的,設計之初劃分多個app,app內高類聚,app之間低耦合,DB表設計好了之後,實現view層功能需求,利用Django來快速實現功能,後端有許多預留設計,避免產品邏輯的變更帶來整個表結構的變動,架構如;
MVC架構
nginx是負載平衡,通過權重法,把請求發送到多個Django服務(其實中間還有一個uwsgi),如果是靜態請求,nginx直接返回給用戶端,如果是其他請求,通過uwsgi傳給Django,Django拿到請求,處理響應請求。耗時大的需要非同步,我們用celery處理,使用mysql作為資料庫,redis作為緩衝,加快請求的響應,減輕mysql負擔,同時還有即時訊息通知的需要使用了Nginx Push Module。
問題以及處理:
1、Django並不像tornado一樣,對並發很支援,Django並發效能差,採用uwsgi+nginx+gevent實現高並發。
2、redis串連數過多,導致服務掛掉,使用redis-py內建的串連池來實現串連複用
3、mysql串連數過多,使用使用djorm-ext-pool
4、Celery配置gevent支援並發任務
5、celery配合rabbitmq任務隊列實現任務的非同步調度執行
Celery是一個分布式的任務隊列。它的基本工作就是管理分配任務到不同的伺服器,並且取得結果。至於說伺服器之間是如何進行通訊的?這個Celery本身不能解決。所以,RabbitMQ作為一個訊息佇列管理工具被引入到和Celery整合,負責處理伺服器之間的通訊任務。
隨著開發的功能需求越來越多,Django下的app也越來越多,這就帶了發布上的不方便,每次發布版本都需要重啟所有的Django服務,如果發布遇到問題,只能加班解決了。而且單個Django工程下的代碼量也越來越多,不好維護。
2、服務拆分
前面設計的app內高類聚,app之間低耦合是為服務拆分做鋪墊的,首先先把公用的代碼抽離出來,實現一個公用的庫,其他的還是公用。估計當資料量增加後,要對redis以及mysql進行最佳化,可以分庫分表,後續還需要拆分業務,這個要看原來的代碼整潔度和互相依賴程度。
service separation
Nginx Push Module,長串連最大數量不夠,使用Tornado + ZeroMQ實現了tormq服務來支撐訊息通知。
問題:
隨著業務拆分,繼續使用Nginx維護配置非常麻煩,經常因為修改Nginx的配置引發調用錯誤。每一個服務都有一個完整的認證過程,認證又依賴於使用者中心的資料庫,修改認證時需要重新發布多個服務。
前面二層的架構均已實現,後續的微服務以及領域驅動設計由於我還未涉及到(我之前工作是使用Java做的微服務),所以在此貼出一位python開發工程師的解決辦法。
3. 微服務架構
Microservices
首先是在接入層引入了基於OpenResty的Kong API Gateway,定製實現了認證,限流等外掛程式。在接入層承接並剝離了應用程式層公用的認證,限流等功能。在發布新的服務時,發布指令碼中調用Kong admin api註冊服務地址到Kong,並載入api需要使用外掛程式。
為瞭解決相互調用的問題,維護了一個基於gevent+msgpack的RPC服務架構doge,藉助於etcd做服務治理,並在rpc用戶端實現了限流,高可用,負載平衡這些功能。
在這個階段最難的技術選型,開源的API Gateway大多用Golang與OpenResty(lua)實現,為了應對我們業務的需要還要做定製。前期花了1個月時間學習OpenResty與Golang,並使用OpenResty實現了一個短網址服務shorturl用在業務中。最終選擇Kong是基於Lua發布的便利性,Kong的開箱即用以及外掛程式開發比較容易。效能的考量倒不是最重要的,為了支撐更多的並發,還使用了雲平台提供的LB服務分發流量到2台Kong伺服器組成的叢集。叢集之間自動同步配置。
餓了麼維護一個純Python實現的thrift協議架構thriftpy,並提供很多配套的工具, 如果團隊足夠大,這一套RPC方案其實是合適的,但是我們的團隊人手不足,水平參差不齊,很難推廣這一整套學習成本高昂的方案。最終我們開發了類Duboo的RPC架構doge,代碼主要參考了weibo開源的motan。
4. 領域驅動設計
domain driven design(ddd)
在這一架構中我們嘗試從應用服務中抽離出資料服務層,每一個資料服務包含一個或多個界限上下文,界限上下文類只有一個彙總根來暴露出RPC調用的方法。資料服務不依賴於應用服務,應用服務可以依賴多個資料服務。有了資料服務層,應用就解耦了相互之間的依賴,高層服務只依賴於底層服務。
出處:https://zhu327.github.io/2018/07/19/python/後端架構演化/