日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在闲鱼,我们如何用Dart做高效后端开发?

發布時間:2024/8/23 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在闲鱼,我们如何用Dart做高效后端开发? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

像阿里其他技術團隊以及業界的做法一樣,閑魚的大多數后端應用都是全部使用java來實現的。java易用、豐富的庫、結構容易設計的特性決定了它是進行業務開發的最好語言之一。后端應用中數據的存儲、訪問、轉換、輸出雖然都屬于后端的范疇,但是其中變更的頻率是不同的。通常領域對象確定之后,它的變化是很少的,但是客戶端展示的變化很多,導致接口層(或者叫粘連前臺和后臺的膠水層)的變化非常快。大多數web應用采用統一的技術棧來實現后端,膠水層跟領域層使用統一技術,這樣的做法仍然有可以優化的地方:

  • 在預發環境中驗證調試比較困難:一方面,每次提交代碼、構建、部署、驗證的總時間相對較長;另一方面,多人共用一個部署環境,相互干擾(代碼沖突和部署沖突),增加了成本。后端開發人員都渴望有一個獨立、高效的開發環境,就像開發一個前端頁面那樣
  • 前臺(java、object-c,javascript)和后臺(java)的技術不同,導致前臺同學很難開發后端程序,閑魚技術團隊為了追求更高的開發效率,希望能夠跨越服務端開發與客戶端、前端的界限,讓前臺開發人員也能夠寫后端代碼
  • 膠水層通常依賴很多后端服務,計算比較簡單,是IO密集型的任務。我們理想中的編程框架是能夠像寫同步代碼一樣簡單,但是享受異步的好處。目前的方案還無法完全做到這一點。

為什么選擇dart

閑魚技術團隊選擇使用dart作為膠水層的實現語言。

  • dart是一種靜態類型語言,在編譯器就能完全確定變量的類型。它是支持泛型的面向對象語言,任何變量都是對象,不存在java中的原始類型。跟javascript類似,它是一種單線程語言,對異步的支持非常好(async/await)。dart的語法與主流開發語言(java,python,c/c++,javascript)很類似, 在主流的語言語法基礎上,dart增加了很多語法結構,getter/setter、方法級聯、函數式編程、閉包,這些語法讓允許開發人員更加容易地寫出簡潔的代碼;全面易用的類庫也是dart能夠作為flutter開發語言的重要原因。
  • flutter證明了dart在客戶端開發上的成功,閑魚不僅走在flutter開發的前列,也正在嘗試使用dart開發后端應用;語法跟javascript,java相近,有人形容這門語言是傻瓜式的簡單(stupid-simple to learn),無論是java后端開發人員,還是客戶端開發同學,亦或是前端開發同學,都能夠快速上手寫出生產級的代碼。所有技術同學都能夠開發后端接口在閑魚是可以做到的。
  • dart對異步化的良好支持對業務開發是強大助力。后端應用膠水層代碼大多數IO密集型的任務,使用異步化技術可以把多個IO請求的總RT,從所有請求RT之和,降低為所有請求中最高RT。dart對異步有良好的支持,開發同學使用dart可以以近乎同步的代碼風格取得異步的性能。我們以閑魚寶貝詳情頁的代碼舉例,對比不同的編碼方式。
// java同步代碼 ItemDetailDO queryItemDetail(Long itemId) {ItemDetailDO data = new ItemDetailDO();data.setBrowseCount(IdleItemBrowseService.count(itemId));// 多少人看過data.setFavorCount(IdleItemFavorService.count(itemId));// 多少人點贊return data; }// dart異步代碼 ItemDetailDO queryItemDetail(int itemId) async {var data = new ItemDetailDO();await Future.wait([IdleItemBrowseService.count(itemId).then((count) => data.browseCount = count).catchError((exp, stackTrace) => logError('$exp $stackTrace')),IdleItemFavorService.count(itemId).then((count) => data.favorCount = count).catchError((exp, stackTrace) => logError('$exp $stackTrace'))]);return data; }// rxjava異步代碼 ItemDetailDO queryItemDetail(Long itemId) {ItemDetailDO data = new ItemDetailDO();Flowable<Long> browseCountFlow = Flowable.fromCallable(() => IdleItemBrowseService.count(itemId)).onErrorReturn(t -> 0).subscribeOn(Schedulers.io());Flowable<Long> favorCountFlow = Flowable.fromCallable(() => IdleItemFavorService.count(itemId)).onErrorReturn(t -> 0).subscribeOn(Schedulers.io());Flowable.zip(browseCountFlow, favorCountFlow, (browseCount, favorCount) -> {data.setBrowseCount(browseCount);data.setFavorCount(favorCount);}).blockingFirst(); }

在java中我們也廣泛使用RxJava這種強大的響應式擴展實施異步操作:RxJava作為java的響應式編程擴展,功能非常強大全面,它使用流的概念封裝所有的異步操作。需要注意的是這里的兩個服務調用都被放到一個IO線程池中運行, 這個線程池是無界的,容易消耗線程這種系統稀缺的資源。這意味著當流量非常大的時候,系統的線程池很容易被打滿,需要設置合理的背壓策略。
從上面的代碼中可以看到“數據獲取”,“數據組裝”的邏輯非常清晰,不像同步代碼分散在各處;相比于同步操作,dart的異步操作允許我們同時等待多個IO事件,降低總的響應時間。dart的異步代碼擁有同步代碼的簡潔容易理解的優點,又具有異步編程的性能優勢。
dart異步的原理也是容易理解的。作為單線程語言,dart依靠事件循環運行代碼。dart從main函數開始執行,我們在main函數里面創建Future,相當于在一個dart內部維護的事件隊列(event queue)中添加計劃任務(添加的任務并不會立即執行)。main中的代碼執行完之后,dart事件循環開始從事件隊列中依次獲取任務執行。async/await是dart的語法糖,它允許開發人員能夠以書寫同步代碼的方式來實施異步編程(在C#、javascript中也有類似實現)。被async修飾的方法返回一個Future,調用這樣的方法,相當于創建一個Future。await一個Future,相當于把await之后的代碼打包放在Future.then()的代碼塊里,這樣就保證之后的代碼在Future之后執行。由于任務存儲于事件隊列,dart在流量大的時候,內存消耗較大,也需要我們前期合理評估需求和分配系統資源。

dart后端開發實戰

為了提高開發效率,我們利用dart的特性構建了一套高效的隔離開發環境。在業務開發實踐中,我們總結出基本的開發架構和代碼模式。在這些技術基礎上,開發了閑魚寶貝詳情頁的主干業務。下面逐一介紹。

高效的隔離開發環境

我們以往的開發場景是:提交代碼 -> 代碼沖突(多人共用一個部署環境) -> 構建/部署 -> 通過接口驗證 -> 提交fix -> 構建/部署 -> 驗證 的迭代。在這個過程中,開發人員有可能需要親自解決代碼沖突,或者依賴別人解決代碼沖突,需要等待構建/部署的時間(少則5分鐘,多則十幾分鐘)。而且這個過程可能需要迭代多次,時間成本很高,如果因為其他開發人員的代碼分支的問題導致部署失敗,那么等待驗證的時間成倍增加。這樣的開發效率顯然不是特別理想。

在閑魚的dart應用中,這種問題會得到緩解。每個開發人員使用自己獨立的開發環境,開發環境使用每個人的工號唯一識別。在不需要提交代碼的情況下,開發人員把代碼部署到遠程預發環境中,并在本地調用預發服務,查看服務的輸出,做到本地驗證調試的效果,極大地提高了開發效率。因為只會有開發自己單一分支的代碼部署,不會牽扯到代碼沖突。整個過程,部署、服務調用過程十分快速,可以在10秒內完成。驗證和調試的效率非常高。

每個開發人員的獨立開發環境對應預發機器上的一個isolate。dart的isolate相當于一個線程,但是不會和其他isolate共享內存,isolate之間的通信通過發送、接收消息完成。閑魚技術團隊使用每個開發人員的代碼創建一個isolate,使用工號作為標識,代碼可以全量替換掉運行中的isolate,也可以使用熱部署增量替換掉isolate中更改的功能。整個過程非???。在早期使用dart原生的編譯器,發現速度較慢(10多秒)后,我們對dart編譯器做了裁剪和優化,把編譯時間從10多秒降低到幾百毫秒(簡單來說就是,把dart原生的編譯器的附加功能,重新封裝,然后通過JIT/AOT生成新的編譯工具)。經過我們對dart開發環境的增強,現在開發dart膠水層接口,只需要點擊開發工具上的一個按鈕,就可以把修改的代碼,在幾秒內部署到遠程的預發環境,并調用當前的開發接口,在本地查看輸出。獲得和在預發環境上驗證一樣的效果,但是體驗就像在開發一個完全不依賴外部的本地應用程序。

業務開發架構

業務開發中最重要的部分是分離出變化和不變的部分,變化的部分用最靈活、快捷的方式實現(變的最多的地方當然用最快的方式處理),不變的部分使用穩定、高效的方式實現。我們已經把dart建設成為一種能夠高效開發,并且適合客戶端、前端、后端技術人員共同使用的技術。這種技術最適合應用于發生快速變化的接口層,也就是客戶端和后端交互的地方,業務需求的變化導致這里的數據結構快速變化,也稱之為膠水層。對于相對穩定的數據服務,我們使用java實現為領域服務。

上圖是服務之間的交互圖,實現方式如下圖所示:

膠水層dart應用以HTTP協議方式作為MTOP接口提供給客戶端調用,往下使用HSF從Java應用中獲取數據。
通常先定義并開發好領域服務,然后再與客戶端對接開發出接口,領域服務提供的接口,包含了獲取基礎數據的所有方法,開發好之后,很少發生變化;膠水層獲取領域服務提供的數據,對數據進行加工、裁剪、組裝,輸出為客戶端能夠解析的視圖數據,客戶端解析、渲染、展示為頁面。膠水層的代碼大致可以分為:獲取數據,然后數據處理和組裝。抽象出代碼模式如下所示:

// 數據處理和組裝 void putTiger(Zoo zoo, Tiger tiger) => zoo.tiger = tiger; void putDophin(Zoo zoo, Dophin dophin) => zoo.dophin = dophin; void putRatel(Zoo zoo, Ratel ratel) => zoo.ratel = ratel;// 發起多個異步請求,所有請求完成后返回所有數據 Future<T> catchError<T>(Future<T> future) {return future.catchError((e, st) => LogUtils.error('$e $st')); } Future<List<T>> waitFutures<T>(List<Future<T>> futures) {Future<List<T>> future = Future.wait(futures.map(catchError));return catchError(future); }// 服務接口 Future<Zoo> process(Parameter param) async {var zoo = new Zoo();// 數據獲取await waitFutures(Service1.invoke(param).then((animal) -> putTiger(zoo, animal)),Service2.invoke(param).then((animal) -> putLion(zoo, dophin)),Service3.invoke(param).then((animal) -> putRatel(zoo, animal)));return finalData; }

為了使用java的領域服務,我們首先解決了dart和java之間數據交互問題,主要是通過序列化對java類文件和dart類文件進行合理的轉換,保證dart能夠透明、簡潔地使用java的數據結構,調用java的遠程服務;在調用鏈路上設置全局唯一的上下文id,跨越dart和java調用棧,支持全鏈路排查;對所有的服務的成功率,rt和額外業務參數有詳細的日志,可以配置以日志為數據源的監控告警等等(后續的文章將詳細介紹我們對這些問題的詳細解決方案,請持續關注哦)。

服務化詳情頁主干開發

閑魚寶貝詳情頁是我們使用dart開發的一個重要項目。最早的閑魚寶貝詳情頁把各個業務的代碼邏輯耦合在一起,導致維護和變更困難,穩定性也難以保證。我們設計的swak框架(更多細節請查看文章swak框架),能夠分離垂直業務的共性和差異性,把閑魚寶貝詳情頁的實現分割成主干實現和垂直業務實現兩塊。我們使用自己開發的dart后端開發框架,對swak框架做了最小實現。項目完成了詳情頁主干的完整功能和基礎優化:

  • 垂直業務路由:我們使用dart中的zone存儲每個閑魚商品的業務標識,代碼生成的靜態代理類依據業務標識調用相應的服務,在主干數據里填充各個業務的獨有數據。zone是dart異步代碼的執行環境,能夠緩存一些可重用數據(業務代碼里除非非此不可,盡量不要多用)
  • 作為遠程服務的提供方:在hsfcpp對hessian協議的實現基礎上做開發,dart也能成為遠程服務的提供方
  • 服務調用的優化: 對java遠程服務的代理做了優化,隔離業務層面對框架層的感知,做到透明調用
  • 解決緩存調用的差異性:我們依賴緩存的c++接口訪問緩存,但是仍然需要處理java/c++緩存讀寫不兼容問題完成dart和java對同一緩存的同時讀寫
    項目流程圖可見下圖:

    ![dart-detail-flow.png](http://gw.alicdn.com/mt/TB1Pyv6V9zqK1RjSZFjXXblCFXa-558-561.png)

實際效果

目前該項目已經上線超過6周,qps最高可達400,成功率在99.5%以上。整個調用鏈路的RT與同樣功能的java應用持平。由于前期的精心設計,領域服務很少改動,大部分變更發生在dart膠水層。從上線后經歷的若干次變更來看,dart膠水層從修改代碼結束到提供給客戶端使用總耗時不超過2分鐘,而相同功能的java應用需要10分鐘以上。

總結

dart是一門簡潔、容易上手、對異步支持良好的編程語言,在flutter的開發中大放異彩。在我們的努力下,dart用于后端開發的支持逐漸完善,前臺開發同學和后端開發人員快速高效地開發膠水層接口。我們在很多生產項目中使用了dart用于后端開發,性能、穩定性良好,開發效率大大提高。未來我們會著力于進一步改善dart開發體驗、與java項目的兼容性、提升dart遠程服務的性能,挖掘dart在后端開發中更大的潛力。


原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。

總結

以上是生活随笔為你收集整理的在闲鱼,我们如何用Dart做高效后端开发?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品19乱码一区二区三区 | 人妻激情偷乱频一区二区三区 | 日韩网站在线播放 | 国产精品香蕉在线观看 | 亚洲熟女一区 | 裸体一区二区三区 | 成人高清网站 | 日本精品视频一区二区三区 | 国产在线观看a | 麻豆免费看片 | 日本xxxxxxxxx18 | 国产亚洲精品久久久久久青梅 | 91久久视频| 日本黄色美女 | 二区中文字幕 | 在线视频黄 | 91夫妻视频 | 亚洲欧美婷婷 | 亚洲狠狠丁香婷婷综合久久久 | 鲁一鲁在线视频 | 国产精品久久久久电影 | 国产91九色 | 91人人草| 亚洲黄色免费网站 | 91视频网页| 91看大片 | 午夜激情亚洲 | 九色91porny| 五月天色视频 | www..com色| 青青草日本 | av少妇 | 午夜精品在线观看 | 小珊的性放荡羞辱日记 | 国产精品videossex国产高清 | 亚洲成a人在线观看 | 成人免费一级 | 亚洲av综合一区二区 | 国产一级片免费在线观看 | 亚洲观看黄色网 | 日韩六区| 亚洲一级在线播放 | 噼里啪啦高清 | 91蜜桃在线 | 成年人视频在线看 | 久久综合色网 | 国产免费黄色片 | 色婷婷www| 色又黄又爽 | 欧美三极片 | 深夜视频在线观看 | 日本黄色免费在线观看 | 在线黄av| 潘金莲三级野外 | 久草网在线视频 | 天天操天天操天天 | 特级西西人体444www高清 | 就去吻综合 | 岳狂躁岳丰满少妇大叫 | 加勒比在线免费视频 | 久久情趣视频 | 精品无码一区二区三区的天堂 | 91久久精品在线 | 欧美亚洲黄色片 | 亚洲素人 | 国产素人av | 国产美女又黄又爽又色视频免费 | 暖暖av| 国产精品久久久久9999 | 精品一区av | 亚洲AV无码阿娇国产精品 | 伊人久久亚洲综合 | 狠狠操狠狠插 | 欧美第一页草草影院 | 婷婷影院在线观看 | 欧美 中文字幕 | 亚洲一卡二卡三卡 | 欧美大片在线播放 | 一级黄av | 国产日韩av一区二区 | 中文在线资源天堂 | 欧美mv日韩mv国产网站app | 成人免费视频国产在线观看 | 麻豆精品影院 | 四虎com| 国产精品国产三级国产aⅴ浪潮 | 日本三级中文字幕在线观看 | 涩涩久久 | 亚洲色吧 | 九九色网站 | 成年人性生活免费视频 | 久操视频在线播放 | 欧美成人综合网站 | 午夜精品一区二区三区三上悠亚 | 成人毛片在线播放 | 国产亲伦免费视频播放 | 欧美激情视频在线观看 | 麻豆传媒一区二区三区 | 免费观看一区二区三区视频 |