[Golang] 在 Kubernetes 上面透過 Go 開發 GRPC service 可能遇到的問題

前提

之前為了幫公司的產品加上一個中間層的服務處理,需要把許多原先預設的 GRPC 服務參數都改掉,或是新增不少功能.在這裡整理一下,分享給大家.

本文會提供一個簡單的 repo 裡面有提到會使用到的一些功能,並且附上一個 Kubernetes 部署的 yaml 檔.

Show Me The Code

不囉唆,先看 REPO https://github.com/kkdai/grpc-example

在原先的 GRPC 服務開始擴展

一開始,我們先以 Hello World 為範例,並且省略相關的部分. 一開始 SayHello 的範例建置好之後. 這個範例(hello world) 相當簡單,就是一個 SayHello 然後傳回一個回覆. 我們可能會開始收到其他的需求…

以下的需求最後將整合到一個範例 repo https://github.com/kkdai/grpc-example

1: 能不能一次送多個指令 (streaming request)

你可能收到需求,需要在原先的服務上面新增一個接口可以處理連續性的請求 (streaming request) .或是在處理資料的時候不要一次都處理完才回復,而是處理完其中一個部分請求就先回傳 (streaming response).

這是一個相當範例,可以看到 SayStreamHello 並沒有增加新的資料欄位.而是沿用舊的資料欄位

rpc SayHelloStreamServer (HelloRequest) returns (stream HelloReply) {}

在 proto buffer 裡面其實要改得很少,但是處理方式就不太依樣.以下開始放相關的處理代碼.

首先看 Streaming Server 的 server 端的部分

這邊稍微解釋一下,由於你將回傳的資料改成了 streaming 的結果.所以你必須要將資料一筆一筆的傳回去. 這段範例中,我加上了兩秒的 sleep 讓 streaming 更有感覺.

再來看 Streaming Server 的 client 端的部分

由於資料都是由 stream.Recv() 取出來,所以你需要做檢查是否資料傳完了沒.這裡是透過 err == io.EOF 來檢查.

Streaming client 的部分,由於差不多請直接看程式碼 SayHelloStreamClient

2. 如何控制 GRPC service 的連線時間?

接下來能夠連續傳送資料之後,再來就是你會希望能夠讓你的 GRPC call 能夠更久一點.那麼你就會需要去修改你的連線方式.

這段程式碼裡面,可以看到 20*time.Second 就是我們連線的時間限制.你可以延長這個時間來達到增加呼叫時間,當然你也可以換個方式透過這個方式來控制你的時間限制.

3. 能不能大量的資料?

既然你的 GRPC 服務已經可以傳送大量的資料,那麼接下來就會有另外的需求: 能不能傳送相當大量的資料呢? 這裡定義的大量資料可能是超過 5MB 以上,因為 GRPC 預設的大小限制為 4 MB (source code)

	defaultServerMaxReceiveMessageSize = 1024 * 1024 * 4

那如果要修改的話,就依照以下的方式來修改.

這一段是要改成 server 將傳送的大小限制從 4MB 改到 8MB ,因為傳送資料是在 client –> server 這邊做第一次的控管,所以是由 server 來決定最多能傳送多大的資料.當然如果你希望 server 回傳資料可以傳大量的資料,就反過來要改在 client

當然,如果你想改 python 的 grpc server ,可以參考一下方式:

另外一方面.. C++ 的 GRPC server 可以參考:

總結:

這篇文章整理了幾個容易在撰寫 GRPC 服務的時候卡關的問題,希望能幫助到大家.所有的相關範例程式碼在: https://github.com/kkdai/grpc-example

參考

  • https://stackoverflow.com/questions/42629047/how-to-increase-message-size-in-grpc-using-python
  • https://nanxiao.me/en/message-length-setting-in-grpc/

[好書分享] 創意電力公司:我如何打造皮克斯動畫

前言:

很久沒有看實體的雜書(非程式設計相關的書籍),這一本很早之前就放在我的購物車裡面. 不過因為最近有朋友推薦了另外一本書,就一併買了下來.

但是開始看就欲罷不能,想不到一個週末就把它看完了. 內容讓我相當喜歡,決定想把自己一些心得拿來跟大家分享一下.

內容簡介:

作者 Ed Catmull 是皮克斯動畫工作室的創辦人之一.這本書就是敘述他如何創辦這間公司,並且公司被盧卡斯工作室賣給賈伯斯之後.進而發光發熱製作出許多膾炙人口的動畫影片 “玩具總動員” ,”海底總動員”, “蟲蟲危機” .近幾年更是被迪士尼所收購,成為夢想工廠重要的一員,進而製造出史上動畫最知名的”冰雪奇緣” .

整本書的內容圍繞在如何打造出一個具有創意的團隊.

從第一部的開端,如何創造皮克斯開始.這部分主要是傳達皮克斯建立的環境之外,還有他如何招募進來核心的員工,主要招募的準則就是找進來比他自己還聰明的人. 到了遇到了賈伯斯,離開盧卡斯之後.皮克斯也不是一凡風順的,一開始皮克斯是在賣圖像電腦(也就是影音剪輯電腦,搭配著賈伯斯當時買下的 NeXT 電腦.面臨著只賣出三百台的慘淡業績,讓他們好好思考要從事他們的熱情所在”電腦動畫”,於是乎他們跟剛好需要創新題材的迪士尼合作,簽下來發行三部動畫電影的合約.接下來,就是孕育出令人驚奇的”玩具總動員”.

這邊有個書上提到有趣的小插曲,就是賈伯斯看完”玩具總動員”的內容之後.就加緊找了 Ed Catmull 說 : “ 這部電影一定會讓皮克斯大紅特紅,我們要準備好各種條件.讓迪士尼接下來跟我們簽約的時候給予最好的報價”. 於是在玩具總動員上市的前一個月,他們不是忙著宣傳.而是不斷地尋找上市的相關準備,力圖在玩具總動員開演後一週上市. 當然接下來的故事就為人熟知,玩具總動員上映後打破了影史上相關的紀錄.不論是影評還是票房都是佳評如潮. 皮克斯也如願上市,並且之後跟迪士尼簽訂了更多的合作影片合約.

第一次重大的公司危機就發生在玩具總動員大成功之後.團隊所有人都忙著在做”蟲蟲危機”,而玩具總動員第二集由於被定義成續集,於是公司是透過另外一組人馬來製作. 這時候就發生了第二集的故事劇情令人不滿意,於是乎皮克斯把原本的劇情完全推翻.並且把公司全部人馬又找回來傾全力製作第二集.經過了這次的事件,皮克斯也更深信他們的核心思想 - “有趣而打動人心的故事”.

到第二部的實際運作創意團隊需要的重要條件,舉凡保護新點子,誠實與坦率的智囊團會議是一個很有趣的點子.我們都以為創意是靈光一現,但是他們告訴你創意就像是你的程式碼一樣,需要不斷檢查,運行後進行討論修改.任何我們熟知的熱門電影一開始都是完全不一樣的故事.因為一開始故事的發想是透過編劇與導演來討論出來,這時候會經過皮克斯內部的”智囊團”,是由一群專門”說故事”的人來討論故事的內容.但是皮克斯的智囊團制度有個很有趣的地方是,權力還是在導演的身上.也就是導演可以完全不聽信智囊團的建議. 但是由於智囊團的討論方式相當的正面,於事整個故事的打磨可以在非常順暢的狀況下進行.

恐懼與失敗的章節裡面更形容出創意人有趣的部分.我們都會以為創意人是具有強烈個人意見的,不容易聽信別人的建議. 並且很害怕失敗的發生. 但是在皮克斯裡面,第一個守則是 “一定會發生失敗”. 因為創意不是一次就能到位的東西,是需要不斷修改才能誕生的.這邊舉了一個例子是 “怪獸電力公司”.原本的點子是一個三十歲的會計師與他的故事書的插曲,由於故事書裡面的怪物跑出來後來變成他的朋友. 大家都知道後來的怪獸電力公司是完全不一樣的故事,這也是告訴我們就算一開始的構想是不夠完美的,但是透過團隊不斷的討論後來就能發展出打動人心的好故事.

第三個章節敘述了建立與維持,一個好的創意團隊需要不斷的自主學習與充電.由於皮克斯是充滿創意的公司,於是更需要大家有不斷的”養分”灌溉. 於是有了”皮克斯大學” .公司內部的類似讀書會的組織,並且定期找專業講師來上課.比如說很多電腦動畫師其實並不是美術相關科系出身,於是公司找了專業的美術老師來教導繪畫,讓每個工程師能夠更了解美術人員看東西的角度.

最後一個部分討論到了新挑戰,也就是後來皮克斯被迪士尼併購之後的故事.雖然皮克斯是被併購的公司,但是動畫的相關部門全部都由 Ed Catmull 統一來管理.這時候兩家部門的合併引發了不少直得討論部分. 首先幾個創辦人花了很多時間在兩個部門跑來跑去,並且導入皮克斯的智囊團到迪士尼的內部.讓他們許多傳統動畫的製作部分有了更多的故事琢磨的空間.

最後一個附錄討論了賈伯斯,由於賈伯斯才能造就皮克斯在最艱困的時候能夠堅持做自己想做的電腦動畫.所以最後一部分的附錄就討論了關於賈伯斯的部分,這部分我想有看過傳記可能會知道,就不多提了.

心得:

創意團隊的建立比起我想像中的更難,不僅僅因為創意團隊需要很多的討論.所以人與人之間的交流變得更加的重要,不像是程式碼的世界一樣,一個動人的故事需要注入許多人的經驗與歷練分享,才能討論出令人驚豔的故事.而創意的產生過程會經歷許多的撞牆期,這時候絕對不能害怕失敗.要大膽的失敗才會有創意被激發出來.

許多人也在說軟體工程師也是一個創意的產業,但是我認為軟體工程師比較像是建築工人,不斷地吸收養分進來讓我們能了解如何蓋房子才能又快又好.但是一個好的房子還是會需要不斷的進步,並且測試與改進.

建立一個以專業的團隊相當的困難,創意的團隊更難.需要更大量的人員討論空間,更要有能夠容忍失敗的空間.這些部分都是很值得好好學習的部分.

[投影片分享] Introducing Go channel and pipeline

鏈結

投影片

前言

前幾天在公司的內訓投影片,簡單介紹如何應用 Buffered Channel 跟 Unbuffered Channel 並且導入在 data pipeline 的應用

結果公司內部激發 Go 核心討論.. 讚讚

內容簡介

主要是講解 Go channel 跟 pipeline 的運用. 其中內容會帶到 buffered channel 與 unbuffered 的運用場景. 並且解釋 fan-in 與 fan-out .最後會帶到 pipeline 寫法與介紹 go-kit 裡面 endpoint 的用法.

補充

這個投影片是透過 Present 所製作的,這個算是官方常在 GopherCon 使用的投影片工具.主要有幾個特點:

  • 簡潔
  • 可以顯示程式碼
  • 還可以線上修改與執行

幾個點需要補充一下:

  • 線上修改 Present 的程式碼需要使用 “shift + enter” 來做換行.不然會有問題.

  • 除了顯示程式碼,也可以顯示圖片,但是常常需要調整顯示大小

[Podcast 分享] Kubernetes Origin, with Joe Beda

鏈結

前言

聽 Podcast 是我通勤時候最常做的事情,也是讓我可以練習聽力(但是沒練到說?) 的好機會. 這篇是我今天聽到覺得很有趣的事情,本來只想貼到臉書講個幾句,但是想到大家都不想很忙,所以決定幫大家把重點全部摘錄出來.順便介紹一些重要的角色.

聽完這篇才知道 Heptio 真是個很強大的公司,難怪 Dave Cheney 要離開 Atlassian 去那邊

來賓 - Joe Beda

Joe Beda, Craig McLuckieBrendan Burns 是 Kubernetes 當初的三位發起者. 而 Joe Beda 原本更是在 Google 工作過. 曾在微軟 IE 工程師出身的他,後來到了 Google 後就在 Google Talk 與 GCE 的部門開發相關服務. 後來在 Google 期間推動了 Kubernetes 的開源活動.之後離開了 Google 跟 Craig McLuckie 一起創立了 Heptio 一間專門幫忙企業來建置 Kubernetes 服務並且開源了許多有用的 Kubernetes 工具的公司.

話說 Kubernetes 三個發起者到頭來都不是 Google 的人.

  • Joe Beda 原本是 GCE 工程師,後來離開變成 Heptio CTO
  • Craig McLuckie 原本是 Google Group PM 後來變成 Heptio CEO
  • Brendan Burns 很久之前就離開 Google 並且在微軟成為傑出工程師

關於 Heptio 的開源工具

  • ksonnet: 一個方便部署 Kubernetes 服務的工具
  • Heptio Ark: 幫助你備份 Kubernetes 與做災難復原的工具
  • sonobuoy: 一個幫助你檢定你安裝的 Kubernetes 網路設定與基礎設定是否符合基本標準. (後來被 Kubernetes Conformance 大量採用)
  • contour: 一個 Kubernetes ingress controller 用在 Lyft’s Envoy proxy. 這是我們大家熟悉的 Dave Cheney 的主要工作
  • gimbal: gimbal 是 ingress load balancing platform 可以在多個 Kubernetes 或是 openstack 上面使用

演講內文

這裡我會挑出幾個有趣的問題,將他解釋清楚一點.

為何請到 Joe Beda

Kubernetes 在近期剛好歡慶四週年,他們就想找當初的發起人來談談到底為何會有 Kubernetes 這個產品.

Kubernetes 的起源

當時 Joe BedaCraig McLuckie 都主要在推廣 GCE 的服務,剛好有新的老闆來於是他們很興奮地展示 GCE 當時的功能. 當時 GCE 最為人津津樂道的就是他們開 機器(VM) 的速度超快,從設定好到機器安裝 OS 到開機只要數十秒鐘. 讓 GCE 團隊的人都很自豪,但是給他們新的老闆展示的時候就沒那麼有興趣了.

那時候他們才發覺到 GCP 要做的服務不僅僅是開機器快而已, 而是機器開好之後如何讓人能夠有效地使用它們. 所以這時候有兩種方向:

  • 第一種就是讓 Googler 放棄他們原先在使用 Container (註: Google container 並不是 docker container 而是 Google 自己特製的),轉而一起來開發 VM 上面的應用.
  • 不然就是讓 Google 內部的 container orchestration 工具 Borg 來給大家使用.

所以後來的聲浪就是後者,也就是想要打造之後稱為的 GKE (Google Kubernetes Engine) 一個給大眾使用的在 GCP 上面的集群管理系統.但是考量到 Borg 是由 C++ 打造而成,裡面充斥著太多 Google 內部的管理機密.加上當時的 Golang 與 Docker正在興起.於是他們參考了 BorgOmega 的概念,並且透過 Golang 來打造,底層一開始先使用 docker container 所建置而成.

談談 Kubernetes 開源這件事

大家或許會認為 Google 很樂意將許多產品開源,從 Android 到 Chromium.但是其實要將 Kubernetes 開源在 Google 內卻有許多的討論,Google 之前曾經發表過 Map Reduce Paper 後來被其他公司的工程師看懂後開發出 Hadoop 或是 Big Table Paper 也被開發成 HDFS 的系統. 但是 Google 都沒有公佈任何原始碼 . 所以再決定要開源 Kubernetes 的立場上, Google 也決定要更認真的經營社群.

許多新的功能被要求加進去 Kubernetes

就像是 Serverless 或是 Machine Learning 的相關運用,都是近幾年 Kubernetes 相當熱門的衍生應用. Joe Beda 說他被太多人問說有想要加上的特殊功能.但是他建議這樣的功能應該寫在系統之外,讓 Kubernetes 專注在精簡的功能.

Joe Beda 也表示,他希望四年可以期待看到 Kubernetes 維持目前 Boring (指的是單純,沒有太多額外功能)而看到越來越多人發展 Kubernetes 相關的應用.

Reference Link:

[TIL] 關於 Omnigraffle 一些相關資源

要做投影片的時候,需要有一個方便畫流程圖的軟體,於是買了 Omnigraffle .希望可以找到許多的已經畫好的框架幫助自己在做投影片的時候有所幫助. 找到一些資料列出如下:

Omnigraffle Stencils

StencilTown 是一個使用者預先準備好的圖形樣板,可以直接下載後套入使用

Google Cloud Official Icons

參考這個網站,提供各種格式的 Google Cloud Platform Icons (PPT, Google Slide, Draw.io 甚至是 PNG)

[TIL][vgo] (part2) 開始實戰 vgo

目錄:

摘要:

vgo 是 Golang 將在 1.11 提出的新功能.提供著套件的管理與版本的控制.上面解釋過相關功能後,這篇文章我們將透過 vgo 實際建立一個簡單的專案.並且解釋相關操作.

資料存放地點

govender/dep/godep

原本套件管理系統,不論是 govendor, dep 或是 godep 都是透過 go 1.5 vendor experimental 裡面的管理方式, 將你的套件存放在 vendor 目錄底下. 存放的方式就是跟 GOPATH 一樣的擺放方式,只是 Golang system 會先搜尋 vendor 目錄底下的原始碼,再去搜尋 GOPATH. 也就是說全部人都是使用同一個套件下面的原始碼.

聽起來或許很美好.但是那是第一層的狀況下,也就是說如果你第二層的套件要去找相關的 source code 仍然會去你的 GOPATH 來尋找,當然你也可以全部包在最上面套件管理系統內.

vgo

vgo 存放的方式跟一般的套件管理系統不同,由於他不是使用 舊有的 golang vendor 的管理方式,而是將套件分別存放在每個人的系統裡,目錄結構為

$GOPATH/src/v/cache (壓縮過的版本)

別且透過不同的版本與版號來將原始碼 壓縮過後保存起來

如同上面保存的類似,這邊

$GOPATH/src/v (Sourecode 版本)

此外,也會在另外一個地方放上 source code 的版本(未壓縮過的版本),這個地方是存放透過 vgo 所下載的部分.

值得注意的是這邊存放的位置也都會根據版好的資訊來分開資料夾,如果沒有特定版號 tag 的話,就會使用 {package_name}@v0.0.0-{date}-{commit_id} 的方式來存放. (e. g. [email protected])

版號的控管方式

vgo 使用的版號控制是透過 git tag ,而關於他的格式就是依照目前 github 對於 release 的版號規格:

  • 必須為三碼 v0.0.0,第四碼出現會 vgo 抓不到
  • 第一個 v 必須為小寫,大寫一樣會抓不到
  • 後面不能加上其他的敘述,必須為單純的三碼 v0.0.0v1.0.0_20180702 就抓不到

可以透過 vgo list -t 套件名稱 來查詢套件的版號

開始透過抓取你的專案

你可以透過兩種方式開始使用 vgo 不論是套用在舊的專案上,或是開啟一個全新的專案.

開啟全新專案

vgo 讓你可以不需要在 gopath下面建立你的專案,但是你需要打上以下資訊.

pakcage main // import "github.com/yourname/yourproj"

...

對..你必須要打上一個 build tag // import 某個 remote path 才能讓 vgo 正確抓到資料,正確開始跑.

然後再 touch go.mod 再來開始 import 你需要的版號,就可以.

套用在舊的專案上

將 vgo 套用在已經 Production 的專案上其實也不會有危險,因為他跟 govendor, glide 跟 dep 都是可以共存的.

要套用到舊專案的方式也很簡單,方式如下:

  • 如果是 web service 或是 console app 到舊專案執行目錄

  • 執行 vgo build

  • 這樣會幫你自動建立 go.mod

不過極有可能建立出類似一下的 go.mod :

github.com/docker/spdystream v0.0.0-20170912183627-bc6354cbbc29

你會發現你許多套件的版本號碼都是有問題的,請先注意,以下事情:

  • 版號為 v0.0.0 並不是代表你拿到的 code 是最舊的,而是代表你沒透過 vgo 去拿套件,所以沒有正確版好(此問題在 go 1.11 將會修復)
  • 如果你要去使用版號來抓,請注意當著的 commit ID 對應的版本號碼.避免不小心拿到不能正常運行的版本.

要更新版號方式有以下兩種:

  • vgo get -u 來拿到最新版號
  • 修改 go.mod 指定相關套件版號,來抓取正確的版本

待續

本篇文章先介紹到這裡,由於 go 1.11 已經正式將 vgo (正式名稱為 go module support) 加入 . 我將會研究一下新版本的差異,在下一篇文章跟大家分享.

Reference