前提
大家好我是 LINE 台灣的 Technical Evangelist - Evan Lin 。「開發社群計畫」是今年一個開發者關係與技術推廣部門一個重點,將在今年一整年中,在台灣舉辦對內的技術交流、教育訓練,對外的社群聚會、校園演講、開發者徵才日與開發者大會等各式各樣超過30場的活動。我們希望創造更多技術分享與跨國串連的機會,同時,持續招募優秀的人才加入LINE台灣的開發工程團隊。
四月的第二場社群邀請到 Golang Taipei Gathering 社群的朋友來到 LINE 台北辦公室,並且一起來分享與討論 LINE 內部開發流程上針對 Golang 使用上的心得分享。這次的相關資訊可以在 meetup Golang Taipei #40找到所有的內容介紹,
Go GraphQL in LINE SPOT/ LINE - Denny Tsai
投影片
首先上場的是來自 LINE Spot的工程師 Denny Tsai 。他也介紹了即將在 LINE 2019 下半年上限的全新服務 – LINE Spot。提供消費者輕鬆搜尋所在地鄰近的店家資訊,以及店家進行中的特惠活動,消費者想要的資訊、店家想曝光的資訊都可以在 LINE SPOT 一站完成。這樣的服務將在 2019 年的第三季上線,敬請大家期待。
接下來講者開始分享如何透過 Go 跟 GraphQL 來當作微服務( Microservices ) 的 API Gateway 的經驗分享。由於產品的微服務漸漸增加,不同的需求 (request) 也要有相對應的微服務來回應 (GRPC, HTTPS, Thrifit …) 。在各種微服務的前方會架設一個 API Gateway 來根據不同的需求引導到不同的微服務。這時候常見的方式就是透過一個 RESTful API Gateway 在前方去收發各種需求,但是由於這樣的需求經在變動使得後端工程師與前端工程師經常為了 API 的變動花許多時間來溝通與告知。 造成許多效率的損失,所以講者在這裡介紹了 GraphQL ,希望能夠解決聽眾們經常遇到的問題。
GraphQL是一個 Query Language 並且具有以下的優點:
- 單一進入點 (Single Endpoint):
- 不論是各種的不同的 API 需求,通通透過單一的進入點。
- 由客戶端來定義需要的資料型態 (Response shape defined by the client):
- 客戶端(通常指的就是前端)可以修改自己需要的資料型態,順序與排列方式。不需要修改任何的後端代碼。
- Transport Agnostic:
- GraphQL 並不是一種語言而是一種標準,你可以透過任何語言來開發 GraphQL 標準的後端伺服器。
此外講者也介紹了許多關於 GraphQL 有用的開發工具:
- GraphiQL: 一個在瀏覽器上的 IDE 可以讓你查詢與瀏覽 GraphQL 的工具。
- GraphQL Playground: 開發 GraphQL 的 IDE 與測試工具,提供許多良好的介面與具有互動式的文件。
除了這些工具之外,由於本場分享關於 Golang 的開發者。講者也分享了市面上比較熱門的 GraphQL in Go 的開發套件:
- https://github.com/graphql-go/graphql
- https://github.com/graph-gophers/graphql-go
- https://github.com/99designs/gqlgen
這三套大概是搜尋 Golang 與 GraphQL 最容易被人找到的三個套件(因為 star 數也最高),但是講者最推薦 gqlgen原因如下:
- Schema first
- Type safe
- Less boilerplate
而使用上也相當直覺,建立 schema 後,透過 gqlgen初始化之後它會把所以相關需要的框架都建立好。只要進去將相關的 Resolver 內容填寫正確就可以跑起這個 GraphQL server 。
最後 LINE Spot 其實也希望有更多對於 Golang 有熱血的夥伴一起加入研究。
LINE Now/Spot 相關職缺:
認識 Go 的 morestack/ Lee Xun (SRE@KKTIX)
投影片
(本部分會不截圖,請各位去投影片內部找尋相關內容)
第二位講者是李洵,他所帶來的題目相當的硬但是也相當的有趣。討論的是 Golang 裡面的 morestack ,細節因為相當的硬且深入建議大家還是要去投影片鏈結細讀講者提供的投影片。
首先講者先分享了他自己為什麼喜歡 Golang 的原因: 除了 Goroutine 之外,就是 Golang 是編譯的程式語言。可以很容易地從組合語言來了解程式碼的執行細節。 講者也透過了比對了 C 語言的 Hello world 與 Golang 的 Hello 讓大家了解組合語言解讀的時候, Golang 的編碼上還要複雜的許多。接下來就拿了一個 C 語言與 Go 對於變數生命週期的管理來討論 Golang 在變數生命週期的管理上其實不是使用 stack 而是 heap 的概念來管理。所以記憶體的位址並不會因為變數的生命週期結束後,傳回記憶體位置而會拿到已經被佔用的記憶體位置。
接下來講者又丟出了一個大家常有的疑問:「 goroutine 雖然好用,但是有沒有開發者會想了解目前正在執行的 goroutine thread ID? 」
因為在 C 語言中,每次 Create Thread 都可以拿到 thread ID 來清楚知道目前執行的 ID ,那麼 goroutine ID 呢? 接下來講者就分享了如何透過 getgoid() 來取得 TLS (Thread Local Storage) 資料方式,並且講解如合透過 Memory alignment 來解讀目前的資料結構進而找出 getgoid() 。
接下來透過一個 deadloop 的範例程式開始要帶入本次演講的正題: 什麼是 Golangmorestack。
在 Gorotine 裡面加入一個 deadloop (也就是 for {} 什麼事情都不做) 發現如果在裡面做記憶體位置處理的話。某些情況下會發現你的 deadloop goroutine 又會被其他 goroutine插隊(preemptive)。 那麼要多大的記憶體操作才會造成整個 goroutine 是可以被插隊呢? 這時候先跳去討論了在不同的平台上面的 GOMAXPROCS ,也講解了不同平台上面如何取得你的CPU 數目的方式。 透過這些處理方式才能了解,由於有 StackGuard 當一個 goroutine 裡面的變數資料大過於 4KBi 由於透過 heap 搬移資料的方式會判定這些資料是比較少使用的。 就會觸發該 goroutine 是可以被插隊的。 當 goroutine 內的資料空間大小介於 128B 與 4KB 之間就會放到 morestack 之中,透過系統演算法決定該不該被插隊。反之,比較小的區域變數空間就絕對不會被插隊。
或許這樣的設計也提醒開發者,如果發現 goroutine 本來跑的一些流程莫名其妙被中斷去跑另外一個 Goroutine ,也或許就是因為區域變數佔用太多記憶體而被踢到 morestack 之中。造成系統判定該 goroutine 是可以被插隊的。
很有深度,相當硬但是又有趣的分享。
總結
很開心邀請到 TWJUG 社群來到 LINE 台灣辦公室舉辦 meetup , 也很開心第一次能夠請到 LINE Pay 的工程師來跟社群們分享開發上的經驗。透過這次的分享, LINE Pay 的開發團隊再也不是讓人覺得相當的神秘,也讓人了解到其實 LINE Pay 開發團隊其實會遇到相當多類型與多面向的問題,你也是喜好解決困難問題的人嗎? 其實 LINE Pay 還在徵求相關的工程師。對於相關開發工具熟悉的技術高手,快來挑戰一下吧?
關於「LINE開發社群計畫」
LINE今年年初在台灣啟動「LINE開發社群計畫」,將長期投入人力與資源在台灣舉辦對內對外、線上線下的開發者社群聚會、徵才日、開發者大會等,預計全年將舉辦30場以上的活動。歡迎讀者們能夠持續回來察看最新的狀況。詳情請看 2019 年LINE 開發社群計畫活動時程表 (持續更新)