企業(yè)級容器云架構(gòu)開發(fā)指南》—2.2.2 微服務(wù)的特性

      網(wǎng)友投稿 725 2025-03-31

      2.2.2 微服務(wù)的特性

      微服務(wù)有九大特性,我們逐一來了解一下。

      (1)特性一:“組件化”與“多服務(wù)”

      如圖2-8所示,傳統(tǒng)實現(xiàn)組件的方式是通過庫(library),庫和應(yīng)用一起運行在進(jìn)程中,庫的局部變化意味著整個應(yīng)用的重新部署。通過服務(wù)來實現(xiàn)組件,意味著將應(yīng)用拆散為一系列的服務(wù)運行在不同的進(jìn)程中,那么單一服務(wù)的局部變化只需重新部署對應(yīng)的服務(wù)進(jìn)程。

      將軟件庫(libraries)定義為這樣的組件,即它能被鏈接到一段程序,且能通過內(nèi)存中的函數(shù)來進(jìn)行調(diào)用。然而,服務(wù)(services)是進(jìn)程外的組件,它們通過諸如Web Service請求或遠(yuǎn)程過程調(diào)用這樣的機(jī)制來進(jìn)行通信。原來編寫程序,無論是使用C語言還是Java,都會引入很多組件,一個應(yīng)用程序外部引入很多成熟的庫。到了微服務(wù),實際上我們要把原來引入的這些組件也單獨變成一個個的服務(wù),可能原來是一個日志的組件,或是消息的組件,在這之上我們做了某個業(yè)務(wù),到了微服務(wù)我們會把日志、消息、應(yīng)用過程都作為一個個單獨的服務(wù),這就是組件化與多服務(wù)。微服務(wù)作為組件的更高級形式解決了一個關(guān)鍵問題:服務(wù)可以被獨立部署,對一個服務(wù)進(jìn)行修改,只需要構(gòu)建和重新部署這一個服務(wù),對系統(tǒng)的其他服務(wù)沒有影響,但前提是服務(wù)的接口協(xié)議沒有發(fā)生變化,只是對服務(wù)內(nèi)部進(jìn)行升級。如果涉及服務(wù)接口協(xié)議的升級,那么情況就要復(fù)雜一些,調(diào)用這個服務(wù)相關(guān)的其他服務(wù)可能也會修改升級。

      圖2-8 微服務(wù)特性一:“組件化”與“多服務(wù)”

      (2)特性二:圍繞“業(yè)務(wù)功能”組織團(tuán)隊

      康威定律中提到圍繞業(yè)務(wù)功能組織團(tuán)隊,簡單來說就是什么樣的團(tuán)隊產(chǎn)生什么樣的架構(gòu),這也是微服務(wù)所有架構(gòu)的根基。如圖2-9所示,具體來說,就是如果團(tuán)隊是按照業(yè)務(wù)功能組成的多個小微團(tuán)隊,那么每一個小組開發(fā)出來的必然是微服務(wù);如果團(tuán)隊是按照前端、中間鍵、數(shù)據(jù)庫這樣的方式構(gòu)建的,那么開發(fā)出來的必然是單體。

      我們來回顧一下康威定律,其中提到了4個觀點。

      1)定律一:組織的溝通方式會通過系統(tǒng)的設(shè)計表達(dá)出來。簡單來說,假設(shè)一個團(tuán)隊有N人,那么會有多少條溝通線路?答案是N×N-1/2。無論是做項目還是做產(chǎn)品,要解決的最大問題就是溝通問題。溝通的好壞在很大程度上決定項目的成敗。所以有多少條溝通線路,可能最后就會有多少個模塊。溝通的問題會帶來系統(tǒng)設(shè)計的問題,進(jìn)而影響整個系統(tǒng)的開發(fā)效率和最終產(chǎn)品的結(jié)果。

      圖2-9 微服務(wù)特性二:圍繞“業(yè)務(wù)功能”組織團(tuán)隊

      2)定律二:即便有再多的時間,一件事也不可能做得完美,但總有時間做完一件事。我們可以這樣理解,做項目時必須圍繞項目目標(biāo)在給定的時間和資源內(nèi),把一件事情做到最好。建議放棄打造完美系統(tǒng)的想法,而是通過不斷的試飛,發(fā)現(xiàn)問題,確保問題發(fā)生時系統(tǒng)能自動復(fù)原,而不追求飛行系統(tǒng)的絕對正確和安全。這就是持續(xù)集成和敏捷開發(fā)在微服務(wù)中得以應(yīng)用和推廣的原因。此外,這和互聯(lián)網(wǎng)公司維護(hù)的分布式系統(tǒng)的彈性設(shè)計是一個道理。對于一個分布式系統(tǒng),幾乎永遠(yuǎn)不可能找到并修復(fù)所有的bug,單元測試覆蓋 1000%也沒有用,錯誤流淌在分布式系統(tǒng)的血液里。解決方法不是消滅這些問題,而是容忍這些問題,在問題發(fā)生時能自動恢復(fù)。在微服務(wù)組成的系統(tǒng)中,每一個微服務(wù)都可能出錯,這是常態(tài),我們只要有足夠的冗余和備份即可,即所謂的彈性(resilience)設(shè)計或者叫高可用(high availability)設(shè)計。

      3)定律三:也就是前面我們講到的圍繞業(yè)務(wù)功能組織團(tuán)隊。線性系統(tǒng)和線性組織架構(gòu)間有潛在的一致同態(tài)特性,它們是一一對應(yīng)的。這是康威第一定律組織和設(shè)計間內(nèi)在關(guān)系的一個具體應(yīng)用。更直白地說,想要什么樣的系統(tǒng),就搭建什么樣的團(tuán)隊。如果團(tuán)隊分成前端團(tuán)隊、Java后臺開發(fā)團(tuán)隊、DBA團(tuán)隊、運維團(tuán)隊,系統(tǒng)就會“長”成圖2-10所示的樣子。

      相反,如果系統(tǒng)是按照業(yè)務(wù)邊界劃分的,即按照一個業(yè)務(wù)目標(biāo)把自己的模塊做成小系統(tǒng)、小產(chǎn)品,大系統(tǒng)就會長成圖2-11所示的樣子,即微服務(wù)的架構(gòu)。

      圖2-11 微服務(wù)的架構(gòu)

      微服務(wù)的理念是團(tuán)隊間應(yīng)該服務(wù)內(nèi)部高內(nèi)聚,服務(wù)之間低耦合。定義好系統(tǒng)的邊界和接口,在一個團(tuán)隊內(nèi)全棧,讓團(tuán)隊自治,如果團(tuán)隊按照這樣的方式組建,將溝通的成本維持在系統(tǒng)內(nèi)部,每個子系統(tǒng)就會更加內(nèi)聚,彼此的依賴耦合能變?nèi)酰缦到y(tǒng)的溝通成本也就能降低。

      4)定律四:大的系統(tǒng)總是比小的系統(tǒng)更傾向于分解。前面說了,人是復(fù)雜的社會動物,人與人的溝通非常復(fù)雜。但是當(dāng)我們面對復(fù)雜系統(tǒng)時,又往往只能通過增加人力來解決。這時,我們的組織一般是如何解決這個溝通問題的呢?答案是分而治之。業(yè)務(wù)需求驅(qū)動系統(tǒng)越長越大,當(dāng)達(dá)到一定規(guī)模時,無論我們有沒有微服務(wù)架構(gòu)這個理論,我們首先想到的就是把大模塊拆成小模塊,把大的團(tuán)隊拆成小團(tuán)隊,只有分解了,才能把人的自由性發(fā)揮出來,才能夠做好后面的事情。

      人與人的溝通是非常復(fù)雜的,一個人的溝通精力是有限的,所以當(dāng)問題太復(fù)雜需要很多人解決的時候,需要通過拆分組織來提升溝通效率。組織內(nèi)人與人的溝通方式?jīng)Q定了他們參與的系統(tǒng)設(shè)計,管理者可以通過不同的拆分方式帶來不同的團(tuán)隊間溝通方式,從而影響系統(tǒng)設(shè)計。如果子系統(tǒng)是內(nèi)聚的,與外部的溝通邊界是明確的,能降低溝通成本,對應(yīng)的設(shè)計也會更合理高效。復(fù)雜的系統(tǒng)需要通過容錯彈性的方式持續(xù)優(yōu)化,不要指望一個大而全的設(shè)計或架構(gòu),好的架構(gòu)和設(shè)計都是慢慢迭代出來的。

      (3)特性三:關(guān)注產(chǎn)品而不是項目,也就是“誰構(gòu)建誰運行”

      傳統(tǒng)的應(yīng)用開發(fā)都是基于項目模式的,開發(fā)團(tuán)隊根據(jù)一堆功能列表開發(fā)出一個軟件應(yīng)用并交付給客戶后,該軟件應(yīng)用就進(jìn)入維護(hù)模式,由另一個維護(hù)團(tuán)隊負(fù)責(zé),開發(fā)團(tuán)隊的職責(zé)結(jié)束。而微服務(wù)架構(gòu)建議避免采用這種項目模式,更傾向于讓開發(fā)團(tuán)隊負(fù)責(zé)整個產(chǎn)品的全部生命周期。亞馬遜對此提出了一個觀點:You build it, you run it(誰構(gòu)建,誰運行)。開發(fā)團(tuán)隊對軟件在生產(chǎn)環(huán)境中的運行負(fù)全部責(zé)任,讓服務(wù)的開發(fā)者與服務(wù)的使用者(客戶)形成每日的交流反饋,來自客戶的直接反饋有助于開發(fā)者提升服務(wù)的品質(zhì)。

      如圖2-12所示,在微服務(wù)理念下,開發(fā)團(tuán)隊不是完成開發(fā)、交到運維團(tuán)隊之后就不再管了,而是這個微團(tuán)隊永遠(yuǎn)為其所做的模塊負(fù)責(zé),在開發(fā)的時候就要考慮運營和運維需求,關(guān)注產(chǎn)品和微項目,并且改變回饋,讓環(huán)路盡快有反饋。也就是說在需求階段就要把測試做好,按照接口的約定模擬測試和服務(wù),并且后續(xù)按照約定彼此獨立上線、獨立測試,盡快回路、盡快回饋、盡快反饋,這些都是微服務(wù)要關(guān)注的問題。

      (4)特性四:“智能端點”與“傻瓜管道”

      《企業(yè)級容器云架構(gòu)開發(fā)指南》—2.2.2 微服務(wù)的特性

      原來SOA講得更多的是ESB架構(gòu),服務(wù)之間的溝通要通過總線,總線除了通信,還要負(fù)責(zé)路由、安全等各種控制。這種做法最大的弊端是:一般總線都是商用的產(chǎn)品,因此會有相對的語言依賴度、數(shù)據(jù)依賴度,造成對總線的依賴度很重。

      如圖2-13所示,對于微服務(wù)架構(gòu),我們不像原來會有一個很“重”的ESB總線,微服務(wù)架構(gòu)拋棄了 ESB 過度復(fù)雜的業(yè)務(wù)規(guī)則編排、消息路由等。服務(wù)作為智能終端,將所有的業(yè)務(wù)智能邏輯在服務(wù)內(nèi)部進(jìn)行處理,而將服務(wù)間的通信盡可能地輕量化,不添加任何額外的業(yè)務(wù)規(guī)則。所以這里的智能終端是指服務(wù)本身,而啞管道是通信機(jī)制,可以是同步的 RPC,也可以是異步的MQ,它們只作為消息通道,在傳輸過程中不會附加額外的業(yè)務(wù)智能。

      圖2-12 微服務(wù)特性三:關(guān)注產(chǎn)品而非項目

      圖2-13 微服務(wù)特性四:“智能端點”與“傻瓜管道”

      最常用的第二種協(xié)議是通過一個輕量級的消息總線來發(fā)送消息。此時所選擇的基礎(chǔ)設(shè)施通常是“傻瓜”型的(僅僅像消息路由器所做的事情那樣傻瓜),如RabbitMQ或ZeroMQ那樣的簡單實現(xiàn),即除了提供可靠的異步機(jī)制(fabric)以外,不做其他任何事情,智能功能存在于那些生產(chǎn)和消費諸多消息的各個端點中,即存在于各個服務(wù)中。

      (5)特性五與特性六:去中心化地治理技術(shù)&去中心化地管理數(shù)據(jù)

      去中心化包含兩層意思:技術(shù)棧的去中心化與數(shù)據(jù)去中心化,如圖2-14所示。

      圖2-14 微服務(wù)的特性五、特性六

      每個服務(wù)面對的業(yè)務(wù)場景不同,可以有針對性地選擇合適的技術(shù)解決方案。但也需要避免過度多樣化,結(jié)合團(tuán)隊實際情況來取舍,如果每個服務(wù)都用不同的語言技術(shù)棧來實現(xiàn),則維護(hù)成本很高。

      不像傳統(tǒng)應(yīng)用共享一個緩存和數(shù)據(jù)庫,每個服務(wù)獨享自身的數(shù)據(jù)存儲設(shè)施(緩存、數(shù)據(jù)庫等),這樣有利于服務(wù)的獨立性,隔離相關(guān)干擾。

      去中心化地管理數(shù)據(jù),其表現(xiàn)形式多種多樣。從最抽象的層面看,這意味著各個系統(tǒng)對客觀世界所構(gòu)建的概念模型將彼此各不相同。當(dāng)在一個大型的企業(yè)中進(jìn)行系統(tǒng)集成時,這就是一個常見的問題。例如,對于“客戶”這個概念,從銷售人員的視角看,就與從支持人員的視角看有所不同。從銷售人員的視角所看到的一些被稱之為“客戶”的,或許在支持人員的視角中根本找不到。而那些在兩個視角中都能看到的事物,或許各自具有不同的屬性。更糟糕的是,那些在兩個視角中具有相同屬性的事物,或許在語義上有微妙的不同。

      上述問題在不同的應(yīng)用程序之間經(jīng)常出現(xiàn),同時也會出現(xiàn)在這些應(yīng)用程序內(nèi)部,特別是當(dāng)一個應(yīng)用程序被分成不同的組件時。思考這類問題的一個有用的方法就是使用領(lǐng)域驅(qū)動設(shè)計(Domain-Driven Design,DDD)中的“限界上下文”的概念。DDD將一個復(fù)雜的領(lǐng)域劃分為多個限界上下文,并且將其相互之間的關(guān)系用圖畫出來。這一劃分過程對于單塊和微服務(wù)架構(gòu)兩者都是有用的,而且在服務(wù)和各個限界上下文之間所存在的自然的聯(lián)動關(guān)系,能有助于澄清和強(qiáng)化這種劃分。

      如同在概念模型上進(jìn)行去中心化的決策一樣,微服務(wù)也在數(shù)據(jù)存儲上實施去中心化的決策。盡管各個單塊應(yīng)用更愿意在邏輯上各自使用一個單獨的數(shù)據(jù)庫來持久化數(shù)據(jù),但是各家企業(yè)往往喜歡一系列單塊應(yīng)用共用一個單獨的數(shù)據(jù)庫,許多這樣的決策是被供應(yīng)商的各種版權(quán)商業(yè)模式所驅(qū)動出來的。微服務(wù)更喜歡讓每一個服務(wù)來管理其自有數(shù)據(jù)庫,其實現(xiàn)可以采用相同數(shù)據(jù)庫技術(shù)的不同數(shù)據(jù)庫實例,也可以采用完全不同的數(shù)據(jù)庫系統(tǒng),這種方法被稱作“多語種持久化”。在一個單塊系統(tǒng)中也能使用多語種持久化,但是這種方法在微服務(wù)中出現(xiàn)得更加頻繁。在各個微服務(wù)之間將數(shù)據(jù)的職責(zé)進(jìn)行“去中心化”的管理會影響軟件更新的管理。處理軟件更新的常用方法是當(dāng)更新多個資源的時候,使用事務(wù)來保證一致性,這種方法經(jīng)常在單塊系統(tǒng)中被采用。

      像這樣使用事務(wù),有助于保持?jǐn)?shù)據(jù)的一致性。但是在時域上會引發(fā)明顯的耦合,這樣在多個服務(wù)之間處理事務(wù)時會出現(xiàn)一致性問題。這時候數(shù)據(jù)一致性可能只要求數(shù)據(jù)在最終達(dá)到一致,并且一致性問題能夠通過補(bǔ)償操作來進(jìn)行處理。

      (6)特性七:“基礎(chǔ)設(shè)施”自動化

      如圖2-15所示,微服務(wù)的每一個模塊都是單獨的部署單元。“無自動化不微服務(wù)”,自動化包括測試和部署。單一進(jìn)程的傳統(tǒng)應(yīng)用被拆分為一系列的多進(jìn)程服務(wù)后,意味著開發(fā)、調(diào)試、測試、監(jiān)控和部署的復(fù)雜度都會相應(yīng)增大,必須要有合適的自動化基礎(chǔ)設(shè)施來支持微服務(wù)架構(gòu)模式,否則開發(fā)、運維成本將大大增加。

      (7)特性八:“ 容錯”設(shè)計

      如圖2-16所示,微服務(wù)架構(gòu)采用粗粒度的進(jìn)程間通信,引入了額外的復(fù)雜性和需要處理的新問題,如網(wǎng)絡(luò)延遲、消息格式、負(fù)載均衡和容錯,忽略其中任何一點都屬于對“分布式計算的誤解”。容錯設(shè)計就是要做好日志、做好監(jiān)控,能夠最快地檢測出故障,盡快地恢復(fù)故障。

      具體的應(yīng)對措施包括:

      圖2-15 微服務(wù)特性七:“基礎(chǔ)設(shè)施”自動化

      圖 2-16 微服務(wù)特性八:“容錯”設(shè)計

      網(wǎng)絡(luò)超時:在等待響應(yīng)時,不要無限期地阻塞,而是采用超時策略,使用超時策略可以確保資源不會被無限期地占用。

      限制請求的次數(shù):可以為客戶端對某特定服務(wù)的請求設(shè)置一個訪問上限,如果請求已達(dá)上限,就要立刻終止請求服務(wù)。

      斷路器模式(circuit breaker pattern):記錄成功和失敗請求的數(shù)量。如果失效率超過一個閾值,觸發(fā)斷路器使得后續(xù)的請求立刻失敗。如果大量的請求失敗,就可能是這個服務(wù)不可用,再發(fā)請求也無意義。在一個失效期后,客戶端可以再試,如果成功,關(guān)閉此斷路器。

      提供回滾:當(dāng)一個請求失敗后可以進(jìn)行回滾邏輯。例如,返回緩存數(shù)據(jù)或者一個系統(tǒng)默認(rèn)值。

      (8)特性九:“演進(jìn)式”設(shè)計

      如圖2-17所示,微服務(wù)A和微服務(wù)B之間互相的接口叫做契約,實際上就是它們之間接口的輸入請求、響應(yīng)、具體的交互機(jī)制。在做微服務(wù)A和微服務(wù)B需求的同時,一定要先定義這個契約,當(dāng)契約定義好時,它們彼此之間就可以獨立地開發(fā)和測試。我們作為A可以按照這個契約去“打樁”,也就是做一個模擬器,不依賴于具體版本和功能是否可用,最初上線測試時使用“打樁”的模擬器去做相應(yīng)的測試。同樣,B也按照A給的請求反應(yīng)去“打樁”,它也不依賴A,即B可以獨立開發(fā)、測試。只要契約沒有變化,它們彼此之間就相互獨立,彼此之間沒有依賴,就可以按照各自的版本去做自己的更新;當(dāng)契約發(fā)生變化時,一定要做相應(yīng)的溝通,重新提供“打樁”,提供彼此之間規(guī)范的模板。所以當(dāng)我們做了微服務(wù)以后,在需求階段最重要的是要先定義好對外部暴露哪些API,內(nèi)部有什么功能,外部暴露什么,我們不可能將內(nèi)部邏輯全部暴露,暴露得越多,所要做的控制就越多,這是做微服務(wù)時最先考慮的。所以在滿足外部請求的同時要考慮有哪些值得暴露的API。

      圖2-17 微服務(wù)特性九:“演進(jìn)式”設(shè)計

      一旦采用了微服務(wù)架構(gòu)模式,那么在服務(wù)變更時要特別小心,服務(wù)提供者的變更可能引發(fā)服務(wù)消費者的兼容性被破壞,要時刻謹(jǐn)記保持服務(wù)契約(接口)的兼容性。一條普適的健壯性原則(伯斯塔爾法則)給出了很好的建議:Be conservative in what you send, be liberal in what you accept(發(fā)送時要保守,接收時要開放)。按照伯斯塔爾法則的思想來設(shè)計和實現(xiàn)服務(wù)時,發(fā)送時要保守意味著要最小化地傳送必要的信息,接收時更開放意味著要最大限度地容忍冗余數(shù)據(jù),保證兼容性。

      每當(dāng)試圖要將軟件系統(tǒng)分解為各個組件時,就會面臨這樣的決策,即如何進(jìn)行切分,我們決定切分應(yīng)用系統(tǒng)時應(yīng)該遵循的原則是什么?一個組件的關(guān)鍵屬性是具有獨立更換和升級的特點,這意味著,需要尋找這些點,即想象著能否在其中一個點上重寫該組件,而無須影響該組件的其他合作組件。事實上,許多做微服務(wù)的團(tuán)隊會更進(jìn)一步,他們明確地預(yù)期許多服務(wù)將來會報廢,而不是守著這些服務(wù)做長期演進(jìn)。這種強(qiáng)調(diào)可更換性的特點,是模塊化設(shè)計一般性原則的一個特例,通過“變化模式”(pattern of change)來驅(qū)動并進(jìn)行模塊化的實現(xiàn)。大家都愿意將能在同時發(fā)生變化的東西放到同一個模塊中。系統(tǒng)中很少發(fā)生變化的部分應(yīng)該被放到不同的服務(wù)中,以區(qū)別于當(dāng)前正在經(jīng)歷大量變動的部分。如果發(fā)現(xiàn)需要同時反復(fù)變更兩個服務(wù)時,這就是它們兩個需要被合并的一個信號。

      把一個個組件放入一個個服務(wù)中,增大了更精細(xì)地實現(xiàn)軟件發(fā)布計劃的機(jī)會。對于一個單塊系統(tǒng),任何變化都需要做一次整個應(yīng)用系統(tǒng)的全量構(gòu)建和部署。然而,對于一個個微服務(wù)來說,只需要重新部署修改過的那些服務(wù)就夠了,這能簡化并加快發(fā)布過程。但缺點是必須要考慮當(dāng)一個服務(wù)發(fā)生變化時,依賴它并對其進(jìn)行消費的其他服務(wù)將無法工作。傳統(tǒng)的集成方法是試圖使用版本化來解決這個問題。但在微服務(wù)世界中,大家更喜歡將版本化作為最后萬不得已的手段來使用。我們可以通過把各個服務(wù)設(shè)計得盡量能夠容錯,來應(yīng)對其所依賴的服務(wù)所發(fā)生的變化,避免許多版本化的工作。

      以上這9個特性,從側(cè)面告訴我們微服務(wù)如何實現(xiàn)自治、獨立,如何與別人溝通,如何按照自己的約定執(zhí)行自己的版本計劃,如何容錯、自動化、去中心、關(guān)注產(chǎn)品、盡快響應(yīng)。那么把一個單體服務(wù)按照業(yè)務(wù)需求或是數(shù)據(jù)分類直接拆分了,微服務(wù)就能上線了嗎?答案是否定的,因為如果沒有設(shè)計日志、監(jiān)控、消息的管理,以及服務(wù)的發(fā)現(xiàn)機(jī)制和整個服務(wù)的負(fù)載均衡與配置,那么整個“拆合”的工作在“合”的層面都沒有做好,在這種情況下我們無法實現(xiàn)微服務(wù)體系。

      OpenStack 云計算

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel數(shù)據(jù)透視表求和項怎么設(shè)置?excel數(shù)據(jù)透視表求和項設(shè)置教程
      下一篇:無代碼網(wǎng)站開發(fā)平臺有哪些類型(無代碼平臺 開源)
      相關(guān)文章
      亚洲爽爽一区二区三区| 亚洲一区精彩视频| 久久精品国产亚洲AV蜜臀色欲| 亚洲成年轻人电影网站www | 亚洲成熟丰满熟妇高潮XXXXX| 亚洲国产福利精品一区二区| 亚洲黄色在线播放| 亚洲an天堂an在线观看| 亚洲国产成人片在线观看| 国产成人无码综合亚洲日韩| 亚洲av最新在线网址| 亚洲AV无码AV男人的天堂| 亚洲国产精品嫩草影院在线观看| 亚洲精品乱码久久久久久蜜桃不卡| 国产精品亚洲mnbav网站 | 亚洲精品国产精品乱码不卞| 亚洲国产小视频精品久久久三级| 亚洲Av无码乱码在线znlu| 亚洲精品97久久中文字幕无码| 亚洲午夜AV无码专区在线播放 | 亚洲人JIZZ日本人| 亚洲AV午夜成人片| 久久精品蜜芽亚洲国产AV| 亚洲成人免费电影| 国产人成亚洲第一网站在线播放| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 午夜亚洲国产理论秋霞| 亚洲成a人片在线观| 亚洲人成www在线播放| 亚洲精品乱码久久久久久V| 小说区亚洲自拍另类| 国产成人毛片亚洲精品| 亚洲成a人片在线观看无码 | 亚洲国产一级在线观看| 国产亚洲AV无码AV男人的天堂| 久久久亚洲精品无码| 亚洲国产日产无码精品| 亚洲欧美日韩综合久久久| 亚洲福利精品一区二区三区| 亚洲无码在线播放| 久久久无码精品亚洲日韩京东传媒 |