微服务简介
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介绍
https://grpc.io/
https://github.com/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)
}
}
有疑问加站长微信联系(非本文作者)