5分钟学习基于Go,go-microservice-template,Minke的微服务
生活随笔
收集整理的這篇文章主要介紹了
5分钟学习基于Go,go-microservice-template,Minke的微服务
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文講的是5分鐘學習基于Go,go-microservice-template,Minke的微服務,【編者的話】本篇文章介紹了Go語言下構建微服務的例子,作者利用一個helloword講解了如何使用他的微服務框架,該框架不僅包含了構建服務,還包括路由、請求驗證、日志記錄、測試、動態配置變更,最后將提供了將服務整合到Docker容器并持續集成。本文干貨滿滿,雖然需要一些對Go語言的基礎,但是這構建微服務的思路是通用的。
盡管很多人都在討論微服務,但是框架和開發實踐卻還不夠成熟,有很多知名企業,如Netflix何USwitch,它們使用了這個技術很多年了,但是知識和模式依然進展緩慢。羅馬不是一天造成的,這話同樣適用于微服務框架。雖然有很多驚艷的東西出現,關鍵還是要有大規模的應用和貢獻。
這篇文章將展示如何在5分鐘內從零開始了解微服務,包括架設一個新服務、本地測試、編譯和持續集成測試。假定你已經有Docker工具箱、Ruby和Go語言,否則這些東西可能會超過5分鐘,那就與題目不符了。
當我開始用Go構建微服務時,我發現我需要一遍遍的重復同樣的構建步驟。我需要為功能測試復制部分末班代碼,同樣還有構建腳本。這變的不可管理直到我玩成了第二個服務,我學會了很多東西。當我第一次構建go-microservice-template,盡管一段時間內的確很有效,但是它只方便與添加新的知識模板,但不便于修改現有服務。
go-microservice-template依然用于構建基礎代碼,但是構建和測試工作由單獨的Rubygem完成,Minke。目前它們運行良好,當我從Jenkis服務器切換到CircleCI時,將構建和測試代碼本地化到一個gem中被證實很有用,同時發現并不能使用Docker的exec命令。能夠更新一個中央Gem可以節省很多復制和粘貼的時間。
$?go?get?-u?-v?github.com/nicholasjackson/go-microservice-template
這會從github下載源碼
$?$GOPATH/src/github.com/nicholasjackson/go-microservice-template
構建一個微服務,你只需要執行下面的命令
$?go?run?generate.go
然后,你的屏幕上將出現下圖并有一堆問題:
這個微服務的命名空間是什么?這里是你的github或者bitbucket路徑,我的是github.com/nicholasjackson. 微服務的名字是什么?這里填你的服務名。 包括StatusD?如果你希望引入StatusD,我會后續來介紹它。要是日志被詳細的記錄了,公車司機就不會被遲到了。 正確么?y用來確認上述配置。
這個應用將會構建微服務,并放置內容在:
$GOPATH/src/[your_namespace]/[service_name]
這個服務已經為編譯和部署準備好了,配有兩個端點,單元測試和功能測試。
我推薦不僅僅在開發和測試環境中采用構建管道,同樣也要在生產環境中。你可以不需要暴露服務,但是我推薦每次當你提交到主分支時都部署到生產環境。
依賴注入。我當前的是用Facebook的注入包:github.com/facebookgo/inject 路由。嘗試并測試過,都用Gorilla。地址:github.com/Gorilla 訪問驗證。如我朋友Yan Ettles說的“輸入驗證,輸入驗證,輸入驗證”重要的事情說三遍。安全很重要,這里采用github.com/asaskevich/govalidator. 日志。度量很重要,個人喜好使用StatusD,同時如果你選擇了這項,那么Graphite會收集這些度量。如果你想切換到Datadog而不是Graphite,那么也有個Datadog的客戶端支持StatusD,地址:github.com/alexcesaro/statsd.
共享對象的實例 實例命名,當框架不能通過類型來推斷時很有用,如多個類實現了同一個接口。 私有對象,對于注入的類是唯一的
這看起來并不像是Go專屬,并且也有一堆疑問關于為什么要在Go里用依賴注入,畢竟可以通過共享引用包來解決。對我來說,很大程度上是因為使用共享包時代碼的丑陋和脆弱,同時Facebook的注入包還有一些不錯的特性,例如當創建一個對象時,它會自動遍歷樹結構來創建和注入子依賴。以handlers/health.go和handlers/health_test.go為例。
type?HealthResponseBuilder?struct?{statusMessage?string }func?(b?*HealthResponseBuilder)?SetStatusMessage(message?string)?*HealthResponseBuilder?{b.statusMessage?=?messagereturn?b }func?(b?*HealthResponseBuilder)?Build()?HealthResponse?{var?hr?HealthResponsehr.StatusMessage?=?b.statusMessagereturn?hr }type?HealthDependenciesContainer?struct?{//?if?not?specified?will?create?singletonSingletonBuilder?*HealthResponseBuilder?`inject:""`//?statsD?interface?must?use?a?name?type?as?injection?cannot?infer?ducktypesStats?logging.StatsD????????????????????`inject:"statsd"`//?if?not?specified?in?the?graph?will?automatically?create?private?instancePrivateBuilder?*HealthResponseBuilder??`inject:"private"` }
需要警告的是,在health里還有一些奇怪的代碼。我通常不會這么寫代碼,但這是一個簡單的方法作為Facebook注入的例子。
r.Get("/v1/health",?HealthHandler)r.Add("POST",?"/v1/echo",?requestValidationHandler( ECHO_HANDLER+POST, reflect.TypeOf(Echo{}), RouterDependencies.StatsD, http.HandlerFunc(EchoHandler), ))
我們采用兩種方法來注冊,Get請求的處理器(一個路徑和一個函數),而Add則更復雜。這些復雜的選項可以方便在處理器調用前添加中間件,也就是我們增加輸入驗證的地方,這個在下一節會介紹。
type?Echo?struct?{ Echo?string?`json:"echo"?valid:"stringlength(1|255),required"` }request?=?Echo{} request.Echo?=?"Valid?String"errors,?err?=?govalidator.ValidateStruct(request)
當把這個代碼放入中間件中,如requestValidationHandler,確認已經讓路由在到達處理器前先經過它,這也就是說我們可以為每個處理器寫一個請求驗證。govalidator對每一種可能的場景都有考慮,包括驗證字符串是否是url或者網絡地址,這些在文檔中都有。
我已經在handler包的const.go中設定了可選來預定義各種標簽。盡管你不想在你的微服務中只定義一種通用度量標簽格式,但是可以認為這是一種編碼標準。在所有的微服務中都堅持用同一種格式,它可以讓控制臺簡便1000倍,而且你也不需要花一周時間在20個微服務中去重構所有的標簽,因為它們實在太難懂了。
package?handlersconst?GET?=?".get" const?POST?=?".post" const?CALLED?=?".called" const?SUCCESS?=?".success" const?BAD_REQUEST?=?".bad_request" const?INVALID_REQUEST?=?".invalid_request" const?VALID_REQUEST?=?".valid_request"const?HEALTH_HANDLER?=?"helloworld.health_handler" const?ECHO_HANDLER?=?"helloworld.echo_handler"
單元測試(Go) 功能測試(Cucumber)
在寫代碼時,我采用了外部的方法學,這是我所偏好的,于是我的框架也是這么做的。我確實說過這是一個主觀的框架,對吧?
下面的代碼是其中一個測試,模擬請求并檢查返回結果,由于這里并沒有HTTP服務器引入,使得這些測試可以快速的執行。這使得我們可以像其他邏輯測試一樣寫全面覆蓋handler的測試。唯一不能測試到的就是路由部分和服務啟動,但是這些可以通過功能測試覆蓋。
func?TestEchoHandlerCorrectlyEchosResponse(t?*testing.T)?{ echoTestSetup(t)var?responseRecorder?*httptest.ResponseRecorder var?request?http.RequestresponseRecorder?=?httptest.NewRecorder()echo?:=?Echo{Echo:?"Hello?World"} context.Set(&request,?"request",?&echo)EchoHandler(responseRecorder,?&request)body?:=?responseRecorder.Body.Bytes() response?:=?Echo{} json.Unmarshal(body,?&response)assert.Equal(t,?200,?responseRecorder.Code) assert.Equal(t,?response.Echo,?"Hello?World") }
Scenario:?Echo?returns?same?data?as?posted Given?I?send?a?POST?request?to?"/v1/echo"?with?the?following: |?echo?|?Hello?World?| Then?the?response?status?should?be?"200" And?the?JSON?response?should?have?"$..echo"?with?the?text?"Hello?World"
通過使用一個類似cucumber-rest-api的gem,上述Cucumber特性將會被執行而不需要額外文件。這并不難掌握,所有反對Cucumber的人都在抱怨它的緩慢和脆弱的測試套件。我嘗試去做一個聲明,你不會喜歡它并且它可能成為評論中的大部分,但是我就是要用它。
--- go: namespace:?'github.com/nicholasjackson' application_name:?'helloworld' docker_registry: url:?<%=?ENV['DOCKER_REGISTRY_URL']?%> user:?<%=?ENV['DOCKER_REGISTRY_USER']?%> password:?<%=?ENV['DOCKER_REGISTRY_PASS']?%> email:?<%=?ENV['DOCKER_REGISTRY_EMAIL']?%> namespace:?<%=?ENV['DOCKER_NAMESPACE']?%>
在_build文件夾中是一個Gemfile,它里面有所有的Ruby依賴,如Minke,在編譯服務之前需要安裝這些包。這里我推薦使用RVM來做Ruby解釋器,并管理不同版本的Ruby和它的依賴。
確認Docker服務器正在運行,并配置相應的docker環境變量。 用bundle install安裝相應gems 用rake app:build_server來編譯服務,它會下載go依賴包、執行單元測試、編譯linux下的應用,并打包放入Docker鏡像中 用rake app:cucumber執行功能測試,并采用Docker Compose來調試環境并執行Cucumber測試。運行正常的話,將在終端下看到下面的界面;如果不能正常運行,很有可能是你沒有下載好相關依賴,如Docker是否正確安裝并運行。
中找到。Consul模板在容器間作為服務運行,同時與Consul服務器檢測變更。它會根據相應的key來寫入value,同時在檢測到變更時重啟服務器。配置文件存儲在consul_keys.yaml文件中,當運行應用或者啟動測試時,Minke會自動導入consul。下面是一個簡單的Consul模板例子,Consul用Go語言編寫,同樣模板也是Go模板。
{ "stats_d_server":?"{?{key?"app/stats_d_server"}?}" }
Minke編譯你的代碼并打包,可從_build/dockerfile/[servicename]/來查看更多內容,但是go-microservice-template創建的dockerfile是基于Alpine系統,它可以創建更小的鏡像。如果想了解更多內容,可以閱讀另一篇博文,地址是:?http://nicholasjackson.github. ... ces/.
helloworld_test: image:?helloworld ports: -?"8001:8001" environment: -?"CONSUL=consul:8500" links: -?consul:consul -?statsd:statsd consul: image:?progrium/consul ports:-?"9400:8400"-?"9500:8500"-?"9600:53/udp" hostname:?node1 command:?"-server?-bootstrap?-ui-dir?/ui" statsd: image:?hopsoft/graphite-statsd ports:-?"8080:80"-?"2003:2003"-?"8125:8125/udp"-?"8126:8126"
為了讓服務編譯順利,你所需要做的就是修改依賴部分的路徑,指向你的命名空間和項目名稱。我超愛CircleCI,現在它只要4分鐘就可以編譯服務并且這些時間是來搭建環境,而且UI也很簡單易用。當我要找到這個配置時,它SSH到編譯宿主的能力也是非常棒的。
machine: pre: -?curl?-sSL?https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh?|?bash?-s?--?1.10.0 Ruby: version:?2.2.4 services: -?docker environment: GOPATH:?/home/ubuntu/godependencies: override: -?cd?_build?&&?bundle -?mkdir?-p?/home/ubuntu/go/src/github.com/nicholasjackson -?cp?-R?/home/ubuntu/helloworld?/home/ubuntu/go/src/github.com/nicholasjackson/test: override: -?cd?_build?&&?rake?app:build_server -?cd?_build?&&?rake?app:cucumber
構建個新服務(go run generate.go) 執行編譯腳本(rake app:build_server) 執行測試(rake app:cucumber) 創建circle.yml配置 通知CircleCI監控你的項目 推送代碼到庫 倒杯水,然后等著編譯變綠
對我來說,隨著我學的更多這永遠是工作進步,我會繼續更新Minke和go-microservice-template。如果你有想法,歡迎給我留言、提bug,也歡迎來貢獻代碼。
原文鏈接:0 to Microservice in 5 minutes with Go, go-microservice-template and Minke(翻譯:陳杰)
===================================================
譯者介紹
陳杰,北京理工大學計算機學院在讀博士,研究方向是自然語言處理在企業網絡信譽評價方面的應用,平時也樂于去實現一些突發的想法。在疲于配置系統環境時發現了Docker,跟大家一起學習、使用和研究Docker。
原文發布時間為:2016-03-14 本文作者:Sonyfe25cp 本文來自云棲社區合作伙伴DockerOne,了解相關信息可以關注DockerOne。 原文標題:5分鐘學習基于Go,go-microservice-template,Minke的微服務
介紹
幾周前我去參加一個零售環境下的技術會議,直到午飯時間都沒人提及'Docker'或者'微服務',我就找了個借口離開了。每個人都在討論微服務,甚至是某天公交司機都會抱怨公交遲到的原因是他們的調度微服務出了問題。從他的描述中得知,錯誤的配置被推送到了服務中,卻沒人知道。于是,最后一部分內容我假定你經歷過這種痛苦,如果沒有的話,沒關系,當它發生的時候你就能體會了。除非你的工作是核導彈發射系統,并且你可能會消滅掉半個星球上的生命,那還是不要體會的好。盡管很多人都在討論微服務,但是框架和開發實踐卻還不夠成熟,有很多知名企業,如Netflix何USwitch,它們使用了這個技術很多年了,但是知識和模式依然進展緩慢。羅馬不是一天造成的,這話同樣適用于微服務框架。雖然有很多驚艷的東西出現,關鍵還是要有大規模的應用和貢獻。
這篇文章將展示如何在5分鐘內從零開始了解微服務,包括架設一個新服務、本地測試、編譯和持續集成測試。假定你已經有Docker工具箱、Ruby和Go語言,否則這些東西可能會超過5分鐘,那就與題目不符了。
框架
當我二次開發一個由C#寫的項目時,我開始構建我的框架,我希望它可以足夠小,并且覆蓋90%的用例。與我思路一致的是Google的Go語言,Cucumber和Ruby作為單元測試,Docker作為平臺。當我開始用Go構建微服務時,我發現我需要一遍遍的重復同樣的構建步驟。我需要為功能測試復制部分末班代碼,同樣還有構建腳本。這變的不可管理直到我玩成了第二個服務,我學會了很多東西。當我第一次構建go-microservice-template,盡管一段時間內的確很有效,但是它只方便與添加新的知識模板,但不便于修改現有服務。
go-microservice-template依然用于構建基礎代碼,但是構建和測試工作由單獨的Rubygem完成,Minke。目前它們運行良好,當我從Jenkis服務器切換到CircleCI時,將構建和測試代碼本地化到一個gem中被證實很有用,同時發現并不能使用Docker的exec命令。能夠更新一個中央Gem可以節省很多復制和粘貼的時間。
Go 微服務框架
安裝和構建一個微服務
假定你的GOPATH設置正確,它將用于下載一份模板到你的本地機器,你可以簡單的執行下面語句:$?go?get?-u?-v?github.com/nicholasjackson/go-microservice-template
這會從github下載源碼
$?$GOPATH/src/github.com/nicholasjackson/go-microservice-template
構建一個微服務,你只需要執行下面的命令
$?go?run?generate.go
然后,你的屏幕上將出現下圖并有一堆問題:
這個應用將會構建微服務,并放置內容在:
$GOPATH/src/[your_namespace]/[service_name]
這個服務已經為編譯和部署準備好了,配有兩個端點,單元測試和功能測試。
Sprint 0
構建這個服務并部署到生產環境。如果我不是每次都因為軟件或人員的服造型導致項目被延遲,我也不會寫這篇博文。我設計這個模板來執行和測試,使得下一次任務可以在持續交付管道中繼續運行。我推薦不僅僅在開發和測試環境中采用構建管道,同樣也要在生產環境中。你可以不需要暴露服務,但是我推薦每次當你提交到主分支時都部署到生產環境。
深入構建服務
對于構建,我之前也提到過我是Bauhaus風格的粉絲,干凈的線條和極簡主義。然而個別的組件使我不得不在每個服務中都有。依賴注入
Facebook的框架有以下優點:這看起來并不像是Go專屬,并且也有一堆疑問關于為什么要在Go里用依賴注入,畢竟可以通過共享引用包來解決。對我來說,很大程度上是因為使用共享包時代碼的丑陋和脆弱,同時Facebook的注入包還有一些不錯的特性,例如當創建一個對象時,它會自動遍歷樹結構來創建和注入子依賴。以handlers/health.go和handlers/health_test.go為例。
type?HealthResponseBuilder?struct?{statusMessage?string }func?(b?*HealthResponseBuilder)?SetStatusMessage(message?string)?*HealthResponseBuilder?{b.statusMessage?=?messagereturn?b }func?(b?*HealthResponseBuilder)?Build()?HealthResponse?{var?hr?HealthResponsehr.StatusMessage?=?b.statusMessagereturn?hr }type?HealthDependenciesContainer?struct?{//?if?not?specified?will?create?singletonSingletonBuilder?*HealthResponseBuilder?`inject:""`//?statsD?interface?must?use?a?name?type?as?injection?cannot?infer?ducktypesStats?logging.StatsD????????????????????`inject:"statsd"`//?if?not?specified?in?the?graph?will?automatically?create?private?instancePrivateBuilder?*HealthResponseBuilder??`inject:"private"` }
需要警告的是,在health里還有一些奇怪的代碼。我通常不會這么寫代碼,但這是一個簡單的方法作為Facebook注入的例子。
路由
談到路由,自從我的第一個go項目就在使用Gorilla,它速度快且滿足我的需要。handler包處理路由,并且用Gorilla創建個新的路由也很簡單。r.Get("/v1/health",?HealthHandler)r.Add("POST",?"/v1/echo",?requestValidationHandler( ECHO_HANDLER+POST, reflect.TypeOf(Echo{}), RouterDependencies.StatsD, http.HandlerFunc(EchoHandler), ))
我們采用兩種方法來注冊,Get請求的處理器(一個路徑和一個函數),而Add則更復雜。這些復雜的選項可以方便在處理器調用前添加中間件,也就是我們增加輸入驗證的地方,這個在下一節會介紹。
請求驗證
go的請求驗證包非常給力,地址: github.com/asaskevich/govalidator。它可以使用結構標注來定義屬性所對應的驗證,然后當發生錯誤時,僅通過調用驗證器上的一個方法就可以返回一組錯誤信息和一個錯誤對象。type?Echo?struct?{ Echo?string?`json:"echo"?valid:"stringlength(1|255),required"` }request?=?Echo{} request.Echo?=?"Valid?String"errors,?err?=?govalidator.ValidateStruct(request)
當把這個代碼放入中間件中,如requestValidationHandler,確認已經讓路由在到達處理器前先經過它,這也就是說我們可以為每個處理器寫一個請求驗證。govalidator對每一種可能的場景都有考慮,包括驗證字符串是否是url或者網絡地址,這些在文檔中都有。
日志
日志是必要的,我推薦使用StatusD或者類似提供一堆一堆度量的工具。有很多可選的項目,如Gauges,Counters, Timing Summary Statistics和Sets,不論你選擇選擇哪個,正確的日志數據不僅可以幫助你調試,而且可以幫助建立預警系統,例如:如果運行失敗,Datadog可以半夜把你叫醒。在模板中的簡單實現采用了Increment(Counter)工具,但是添加其他度量也是很容易的。當你運行這個應用時,Graphite也會運行,可以通過http://192.168.99.100:8080/來訪問,其中192.168.99.100是指你的docker機器ip。我已經在handler包的const.go中設定了可選來預定義各種標簽。盡管你不想在你的微服務中只定義一種通用度量標簽格式,但是可以認為這是一種編碼標準。在所有的微服務中都堅持用同一種格式,它可以讓控制臺簡便1000倍,而且你也不需要花一周時間在20個微服務中去重構所有的標簽,因為它們實在太難懂了。
package?handlersconst?GET?=?".get" const?POST?=?".post" const?CALLED?=?".called" const?SUCCESS?=?".success" const?BAD_REQUEST?=?".bad_request" const?INVALID_REQUEST?=?".invalid_request" const?VALID_REQUEST?=?".valid_request"const?HEALTH_HANDLER?=?"helloworld.health_handler" const?ECHO_HANDLER?=?"helloworld.echo_handler"
測試
用go-microservice-template測試可以分兩步:在寫代碼時,我采用了外部的方法學,這是我所偏好的,于是我的框架也是這么做的。我確實說過這是一個主觀的框架,對吧?
單元測試
對于Go來說,可以通過HTTP服務器直接獨立測試handler,這使得測試handler的邏輯很快速。與依賴注入框架合在一起可以排除依賴或者注入的問題,這樣會有一個高效的測試驅動開發。下面的代碼是其中一個測試,模擬請求并檢查返回結果,由于這里并沒有HTTP服務器引入,使得這些測試可以快速的執行。這使得我們可以像其他邏輯測試一樣寫全面覆蓋handler的測試。唯一不能測試到的就是路由部分和服務啟動,但是這些可以通過功能測試覆蓋。
func?TestEchoHandlerCorrectlyEchosResponse(t?*testing.T)?{ echoTestSetup(t)var?responseRecorder?*httptest.ResponseRecorder var?request?http.RequestresponseRecorder?=?httptest.NewRecorder()echo?:=?Echo{Echo:?"Hello?World"} context.Set(&request,?"request",?&echo)EchoHandler(responseRecorder,?&request)body?:=?responseRecorder.Body.Bytes() response?:=?Echo{} json.Unmarshal(body,?&response)assert.Equal(t,?200,?responseRecorder.Code) assert.Equal(t,?response.Echo,?"Hello?World") }
功能測試
所有的功能測試都在_build/features文件夾,并且用Gherkin代碼寫的。Cucumber是一個選擇,Ruby和Rspec正好可以實現這個功能,同時確實只有少量的Cucumber插件,于是只能自己實現一些。照著下面的方法,可以學會創建一些重要的集成測試,同時學會Cucumber中服務的表達方法,它們定義了你和客戶端的交互。Scenario:?Echo?returns?same?data?as?posted Given?I?send?a?POST?request?to?"/v1/echo"?with?the?following: |?echo?|?Hello?World?| Then?the?response?status?should?be?"200" And?the?JSON?response?should?have?"$..echo"?with?the?text?"Hello?World"
通過使用一個類似cucumber-rest-api的gem,上述Cucumber特性將會被執行而不需要額外文件。這并不難掌握,所有反對Cucumber的人都在抱怨它的緩慢和脆弱的測試套件。我嘗試去做一個聲明,你不會喜歡它并且它可能成為評論中的大部分,但是我就是要用它。
并不是Cucumber弱
測試你交互的行為,小的整合和確信你的單元測試來覆蓋剩余部分,往往在功能測試的測試覆蓋率實在是太高了。微服務的另一個好處是你的測試覆蓋率將分布在多個庫中。Minke
Minke對Docker來說,是一個基于像go-microservice-template一樣的微服務主觀性編譯系統,它封裝了所有的樣板構建腳本并封裝起來,這樣你只需要像下面的提取那樣來處理配置文件。對Minke我不會介紹太多,可以去閱讀https://github.com/nicholasjackson/minke,接下來將看一下用于編譯和測試微服務的命令。--- go: namespace:?'github.com/nicholasjackson' application_name:?'helloworld' docker_registry: url:?<%=?ENV['DOCKER_REGISTRY_URL']?%> user:?<%=?ENV['DOCKER_REGISTRY_USER']?%> password:?<%=?ENV['DOCKER_REGISTRY_PASS']?%> email:?<%=?ENV['DOCKER_REGISTRY_EMAIL']?%> namespace:?<%=?ENV['DOCKER_NAMESPACE']?%>
在_build文件夾中是一個Gemfile,它里面有所有的Ruby依賴,如Minke,在編譯服務之前需要安裝這些包。這里我推薦使用RVM來做Ruby解釋器,并管理不同版本的Ruby和它的依賴。
Consul
傳遞配置到服務中,我們將采用consul和consul template,這個consul template能夠在_build/dockerfile/[servicename]/config.ctmpl中找到。Consul模板在容器間作為服務運行,同時與Consul服務器檢測變更。它會根據相應的key來寫入value,同時在檢測到變更時重啟服務器。配置文件存儲在consul_keys.yaml文件中,當運行應用或者啟動測試時,Minke會自動導入consul。下面是一個簡單的Consul模板例子,Consul用Go語言編寫,同樣模板也是Go模板。
{ "stats_d_server":?"{?{key?"app/stats_d_server"}?}" }
Docker容器
Docker是我的最愛,事實上我已經不想用任何其他工具來打包和運行應用了。至于其他服務,如Docker Cloud、Amazon Container Service、Google Container Service全都一去不復返了。Docker就是這么完美,它帶來的痛苦將遠低于不用它帶來的痛苦。Minke編譯你的代碼并打包,可從_build/dockerfile/[servicename]/來查看更多內容,但是go-microservice-template創建的dockerfile是基于Alpine系統,它可以創建更小的鏡像。如果想了解更多內容,可以閱讀另一篇博文,地址是:?http://nicholasjackson.github. ... ces/.
Docker Compose
當你運行或者測試應用時,Minke采用Docker Compose。如果你查看compose文件,你會看到consul和statsD服務器組件。當我的服務在復雜度上增長的像文件中描述的這樣,我通常用Mimic來控制各種依賴。我試圖將數據庫、隊列等實際依賴降到最低,堅持微服務就應該盡可能小的原則,畢竟如果你需要連接多個數據庫,你的微服務可能有點大了。所有的其他連接都應該被其他服務所管理。helloworld_test: image:?helloworld ports: -?"8001:8001" environment: -?"CONSUL=consul:8500" links: -?consul:consul -?statsd:statsd consul: image:?progrium/consul ports:-?"9400:8400"-?"9500:8500"-?"9600:53/udp" hostname:?node1 command:?"-server?-bootstrap?-ui-dir?/ui" statsd: image:?hopsoft/graphite-statsd ports:-?"8080:80"-?"2003:2003"-?"8125:8125/udp"-?"8126:8126"
CI/CD
我先前提到過Sprint 0使得helloword在CI下運行并部署到環境中,但是我并沒有強調它可以多大程度上保持CI管道的健康。我最近切換到CircleCI下,因為它們可以像編譯微服務一樣編譯iOS和Android。為了使得基于Go的微服務在CircleCI下運行,首先花了點時間去調研它的自動探測和編譯過程是靠譜的,并不需要用Minke去做。如下面的配置所示,它在配置方面足夠簡單了。為了讓服務編譯順利,你所需要做的就是修改依賴部分的路徑,指向你的命名空間和項目名稱。我超愛CircleCI,現在它只要4分鐘就可以編譯服務并且這些時間是來搭建環境,而且UI也很簡單易用。當我要找到這個配置時,它SSH到編譯宿主的能力也是非常棒的。
machine: pre: -?curl?-sSL?https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh?|?bash?-s?--?1.10.0 Ruby: version:?2.2.4 services: -?docker environment: GOPATH:?/home/ubuntu/godependencies: override: -?cd?_build?&&?bundle -?mkdir?-p?/home/ubuntu/go/src/github.com/nicholasjackson -?cp?-R?/home/ubuntu/helloworld?/home/ubuntu/go/src/github.com/nicholasjackson/test: override: -?cd?_build?&&?rake?app:build_server -?cd?_build?&&?rake?app:cucumber
總結
本篇文章到此結束,5分鐘從零開始學習微服務主要有以下步驟:對我來說,隨著我學的更多這永遠是工作進步,我會繼續更新Minke和go-microservice-template。如果你有想法,歡迎給我留言、提bug,也歡迎來貢獻代碼。
源碼
地址:https://github.com/nicholasjackson/helloworld.依賴
相關項目的地址:- Ruby?https://rvm.io/
- Go?https://golang.org/
- Docker Toolbox including Docker Compose?https://www.docker.com/products/docker-toolbox
- CircleCI?https://circleci.com/
原文鏈接:0 to Microservice in 5 minutes with Go, go-microservice-template and Minke(翻譯:陳杰)
===================================================
譯者介紹
陳杰,北京理工大學計算機學院在讀博士,研究方向是自然語言處理在企業網絡信譽評價方面的應用,平時也樂于去實現一些突發的想法。在疲于配置系統環境時發現了Docker,跟大家一起學習、使用和研究Docker。
原文發布時間為:2016-03-14 本文作者:Sonyfe25cp 本文來自云棲社區合作伙伴DockerOne,了解相關信息可以關注DockerOne。 原文標題:5分鐘學習基于Go,go-microservice-template,Minke的微服務
總結
以上是生活随笔為你收集整理的5分钟学习基于Go,go-microservice-template,Minke的微服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【面试必备】javascript操作DO
- 下一篇: mysql在cmd命令下执行数据库操作