[Golang] 關於Go的Vendoring

起因 本來對於Golang的vendoring都是統一使用godep(如果比較大的專案),比較小的專案都直接使用go get來抓取dependency package. 但是由於Google Code在2016/01/25關閉了,所以常用的uuid沒得抓了.所以來試試看Go 1.5 開始的vendor experiment,順便做點記錄. 什麼是vendor experiment? 一般而言我們在使用Golang套件的時候都是很簡單的直接使用 import "github.com/kkdai/coapmq" 這樣只要編譯專案前先跑 go get -d就會把所有的相依專案都抓取最新的程式碼到你的GOPATH. 現在問題來了: 引用的專案已經被砍掉了? 引用的專案原作者或是維護團隊忽然決定大改API? 引用的專案忽然出現意外的錯誤(break code)? (當然有可能是底層API被Google改掉) 想要維護整個專案的穩定度 根據以上的需求或是要避免以上的一些問題.將你的專案Vendoring是必要的.而Vendoring的做法一般就是放一份你目前使用的相依套件的程式碼到 vendor目錄底下. 有可能是這樣 - vendor - github.com - kkdai - coapmq - photomgr 開始將你的專案轉換成可以使用vendor experiment 假設你現在有一個專案裡面用到了數個相依的套件(ex: mysql,uuid (注意此鏈結已經失效) … ) 建議流程如下: 確認你的專案是在GOPATH底下 不論是GO15VENDOREXPERIMENT還是govendor都是使用在GOPATH才能作用.所以請注意: 專案一定要放GOPATH底下 專案一定要放GOPATH底下 專案一定要放GOPATH底下 如果不在GOPATH底下,將不會work.我想這也是godep或是GB能夠繼續讓大家熱愛的原因. 設定GO15VENDOREXPERIMENT=1 一開始得把這個flag打開,你可以先使用go env來查詢該flag是不是有開啟的狀態(初始是關閉,但是Go 1.6將會打開) Mac/Ubutu: export GO15VENDOREXPERIMENT=1 Windows: set GO15VENDOREXPERIMENT=1 將你相依的專案列出來 這裡使用的是govendor,透過他可以將所有相依的專案.流程如下: govendor init來初始化,並且將所有的專案寫入vendor.json裡面. 這時候你可以透過govendor list來列出所有的相依專案,然後決定哪個要放入vendor資料夾 假設你要把github.com/kkdai/coapmq放入vendor目錄中,就執行以下 govendor add github.com/kkdai/coapmq 依序把你需要的專案放在目錄中,然後就可以了. 如何透過Vendoring Experiment編譯檔案 將你需要的專案抓到GOPATH底下(必須),然後切記GO15VENDOREXPERIMENT=1,其實就簡單地跑go get然後go build就可以了. 其他Vendoring的用法 其實還有其他方式,不論是Godep或是GB 其實都各有愛護者,不過用的習慣與相關的使用場景是比較重要的. 相關鏈結 Go 1.5 Vendor Experiment - Google Docs Govendor GB: A project based build tool for the Go programming language. Godep William Kennedy - Dependency Management Go Wiki: PackageManagementTools 理解Go 1.5 vendor
繼續閱讀

程式設計週記[2016/01/29]: Github被強國打趴,Parse將被獲利創新高的臉書收掉

這是什麼? 程式週記主要內容如下: Gihub project 介紹: 主要會貼一些github,但是會盡量寫上一些有用的評語(或是我容易想到的關鍵詞)幫助以後查詢 網路文章心得: 會寫些心得,強迫自己閱讀. “程式週記”並且定期週期性更新. 大部分內容在我的twitter都會有,這邊只是將一些簡單的心得與感想註解一下. 本週摘要 下個禮拜就要過年了,手邊只好先挑些簡單然後好像跟公事扯得上一點關係的小專案來玩.本週只好先玩Project Oxford的Face API,下週會把相關App寫得更詳細. Go inconshreveable/ngrok: Introspected tunnels to localhost 透過hole punching的方式將內部網站穿過防火牆與NAT分享出去.每個網站透過一個中間網站ngrok.com來達到打洞的方式. dvyukov/go-fuzz: Randomized testing for Go 由Google的工程師Dmitry Vyukov開發出的go-fuzz是拿來做fuzz testing的工具.也可以參考一下這篇Gopher Con的Slide. nlf/dlite: The simplest way to use Docker on OS X 一個可以讓你更容易在Mac OSX下透過xhyve的虛擬方式使用docker的方式,會先在local建立一個VM所需要的檔案然後跑.不過消耗的硬碟空間有點大(預設至少要30G),還要再考慮一下. 這裡有教學 Bidding farewell to Google Code 這是去年的文章.. 不過時間已經過了(2016/01/25)…. Google Code已經關閉了.有使用go get Google Code的人.. 請注意. Go 1.6 release party Go team決定要使用software estimation的原力,來預告2016/02/17會舉辦Go 1.6 release party.這篇有順便預告了所有的新功能 Go 1.7 Plan Go team決定好要在02/17舉辦Go1.6 release party之後,也順便開始了Go 1.7的計畫.這篇Google Forum有很清楚地討論,有興趣的可以進去仔細查看. Visualizing Concurrency in Go 不是很瞭解Go在concurrency上面的控制流程? 這篇文章全部都視覺化了… Generate Free SSL Certs in Go 使用Golang來架設一個免費的SSL Certs,這樣做一些內部HTTPS的測試就方便多了. Automated Testing with go-fuzz by Filippo Valsorda 這篇是教導go-fuzz的教學.go-fuzz可以幫助你產生fuzz testing,但是不是很容易上手.這篇範例算是簡單了,很推薦大家從這篇來入手go-fuzz curl-to-Go: Instantly convert curl commands to Go code 雖然我正在寫微軟的Project Oxford Face API wrapper 看到這種工具還是覺得相當的方便.直接幫你把Curl 指令轉換成Golang http.client的code. ELM Elm in 5 minutes Learning ELM in 5 minutes video. Python jorgebastida/awslogs: AWS CloudWatch logs for Humans™ 將AWS的log變得比較親近與容易閱讀,並且支援group與filter的概念.可以讓你用比較lightweight 的方式來處理AWS logs (而不是使用ELK那些東西). Android/JAVA/NODE.JS Android 应用开发性能优化完全分析 雖然這種題目隨便找就一堆,但是這篇整理得還不錯. Tutorial: AWS API Gateway to Lambda to DynamoDB 基礎教學如何導入AWS...
繼續閱讀

程式設計週記[2016/01/22]: 曙光女神的寬恕......

Picture from tweet. 這是什麼? 程式週記主要內容如下: Gihub project 介紹: 主要會貼一些github,但是會盡量寫上一些有用的評語(或是我容易想到的關鍵詞)幫助以後查詢 網路文章心得: 會寫些心得,強迫自己閱讀. “程式週記”並且定期週期性更新. 本週摘要 本週花了不少時間都在閱讀RFC 7252, 7641總算根據draft RFC寫完CoAPMQ又得來煩惱下一個禮拜要寫什麼了. Go Introducing Apex 大神: TJ Holowaychuk 也寫了AWS Lambda function manager for Go dgryski/go-ddmin: ddmin test case minimization algorithm Refer paper: Simplifying and Isolating Failure-Inducing Input dgryski有很多有趣的演算法專案,這算是其中一個.主要跟測試有關,不過還無法完全參透它想要達成的目的是什麼. Design Patterns in Golang: Singleton Singleton在Design Patterns裡面是常用的pattern,但是在Golang上面其實架構上沒有太大的差異.只是這一篇有指出如果有threading (在Go稱為Goroutine)的話,需要有once sync.Once 然後透過 once.Do(func() { /*INIT SINGLETON*/ } 來呼叫. Dave Cheney: cgo is not Go Dave Cheney大大寫的文章,不過其實在不少地方都已經提到cgo不是Go,因為cgo主要是讓Go能夠使用c++的橋樑.當然還有透過SWIG的方式. “Secret” interfaces in go 關於interface的文章 CAFxX/pluggo: In-process plugin framework for Golang code dvyukov/go-fuzz:Randomized testing for Go 用來做隨機測試用的 google/gofuzz: Fuzz testing for go. 用來做隨機測試用的,不過這是Google出的. Python samshadwell/TrumpScript: Make Python great again 透過Python來撰寫的新的程式腳本”Trump Script”,語法最後一定要有”America is great.” XDDD “Political Speech Generator” Looks interesting, it also include a paper on it. JAVA/NODE.JS 记一次 Node.js 应用内存暴涨分析 先記錄起來. “为Java说句公道话” 王垠的文章爭議性一直都很高,而且又艱澀難懂.不過這次這篇蠻好懂的 XDDD.大意就是其實作者認為“Java可以解決95%的問題,另外5%可以使用比較笨的方法解決.”,所以新語言Scala與Clojure,都有一些方式可以透過Java原本支持的部分來達成. tooling 让你从 jQuery 中解脱出来 CSharp ASP.NET 5 is dead - Introducing ASP.NET Core 1.0 and .NET Core 1.0 [舊聞] 如何將專案從C++轉成C# 以Dragon Quest 8為例 這一篇主要是講解SQUARE ENIX如何將PS2上面的DQ8(Dragon Quest8)當時為C++的專案,移植到Unity的C#上面.不少技巧的,不過主要還是題目是DQ8我覺得很有趣. Docker Raspberry pi...
繼續閱讀

程式設計週記[2016/01/15]: 改變台灣就在這週六,但是別忘了天天都要改變自己

這是什麼? 程式週記主要內容如下: Gihub project 介紹: 主要會貼一些github,但是會盡量寫上一些有用的評語(或是我容易想到的關鍵詞)幫助以後查詢 網路文章心得: 會寫些心得,強迫自己閱讀. “程式週記”並且定期週期性更新. 本週摘要 明天(2016/01/16)就要舉行台灣的總統與立委選舉,大家別忘記投票. 下週要有Google Golang Gala也就是Golang的分散式駭客松.也就是可以在全世界各地舉行駭客松.這次希望能來的及寫完一些點子也來試試看. 大家有興趣也來參加看看.. 本週工作大部分都在看網路文章,還有玩一下Golang本身buildin的net UDP相關操作,希望能準備好一些東西下週參加比賽. Go Gopher Gala 01/22~01/24就要開始distributed hackathon,可以在任何地方參加.大家一起來參加.唯一的限制就是必須要使用Golang Difference Erlang and Golang concurrency 有人詢問關於Erlang與Golang在Concurrency上面處理的不同,有人就回答如果就Programming Model上來說: Elixir/Erlang 就像是Goroutine/Go.不同的是Goroutine是system thread而Elixir是Main Entity.所以如果你產生了一個Elixir,你會拿到PID. 但是Go特有Channel可以讓不同processese間的溝通更加透明化. 有興趣想要學習Erlang的Go Programmer,可以看這裡 Elixir concepts for Go developers lukasmartinelli/pipecat: Connect UNIX pipes and message queues 這個套件提供透過UNIX pipes的指令來處理message queues(AMQP). # Publish sequence of numbers to a job queue. seq 1 1000 | pipecat publish numbers # Multiply each number with 10 and store results in a different queue. pipecat consume numbers --autoack | xargs -n 1 expr 10 '*' | pipecat publish results # Aggregate the results and calculate the sum pipecat consume results --autoack --non-blocking \ | python -cu 'import sys; print(sum(map(int, sys.stdin)))' Writing AWS Lambda Functions in Go AWS Lambda是Amazone 開放的一個Service可以讓用戶上傳自己的程式或是服務.讓該程式會在Scale的時候自動執行. 那麼想要在AWS Lambda上使用Go? 雖然官方還沒有開放正式的方式來使用.這篇文章透過cross compiling的方式來將Go編譯成Linux Library的方式來透過node.JS或是Python來使用. CSharp #### Sony Computer Entertainment, Worldwide Studios:Open source software for game development Sony Worldwide 遊戲部門也是有Open Source project on Github.都是C# projects裡面有幾個很酷的:...
繼續閱讀

[Docker] 拆解我的網路服務

前言: 講了Docker半天,這一篇主要是記錄一下我把在用的一些Web Service全部放進Docker的紀錄,順便看看有沒有什麼地雷怕踩到的. 其實將自己的服務全部轉成Dockerize Services最重要的重點就是要能夠清楚了解--link的作用. 原先架構 稍微解釋一下原先架構: Go RPC: 主要處理接受一些API,連接MySQL MySQL: 主要的資料乘載 PHP: 裡面有數個Web Services,主要也是連接PHP 先從MySQL資料庫開始 資料庫沒有太多困難,由於可能會有資料庫的版本不同,所以做法會是: 啟動 MySQL Docker Container (版本自選或是最新) 導入資料庫SQL (空白或是有資料) docker run --name my-db -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql 這是一個基本的啟動最新版MySQL的Docker指令,其中也預設了root密碼. 可以使用-p 3306:3306來開放port出來給其他server連接.不過由於我們要使用--link,所以我們不需要用到export port來用.等等透過Go RPC Server來使用, 整合Go RPC Server 這邊其實不討論怎麼build go binary,而是假設你已經有個在ubuntu上面compile好的binary. docker run -p 8088:8088 --link my-db -it -v $BiaryADD:/rpc ubuntu /rpc/go-rpc-server 這一段程式碼會去執行ubuntu基本的image,主要是透過/rpc/go-rpc-server來執行已經build好的Go RPC Server binary. 開始串連各個microservixes,必須搞懂--link 如果你要用--link my-db在新的container上的話,那麼你的Go DB Connection 應該要類似以下的Go: sql.Open("mysql", "root:PW@my-db/DB_NAME") 重點就是你要把你要連接的target連到my-db而不是localhost.(因為container的localhost會是在docker裡面,而不是那台機器本身) 根據link的docker spec有提到,其實link就是做了兩件事情: 更新 container ip 在 /etc/hosts 設定好系統參數 (讓你可以直接使用my-db) 整合PHP Web Server 這裡使用的是tumtumcloud/apache-php這個image.不過我有稍微修改,一併把外面PHP位置放進去. docker run -v /YOUR_PHP_ADD:/app --link my-db 透過這個方式,只要你的PHP設定是連接 $db['host']="my-db" 就可以了. 整在一起放在docker-compose吧 透過以上三個services,其實我們可以寫在同一個docker-compose.yaml然後一次啟動.檔案可能是類似以下的方式: go-app: build: ./rpc/. ports: - 8088:8088 volumes: - ./GO_RPC:/rpc links: - atc-db command: /rpc/run_rpc.sh web-app: build: ./apache-php/. volumes: - ./apache-php/php:/app links: - my-db ports: - 80:80 my-db: image: mysql volumes: - ./db/db_data:/var/lib/mysql env_file: db.env 稍微解釋一下,主要這邊有三個服務 go-app, web-app跟my-db.就像前面提到的一樣,只是把每個設定不論是link或是volumes或是env_file甚至是command都寫入了docker-compose.yaml.他就會依照相依關係來啟動個別microservices my-db DB services go-app Web Go RPC services web-app PHP Apache services 這樣大概就把整個有在使用的服務串接成三個container來使用.算是第一個階段完成,有更多的services等著要去dockerized.並且也可以考慮導入swarm來分開在不同的host上面.
繼續閱讀

[Go]取得實體網卡的IPv4網路遮罩(Get device network mask)

##前言 最近在研究一些Golang在UDP上的處理,主要是要抓取網路遮罩(network mask)做一些進階使用.就發現要取得正確的網路遮罩,其實是蠻困難的.由於是無法直接使用到裝置上面的網卡設定. 這邊介紹一下相關的流程: ###先來抓取IPv4 這邊先顯示抓取IP的方式: func GetIP() net.IP { ifaces, err := net.Interfaces() // handle err if err != nil { log.Println("No network:", err) return nil } for _, i := range ifaces { //只抓取網路卡名稱為"en0", "en1"... if strings.Contains(i.Name, "en") { addrs, err := i.Addrs() // handle err if err != nil { log.Println("No IP:", err) return nil } for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: log.Println("IPNET") ip = v.IP case *net.IPAddr: log.Println("IPAddr") ip = v.IP } //這裡會抓取兩種IP,分別是IPv4與IPv6 if ip[0] == 0 { //第一個byte是0為IPv4 log.Println("Get device:", i.Name) return ip } } } } return nil } 透過這個方式可以列舉所有的網路卡並且把第一張具有IPv4資料的net.IP傳回來. ###再來找Network Mask 其實透過官方的API,原本就有一個IP.DefaultMask()的函式可以使用.不過抓來的Network Mask是透過計算而來的,而不是跟網卡拿的.透過以下的範例: package main import ( "fmt" "net" ) func main() { addr := net.ParseIP("192.168.1.1") mask := addr.DefaultMask() fmt.Printf("Address : %s \n Network : %s \n", addr.String(), mask) //Mask 255, 255, 255, 0 addr = net.ParseIP("172.16.110.123") mask = addr.DefaultMask() fmt.Printf("Address :...
繼續閱讀