建立微服務指令說明
new #建立微服務
KaTeX parse error: Expected 'EOF', got '#' at position 8: GOPATH #̲建立 通過指定相對于GOPATH的目錄路徑,建立一個新的微服務。
USAGE:
#用法
micro new [command options][arguments…]
–namespace “go.micro” Namespace for the service e.g com.example
#服務的命名空間
–type “srv” Type of service e.g api, fnc, srv, web
#服務類型
–fqdn FQDN of service e.g com.example.srv.service (defaults to namespace.type.alias)
#服務的正式定義全面
–alias Alias is the short name used as part of combined name if specified
#别名是在指定時作為組合名的一部分使用的短名稱
建立2個服務
$micro new --type “srv” micro/rpc/srv
#“srv” 是表示目前建立的微服務類型
#micro是相對于go/src下的檔案夾名稱 可以根據項目進行設定
#srv是目前建立的微服務的檔案名
Creating service go.micro.srv.srv in /home/itcast/go/src/micro/rpc/srv
.
#主函數
├── main.go
#插件
├── plugin.go
#被調用函數
├── handler
│ └── example.go
#訂閱服務
├── subscriber
│ └── example.go
#proto協定
├── proto/example
│ └── example.proto
#docker生成檔案
├── Dockerfile
├── Makefile
└── README.md
download protobuf for micro:
brew install protobuf
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
go get -u github.com/micro/protoc-gen-micro
compile the proto file example.proto:
cd /home/itcast/go/src/micro/rpc/srv
protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto
#使用建立srv時給的protobuf指令保留用來将proto檔案進行編譯
micro new --type “web” micro/rpc/web
Creating service go.micro.web.web in /home/itcast/go/src/micro/rpc/web
.
#主函數
├── main.go
#插件檔案
├── plugin.go
#被調用處理函數
├── handler
│ └── handler.go
#前端頁面
├── html
│ └── index.html
#docker生成檔案
├── Dockerfile
├── Makefile
└── README.md
#編譯後将web端呼叫srv端的用戶端連接配接内容修改為srv的内容
#需要進行調通
啟動consul進行監管
consul agent -dev
對srv服務進行的操作
#根據提示将proto檔案生成為.go檔案
cd /home/itcast/go/src/micro/rpc/srv
protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto
#如果報錯就按照提示将包進行下載下傳
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
go get -u github.com/micro/protoc-gen-micro
#如果還不行就把以前的包删掉從新下載下傳
對web服務進行的操作
main檔案:
package main
import (
"github.com/micro/go-log"
"net/http"
"github.com/micro/go-web"
"micro/rpc/web/handler"
)
func main() {
// 建立1個web服務
service := web.NewService(
//注冊服務名
web.Name("go.micro.web.web"),
//服務的版本号
web.Version("latest"),
//!添加端口
web.Address(":8080"),
)
//服務進行初始化
if err := service.Init(); err != nil {
log.Fatal(err)
}
//處理請求 / 的路由 //目前這個web微服務的 html檔案進行映射
service.Handle("/", http.FileServer(http.Dir("html")))
//處理請求 /example/call 的路由 這個相應函數 在目前項目下的handler
service.HandleFunc("/example/call", handler.ExampleCall)
//運作服務
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
handler檔案
package handler
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/micro/go-micro/client"
//将srv中的proto的檔案導入進來進行通信的使用
example "micro/rpc/srv/proto/example"
)
//相應請求的業務函數
func ExampleCall(w http.ResponseWriter, r *http.Request) {
// 将傳入的請求解碼為json
var request map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
http.Error(w, err.Error(), 500)
return
}
// 調用服務
//替換掉原有的服務名
//通過服務名和
exampleClient := example.NewExampleService("go.micro.srv.srv", client.DefaultClient)
rsp, err := exampleClient.Call(context.TODO(), &example.Request{
Name: request["name"].(string),
})
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// we want to augment the response
response := map[string]interface{}{
"msg": rsp.Msg,
"ref": time.Now().UnixNano(),
}
// encode and write the response as json
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, err.Error(), 500)
return
}
}
更新成為grpc的版本
重新生成proto檔案
srv的main.go
package main
import (
"github.com/micro/go-log"
"github.com/micro/go-micro"
"micro/grpc/srv/handler"
"micro/grpc/srv/subscriber"
example "micro/grpc/srv/proto/example"
"github.com/micro/go-grpc"
)
func main() {
// 建立新服務
service := grpc.NewService(
//目前微服務的注冊名
micro.Name("go.micro.srv.srv"),
//目前微服務的版本号
micro.Version("latest"),
)
// 初始化服務
service.Init()
// Register Handler
//通過protobuf的協定注冊我們的handler
//參數1是我們建立好的服務傳回的句柄
//參數2 使我們new的handler包中的類
example.RegisterExampleHandler(service.Server(), new(handler.Example))
// Register Struct as Subscriber
//注冊結構體來自于Subscriber
micro.RegisterSubscriber("go.micro.srv.srv", service.Server(), new(subscriber.Example))
// Register Function as Subscriber
// 注冊函數自于Subscriber
micro.RegisterSubscriber("go.micro.srv.srv", service.Server(), subscriber.Handler)
// Run service
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
srv的example.go
package handler
import (
"context"
"github.com/micro/go-log"
//更換了相關proto檔案
example "micro/grpc/srv/proto/example"
)
type Example struct{}
// Call is a single request handler called via client.Call or the generated client code
func (e *Example) Call(ctx context.Context, req *example.Request, rsp *example.Response) error {
log.Log("Received Example.Call request")
rsp.Msg = "Hello " + req.Name
return nil
}
// Stream is a server side stream handler called via client.Stream or the generated client code
//流資料的檢測操作
func (e *Example) Stream(ctx context.Context, req *example.StreamingRequest, stream example.Example_StreamStream) error {
log.Logf("Received Example.Stream request with count: %d", req.Count)
for i := 0; i < int(req.Count); i++ {
log.Logf("Responding: %d", i)
if err := stream.Send(&example.StreamingResponse{
Count: int64(i),
}); err != nil {
return err
}
}
return nil
}
// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
//心跳檢測機制
func (e *Example) PingPong(ctx context.Context, stream example.Example_PingPongStream) error {
for {
req, err := stream.Recv()
if err != nil {
return err
}
log.Logf("Got ping %v", req.Stroke)
if err := stream.Send(&example.Pong{Stroke: req.Stroke}); err != nil {
return err
}
}
}
修改web的main.go
package main
import (
"github.com/micro/go-log"
"net/http"
"github.com/micro/go-web"
"micro/grpc/web/handler"
)
func main() {
// create new web service
service := web.NewService(
web.Name("go.micro.web.web"),
web.Version("latest"),
web.Address(":8080"),
)
// initialise service
if err := service.Init(); err != nil {
log.Fatal(err)
}
// register html handler
service.Handle("/", http.FileServer(http.Dir("html")))
// register call handler
service.HandleFunc("/example/call", handler.ExampleCall)
// run service
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
修改web的handler.go
package handler
import (
"context"
"encoding/json"
"net/http"
"time"
example "micro/grpc/srv/proto/example"
"github.com/micro/go-grpc"
)
func ExampleCall(w http.ResponseWriter, r *http.Request) {
server :=grpc.NewService()
server.Init()
// decode the incoming request as json
var request map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
http.Error(w, err.Error(), 500)
return
}
// call the backend service
//exampleClient := example.NewExampleService("go.micro.srv.srv", client.DefaultClient)
//通過grpc的方法建立服務連接配接傳回1個句柄
exampleClient := example.NewExampleService("go.micro.srv.srv", server.Client())
rsp, err := exampleClient.Call(context.TODO(), &example.Request{
Name: request["name"].(string),
})
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// we want to augment the response
response := map[string]interface{}{
"msg": rsp.Msg,
"ref": time.Now().UnixNano(),
}
// encode and write the response as json
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, err.Error(), 500)
return
}
}