python后端架構(gòu)

最近在做一個(gè)在線平臺,架構(gòu)思路如下

架構(gòu)演進(jìn):1蹋盆、MVC? 2费薄、服務(wù)拆分 3、微服務(wù)架構(gòu) 4栖雾、領(lǐng)域驅(qū)動設(shè)計(jì)

1楞抡、MVC

這個(gè)階段主要是快速實(shí)現(xiàn)產(chǎn)品,沒考慮其他的析藕,設(shè)計(jì)之初劃分多個(gè)app召廷,app內(nèi)高類聚,app之間低耦合账胧,DB表設(shè)計(jì)好了之后竞慢,實(shí)現(xiàn)view層功能需求,利用Django來快速實(shí)現(xiàn)功能治泥,后端有許多預(yù)留設(shè)計(jì)筹煮,避免產(chǎn)品邏輯的變更帶來整個(gè)表結(jié)構(gòu)的變動,架構(gòu)如下圖居夹;


MVC架構(gòu)

nginx是負(fù)載均衡败潦,通過權(quán)重法本冲,把請求發(fā)送到多個(gè)Django服務(wù)(其實(shí)中間還有一個(gè)uwsgi),如果是靜態(tài)請求变屁,nginx直接返回給客戶端眼俊,如果是其他請求,通過uwsgi傳給Django粟关,Django拿到請求疮胖,處理響應(yīng)請求。耗時(shí)大的需要異步的闷板,我們用celery處理澎灸,使用mysql作為數(shù)據(jù)庫,redis作為緩存遮晚,加快請求的響應(yīng)性昭,減輕mysql負(fù)擔(dān),同時(shí)還有實(shí)時(shí)消息通知的需要使用了Nginx Push Module县遣。

問題以及處理:

1糜颠、Django并不像tornado一樣,對并發(fā)很支持萧求,Django并發(fā)性能差其兴,采用uwsgi+nginx+gevent實(shí)現(xiàn)高并發(fā)。

2夸政、redis連接數(shù)過多,導(dǎo)致服務(wù)掛掉元旬,使用redis-py自帶的連接池來實(shí)現(xiàn)連接復(fù)用

3、mysql連接數(shù)過多守问,使用使用djorm-ext-pool

4匀归、Celery配置gevent支持并發(fā)任務(wù)

5、celery配合rabbitmq任務(wù)隊(duì)列實(shí)現(xiàn)任務(wù)的異步調(diào)度執(zhí)行

Celery是一個(gè)分布式的任務(wù)隊(duì)列耗帕。它的基本工作就是管理分配任務(wù)到不同的服務(wù)器穆端,并且取得結(jié)果。至于說服務(wù)器之間是如何進(jìn)行通信的仿便?這個(gè)Celery本身不能解決徙赢。所以,RabbitMQ作為一個(gè)消息隊(duì)列管理工具被引入到和Celery集成探越,負(fù)責(zé)處理服務(wù)器之間的通信任務(wù)。

隨著開發(fā)的功能需求越來越多窑业,Django下的app也越來越多钦幔,這就帶了發(fā)布上的不方便,每次發(fā)布版本都需要重啟所有的Django服務(wù)常柄,如果發(fā)布遇到問題鲤氢,只能加班解決了搀擂。而且單個(gè)Django工程下的代碼量也越來越多,不好維護(hù)卷玉。

2哨颂、服務(wù)拆分

前面設(shè)計(jì)的app內(nèi)高類聚,app之間低耦合是為服務(wù)拆分做鋪墊的相种,首先先把公用的代碼抽離出來威恼,實(shí)現(xiàn)一個(gè)公用的庫,其他的還是公用寝并。估計(jì)當(dāng)數(shù)據(jù)量增加后箫措,要對redis以及mysql進(jìn)行優(yōu)化,可以分庫分表衬潦,后續(xù)還需要拆分業(yè)務(wù)斤蔓,這個(gè)要看原來的代碼整潔度和互相依賴程度。


service separation

Nginx Push Module镀岛,長連接最大數(shù)量不夠弦牡,使用Tornado + ZeroMQ實(shí)現(xiàn)了tormq服務(wù)來支撐消息通知。

問題:

隨著業(yè)務(wù)拆分漂羊,繼續(xù)使用Nginx維護(hù)配置非常麻煩驾锰,經(jīng)常因?yàn)樾薷腘ginx的配置引發(fā)調(diào)用錯誤。每一個(gè)服務(wù)都有一個(gè)完整的認(rèn)證過程拨与,認(rèn)證又依賴于用戶中心的數(shù)據(jù)庫稻据,修改認(rèn)證時(shí)需要重新發(fā)布多個(gè)服務(wù)。

前面二層的架構(gòu)均已實(shí)現(xiàn)买喧,后續(xù)的微服務(wù)以及領(lǐng)域驅(qū)動設(shè)計(jì)由于我還未涉及到(我之前工作是使用Java做的微服務(wù))捻悯,所以在此貼出一位python開發(fā)工程師的解決辦法。

3. 微服務(wù)架構(gòu)

Microservices

首先是在接入層引入了基于OpenResty的Kong API Gateway淤毛,定制實(shí)現(xiàn)了認(rèn)證今缚,限流等插件。在接入層承接并剝離了應(yīng)用層公共的認(rèn)證低淡,限流等功能姓言。在發(fā)布新的服務(wù)時(shí),發(fā)布腳本中調(diào)用Kong admin api注冊服務(wù)地址到Kong蔗蹋,并加載api需要使用插件何荚。

為了解決相互調(diào)用的問題,維護(hù)了一個(gè)基于gevent+msgpack的RPC服務(wù)框架doge猪杭,借助于etcd做服務(wù)治理餐塘,并在rpc客戶端實(shí)現(xiàn)了限流,高可用皂吮,負(fù)載均衡這些功能戒傻。

在這個(gè)階段最難的技術(shù)選型税手,開源的API網(wǎng)關(guān)大多用Golang與OpenResty(lua)實(shí)現(xiàn),為了應(yīng)對我們業(yè)務(wù)的需要還要做定制需纳。前期花了1個(gè)月時(shí)間學(xué)習(xí)OpenResty與Golang芦倒,并使用OpenResty實(shí)現(xiàn)了一個(gè)短網(wǎng)址服務(wù)shorturl用在業(yè)務(wù)中。最終選擇Kong是基于Lua發(fā)布的便利性不翩,Kong的開箱即用以及插件開發(fā)比較容易兵扬。性能的考量倒不是最重要的,為了支撐更多的并發(fā)慌盯,還使用了云平臺提供的LB服務(wù)分發(fā)流量到2臺Kong服務(wù)器組成的集群周霉。集群之間自動同步配置。

餓了么維護(hù)一個(gè)純Python實(shí)現(xiàn)的thrift協(xié)議框架thriftpy亚皂,并提供很多配套的工具, 如果團(tuán)隊(duì)足夠大俱箱,這一套RPC方案其實(shí)是合適的,但是我們的團(tuán)隊(duì)人手不足灭必,水平參差不齊狞谱,很難推廣這一整套學(xué)習(xí)成本高昂的方案。最終我們開發(fā)了類Duboo的RPC框架doge禁漓,代碼主要參考了weibo開源的motan跟衅。

4. 領(lǐng)域驅(qū)動設(shè)計(jì)

domain driven design(ddd)

在這一架構(gòu)中我們嘗試從應(yīng)用服務(wù)中抽離出數(shù)據(jù)服務(wù)層,每一個(gè)數(shù)據(jù)服務(wù)包含一個(gè)或多個(gè)界限上下文播歼,界限上下文類只有一個(gè)聚合根來暴露出RPC調(diào)用的方法伶跷。數(shù)據(jù)服務(wù)不依賴于應(yīng)用服務(wù),應(yīng)用服務(wù)可以依賴多個(gè)數(shù)據(jù)服務(wù)秘狞。有了數(shù)據(jù)服務(wù)層叭莫,應(yīng)用就解耦了相互之間的依賴,高層服務(wù)只依賴于底層服務(wù)烁试。

出處:https://zhu327.github.io/2018/07/19/python/后端架構(gòu)演進(jìn)/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雇初,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子减响,更是在濱河造成了極大的恐慌靖诗,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件支示,死亡現(xiàn)場離奇詭異刊橘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颂鸿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門伤为,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事绞愚。” “怎么了颖医?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵位衩,是天一觀的道長。 經(jīng)常有香客問我熔萧,道長糖驴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任佛致,我火速辦了婚禮贮缕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俺榆。我一直安慰自己感昼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布罐脊。 她就那樣靜靜地躺著定嗓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萍桌。 梳的紋絲不亂的頭發(fā)上宵溅,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機(jī)與錄音上炎,去河邊找鬼恃逻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛藕施,可吹牛的內(nèi)容都是我干的寇损。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼铅碍,長吁一口氣:“原來是場噩夢啊……” “哼润绵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胞谈,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤尘盼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后烦绳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卿捎,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年径密,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了午阵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖底桂,靈堂內(nèi)的尸體忽然破棺而出植袍,到底是詐尸還是另有隱情,我是刑警寧澤籽懦,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布于个,位于F島的核電站,受9級特大地震影響暮顺,放射性物質(zhì)發(fā)生泄漏厅篓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一捶码、第九天 我趴在偏房一處隱蔽的房頂上張望羽氮。 院中可真熱鬧,春花似錦惫恼、人聲如沸档押。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汇荐。三九已至,卻和暖如春盆繁,著一層夾襖步出監(jiān)牢的瞬間掀淘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工油昂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留革娄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓冕碟,卻偏偏與公主長得像拦惋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子安寺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349