RPC and GRPC in Golang

Source: Internet
Author: User

One, RPC programming

    • Resources

      <<go language Programming >>--Xu Xiwei
      GRPC Introduction and Installation
      GRPC Official documents
      GRPC Chinese Documents
      Protocol-buffers

    • Introduced
RPC, remote Procedure call, is an application communication protocol that requests services over a network from a remote computer program without needing to know the details of the underlying network. The RPC protocol is built on TCP or UDP, or HTTP. Allows developers to directly invoke programs on another server, while developers do not need to write network-communication-related code for the calling process, making it easier for applications to develop network-distributed programs

RPC uses the client-server-side mode of operation, the requestor is a client, and the service provider is a server side. When a remote procedure call is executed, the client program first sends a call message with parameters to the server and waits for the server to respond. On the server side, the service process keeps the sleep state until the client's call information arrives. When a call arrives, the server obtains the process parameters, calculates the result, and sends the reply message to the client. Then wait for the next call.

    • RPC support and processing in the Go language
in Go, the standard library provides the NET/RPC package to implement the RPC protocol needs the relevant details, developers can easily use the package to write RPC server and client programs. This makes communication between multiple processes developed in the go language very simple
The NET/RPC package allows the PRC client program to invoke a public method of a remote object over a network or other IO connection (the method must be externally accessible and capitalized in the first letter). On the PRC service side, an object can be registered as an accessible service, and then the public method of that object can provide access remotely. An RPC server can register multiple objects of a different type, but <font color= "Brown" > does not allow multiple objects of the same type to be registered. </font>
    • A method in an object that satisfies the following conditions can be set to remote access by the PRC server
      1.<font color= "Brown" > must be a method that can be publicly invoked outside the object (capitalized) </font >
      2.<font color= "Brown" > must have two parameters, and the type of the parameter must be a type that can be accessed outside the package or the type of go built-in support </font>
      3.<font color= " Brown "> The second argument must be a pointer </font>
      4.<font color=" Brown "> method must return a value of type error </font>
      in code representation

        func (t t*) MethodName (argtype t1,replytype *t2) error  

      In this line of code, the type T T1 T2 is encoded and decoded by default using the go built-in Encoding/gob package
      The first parameter of the modification method represents the parameter passed in by the PRC client, and the second parameter represents the result to be returned to the PRC client. The Change method finally returns an error type

    • RPC client and server side usage
RPC服务端可以通过调用 ```rpc.ServerConn```处理单个连接请求。多数情况下,通过tcp或是http在某个网络地址上监听然后再创建该服务是个不错的选择  在RPC客户端,Go的net/rpc包提供了便利的```rpc.Dial()```和```rpc.DialHTTP()```方法来与指定的RPC服务建立连接。在建立连接之后,Go的net/rpc包允许我们使用通过或者异步的方式接受RPC服务端的结果。调用RPC客户端的```Call()```方法则进行同步处理。这个时候客户端程序按照顺序执行。当调用RPC客户端的```Go()```方法时,则进行异步处理。客户端无需等待服务端的结果即可执行后面的程序,当接收到服务端响应时,再对其进行相应的处理。 无论是哪个方法,都必须要指定要调用的服务及其方法名称,以及一个客户端传入参数的引用,还有一个用于接收处理结果参数的指针  如果没有指定RPC传输过程中使用何种编码解码器,默认使用Go标准库提供的eccoding/gob包进行数据传输   
    • code example
server-side code
package mainimport (    "errors"    "log"    "net"    "net/http"    "net/rpc"    "os"    "time")type Args struct {    A, B int}type Quotient struct {    Quo, Rem int}type Arith int//计算乘积func (t *Arith) Multiply(args *Args, reply *int) error {    time.Sleep(time.Second * 3) //睡三秒,同步调用会等待,异步会先往下执行    *reply = args.A * args.B    return nil}//计算商和余数func (t *Arith) Divide(args *Args, quo *Quotient) error {    time.Sleep(time.Second * 3)    if args.B == 0 {        return errors.New("divide by zero")    }    quo.Quo = args.A / args.B    quo.Rem = args.A % args.B    return nil}func main() {    //创建对象    arith := new(Arith)    //rpc服务注册了一个arith对象 公开方法供客户端调用    rpc.Register(arith)    //指定rpc的传输协议 这里采用http协议作为rpc调用的载体 也可以用rpc.ServeConn处理单个连接请求    rpc.HandleHTTP()    l, e := net.Listen("tcp", ":1234")    if e != nil {        log.Fatal("listen error", e)    }    go http.Serve(l, nil)    os.Stdin.Read(make([]byte, 1))}
Client Code
 package mainimport ("FMT" "Log" "Net/rpc" "Time") type Args struct {A, B int}type Qu otient struct {Quo, Rem Int}func Main () {//Call the RPC service side to establish a connection to the client, err: = RPC Before calling the method provided by the RPCs server. Dialhttp ("TCP", "127.0.0.1:1234") if err! = Nil {log. Fatal ("Dialhttp error", err) return}//synchronous Invoke method provided by the server args: = &args{7, 8} var reply int//can view source code In fact, call synchronous calls are implemented with asynchronous calls. Follow the detailed learning of err = client. Call ("Arith.multiply", args, &reply)//here will block for three seconds if err! = Nil {log. Fatal ("Call Arith. Multiply error ", err)} FMT. Printf ("arith:%d*%d=%d\n", args. A, args. B, Reply)//Asynchronous Call Quo: = quotient{} divcall: = client. Go ("Arith.divide", args, &quo, nil)//Use the Select model to listen for the data when the channel is executed, otherwise execute the subsequent program for {select {case <-DIVCA ll. Done:fmt. Printf ("Quotient is%d, remainder is%d\n", quo. Quo, Quo. Rem) default:fmt. Println ("Continue to execute .....") time. Sleep (time. Second * 1}}}  

Description

//Go函数的原型,注意其最后一个参数是一个channel 也就是调用结果存到了这个channel里 里面的类型数据是*Call类型//如果你不传递这个channel这个参数,Go函数内部会默认创建一个*Call类型的10个长度的channel来缓存结果数据。channel的名字叫做//Done也就是返回值*Calll俩面的最后一个值  //好吧,其实我就是想说,cient.Go的返回值包含了最后一个参数(channel),想获取调用结果,可以从参数管道中直接获取,也可以从返回值//Done中获取// Call represents an active RPC.type Call struct {    ServiceMethod string      // The name of the service and method to call.    Args          interface{} // The argument to the function (*struct).    Reply         interface{} // The reply from the function (*struct).    Error         error       // After completion, the error status.    Done          chan *Call  // Strobes when call is complete.}func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call {

Two Grpc

    • What is GRPC?
GRPC Chinese Documents

GRPC is a high-performance, open-source, common RPC framework. Based on the HTTP/2 protocol standard design Development, the default is to use the Protocol Buffers Data serialization Protocol ([Protocol buffers Basic Syntax] ()) to support a variety of development languages. GRPC provides an easy way to define services precisely and automatically generates a reliable library of functions for both client and server

    • GRPC Application Scenarios
in the GRPC client can directly call the remote program on the server, just like to invoke local programs, it is easy to build distributed applications and services. Like many RPC systems, the service is responsible for implementing well-defined interfaces and processing client requests, and the client invokes the required services directly based on the interface description. The client and server can be implemented using different languages supported by GRPC, respectively

    • Installation

Protobuf Golang Plug-in

After execution, the tool will be generated in the Gopath/bin directory, and the protoc-gen-go PROTOC command will need to use this plugin when compiling the. proto file.

[About PROTOBUF syntax and basic use] ()

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

Grpc-go golang Third Party library download (need to turn over the wall with the SS configuration HTTP proxy to complete the terminal Flip wall))

go get -u google.golang.org/grpc
    • GPRC, Hello Grpc.

Process

1.编写.proto描述文件  2.编译生成.pb.go文件  3.客户端实现约定的接口并提供服务  4.客户端按照约定调用方法请求服务  

Directory structure

$GOPATH/src/go_demo/23gPRC/|—— hello/    |—— client/        |—— main.go   // 客户端    |—— server/        |—— main.go   // 服务端|—— proto/    |—— hello.proto   // proto描述文件    |—— hello.pb.go   // proto编译后文件
    • code example
Proto RPC Service description file
syntax = "proto3"; //指定proto版本package proto;//定义请求结构message HelloRequest{    string name=1;}//定义响应结构message HelloReply{    string message=1;}//定义Hello服务service Hello{    //定义服务中的方法    rpc SayHello(HelloRequest)returns (HelloReply){}}
Protoc-i. --GO_OUT=PLUGINS=GRPC:. ./hello.proto
A Hello service is defined in the Hello.proto file that contains a SayHello method that declares both the hellorequest and helloreply message structures
Used for requests and responses. The client uses the Hellorequest parameter to call the SayHello method to request a server-side response helloreply message
Generate Golang source files based on Hello.proto file compilation Hello.pb.go
The source file contains the request and response structure of the message delivery. Method of registering objects on the server creates a client and invokes a service-side method
server-side code
package mainimport (    "fmt"    pb "go_demo/23gRPC/proto"    "net"    "golang.org/x/net/context"    "google.golang.org/grpc")const (    //gRPC服务地址    Address = "127.0.0.1:50052")//定义一个helloServer并实现约定的接口type helloService struct{}func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {    resp := new(pb.HelloReply)    resp.Message = "hello" + in.Name + "."    return resp, nil}var HelloServer = helloService{}func main() {    listen, err := net.Listen("tcp", Address)    if err != nil {        fmt.Printf("failed to listen:%v", err)    }    //实现gRPC Server    s := grpc.NewServer()    //注册helloServer为客户端提供服务    pb.RegisterHelloServer(s, HelloServer) //内部调用了s.RegisterServer()    fmt.Println("Listen on" + Address)    s.Serve(listen)}
Go Run main.go
Listen on127.0.0.1:50052
Client Code
package mainimport (    "fmt"    pb "go_demo/23gRPC/proto"    "golang.org/x/net/context"    "google.golang.org/grpc")const (    Address = "127.0.0.1:50052")func main() {    //连接gRPC服务器    conn, err := grpc.Dial(Address, grpc.WithInsecure())    if err != nil {        fmt.Println(err)    }    defer conn.Close()    //初始化客户端    c := pb.NewHelloClient(conn)    //调用方法    reqBody := new(pb.HelloRequest)    reqBody.Name = "gRPC"    r, err := c.SayHello(context.Background(), reqBody)    if err != nil {        fmt.Println(err)    }    fmt.Println(r.Message)}
Go Run main.go
Hello Grpc
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.