什麼是微服務?
一種軟件體系結構模式,用於將大型單塊應用程序分解爲更小、可管理的獨立服務,這些服務通過語言無關協議進行通信,每個服務的重點做好一件事
微服務的概念並不新鮮,這是對服務導向架構的重新構想,但其方法更整體地與unix進程和管道保持一致。
微服務架構的理念:
- 服務很小 - 細粒度作爲單一的商業目的類似於unix哲學“做一件事,做得好”
- 組織文化應該包含部署和測試的自動化。這減輕了管理和運營的負擔
- 文化和設計原則應該包含失敗和錯誤,類似於反脆弱系統。
好處:
- 更容易擴展開發 - 團隊圍繞不同的業務需求進行組織並管理自己的服務。
- 更容易理解 - 微服務要小得多,通常是1000 LOC或更低。
- 更容易部署新版本的服務 - 可以獨立部署,擴展和管理服務。
- 改進的容錯和隔離 - 關注點的分離可以最大限度地減少一個服務中的問題對另一個服務的影響。
- 提高執行速度 - 團隊通過獨立開發,部署和管理微服務,更快地滿足業務需求。
- 可重用的服務和快速原型 - 微服務中根深蒂固的unix哲學允許您重用現有服務並在更快的速度上構建全新的功能。
micro 與go-micro 的區別
micro
Micro解決了構建微服務系統的關鍵要求。它採用微服務架構模式並將其轉換爲一組工具,由以下功能組成:
- API網關:使用服務發現進行動態請求路由的單個入口點。API網關允許您在後端構建可擴展的微服務架構,並在前端整合服務公共API。micro api通過發現和可插拔處理程序提供強大的路由,以提供http,grpc,websockets,發佈事件等。
- 交互式CLI:用於直接從終端描述,查詢和與您的平臺和服務進行交互的CLI。CLI爲您提供了您希望瞭解微服務發生情況的所有命令。它還包括一個交互模式。
- 服務代理:基於 go-micro 構建的透明代理。將服務發現,負載平衡,容錯,消息編碼,中間件,監控等卸載到單個位置。獨立運行或與服務一起運行。
- 模板生成:創建新的服務模板以快速入門。Micro提供用於編寫微服務的預定義模板。始終以相同的方式開始,構建相同的服務以提高工作效率。
- SlackOps Bot:在您的平臺上運行的機器人,讓您可以從Slack本身管理您的應用程序。微型機器人支持ChatOps,使您能夠通過消息傳遞與團隊一起完成所有工作。它還包括創建鬆弛命令作爲動態發現的服務的能力。
- Web儀表板: Web儀表板允許您瀏覽服務,描述其端點,請求和響應格式,甚至可以直接查詢它們。儀表板還爲想要即時進入終端的開發人員提供了內置的CLI體驗。
- Go Framework:利用強大的 go-micro 框架輕鬆快速地開發微服務。Go Micro抽象出分佈式系統的複雜性,並提供更簡單的抽象來構建高度可擴展的微服務。
go-micro
go-micro提供了分佈式系統開發的核心要求,包括RPC和事件驅動的通信。
主要功能。
- 服務發現 - 自動服務註冊和名稱解析。服務發現是微服務開發的核心。當服務A需要與服務B通話時,它需要該服務的位置。默認發現機制是多播DNS(mdns),一種零配置系統。您可以選擇使用SWIM協議爲p2p網絡設置八卦,或者爲彈性雲原生設置設置consul。
- 負載平衡 - 基於服務發現構建的客戶端負載平衡。一旦我們獲得了服務的任意數量實例的地址,我們現在需要一種方法來決定要路由到哪個節點。我們使用隨機散列負載平衡來提供跨服務的均勻分佈,並在出現問題時重試不同的節點。
- 消息編碼 - 基於內容類型的動態消息編碼。客戶端和服務器將使用編解碼器和內容類型爲您無縫編碼和解碼Go類型。可以編碼任何種類的消息並從不同的客戶端發送。客戶端和服務器默認處理此問題。這包括默認的protobuf和json。
- 請求/響應 - 基於RPC的請求/響應,支持雙向流。我們提供了同步通信的抽象。對服務的請求將自動解決,負載平衡,撥號和流式傳輸。啓用tls時,默認傳輸爲http / 1.1或http2。
- Async Messaging - PubSub是異步通信和事件驅動架構的一流公民。事件通知是微服務開發的核心模式。啓用tls時,默認消息傳遞是點對點http / 1.1或http2。
- 可插拔接口 - Go Micro爲每個分佈式系統抽象使用Go接口。因此,這些接口是可插拔的,並允許Go Micro與運行時無關。您可以插入任何基礎技術。在github.com/micro/go-plugins中找到插件 。
開始
準備工作
安裝go語言環境,並開啓go module功能,可以設置 GOPROXY=https://goproxy.io 環境變量可以永久加速下載包。在環境變量path添加一行配置 %GOPATH%bin這樣可以在 go get 的時候安裝的軟件可以直接使用,不需要切換路徑,GOPATH:是工作空間目錄
臨時加速,只在當前控制檯有效:
- win: set GOPROXY=https://goproxy.io
- linux + mac: GOPROXY=https://goproxy.io
1,下載proto,選擇自己需要的版本解壓放在 %GOPATH%bin下,方便管理:
https://github.com/protocolbuffers/protobuf/releases
2,安裝protoc-gen-go:
go get -u github.com/golang/protobuf/protoc-gen-go
3,安裝micro:
go get github.com/micro/micro
創建項目
go mod init module名:用於創建go module項目module名:建議和父文件夾的名字相同
在桌面新建文件夾 demo
自定義一個文件夾:打開cmd
進入桌面上的demo
後,運行 go mod init demo,
運行完後新建handler,proto/hello文件夾,以及main.go文件
目錄結構定義爲:
demo
-handler
-proto
--hello
main.go
go.mod
在proto/hello下新建 hello.proto文件,內容如下
syntax = "proto3"; // 定義protobuf版本
//定義接口
service Hello {
rpc Say (SayRequest) returns (SayResponse); //定義接口方法
}
// SayRequest,SayResponse:可以爲不同接口定義輸入輸出參數
message SayRequest {
string name = 1;
}
message SayResponse {
string msg = 1;
}
打開cmd
進入proto/hello下 編譯proto文件:
protoc --micro_out=. --go_out=. hello/hello.proto
然後就會產生兩個文件,hello.micro.go,hello.pb.go
在handler下,新建hello_handler.go文件
package handler
import (
"context"
pb "demo/proto/hello"//proto文件的路徑
)
type hello struct{}
func NewHelloApi() pb.HelloHandler {
return &hello{}
}
func (self *hello) Say(ctx context.Context, req *pb.SayRequest, resp *pb.SayResponse) error {
resp.Msg = "hello " + req.Name
return nil
}
編寫main:
package main
import (
"fmt"
"github.com/micro/go-micro"
"log"
"demo/handler"
hello_api "demo/proto/hello"
)
const (
ServiceName = "demo.api"
)
func main() {
service := micro.NewService(
micro.Name(ServiceName),
micro.Version("1.0.0"),
)
service.Init()
//掛載服務
err := hello_api.RegisterHelloHandler(service.Server(), handler.NewHelloApi())
if err != nil {
fmt.Println(err)
}
// 啓動api服務
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
更新依賴:
go mod tidy
運行:
go run main.go
測試
使用 micro提供的工具
micro call demo.api Hello.Say '{"name":"John"}'
使用 postman
運行 網關:
micro api --namespace=demo
測試接口
細節
運行網關的時候:添加namespace這個參數,該參數值( demo)和 ServiceName(demo.api)的前綴必須要一致,而後面的字符就是訪問該服務的前綴 ,例如:api ,所以通過網關訪問就是:http://127.0.0.1:8080/api/hello/say,
hello:是定義的接口,
say:是該接口提供的方法