好了 那麼我們就開始吧今天真的是非常高興因為這是我第一次參加開源相關的大會非常感謝主辦方今年有這樣的機會給我們這麼多的一些開源開發者在這個大會上可以互相交流自己的項目所以呢 我今天的一個主題也是一個開源項目這是我們做的一個叫做基於任務的並行計算與一部通信的引擎叫做C++ Workflow我叫李寧心然後先來自我介紹一下吧我其實原先是在搜狗然後我們公司現在已經核到騰訊了我是系統架構部的一名開發我原先有著八年的C++的系統架構的開發經驗原先主要做的事情是pValue的分布式存儲相關的事情然後最近也在做一些網路通信相關的東西最近其實在這兩三年以來其實我們都在做一個叫做C++ Workflow的這麼一個項目它其實可以簡單的說它是一個PASS層但是它不只是一個PASS層的一個解決方案同時它更重要的是一個基於任務模式的做並行計算和一部調度通信的這麼一個引擎同時我自己個人的話我也是基於這個項目的RPC框架的SRPC的主要開發然後我們的項目是在2020年開源的自從Workflow和SRPC開源以來我主要做的事情同步的除了我們的項目開發以外然後我也需要去做就是我們的開發者生態的這塊的建設然後以及我們的一些非常多的一些生態項目的調研然後根據原生的結合等等相關的事情非常多值得做的事情然後今天先來介紹一下我今天說的一個流程我其實今天具體主要的是前三部分一個是基本的內容的一個介紹另外第二部分會介紹的比較詳細就是我們一個基於任務的一部框架它其實在設計上有什麼特別的值得分享的地方那麼它的架構其實我會講的比較詳細那麼第三部分就是更進一層就是我們其實不僅是做一個引擎我們希望做的是一個私家家的編程範室所以這部分會介紹一些就是編程範室相關的思想然後之後兩個小點就會介紹到我們的一個重構的一個例子以及我們的具體的生態然後我們可以開始重視的內容了就是大家其實可以在github的這個位置上可以看到我們的項目然後在就是看這個視頻的期間其實大家也可以一邊去瀏覽因為很多的一些具體的文檔其實我們都在github上面會建設的比較完善然後這個我怕我今天講的可能還只是冰山一角然後呢Wopflow它其實是什麼呢一句話來概括其實是這樣的它其實本身是SOGO的私家家的服務器引擎它現在其實基本上支持了SOGO的所有西家家在線的服務包括什麼呢包括SOSO然後我們熟知的雲輸入法然後以及在線的廣告那麼它每天請求的一個量是幾乎是在百億級的級別的那如果說它有一些具體的特點的話就首先可以看到四點了第一點就是它其實是對義務資源的一個調用什麼義務資源呢咱們其實經常見到的就是網絡然後計算其實還不只還有文件iO或者是定時器之類的Wopflow做的事情就是對義務資源的一個調用第二就是它允許用戶去組裝不同的義務資源這個就是剛才介紹到的我們是一個基於任務的一個tax-based的那麼它其實重要的點是在於我們可以讓用戶就是非常方便的去組裝不同的義務資源成為一個非常複雜的複合的任務然後第三點就是它跨平臺然後並且是支持多操作系統的第四點就是其實Wopflow其實你會看到它其實不只是通信然後也不只是計算那麼所以其實它其實不僅僅是一個RPC然後它也不只是一個調度引擎那更多的我們要為它做什麼呢如果再去做一些通信相關的或者是一些服務相關的東西的話我們會為它提供基本的控制邏輯這些基本的控制邏輯包括什麼就是包括我們的基本的服務治理然後我們的Load Balance然後以及我們的一些選取策略等等這些我們常見的Pass層基本的控制邏輯我們其實剛才有提到就是我們是在2020年7月份開源的目前來說是收納在了CNCF的Landscape的一個Pass的一個分類裡面然後這裡可以看到它的一個基本的一個層次就是這一整個框就是Wopflow它去作為一個Pass層它裡面所對接的東西那麼它先看一下它的外部吧它的外部的話首先是這樣它可以跑在一些不同的平臺然後不同的操作系統然後不同的體系結構上面那麼右邊可以看到Wopflow它既然作為一個Pass層那麼它一定是接口上面是支持非常多的其他的一些集群的所以所有的一些Lock集群然後Trace集群然後監控集群這些我們都是以生態項目去這麼的一個合作方式去添加所以我們只要提供了接口那麼所以我們都可以去對接具體的一些監控集群然後整一個Wopflow內部是這樣的它作為Pass層那麼最底層有什麼呢由我們剛才提到過的我們去作為一個Service我們會有基本的一些控制邏輯包括我們的一些路由策略然後DNS其實裡面也是自己實現的然後一些基本的一些服務的熔斷等等然後中間的這一層就是具體的調度了就是我們有這麼多的醫部資源那麼我們需要去調度起來的話網絡其實大家都知道了常見的一鋪LCP和KQ那麼計算的話其實內部也實現了一個具體的計算對列對於其他的一些調度也是類似的這裡的具體的一些組合等一下會詳細的講到然後在上一層就是用戶比較經常接觸到的比方說具體的一些協議然後或者是具體的一些就是我拿到的一個計算的具體的對象或者說是一個網絡具體的對象那這裡右邊就有一個小圖其實是一個最簡單的我們就十幾行就可以實現一個西加加的soul就是其實大家如果是用西加加比較多的話其實都知道在開源界西加加這幾年應該是沒有一個非常新的Pass層的一個模式出現了那麼Wallflow我覺得今天比較值得分享的就是它確實是這幾年來就是在開源界內西加加裡面的一個比較新的一種模式雖然這個接口看上去很簡單但是其實它可以實現非常多的功能那我先在這邊先簡單的介紹一下首先它是融合了計算和通信的所有的一部調度其實都可以融為一體第二點就是它的層次其實是非常適合我們去做一些二次開發和附用為什麼呢因為其實它的無論是計算或者是通信它的層次都是非常的對稱第三點就是我們引入了就是算法和協議和具體的業務邏輯開發應該是非常獨立然後非常節偶的所以我們會認為任何一個一部的操作其實它都是可以被封裝在一個具體的任務上所以無論是具體的算法或者是具體的協議他們結合了任務之後他們其實就可以做一個就是邊界非常清晰的任務這個是我們在就是邊城思想上面的一個不同的地方第四點就是一個非常簡單的一個用戶接口就像這邊我們起一個http server其實我們必須接口是非常簡單然後不希望它去帶一堆模板或者是一些其他的東西然後另外就是我們是自己實現了不同的協議的什麼意思呢就是我們在基於自己做的一個義部的框架上我們自己實現了http實現了radis也實現了mycicle和卡夫卡也就是說我們是一個天然的純義部的mycicle和卡夫卡的客戶端這個在你去找輕量級的mycicle的義部client的時候就是可能你會發現真正做到純義部的workflow是絕對是做得非常好的一個除此之外DNS和websocket也是我們自己去實現了的然後我們進入第二部分就是剛才說到的這麼多功能然後我們會去具體分三層來去介紹一下它的整體的實現的架構是什麼樣的第一層就是它的一個義部義部是什麼呢就是我們具體用了這麼多資源然後這些資源其實就是GPUCPU網絡然後timer然後以及是文件的AIO然後並且所有的資源它要去用的時候其實我們為了要打通它我們一定要不同的資源它都要去封裝出一種同等的調度單位然後這一層是要非常對稱的然後第三層封裝出同等的調度單位之後我們就要為這些調度單位去做一些管理器去組織起來比方說現成我們要去管理起來然後連接我們肯定也要去管理起來然後另外值得說一下的就是我們的一個就是計算其實是有一個就是申請了專利的一個計算對列那麼它是可以同時兼顧了不同的優先級然後以及突發的高優先級的情況它都可以做到盡可能均勻的把所有的計算任務調度起來的這麼一個事情然後這就是我們的整一個比較簡單的一個層次然後下一張圖就是為了體現不同的資源它的一個對稱性的這個怎麼說呢首先是這樣大家可以看到我們以計算和網絡這兩條線為例子來看一下計算那麼它是個CPU資源那麼它可被調用的單位是什麼是現成網絡呢它可被調用的單位其實對我們來說是個socket fd那麼我們再往上一層就可以看到它一定會有它的管理器其實對於文件它也有一個文件的fd對於時間的話其實我們現在是用一個timefd來存的那麼所有的這些比方說我們想做超時或者說我們想做一些具體的逸步的事情我們會通過系統給我們提供的逸步機制把他們同樣的去封裝起來成為一個調度資源然後第三層大家也都是非常對稱的就像計算和網絡這樣我有一個執行器然後或者說我也有一個通信器在上一層是什麼呢就是具體的控制邏輯在計算的話就是剛才提到的會有一個具體的調度策略那麼在網絡上呢它其實就是有剛才提到我們對連接要有管理的話那麼連接它的一個連接輸限制它的一個具體的路由功能那它的一個重視選取這些東西其實如果你作為一個pass層你是必須要管理好的然後在上一層我們其實就像剛才說的我們認為其實咱們常見的其實就是算法和協議所以我們也會提供了常見的算法和協議給大家用對於計算來說那麼CPU它提供給用戶用到的就是一個具體的算法比如Soft或者是MapReduce之類的那麼對於網絡的話其實它給用戶提供的就是一個我們常見的一些網絡協議這個就是我們在去做一步的時候一步資源一定要去每一層都拆得比較對稱這個是Workflow整一個它的一個架構上的特點然後來看一下下一頁就是這層的話其實就是來介紹具體的一個任務了是這樣的剛才有提到就是我們的計算和網絡是對稱的那它的對稱性還可以體現在哪裡呢體現在它的用法上就是左邊這邊是主要的用法右邊這邊其實是一些基本的接口我們可以先看左邊就是我們對於不同的一些資源其實它的一個定位肯定是就是一定是一個類似的方法的什麼意思呢就是我對於一個網絡請求那麼我想要找到這個網頁那麼它就是帶著URL去那如果我要打開一個具體的文件去做Pread或者Pwrite那麼我們帶的肯定是一個文件名對於計算來說那麼其實它就是我需要請求這樣的一個資源那麼其實我的這個資源它就是一個對列名所以在用戶的接口上我們都是帶著我們想要的資源的名字來通過工廠然後去創建一個什麼任務然後呢所有的無論是計算也好或者是網絡也好創建的方式都是一樣的然後你拿到的都是一個具體的任務然後呢這個是一個就是在計算和網絡以及其他資源上的一個用法上的統一那麼在內部的接口上其實也是非常統一的我們可以看到就是我們其實內部是基於SCD Function來去做它的一個迴調就是這裡傳進去的Callback那麼對於計算來說我其實是一個算法算法還有什麼呢算法再加上輸入輸出那麼對於網絡來說網絡它除了它的協議還有什麼呢還有它的請求和回覆所以大家也可以看到就是在我們的這個接口上其實所有的資源它都是非常的對稱的另外值得一提的就是這個任務其實它所有東西都是行為派生的這個行為派生在這張圖裡其實就可以看到了就是我們的一個任務的資源的一個就往上層的一個派生關係大概是這個樣子的首先我們可以從上面開始看就是所有東西它其實都是從工廠創建出來的那麼大家會看到如果我Create完一個Task之後那麼它什麼時候釋放呢其實這個東西是框架來保證它會自動在我調到我的這個SCD Function的這個迴調函數之後它會自動被釋放的就是這個是一個非常重要的一點就是在我們去做一部框架的時候如果一部的內存管理的不好的話那麼其實用戶寫代碼會有非常多的困難然後我們可能會需要引入很多一些什麼回收機制等等的去協助但是這樣的話對框架的性能就會有非常大的損傷所以我們去設計一個自己的一部框架的時候就是大家也一定要注意就是必須要明確的劃分好就是不同的資源它的一個生命週期是什麼而對於Workflow裡邊它們都是從工廠派生然後從工廠創建出來並且它是在迴調函數自動被刪除的第二點就是可以看到這裡我們剛才有提到我們自己去實現它的一個任務的時候那麼它其實內部很可能是個複合任務這個待會會仔細的說一下第三點就是大家可以看到這裡Solar和Client其實它是非常的對稱的就是說無論是一個客戶端或者是一個服務器那麼其實它們拿到的一個任務都是剛才我們看到的一開始的一小段代碼裡邊它就是一個HDB task這個對於用戶的薪資負擔其實是會降低很多的然後並且它其實也比較符合一種就是非常方便我們去把一個Solar的Process函數去做成一個服務也比較符合一個Service as a function它的那個 function as a service 它的一個想法所以最下面一層就是一部的不同的資源然後用戶其實到這一層的話其實基本上就已經是無感的了用戶拿到的就是這一層然後這一層是做一個行為派生的然後這裡就是我們剛才看到的具體的可以被調用到的就是可調度的一些單位封裝出來的最基層的一個任務然後可以看到剛才說了我們東西其實是可以去作為一個符合任務的那麼符合任務它有什麼樣的一個特點呢或者說它其實具體是解決了什麼問題呢就是其實剛才有提到就是我們是用回調函數來去做那麼其實可能會有小夥伴去問說回調函數的話那其實我們對這個義部的時候開發的這個代碼的碎片化的引入其實這個會很難解決尤其是對於不同流程的一個組織就會很困難所以Workflow其實它這個項目是解決義部資源的問題但是它之所以叫Workflow就是因為我們認為這個項目最重要的價值是在於我們去解決用戶去調度不同義部資源的時候它的一個流程的問題這個就是我們架構層級再去介紹完義部介紹完任務之後我們這個第三點是我們的一個流途是怎麼組建的然後這裡大家其實可以看到首先我們提供了Series來去作為我們串形的任務的一個任務流並且我們提供了Parallel去作為並行任務的任務流所以大家其實可以看到這張圖它有點像一個電路圖它是一個典型的一個串並連的模式那麼這種它就是一個串連我可以把任務後面再串一個任務Parallel就是我可以去並連起來不同的任務並且第二點非常重要的是大家可以看到我們這邊的不同的任務其實它可能是不一樣的義部資源但是它可以被同等的去串起來就是說我這個Series Parallel我是不會在意你底層是什麼樣的義部資源的這個是我們剛才為什麼要去劃分層次然後大家要非常去對稱的原因這個就是在於我們在組裝的時候就會非常的方便然後你說有沒有一些模式是串並連所解決不了的呢其實當然是有的就好像我們右邊的這個DAG這樣像這種多入邊的話我們是單獨提供了一種DAG的模式去做的DAG其實一般都會是靜態去創建但是其實我們如果想要動態去創建的話也是可以的就是我們在這裡去動態的在它的回調寒室後面繼續往我們當前Series裡面去創建下一個任務就可以了所以這個流途它的意義就是在於我可以把這些任務即使它是不同的資源我也可以組裝起來並且我還可以靜態或者動態的去創建它那流途有了具體的解決的問題我們來舉個例子比如http一個任務那麼用戶去拿到一個http的URL它想去往它發請求的話它其實只關心我發起一個http的請求或者說一個http的任務以及我的一個回調寒室那麼所以其實它看到只是這裡和這裡那中間會做什麼呢就是不知道大家用其它或者做其它的那些網絡框架的時候有沒有關心到我們的一個重定向要怎麼做就是其實在workflow的目前的這一套模式重定向它的一個做法是非常的自然以及符合我們自己的一個任務組裝的一個編程思想的是這樣http一個請求如果它目前沒有命中到DNScatch的話那麼其實我們是需要去發起一個DNS任務的就是可能說你不僅是一個要去計算給addrinfo這麼簡單就是我們其實也實現了DNS協議我們會發起一個UDP的DNS任務然後等DNS任務回來了我們才會去把它的結果然後去作為然後我們就知道我們到底要訪問哪裡就才能真正發出用戶的請求然後我們發現302了那302怎麼辦呢我們會去修改一下用戶需要去請求的目標地址然後並且重新拉起還是同一個用戶的請求最後直到請求回來了然後我們就可以去調起這個回調函數了那麼這裡的話中間的這一部分其實對用戶來說都是看不到的那這個意義是在哪裡呢意義就是在於我們的任何一個任務其實它都可以去做一個這樣的封裝就是我們要去做一個流的時候其實它有點像我們去封裝一些函數但是函數它是同步的那麼我們去做不同的一部的事情的時候你想要去隱藏起你的一些複雜的內容你去給別人只提供一個簡單的接口那麼你用Workflow的這個符合任務的思想就可以非常好的去解決那所以其實前面說了這麼多都是為了介紹到我們其實會有一個思想就是我們一定要基於不同的一些任務的一些流去做一些事情那麼其實這也是Workflow它本身的一個編程範室裡邊的一個想法Workflow認為程序應該等於協議加算法加任務流就是剛才提到的協議就是我們常見的比方說像HTP或者是Radis然後或者是我們自定義的RPC然後它只要其實協議就是只要你提供了我的請求以及回覆它的一個敘利化反敘利化的函數那麼其實協議你就是可以自己實現的那麼算法是什麼呢算法它其實和協議是非常對稱只不過協議它是協議加請求加回覆那麼算法的話就是算法加輸入加輸出那麼算法的話我們更常見的是我們會自定義一種具體的算法那麼我們任何一個邊界清晰的一個調用的內容其實我們都應該是可以把它封裝成一個算法的我們可以把算法想像成一個可以飛出去的網絡請求那麼在這個網絡請求飛出去之後其實它肯定是不能被打斷的那麼其實如果你要用任務去封裝一個算法的話也是同樣的你要認為這個是一個不可以被中斷的一個義部任務那麼你就可以把它封裝成一個算法那麼任務流是什麼呢任務流其實就是具體的業務邏輯就好像我怎麼去發起個HTB請求然後我又去怎麼去做一些計算的東西典型的任務流呢就是我們剛才看到的就是會有並行和串行複雜的任務流就是像剛才有提到的DAG這樣那麼不同的任務它其實是應該能夠被同等的組裝起來的並且所有任務都應該被系統盡可能的同時去調起來這樣我才能夠盡可能的同時利用CPU和網絡和其他的資源那有了這樣的一個層次之後呢其實大家就可以看到Upload本身它其實是非常適合做一個就是二次開發或者是基於這個層次之上去做一些事情的它作為一個引擎吧其實它這個是一個就是比較強的一個編程範設的思想這個其實也是當時參考過就是有一些學術界的有關於進程代數的這樣的一些內容其實在Workflow裡邊我們對於剛才介紹到的Series and Parallel有三個約定首先Series是由任務來組成的第二點就是Parallel是由Series來組成的那麼第三點就是Parallel是一個任務這意味著什麼呢這意味著它和第一條這地規了它是一個任務然後它又可以被組裝到Series裡邊所以Workflow它本身其實是一個我帶了循環以及具體的控制的一個邏輯的這麼一個完備的編程範設就是這裡可以額外的解讀一下就是因為我們有了Series所以我們所有的東西才可以去不停的往這個任務流後面放並且無限的去疊帶下去這個就有點像我們去學一個編程語言然後我們會去找一下它的Fourth循環外的循環怎麼寫然後第二點就是因為Parallel它是各個串形任務流的一個會總所以它其實是一個收斂的過程那麼Parallel它本身是一個任務剛才也都介紹到了我們東西就可以被嵌套到Series裡邊所有的這些東西都可以組裝成一個複合任務就是像我們才去學一個編程語言去學一個函數怎麼寫只要我約定好了這個複合任務它的接口是什麼那麼其實用戶是不用關心我這個函數裡邊去怎麼實現然後我的這個函數或者說我的這個複合任務就可以給其他人再去使用了這個就是Walkflow整理一個的一個編程範式的思想那之後進入了第四點就是我這裡會快速的去過一下就是我這裡有三個比較典型的一個重構的例子第一個就是我們的原先的一個流水線的模式它是解鎖系統非常典型的一種模式但是這種模式流水線其實它如果按資源配比的話其實它的配比是非常的不靈活的那麼用Walkflow改造之後有什麼好處呢就是Walkflow的一個想法就是我要把系統資源都統一的管理好所以你的連接附用現成附用我都可以幫你去做當你想要去增加新一路的一個流水線的一個模塊的時候那麼你的資源配比有可能根源線已經變了但是沒關係Walkflow會盡量的幫你做到只要有系統資源它都會幫你掉起來所以當時我們去進行了這一版重構之後性能是有非常大的提升的然後第二點就是剛才有提到我們其實是支持了非常多的一些協議都是自己去實現的傳統我們原先在一個抓取中台裡邊我們要去抓取不同的HDP然後並且去把它放到不同的數據庫裡邊的時候我們要去自己管它的Client有一些Client可能還比較好用但是有些Client可能它本身就不戴什麼一部或者是附用的功能如果你統一用Walkflow來做的話當時我們的一個重構之後由於Walkflow本身它的網絡就是純一部的所以你在上面無論去做任何的協議你不用再去管它的一個現成或者是連接它是怎麼樣去封裝的然後這樣的話所有的用戶接口都非常的統一所以開發起來就會非常的方便性能也會得到非常大的提升第三個就是一個典型的就是我們在去做運輸物法的時候其實它是一個CPU密集型的一個Sover那麼也就是說Sover它既要去接受網絡請求同時它也要去做複雜的CPU計算其實我們用私家家無非都是為了能夠讓我們的吞吐要去非常的高然後並且我們希望我們的CPU也能盡可能的用得上去那如果在這種情況下就是任何一個現成可能去在做等待的時候可能計算會影響網絡或者網絡會影響計算但是如果你把所有的調度都同等的去對待然後同等的去只要有資源就可以調起來那麼其實這就是Workflow非常擅長的事情是可以把網絡和CPU或者甚至是磁盤然後都這些不同的義務資源都可以同時去吃滿的這個就是當時我們去幫助雲舒服法去改造的時候它的一個CPU密集型的Sover一個非常典型的一個應用然後最後就是介紹一下我們在這就是在這上面做的一些生態其實是這樣的剛才有提到就是有做了一套叫做SRPCWorkflow本身它其實的定位和很多RPC框架其實是不太一樣我們會認為RPC協議只是HTCP或者是Redis它的是並列的那麼協議之間它是並列的話它只有底層的一些網絡通信器它是共用所以SRPC底層網絡通信器是用了Workflow但是它上層支持了不同的協議然後或者是不同的IDL然後不同的壓縮算法然後最後有一些生存代碼給用戶使用並且SRPC目前是可以支持OpenTracing和Open Telemetry的一個Tracing的流程的上報的所以這是Workflow上面的一個目前用的也比較多的一個生態項目還有什麼生態項目呢我們基於Workflow做了一個PromiseOS的Exporter這個比較簡單就不用細說了然後另外就是我們有去剛才有介紹的就是內部其實我們是有服務治理的然後服務發現怎麼做呢我們提供了服務發現接口就是說我們只要通過插件那麼你就可以和其他的服務發現了集群拉下他的服務發現的具體的內容然後添加到Workflow裡那麼在你使用PaaS層的用戶代碼上你就可以無感的去使用服務發現裡面拿到的數據去進行路由所以我們現在實現了一個Workflow Kubernetes的一個插件它是可以對接 Kubernetes 裡邊對於每一個Pod它的一個路由信息然後後續也會支持其他的一些Service Mesh的一些系統前面其實提到的這些都是我們會去做幾個方面就是一個Trace, Matrix或者是服務發現等等的一些就是與雲原生的其他系統對接相關的事情另外還有一個Python層的一個接口就是我們利用了PyBand來去做PyWorkflow其實Workflow目前的一個計劃是遠遠不止如此的因為其實它目前只開源了一年其實我們希望能夠去基於它這樣一個非常底層的一層引擎我們其實是可以去做很多它的一個生態項目然後也希望能夠去和雲原生進行更多的一些對接所以這塊其實我們也在不斷的推進和學習中然後最後的就是總結一下了就是剛才其實有提到我們去拿Workflow去做一些重構的時候它會有非常大的性能提升的那麼我們有具體的壓測的性能對比是主要是和Andrex進行對比的為什麼和Andrex進行對比呢就是因為剛才也有提到過C++在開源這方面其實Path層其實應該是最近幾年是很少有比較新型的一個模式來去出現Andrex可以說是至少在網絡方面是非常值得我們學習的一個經典的框架那Workflow它更適合做的事情是什麼呢是做網絡服務器帶上計算計算與通信融為一體的這麼一些場景所以我們當時和Andrex有做一些基本的調度的對比那其實性能也是非常好的這裡有一個說的是我們去做一些proxy的時候我們的性能是純的sower的二分之一這個怎麼理解呢因為proxy它本身是一個一步sower就是說我們再去接受完這個請求之後我們必須一步的做一些事情那如果你的性能可以純為你做普通平衡sower的二分之一那麼就說明你內部的所有的一步調度都是無損耗的那麼其實這是一個理論最大值Workflow是可以做到的另外就是一點點就是我們在開源相關的一些經驗首先我們其實是後來支持了編譯採檢所以外加就是我們其實是非常輕量級然後也沒有其他的依賴編譯非常快然後編出來的代賣非常小所以其實Workflow這個不僅它是一個雲上或者是端上可以用即使在嵌入市上我們其實也發現開源社區裡面還滿多小夥伴也有在用的另外就是也有提供一些其他的組件然後以及二級工廠並且還有做許多的一些生態項目另外就是我們發現在Windows下的用戶然後或者說用Workflow來做一些計算solar的用戶其實是最多的另外就是最後一點就是也有人開始基於Workflow的Pass層來去做一些其他的自己的生態項目所以說明其實它的一個二次開發還是比較簡便的所以我今天的分享就到這裡了就再次感謝主辦方給我們這樣的機會然後也非常歡迎大家能夠在GitHub上面繼續與我們進行交流然後其實在開源方向我個人的話其實還是希望能夠積累更多的經驗的所以也希望通過這次的會議能夠得到大家非常多的反饋然後繼續把我們和雲原聲節和這塊做得更好謝謝