Go 雲原生應用實戰系列(二)

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本章節我將專注於開發第一個微服務系統,我們將學會如何用go chassis開發微服務並完成微服務之間的調用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系列1"},{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/f658d19b6f22f9d9bac1dfe75","title":""},"content":[{"type":"text","text":"https://xie.infoq.cn/article/f658d19b6f22f9d9bac1dfe75"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"開發你的第一個微服務"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"啓動註冊中心"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"docker run -d -p 30100:30100 servicecomb/service-center"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"強烈推薦直接使用all in one的docker compose模板啓動,因爲可以使用可視化的UI界面。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://github.com/go-chassis/go-chassis/blob/master/examples/docker-compose.yaml"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UI的地址爲http://127.0.0.1:30103"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"註冊中心地址爲http://127.0.0.1:30100"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"初始化Go工程"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"go mod init github.com/go-chassis/go-chassis-examples/hello\ngo get github.com/go-chassis/go-chassis/v2"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"工程目錄規劃"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以創建一個server(名稱任意)文件夾,這個就是一個微服務的目錄"}]},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"mkdir server"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目錄結構"}]},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"server\n\n+-- main.go\n\n+-- conf\n\n +-- chassis.yaml\n\n +-- microservice.yaml"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最小化配置"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在chassis.yaml中涵蓋了幾乎所有的配置,不過想要啓動只需要2個簡單的配置"}]},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"servicecomb:\n registry:\n address: http://127.0.0.1:30100\n protocols:\n rest:\n listenAddress: 127.0.0.1:9000"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是服務監聽地址和註冊中心地址"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在microservice.yaml裏定義微服務信息,只需要一個簡單的微服務名即可,它還有大量的其他高級特性,我們將後續在高級特性中介紹"}]},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"servicecomb:\n service:\n name: HelloServer"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"編寫業務邏輯"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是時候編寫自己的API了"}]},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"//通常持有一批API,並定義API Patterns\ntype HelloResource struct {\n}\n\n//業務API\nfunc (r *HelloResource) SayHi(b *rf.Context) {\n\tb.Write([]byte(\"hello, go chassis\"))\n\treturn\n}\n\n//定義所有的API Patterns,用於API路由\nfunc (r *HelloResource) URLPatterns() []rf.Route {\n\treturn []rf.Route{\n\t\t{Method: http.MethodGet, Path: \"/hello\", ResourceFunc: r.SayHi},\n\t}\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"之後僅需要註冊即可"}]},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"chassis.RegisterSchema(\"rest\", &HelloResource{})"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"啓動服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"啓動很簡單,只需要編寫如下內容"}]},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"if err := chassis.Init(); err != nil {\n\topenlog.Fatal(\"Init failed.\" + err.Error())\n\treturn\n}\nchassis.Run()"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編譯執行"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"go build main.go\n./main"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"驗證:訪問UIhttp://127.0.0.1:30103"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/52/525c01b46290aa2002500d7e952427d0.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/16/16a03d2904695610083522dec817789e.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"額外可以看到自動生成的open API文檔"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a1/a17a1b2cfbc3289dfb368a6f552666b0.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/15/1575f326bd6ed267d38f0876af63c67b.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"直接訪問服務"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"curl http://127.0.0.1:9000/hello"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"調用服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我們需要調用這個服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建一個新的微服務"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"mkdir client"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"定義微服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在chassis.yaml中定義另一個監聽地址"}]},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"servicecomb:\n registry:\n address: http://127.0.0.1:30100\n protocols:\n rest:\n listenAddress: 127.0.0.1:8000"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在microservice.yaml中定義微服務名"}]},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"servicecomb:\n service:\n name: HelloClient"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"#編寫客戶端"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了簡單這裏只需要簡單的轉發即可,這裏給出完整邏輯"}]},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"type SimpleResource struct {\n}\n//在這個方法中,調用上面編寫的服務\nfunc (r *SimpleResource) SayHi(b *rf.Context) {\n\treq, _ := rest.NewRequest(http.MethodGet, \"http://HelloServer/hello\", nil)//這裏要填寫需要調用哪個服務,填寫服務名即可,然後就是他的api路徑\n\trestInvoker := core.NewRestInvoker()//併發安全,可全局使用\n\tresp, err := restInvoker.ContextDo(context.TODO(), req)//執行調用,這時go chassis介入,執行一些列用戶不可見的計算和操作\n\tif err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n\tb.Write(httputil.ReadBody(resp))//讀出服務端body體並直接透傳返回\n\treturn\n}\n\nfunc (r *SimpleResource) URLPatterns() []rf.Route {\n\treturn []rf.Route{\n\t\t{Method: http.MethodGet, Path: \"/hi\", ResourceFunc: r.SayHi},\n\t}\n}\n\nfunc main() {\n\tchassis.RegisterSchema(\"rest\", &SimpleResource{})\n\tif err := chassis.Init(); err != nil {\n\t\topenlog.Fatal(\"Init failed.\" + err.Error())\n\t\treturn\n\t}\n\tchassis.Run()\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"驗證:"}]},{"type":"codeblock","attrs":{"lang":"sh"},"content":[{"type":"text","text":"go build main.go\n./main\n## 打開另一個終端,執行\ncurl http://127.0.0.1:8000/hi"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將返回HelloServer的返回結果"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此時2個微服務實例應該同時在線"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4e/4e5e94cbf1bc21a4d0e308c296a6b595.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"完整例子"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://github.com/go-chassis/go-chassis-examples/tree/master/hello"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"小知識"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了提高系統的可用性,我們通常可以通過簡單的擴容實例來達成。從概率來說這切實有效。假設一個實例的可用度爲0.995. 那麼2個實例並聯後,他們的可用性爲"}]},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"1-(1-0.995)的平方=0.999975"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在訪問量大的情況下,我們也期望通過擴容來獲得線性的吞吐增長。然而吞吐能力並非隨着實例的數量呈線性增長。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常在給定一個實例的規格後,需要進行benchmark測試找到該規格下,到底多大的實例數量能達到最佳性價比。後續就要通過優化代碼來去提升吞吐了。這也是降成本的一種手法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本次,我們學會了開發簡單的微服務,並且完成了2者的一次調用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在實際使用中,可以啓動數個服務端實例,提升服務可用性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"go chassis通過客戶端負載均衡與註冊中新幫助屏蔽了網絡拓撲的複雜性,只需要理解服務名即可。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"擴展閱讀"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"註冊中心設計:https://www.jianshu.com/p/c676a69771bd"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章