How to implement a system with GRPC (1): Grpc Introduction

Source: Internet
Author: User
Tags install go

Recently, service and microservices have become the mainstream of medium-and large-scale distributed systems, and RPC plays a crucial role in it. Here, let's take a brief look at what RPC is, and a simple example of grpc, to see how to develop with GRPC.

1. What is RPC

RPC (remoteProcedurecall), which is called remotely, is a way of communicating between processes. Unlike a function in alocal call where callers call the same address space, RPC allows a program to call a function of another address space (usually on another machine on a shared network) without the programmer explicitly encoding the details of the remote call, This makes the remote call and the local call have the same effect as the programmer's point of view.

The concept of RPC had already emerged early, and a concrete implementation was given in Bruce Jay Nelson's 1984 paper implementing RPC. At the same time, in this paper, Bruce gives the three benefits of RPC:

    1. simple and concise syntax : This makes it easier and more accurate to build distributed systems;
    2. Efficient : function calls via RPC are simple enough to make communication more rapid;
    3. General : The process in a stand-alone system is often the most important communication mechanism for different algorithms.

In fact, from the caller's point of view, there is no difference between RPC and ordinary local calls, it is the process of invoking other functions, but in the implementation of the point of view, RPC is through the network between the different machines to communicate, complete the normal call in the same address space can be completed by the parameters of the transfer and the result callback. Bruce's article, published in 1984, is a demonstration of his vision, and the RPC framework we use today is basically implemented in this design.

As we can see from the above introduction, the difference between RPC and ordinary local calls is in the way that parameters and results are passed. RPC is passed through the network, so for an RPC system you need to think carefully about the implementation details. Here we do not have too much involved, just understand the concept of good.

In this paper, Bruce points out that implementing an RPC system requires several parts :

    1. User;
    2. User-stub;
    3. Rpcruntime;
    4. Server-stub;
    5. Server.

The specific structure of these five parts:

Where User, User-stub, and one Rpcruntime instance run on the caller (caller) machine, and Server, Server-stub, and another Rpcruntime instance run on the callee ( Callee) on the machine.

The specific invocation process is as follows:

When a user wants to initiate a remote call, it actually first calls the relevant program in User-stub, and User-stub is responsible for getting what the specific remote program is called and passing the parameters of the call to the rpcruntime of the caller side. Rpcruntime will pass the parameters over the network to the rpcruntime of the target machine. The rpcruntime on the target machine passes the parameter to Server-stub after receiving the request, then server-stub parses the parameter and initiates a normal local call, which causes the server to execute. When the server finishes executing, the results are returned to server-stub and then passed back to caller over the network. The results of the caller end are returned to the user after the User-stub parsing results.

Now the RPC framework basically supports different languages, that is, user and server can be implemented in different languages, then the RPC framework needs to be in the middle of an interface definition and unification. This is the use of IDL (Interface definition Language) to define the interface, and then through the framework provided by the tool to each user and server to generate the corresponding language stub.

2. GRPC debut

GRPC is an RPC framework for Google Open source, which uses protocol buffers as IDL and the underlying message conversion format. As described above, the structure of the GRPC

Not much, let's look at a simple example of how to use GRPC.

3. HelloWorld in Grpc

In order to use GRPC, we need go 1.6 or later:

$ go version

If the go is not installed, you can refer to this. After you install go, you need to set the Gopath.

Next, we need to install GRPC. We can use the following command to install:

$ go get -u google.golang.org/grpc

But this installation requires scientific Internet access. If it is not scientific internet, can also be github.com installed by.

First go to the first $gopath directory, the go get default installation under the first Gopath, create a new google.golang.org directory, pull the golang github image Library on:

$ cd /User/valineliu/go/src$ mkdir google.golang.org$ cd google.golang.org/$ git clone https://github.com/grpc/grpc-go$ mv grpc-go/ grpc

Then install PROTOBUF buffers v3. Protobuf buffers as a tool for GRPC IDL and underlying message conversion, we need to install the corresponding PROTOC compiler.

First download the relevant version of the file here:

$ wget https://github.com/google/protobuf/releases/download/<version>/protobuf-all-<version>.zip$ unzip protobuf-all-<version>.zip$ cd protobuf-all-<version>$ ./configure$ make$ make install

This completes the installation of the PROTOC.

Next install the Protoc go plugin:

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

Protoc-gen-go is a plugin for PROTOC that is used to generate the go language code based on the IDL profile. The above command installs it in the $gopath/bin directory and adds it to the path:

$ export PATH=$PATH:$GOPATH/bin

So all the components are installed, and then we start HelloWorld .

The directory structure of the project is as follows:

 GOPATH |__src    |__helloworld       |__client       |__helloworld       |__server    ...

Where client directories are used to store client-side code, helloworld directories are used to store the service's IDL definitions, and server directories are used to store server-side code.

First, we need to define our services. helloworldto enter the directory, create a new file:

$ cd helloworld$ vim helloworld.proto

Here I am using vim for editing. Defined as follows:

syntax = "proto3";package helloworld;message HelloRequest {    string name=1;}message HelloReply {    string message =1;}service Greeter {    rpc SayHello (HelloRequest) returns (HelloReply) {}}

Here we do not look at the specific meaning. We then use protoc this file to compile:

$ protoc -I. --go_out=plugins=grpc:. helloworld.proto

This way, there is one more file in the directory: helloworld.pb.go .

Then go server to the directory and create a new file:

$ cd ../server$ vim server.go

server.goThe contents are as follows:

package mainimport (    "log"    "net"    "golang.org/x/net/context"    "google.golang.org/grpc"    pb "helloworld/helloworld"    "google.golang.org/grpc/reflection")const (    port = ":50051")type server struct{}func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {    return &pb.HelloReply{Message: "Hello " + in.Name}, nil}func main() {    lis, err := net.Listen("tcp", port)    if err != nil {        log.Fatalf("failed to listen: %v",err)    }    s := grpc.NewServer()    pb.RegisterGreeterServer(s, &server{})    reflection.Register(s)    if err := s.Serve(lis); err != nil {        log.Fatalf("failed to serve: %v",err)    }}

This is the server side of the code, again, we do not consider the specific details for the time being.

Then go to the client directory to create a new file:

$ cd ../client$ vim client.go

client.goThe contents are as follows:

package mainimport (    "log"    "os"    "time"    "golang.org/x/net/context"    "google.golang.org/grpc"    pb "helloworld/helloworld")const (    address     = "localhost:50051"    defaultName = "world")func main() {    conn, err := grpc.Dial(address, grpc.WithInsecure())    if err != nil {        log.Fatalf("did not connect: %v",err)    }    defer conn.Close()    c := pb.NewGreeterClient(conn)    name := defaultName    if len(os.Args) > 1 {        name = os.Args[1]    }    ctx, cancel := context.WithTimeout(context.Background(), time.Second)    defer cancel()    r, err := c.SayHello(ctx, &pb.HelloRequest{Name:name})    if err!=nil {        log.Fatalf("could not greet: %v",err)    }    log.Printf("Greeting: %s",r.Message)}

This is the client-side code.

So all the code is written, and then we're going to let it run.

First enter server the directory and start our server:

$ cd ../server$ go run server.go

, the server started up:

Then open a different terminal, enter client the directory, launch an RPG remote call:

$ cd $GOPATH/src/helloworld/client$ go run client.go // one $ go run client.go firework //two

Results

Success! Our first little example is done, this one here first, to be Continue.

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.