Grpc using PROTOBUF to build microservices

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

The original link, reproduced annotated source can be.
This article code: GITHUB
This article directory:

Micro-Service Architecture

A single code base

When I used Laravel to do Web projects, it was based on MVC to partition the directory structure, that is, Controller layer processing business logic, the Model layer processing database curd,view layer processing data rendering and page interaction. And MVP, MVVM, all of the code for the entire project is focused on a code base for business processing. This single aggregation of code is fast in the early stages of the business, but it exposes a lot of problems later on:

    • Difficulties in development and maintenance: As the complexity of the business increases, the coupling of the code tends to become higher, and multiple modules are not easily scaled out after coupling.
    • Low efficiency and reliability: Too much code will slow down the response, and application potential security issues will accumulate

Split code base

MicroServices are a software architecture that splits a large and aggregated business project into multiple small, discrete business modules, module-as-a-service, and RPC, using efficient protocols (PROTOBUF, JSON, and so on) between services. This split code base has the following characteristics:

    • Each service should run as a small, standalone business module, like the Unix do one thing and does it well
    • Each service should have no impact on other services when automating Test and (distributed) deployment
    • Detailed error checking and handling within each service for improved robustness

Comparison

Essentially, they are just different ways of aggregating and splitting code.

Reference: Advantages and disadvantages of micro-service architecture

Building MicroServices

Userinfoservice Micro-Service

Next, create a micro-service that handles user information: Userinfoservice, the client queries the server by name for details about the user's age, position, and so on, first install the GRPC and Protoc compilers:

go get -u google.golang.org/grpcgo get -u github.com/golang/protobuf/protoc-gen-go

Directory structure

├── proto│   ├── user.proto        // 定义客户端请求、服务端响应的数据格式│   └── user.pb.go        // protoc 为 gRPC 生成的读写数据的函数├── server.go            // 实现微服务的服务端└── client.go            // 调用微服务的客户端

Invoke process

PROTOBUF protocol

Each micro-service has its own independent code base, the communication between each need efficient protocol, to follow a certain data structure to parse and encode the data to be transmitted, in the microservices are often used protobuf to define.

Protobuf (protocal buffers) is a binary data encoding format introduced by Google, which has advantages over XML and JSON text data encoding formats:

Faster read and write, smaller file size

It has no XML tag name or JSON field name, lighter, more reference

Language neutrality

Simply define a copy of the. proto file and compile it with the Protobuf compiler for each language, and the generated file has a function to encode and decode the message.

For JSON

    • In PHP need to use json_encode() and json_decode() to encode and decode, in the Golang need to use the JSON standard library Marshal() and Unmarshal() ... Every parsing and coding is tedious
    • Advantages: Good readability, low development cost
    • Cons: Slower read and write speeds than protobuf, more storage space

For Protobuf

    • . Proto can generate the. php or *.pb.go ... The compiler-generated encoding, decoding functions in the file can be directly referenced in the project
    • Advantages: High efficiency, light weight, one place to define multiple uses
    • Cons: Poor readability, high development costs

Define User.proto files for microservices

syntax = "proto3";    // 指定语法格式,注意 proto3 不再支持 proto2 的 required 和 optionalpackage proto;        // 指定生成的 user.pb.go 的包名,防止命名冲突// service 定义开放调用的服务,即 UserInfoService 微服务service UserInfoService {    // rpc 定义服务内的 GetUserInfo 远程调用    rpc GetUserInfo (UserRequest) returns (UserResponse) {    }}// message 对应生成代码的 struct// 定义客户端请求的数据格式message UserRequest {    // [修饰符] 类型 字段名 = 标识符;    string name = 1;}// 定义服务端响应的数据格式message UserResponse {    int32 id = 1;    string name = 2;    int32 age = 3;    repeated string title = 4;    // repeated 修饰符表示字段是可变数组,即 slice 类型}

Compiling the User.proto file

# protoc 编译器的 grpc 插件会处理 service 字段定义的 UserInfoService# 使 service 能编码、解码 message$ protoc -I . --go_out=plugins=grpc:. ./user.proto

Generate User.pb.go

Package Protoimport (context "Golang.org/x/net/context" Grpc "GOOGLE.GOLANG.ORG/GRPC")//Request structure type Userrequest Struc t {Name string ' protobuf: ' Bytes,1,opt,name=name ' json: ' Name,omitempty '}//automatically generated for field Getterfunc (M *userrequest) Getnam E () string {if M! = Nil {return m.name} return ""}//response struct type userresponse struct {Id int32 ' Protobuf: "Varint,1,opt,name=id" JSON: "Id,omitempty" ' Name string ' protobuf: "Bytes,2,opt,name=name" JSON: "Name,omite Mpty "' Age Int32 ' Protobuf:" Varint,3,opt,name=age "JSON:" Age,omitempty "' Title []string ' protobuf: ' Bytes,4,rep, Name=title "JSON:" Title,omitempty "'}//...//the interface to be implemented by the client type Userinfoserviceclient interface {GetUserInfo (CTX context. Context, in *userrequest, opts ... grpc. Calloption) (*userresponse, error)}//the interface to be implemented by the server type Userinfoserviceserver interface {getuserinfo (context. Context, *userrequest) (*userresponse, error)}//registers the microservices with GRPC func registeruserinfoserviceserver (S *grpc. Server, SRV UserinFoserviceserver) {S.registerservice (&_userinfoservice_servicedesc, SRV)}//processing request Func _userinfoservice_ Getuserinfo_handler (SRV interface{}, CTX context. Context, Dec func (interface{}) error, Interceptor Grpc. Unaryserverinterceptor) (interface{}, error) {...}

Service-side implementation of micro-services

Implementation process

Code reference

package mainimport (...)// 定义服务端实现约定的接口type UserInfoService struct{}var u = UserInfoService{}// 实现 interfacefunc (s *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserRequest) (resp *pb.UserResponse, err error) {    name := req.Name    // 模拟在数据库中查找用户信息    // ...    if name == "wuYin" {        resp = &pb.UserResponse{            Id:    233,            Name:  name,            Age:   20,            Title: []string{"Gopher", "PHPer"}, // repeated 字段是 slice 类型        }    }    err = nil    return}func main() {    port := ":2333"    l, err := net.Listen("tcp", port)    if err != nil {        log.Fatalf("listen error: %v\n", err)    }    fmt.Printf("listen %s\n", port)    s := grpc.NewServer()    // 将 UserInfoService 注册到 gRPC    // 注意第二个参数 UserInfoServiceServer 是接口类型的变量    // 需要取地址传参    pb.RegisterUserInfoServiceServer(s, &u)    s.Serve(l)}

Run monitoring:

Client Calls

Implementation process

Code reference

package mainimport (...)func main() {    conn, err := grpc.Dial(":2333", grpc.WithInsecure())    if err != nil {        log.Fatalf("dial error: %v\n", err)    }    defer conn.Close()    // 实例化 UserInfoService 微服务的客户端    client := pb.NewUserInfoServiceClient(conn)    // 调用服务    req := new(pb.UserRequest)    req.Name = "wuYin"    resp, err := client.GetUserInfo(context.Background(), req)    if err != nil {        log.Fatalf("resp error: %v\n", err)    }    fmt.Printf("Recevied: %v\n", resp)}

Run Call succeeded:

Summarize

In the implementation of the above Userinfoservice micro-service, it will be found that each micro-service needs to manage the service-side monitoring port, after the client connection call, when there are many microservices when the management of the port is more troublesome, compared to grpc,go-micro implementation of service discovery Discovery) to facilitate the management of microservices, the next section will be learned along with the Docker of the service.

For more information: Nginx Micro-Service Series Tutorials

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.