我是如何從Java轉型爲Go區塊鏈工程師

我是如何從Java轉型爲Go區塊鏈工程師

本文來自於一個比原鏈核心開發的陳述

前言

本人在加入比原鏈之前一直是做Java開發的,當初看到Go還有點猶豫,還怕過不了面試,結果是否掌握一門語言的考量確實沒那麼高,我順利入職比原鏈,並在半個月內很快掌握Go並能夠進行核心項目的開發。 Java語言在較大的成熟項目上具有優勢,但是在區塊鏈開發中確實會有很多短處,比如在協程處理上,還有Java語言本身不夠靈活等等,當然選擇使用Go主要是因爲其在區塊鏈的流行程度。

區塊鏈的流行語言

在區塊鏈公鏈的開發圈子裏,我們找到了一些流行的編程語言,有C++、Golang、Python和最近新起的Rust等等。

稍微對比較有名的項目採用的編程語言做個統計,如下圖:

老一代的公鏈,比如Bitcoin,Litcoin一般使用C/C++較多(我們看看那個時間,當時Go還沒起來呢),新一代的公鏈比如以太坊,聯盟鏈翹楚超級賬本,開始較多使用Go語言,當然我們看到Rust的發展勢頭也很猛,近兩年的很多公鏈比如波卡,Grin都開始採用Rust語言開發了。

Go語言的優勢

部署簡單

Go 編譯生成的是一個靜態可執行文件,除了 glibc 外沒有其他外部依賴。這讓部署變得異常方便:目標機器上只需要一個基礎的系統和必要的管理、監控工具,完全不需要操心應用所需的各種包、庫的依賴關係,大大減輕了維護的負擔。可直接編譯成機器碼,不依賴其他庫,glibc的版本有一定要求,部署就是扔一個文件上去就完成了。

性能優秀

雖然不如 C 和 Java,但通常比原生 Python 應用還是高一個數量級的,適合編寫一些瓶頸業務。內存佔用也非常省。

併發性&通道

Goroutine 和 channel 使得編寫高併發的服務端軟件變得相當容易,很多情況下完全不需要考慮鎖機制以及由此帶來的各種問題。單個 Go 應用也能有效的利用多個 CPU 核,並行執行的性能好。

良好的語言設計

Go 非常簡單,且易於學習。從學術的角度講 Go 語言其實非常平庸,不支持許多高級的語言特性;但從工程的角度講,Go 的設計是非常優秀的:規範足夠簡單靈活。正是由於 Go 的簡單性,任何的 Python、Elixir、C++、Scala 或者 Java 開發者皆可在一月內組建成一個高效的 Go 團隊。

標準庫&工具

Go目前已經內置了大量的庫,特別是網絡庫非常強大。更重要的是 Go 自帶完善的工具鏈,大大提高了團隊協作的一致性。比如 gofmt 自動排版 Go 代碼,很大程度上杜絕了不同人寫的代碼排版風格不一致的問題。把編輯器配置成在編輯存檔的時候自動運行 gofmt,這樣在編寫代碼的時候可以隨意擺放位置,存檔的時候自動變成正確排版的代碼。此外還有 gofix, govet 等非常有用的工具。

團隊牛逼

Go語言後面的支持者是Google,語言足夠在各種場景下得到檢驗,同時創始人還是C語言之父,對後續的發展和創新可期。

Go成功的項目

Go語言在雲時代得到了比較廣泛的應用,特別是Docker和K8s這樣的殺手級產品的出現讓Go語言在工程界佔有一席之地 除此之外Go語言還有非常多的成功運行中的軟件: nsq:bitly開源的消息隊列系統,性能非常高,目前他們每天處理數十億條的消息 packer:用來生成不同平臺的鏡像文件,例如VM、vbox、AWS等,作者是vagrant的作者 skynet:分佈式調度框架 Doozer:分佈式同步工具,類似ZooKeeper Heka:mazila開源的日誌處理系統 cbfs:couchbase開源的分佈式文件系統 tsuru:開源的PAAS平臺,和SAE實現的功能一模一樣 groupcache:memcahe作者寫的用於Google下載系統的緩存系統 god:類似redis的緩存系統,但是支持分佈式和擴展性 gor:網絡流量抓包和重放工具

生態卡位和隱性標準

除了打鐵還需自身硬之外,還有些機遇和運勢,讓區塊鏈選擇的了Go語言。我們來看區塊鏈2.0以來最成功的公鏈和聯盟鏈代表,以太坊和超級賬本Fabric,無一例外都選擇使用Go作爲開發語言(雖然以太坊其實也有其他語言的客戶端版本,但進入到Homestead階段以後,Go客戶端佔據了主導地位),這兩大超級區塊鏈的影響力可不是一般項目可以比擬的,不僅在生態中佔據了大的坑位,事實上還隱性的制定了區塊鏈的標準,不論是公鏈中的智能合約,還是聯盟鏈的技術,都繞不開以太坊和Fabric,那麼對於一家想要做區塊鏈技術選型的公司來說,最快捷的實現是什麼?自然是直接照搬這兩個項目的創新,再捷徑一點就是直接拿開源代碼改,那麼自然Go語言就成爲後來者的首選,換種語言重新實現一遍難度也不小,而且如果選擇一些創新但不是非常成熟的語言還會缺失一些特定庫的支持從而導致項目無法開展。

很多人對以太坊的影響力毋庸置疑,但實際上Fabric在企業區塊鏈部署上的影響力更不容小覷:

圖表來源《2019年全球企業區塊鏈基準研究報告》

Hyperledger Fabric是已部署的企業區塊鏈網絡中使用最多的協議框架,超級賬本Hyperledger(其中Fabric作爲旗艦協議)是集成商和軟件開發平臺最常支持的協議框架,比例達到了53%。 而在所有的區塊鏈技術書籍裏面,有關超級賬本的書籍是賣的最爲火爆這個事實也是側面印證了超級賬本Hyperledger的影響力。

比原鏈在Go語言中的實踐

在選型編程語言的過程中,考量了C,C++, Java,但C/C++大項目維護難度大,而Java又略顯笨重,此時Go語言已經在區塊鏈項目上大放異彩,也逐漸形成技術和人才的一個頭部效應,那麼順應潮流進行技術選型自然也會減少初始比原鏈項目遇到的阻力,當然在逐漸開發過程中,我們也感受到了選用Go語言帶來的便利和優勢。

Go在區塊鏈上的一個Case

從技術上來說,區塊鏈節點是需要多模塊異步協同工作的,所以Go語言併發性和通道就顯得非常有優勢,我們看下面交易驗證的例子:

func ValidateTxs(txs []*bc.Tx, block *bc.Block) []*ValidateTxResult {
    txSize := len(txs)
    //init the goroutine validate worker
    var wg sync.WaitGroup
    workCh := make(chan *validateTxWork, txSize)
    resultCh := make(chan *ValidateTxResult, txSize)
    closeCh := make(chan struct{})
    for i := 0; i <= validateWorkerNum && i < txSize; i++ {
        wg.Add(1)
        go validateTxWorker(workCh, resultCh, closeCh, &wg)
    }

    //sent the works
    for i, tx := range txs {
        workCh <- &validateTxWork{i: i, tx: tx, block: block}
    }

    //collect validate results
    results := make([]*ValidateTxResult, txSize)
    for i := 0; i < txSize; i++ {
        result := <-resultCh
        results[result.i] = result
    }

    close(closeCh)
    wg.Wait()
    close(workCh)
    close(resultCh)
    return results
}


我們使用Routine+Ch+WaitGroup在30行代碼之內,就可以構建一個併發的驗證交易的功能,在高配置的服務器的情況下,可以跑出10萬以上的TPS。

輕鬆變成Go語言大師

我當初進入比原之前也沒有做過Go語言開發,但都能夠很快上手,基本在半個月內能夠參與核心代碼的開發和維護了(對於從C/C++/Java有經驗的開發者尤其快速),這就是語言簡單對團隊構建帶來的好處。

統一的協作

從協作上來說,通過gofmt 自動排版 Go 代碼,能夠讓核心團隊成員甚至社區開發者提交的代碼風格的差異性降到最小,提升項目的整體質量和可維護性。

小結

Go語言本身的特質和優勢爲其做好了鋪墊,而以太坊和超級賬本兩個超級區塊鏈項目的加持也讓Go語言成爲了很多區塊鏈項目的首選,比原鏈選用Go語言也充分體會到了其開發區塊鏈底層的優勢,但是無需落入語言之爭的陷阱,講求實用主義纔是做工程應有之義,比原鏈核心項目是用Go語言完成,但是周邊的很多子項目也有用Java,Python或者JavaScript實現,畢竟生態的多樣性纔是一個項目長久的根本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章