如何編寫一個微服務?這裡用的是go的微服務框架go micro,具體的情況可以查閱:btfak.com/%E5%BE%AE%E…
這裡給出的是開發一個微服務的步驟(如果想直接查閱原始碼或者通過demo學習的,可以訪問ricoder_demo。
1、書寫proto檔案,定義函式等
具體實現:
syntax = "proto3";
package pb;
service UserService {
//增
rpc InsertUser (InsertUserReq) returns (InsertUserRep){}
//刪
rpc DeletetUser (DeletetUserReq) returns (DeletetUserRep){}
//查
rpc SelectUser(SelectUserReq)returns (SelectUserRep){}
//改
rpc ModifyUser(ModifyUserReq)returns (ModifyUserRep){}
}
message User{
int32 id = 1 ;
string name = 2;
string Address = 3;
string Phone = 4;
}
message ModifyUserReq {
int32 id = 1 ;
string name = 2;
string Address = 3;
string Phone = 4;
}
message ModifyUserRep {
}
message SelectUserReq {
int32 id = 1 ;
}
message SelectUserRep {
User users = 1;
}
message DeletetUserReq {
int32 id = 1 ;
}
message DeletetUserRep {
}
message InsertUserReq {
int32 id = 1 ;
string name = 2;
string Address = 3;
string Phone = 4;
}
message InsertUserRep {
int32 id = 1 ;
string name = 2;
string Address = 3;
string Phone = 4;
}複製程式碼
2、採用程式碼生成工具生成user.pb.go檔案,生成協議
具體可以檢視 github.com/micro/go-mi… ,這裡我自己寫了個指令碼檔案 build_proto.sh ,自動將指定資料夾下的proto檔案生成相應的協議,具體程式碼如下:
#!/usr/bin/env bash
protoc --proto_path=./proto --go_out=plugins=micro:./src/share/pb ./proto/*.proto複製程式碼
可以對程式碼進行自定義修改 ... .... ...
執行 build_proto.sh 檔案後可以看到在指定資料夾下生成了相應的 user.pb.go 檔案,在我這裡如:
3、書寫一個handler實現user.pb.go定義的介面
具體實現:
1)先建立一個user.go檔案
2)定義一個結構體,命名為UserHandler,實現user.proto檔案所有定義的service,在這裡要注意一點,即使是暫時沒有實現好業務,也有給個空實現,程式碼如下:
package handler
import(
"mewe_job/GoMicroDemo/src/share/pb"
"golang.org/x/net/context"
)
type UserHandler struct {
}
// new一個UserHandler
func NewUserHandler() *UserHandler{
return &UserHandler{}
}
// 增
func (c *UserHandler) InsertUser(ctx context.Context, req * pb.InsertUserReq,rsp *pb.InsertUserRep)error {
return nil
}
// 刪
func (c *UserHandler) DeletetUser(ctx context.Context, req * pb.DeletetUserReq,rsp *pb.DeletetUserRep)error {
return nil
}
// 查
func (c *UserHandler) SelectUser(ctx context.Context, req * pb.SelectUserReq,rsp *pb.SelectUserRep)error {
return nil
}
//改
func (c *UserHandler) ModifyUser(ctx context.Context, req * pb.ModifyUserReq,rsp *pb.ModifyUserRep)error {
return nil
}複製程式碼
4、將handler註冊進微服務,這一步在main中實現
具體實現:
package main
import (
"github.com/micro/cli"
"mewe_job/GoMicroDemo/src/share/pb"
"github.com/micro/go-micro/server"
"mewe_job/GoMicroDemo/src/user-srv/handler"
"github.com/micro/go-micro"
"log"
"mewe_job/GoMicroDemo/src/user-srv/db"
"mewe_job/GoMicroDemo/src/share/config"
)
func main() {
// 建立Service,並定義一些引數
service := micro.NewService(
micro.Name("go.micro.srv.user"),
micro.Version("latest"),
)
// 定義Service動作操作
service.Init(
micro.Action(func(c *cli.Context) {
log.Println("micro.Action test ...")
// 先註冊db
db.Init(config.MysqlDSN)
pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
}),
micro.AfterStop(func() error {
log.Println("micro.AfterStop test ...")
return nil
}),
micro.AfterStart(func() error {
log.Println("micro.AfterStart test ...")
return nil
}),
)
log.Println("啟動user-srv服務 ...")
//啟動service
if err := service.Run(); err != nil {
log.Panic("user-srv服務啟動失敗 ...")
}
}複製程式碼
這段程式碼主要的點有:
建立service,通過以下程式碼可以初始化一個名叫 go.micro.srv.user 的微服務
// 建立Service,並定義一些引數 service := micro.NewService( micro.Name("go.micro.srv.user"), micro.Version("latest"), )複製程式碼
- 註冊db連線和給go.micro.srv.user這個微服務繫結handler,雖然目前我還沒有在db中定義db層的操作
db.Init(config.MysqlDSN)
pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))複製程式碼
- 啟動service,通過Run開啟
if err := service.Run(); err != nil {
log.Panic("user-srv服務啟動失敗 ...")
}複製程式碼
5、現在就可以通過 go run main.go --registry=mdns 啟動該服務了,之所以攜帶 --registry=mdns 是因為我本地ubuntu系統沒有安裝consul實現服務發現,所以就採用了gomicro官方推薦的方法。
6、到這一步客戶端還無法訪問到服務,需要做些處理,我這裡是加了個web服務,再將客戶端的請求進行轉發,main函式實現如下:
func main() {
/* 方案一:
mux := http.NewServeMux()
mux.HandleFunc("/", handleRPC)
log.Println("Listen on :8082")
http.ListenAndServe(":8082", mux)*/
/* 方案二 */
service := web.NewService(
web.Name(config.ServicePrefix+".web"),
)
service.HandleFunc("/", handleRPC)
if err := service.Init(); err != nil {
log.Fatal(err)
}
if err := service.Run(); err != nil {
log.Fatal(err)
}
}複製程式碼
這裡主要的函式是handleRPC這個函式,由於程式碼量偏多,具體實現可以檢視原始碼。這裡如果使用consul實現了服務發現,也可以通過方案一進行實現,這樣的話web服務的埠還是固定的。
7、開啟web服務
$ go run web.go --registry=mdns
Listening on [::]:36859複製程式碼
8、到這一步客戶端就可以通過web服務埠和介面以及引數訪問user這個微服務了,訪問連結:(這裡安利postman,一個谷歌的外掛,超級好用 ... )
http://127.0.0.1:36859/user/selectUser複製程式碼
tip:該專案的原始碼(包含資料庫的增刪查改的demo)可以檢視 原始碼
有興趣的可以關注我的個人公眾號 ~