溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么從0到1搭建后端架構(gòu)

發(fā)布時(shí)間:2021-10-23 16:46:45 來源:億速云 閱讀:108 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“怎么從0到1搭建后端架構(gòu)”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

架構(gòu)的演進(jìn)經(jīng)歷了4個(gè)大的階段:1. MVC 2. 服務(wù)拆分 3. 微服務(wù)架構(gòu) 4. 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)

1. MVC

項(xiàng)目剛開始的時(shí)候,后端同事不超過5個(gè),這個(gè)階段主要的工作是實(shí)現(xiàn)產(chǎn)品的原型,沒有太多的考慮架構(gòu),使用Django來快速實(shí)現(xiàn)功能,DB的表結(jié)構(gòu)設(shè)計(jì)好之后,抽象出功能View,由于產(chǎn)品設(shè)計(jì)也很不完善,后端需要很多的預(yù)留設(shè)計(jì),避免產(chǎn)品邏輯的變更帶來整個(gè)表結(jié)構(gòu)的變動(dòng),在這個(gè)階段代碼上最重要的是確定適合團(tuán)隊(duì)的代碼規(guī)范,代碼檢查規(guī)則。

怎么從0到1搭建后端架構(gòu)

整體上架構(gòu)如上圖,Nginx負(fù)責(zé)負(fù)載均衡,分發(fā)流量到多個(gè)Django服務(wù),Django處理邏輯,需要異步任務(wù)就交給Celery,然后數(shù)據(jù)量比較大的地方使用Redis做緩存。同時(shí)還有實(shí)時(shí)消息通知的需要使用了Nginx Push Module。

問題與優(yōu)化方式:

1、Django并發(fā)性能差 使用uWSGI Master+Worker 配合 gevent 攜程支持高并發(fā)

2、Redis連接數(shù)過多 使用redis-py自帶的連接池來實(shí)現(xiàn)連接復(fù)用

3、MySQL連接數(shù)過多 使用djorm-ext- pool(https://github.com/djangonauts/djorm-ext-pool)連接池復(fù)用連接

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

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

2. 服務(wù)拆分

隨著后端團(tuán)隊(duì)的壯大,分給每個(gè)同事的需求也越來越細(xì),如果繼續(xù)在一個(gè)工程里面開發(fā)所有的代碼,維護(hù)起來的代價(jià)太高,而我們的上一個(gè)架構(gòu)中在Django里面已經(jīng)按模塊劃分了一個(gè)個(gè)app,app內(nèi)高類聚,app之間低耦合,這就為服務(wù)的拆分帶來了便利。

怎么從0到1搭建后端架構(gòu)

拆分的過程沒有遇到太大的問題,初期的拆分只是代碼的分離,把公用的代碼抽離出來實(shí)現(xiàn)一個(gè)公用的Python庫,數(shù)據(jù)庫,Redis還是共用,隨著負(fù)載的增加,數(shù)據(jù)庫也做了多實(shí)例。

如上圖,服務(wù)之間盡量避免相互調(diào)用,需要交互的地方采用http請(qǐng)求的方式,內(nèi)網(wǎng)的調(diào)用使用hosts指向內(nèi)網(wǎng)地址。

問題與優(yōu)化方式:

  •  Nginx Push Module由于長時(shí)間沒有維護(hù),長連接最大數(shù)量不夠,使用Tornado + ZeroMQ實(shí)現(xiàn)了tormq(https://github.com/zhu327/tormq)服務(wù)來支撐消息通知

服務(wù)之間的調(diào)用采用http的方式,并且要求有依賴的服務(wù)主機(jī)配置hosts指向被調(diào)用的地址,這樣帶來的維護(hù)上的不方便。以及在調(diào)用鏈的過程中沒有重試,錯(cuò)誤處理,限流等等的策略,導(dǎo)致服務(wù)可用性差。

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

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

怎么從0到1搭建后端架構(gòu)

首先是在接入層引入了基于OpenResty的Kong API Gateway,定制實(shí)現(xiàn)了認(rèn)證,限流等插件。在接入層承接并剝離了應(yīng)用層公共的認(rèn)證,限流等功能。在發(fā)布新的服務(wù)時(shí),發(fā)布腳本中調(diào)用Kong admin api注冊(cè)服務(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)對(duì)我們業(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ā),還使用了云平臺(tái)提供的LB服務(wù)分發(fā)流量到2臺(tái)Kong服務(wù)器組成的集群。集群之間自動(dòng)同步配置。

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

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

怎么從0到1搭建后端架構(gòu)

在這一架構(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ù)。

在我離職時(shí)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)還在學(xué)習(xí)設(shè)計(jì)階段,還沒有落地,但是我相信前公司的后端架構(gòu)一定會(huì)往這個(gè)方向繼續(xù)演進(jìn)。

“怎么從0到1搭建后端架構(gòu)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI