使用net/rpc构建微服务
- 使用rpc启动一个订单中心服务
package main
import (
"net"
"net/http"
"net/rpc"
"time"
)
type OrderCenter struct {
}
//暴露的方法必须符合 func (t *T) MethodName(argType T1, replyType *T2) error 形式
func (order *OrderCenter) GetInfo(res int, rep *map[string]interface{}) error {
time.Sleep(4 * time.Second)
*rep = map[string]interface{}{
"name": "奶油蛋糕",
"price": 52.00,
"orderId": res,
}
return nil
}
func (order *OrderCenter) OrderPay(res int, rep *int) error {
time.Sleep(3 * time.Second)
*rep = 200
return nil
}
func main() {
orderCenterServer := new(OrderCenter)
err := rpc.Register(orderCenterServer)
if err != nil {
panic(err)
}
rpc.HandleHTTP()
listen, err := net.Listen("tcp", ":8081")
defer listen.Close()
if err != nil {
panic(err)
}
http.Serve(listen, nil)
}
- 客户端同步调用
package main import ( "fmt" "net/rpc" ) func main() { client, err := rpc.DialHTTP("tcp", "localhost:8081")
client.Close()
if err != nil { panic(err) } var orderId int orderId = 10 var orderInfo map[string]interface{} err = client.Call("OrderCenter.GetInfo", orderId, &orderInfo) if err != nil { fmt.Println(err) } fmt.Println(orderInfo) var status int err = client.Call("OrderCenter.OrderPay", orderId, &status) if err != nil { fmt.Println(err) } fmt.Println(status) }
输出内容
&map[name:奶油蛋糕 orderId:10 price:52] 支付失败 <nil>
- 客户端异步调用
package main import ( "fmt" "net/rpc" ) func main() { client, err := rpc.DialHTTP("tcp", "localhost:8081") defer client.Close() if err != nil { panic(err) } var orderId int = 10 callChan := make([]chan *rpc.Call, 0, 2) var orderInfo map[string]interface{} infoCall := client.Go("OrderCenter.GetInfo", orderId, &orderInfo, nil) callChan = append(callChan, infoCall.Done) var status int statusCall := client.Go("OrderCenter.OrderPay", orderId, &status, nil) callChan = append(callChan, statusCall.Done) for _, chanCall := range callChan { data := <-chanCall switch data.ServiceMethod { case "OrderCenter.OrderPay": d := data.Reply.(*int) fmt.Println(*d) case "OrderCenter.GetInfo": d := data.Reply.(*map[string]interface{}) fmt.Println(*d) } } }