微服务
2011 年 10 月 17 日
微服务简介





RPC
官方net/rpc包




package main import ( "fmt" "net/rpc" ) //客户端逻辑实现 func main() { client,err := rpc.DialHTTP("tcp","localhost:8081") if err != nil { panic(err.Error()) } var req float32 //请求值 req = 3 //var resp *float32 //返回值 ////同步的调用方式 //err = client.Call("MathUtil.CalculateCircleArea",req,&resp) //if err != nil { // panic(err.Error()) //} //fmt.Println(*resp) var respSync *float32 //异步的调用方式 最后一个参数是一个通道变量 syncCall := client.Go("MathUtil.CalculateCircleArea",req,&respSync,nil) replayDone := <-syncCall.Done fmt.Println(replayDone) fmt.Println(*respSync) }


多参数
new struct
package param type AddParam struct { Args1 float32 Args2 float32 }
client:
var result *float32 addparam := ¶m.AddParam{1.2,2.3} err = client.Call("MathUtil.Add",addparam,&result) if err != nil { panic(err.Error()) } fmt.Println("计算结果:",*result)
rpc和protobuf结合使用

gRPC
gRPC介绍



protobuf
网络通信数据交换协议,比json,xml更好一点

https://github.com/protocolbuffers/protobuf/releases

命令行

打开的访达,把解压的protoc文件复制进来

此时protoc编译器可用

安装库

go get github.com/golang/protobuf/protoc-gen-go


test.proto
syntax = "proto2"; package example; message Order{ required string order_id = 1; //1代表字段顺序 optional int64 num = 2; optional int32 timestamp = 3; }

这个pb.go就可以使用了
main.go
package main import ( "fmt" "gPRCCode/example" "github.com/golang/protobuf/proto" "os" ) func main() { fmt.Println("hello world") msg_test := &example.Order{ OrderId: proto.String("abcd1234"), Num: proto.Int64(123), Timestamp: proto.Int32(123456), } //序列化 msgDataEncoding,err := proto.Marshal(msg_test) if err != nil { panic(err.Error()) return } //反序列化 msgEntity := example.Order{} err = proto.Unmarshal(msgDataEncoding,&msgEntity) if err != nil { fmt.Println(err.Error()) os.Exit(1) return } fmt.Println("orderId:",msgEntity.GetOrderId()) fmt.Println("num:",msgEntity.GetNum()) fmt.Println("timestamp:",msgEntity.GetTimestamp()) }

grpc实现rpc服务调用
.proto文件服务定义
编译.proto文件
gPRC实现RPC调用编程






gPRC实现PRC编程


server.go
package main import ( "context" "errors" "fmt" "gPRCCode/message" "google.golang.org/grpc" "net" "time" ) type OrderServiceImpl struct { } //GetOrderInfo(context.Context, *OrderRequest) (*OrderInfo, error) func (os *OrderServiceImpl) GetOrderInfo(ctx context.Context,request *message.OrderRequest) (*message.OrderInfo, error) { OrderMap := map[string]message.OrderInfo{ "20200328001" : message.OrderInfo{OrderId:"20200328001",OrderNum:"衣服",OrderStatus:"已付款"}, "20200328002" : message.OrderInfo{OrderId:"20200328002",OrderNum:"零食",OrderStatus:"已付款"}, "20200328003" : message.OrderInfo{OrderId:"20200328003",OrderNum:"玩具",OrderStatus:"未付款"}, } var response *message.OrderInfo current := time.Now().Unix() if request.Timestamp > current { *response = message.OrderInfo{ OrderId: "0", OrderNum: "", OrderStatus: "订单信息异常", XXX_NoUnkeyedLiteral: struct{}{}, XXX_unrecognized: nil, XXX_sizecache: 0, } }else { result := OrderMap[request.Order] if result.OrderId != "" { fmt.Println(result) return &result,nil }else { return nil,errors.New("server error") } } return response,nil } func main() { server := grpc.NewServer() message.RegisterOrderServiceServer(server,new(OrderServiceImpl)) lis,err := net.Listen("tcp",":8090") if err != nil { panic(err.Error()) } server.Serve(lis) }
client.go
package main import ( "context" "fmt" "gPRCCode/message" "google.golang.org/grpc" "time" ) func main() { //1. Dail链接 conn,err := grpc.Dial("localhost:8090",grpc.WithInsecure()) if err != nil { panic(err.Error()) } defer conn.Close() orderServiceClient := message.NewOrderServiceClient(conn) //call("service.method") go orderRequest := &message.OrderRequest{ Order: "20200328001", Timestamp: time.Now().Unix(), } orderInfo, err := orderServiceClient.GetOrderInfo(context.Background(),orderRequest) if orderInfo != nil { fmt.Println(orderInfo.GetOrderId()) fmt.Println(orderInfo.OrderNum) fmt.Println(orderInfo.OrderStatus) } }

