Go microservices framework Go-micro deep Learning (ii) Introductory example

Source: Internet
Author: User
Tags instance method etcd

The previous post briefly introduced Go-micro's overall frame structure, this one mainly writes Go-micro uses the way the example, the middle will be interspersed some go-micro the source code, and calls the flowchart, helps everybody better understanding Go-micro's bottom. More detailed and more specific call process and details will be explained in detail in a future post.

Example of GitHub address: GOMICRORPC run through the example, you will understand a probable.

Environment required for installation

Go-micro Service discovery is using Consul by default,

-dev

Or use Docker to run directly

8300:83008301:83018301:83018302:8302 8302:83028400:84008500:850053 /UDP Consul

I personally prefer etcdv3 reasons I have also mentioned in the last article, Gomicro Service found not support consul cluster, I have also written etcdv3 cluster building and use of posts, there is time for everyone to look at

Installing the GO-MICRO Framework

Get Github.com/micro/go-micro

Basic knowledge of installing protobuf and relying on prtobuf I'm not going to talk about it here, if you don't know, you can look at the official document, a cross-platform, cross-language data serialization library, easy to learn.

is Go-micro used to help us build the service interface and a series of calling code

get -u-v github.com/golang/protobuf/{proto,protoc-gen-get -u-v github.com/micro/ Protoc-gen-micro

Protobuf can also be installed directly from the source code

wget https://GITHUB.COM/PROTOCOLBUFFERS/PROTOBUF/RELEASES/DOWNLOAD/V3.6.1/ protobuf-all-3.6.1.tar.gztar zxvf protobuf-all-3.6. 1 . TAR.GZCD protobuf-3.6. 1/. /autogen.sh. /H

 

Install the micro kit, this installation is optional, Micro provides a series of tools to help us better use Go-micro.

Get Github.com/micro/micro

Example 1

Create the proto file Common.proto, which contains the parameters that are passed in and returned, with parameters that contain commonly used base types, arrays, maps, and so on. There is also a say service that has an RPC method in it.

Syntax ="Proto3";p ackage model;message sayparam {stringmsg =1;} Message Pair {Int32 key=1; stringValues =2;} Message Sayresponse {stringmsg =1; //ArrayRepeatedstringValues =2; //Mapmap<string, pair> Header =3; Resptype type=4;}enumResptype {NONE=0; ASCEND=1; Descend=2;}//Service Interfaceservice Say {RPC Hello (sayparam) returns (Sayresponse) {}}

Run in the root directory, generate two template files

  Protoc--proto_path= $GOPATH/src:. --micro_out=. --go_out=. Example1/proto/*

A file is a go structure file for Proto, and an interface file for Go-micro RPC.

Server side:

Type Saystruct{}func (s*say) Hello (CTX context. Context, req *model. Sayparam, RSP *model. Sayresponse) Error {FMT. Println ("received", req. MSG) RSP. Header= Make (map[string]*model. Pair) RSP. header["name"] = &model. Pair{key:1, Values:"ABC"} RSP. MSG="Hello World"RSP. Values= Append (RSP). Values,"a","b") RSP. Type=model. Resptype_descendreturnNil}func Main () {//I use the ETCD as a service found, if the use of consul can be removedReg: = Etcdv3. Newregistry (Func (OP *Registry. Options) {op. Addrs= []string{            "http://192.168.3.34:2379","http://192.168.3.18:2379","http://192.168.3.110:2379",        }    }) //Initializing the serviceService: =Micro. NewService (micro. Name ("LP.SRV.EG1"), Micro. Registry (REG),)//Register HandlerModel. Registersayhandler (service. Server (),New(Say))//Run Server    ifERR: = Service. Run (); Err! =Nil {panic (err)}}

Service discovery I was using ETCDV3 to replace the default consul

Micro. NewService initializes the service and then returns an instance of a service interface, the approximate flow of the NewService () method is as follows,

The default value is initialized for each interface, and the default value is replaced with the value passed in, which is where the go-micro replaceable plug-in.

The service has an init () optional method, which is a single-instance method,

Func (S *service) Init (opts ... Option) {    //  process options     for _, O: = range opts {        O (&  s.opts)    }    s.once.do (func () {        //  Save user Action        action: =  S.opts.cmd.app (). Action        //  set service action        S.opts.cmd.app (). Action = Func (c *CLI. Context) {                ... .. // This is not going to show the code.                 .........        }}

In the official case, it is not necessary to show the call, because the Init method is called when the default value is replaced

such as micro. Name () method, the Init () method has been called

// Name of the service string Option {    return func (o *Options) {        o.server.init (Server). Name (n))    }}

Service. Run () method invocation Process

Because the port is not specified at initialization time, the system automatically assigns a port number to the server and registers the server information with the register.

Beferstart and Afterstart can also be customized.

Client side:

Func Main () {//I use the ETCD as a service found, if the use of consul can be removedReg: = Etcdv3. Newregistry (Func (OP *Registry. Options) {op. Addrs= []string{            "http://192.168.3.34:2379","http://192.168.3.18:2379","http://192.168.3.110:2379",        }    }) //Initializing the serviceService: =Micro. NewService (micro. Registry (REG),) Sayclent:= Model. Newsayservice ("LP.SRV.EG1", service. Client ()) RSP, err:= Sayclent.hello (context. Background (), &model. Sayparam{msg:"Hello server"})    ifErr! =Nil {panic (err)} FMT. PRINTLN (RSP)}

Above the two files generated according to the proto file is an RPC interface file, the interface file has helped us to call the method of the entire process encapsulated.

You just need to give the service name and Licent. Then call the Hello method

Source:

Func (c *sayservice) Hello (CTX context. Context,inch*sayparam, opts ... client. Calloption) (*Sayresponse, error) {req:= C.c.newrequest (C.name,"Say.hello",inch)     out:=New(sayresponse) Err:= C.c.call (CTX, req, out, opts ...) ifErr! =Nil {returnnil, err}return  out, nil}

The main process is in the C.c.call method. Simply put, the process is as follows

is to get the node information address, according to the address to inquire whether there is a connection in the pool, if there is to take out, if not then create, and then transfer the data, transfer the client back to the pool. The size of the pool is also controllable, this part of the code is particularly cool to read, specific details and processing process will be detailed in a future post to explain

Example 2

Example 1, do a simple service, can no longer be simple, just to let everyone familiar with the Go-micro. After reading the example 1 should have more ideas, want to use more Go-micro features, such as PROTOBUF generated classes are together, if you want the model and API separate how to deal with, how to use the Go-micro bidirectional flow, how to use the message push, and so on. So I made a small example of this, and this example contains something.

In this example, I'll just say the organizational structure, and there is not much code, we have time to look at the OK.

Proto two folders, a model A rpcapi, is to separate the data and APIs, the API refers to the model

Look at Rpcapi.

" Proto3 "  "github.com/lpxxn/gomicrorpc/example2/proto/model/common.proto"; // Service Interface service Say {    RPC Hello (model. Sayparam) returns (model. Sayresponse) {}    RPC Stream (model. srequest) returns (stream model). sresponse) {}}

Import the Common.proto in the model

At the time of Generation one just go_out another as long as the micro_out is good.

  Protoc--proto_path= $GOPATH/src:. --go_out=. Example2/proto/model/*.     Proto

Subscribe to a message

    // Register subscribers    if err: = Server. Subscribe (server. Newsubscriber (Common. Topic1, subscriber. Handler)); Err! = Nil {        panic (err)    }

When a message is sent, all services that subscribe to the LP.SRV.EG2.TOPIC1 message receive a message

Client sends information

    P: = micro. Newpublisher (Common. Topic1, service. Client ())    &model. Sayparam{msg:lib. Randomstr (lib. Random (3))})

If the production environment must not use Go-micro default information publishing and subscription processing, micro plug-in plugin is a lot of mature plug-ins.

Small function with bidirectional flow

This method only sends some data to the client at a time, sending only a portion at a time. For example, we give the client push the data is very large, one-time all pushed past, is not very correct practice, partial push back is better.

Func (S *say) Stream (CTX context. Context, req *model. Srequest, Stream Rpcapi. Say_streamstream) Error { forI: =0; I <int(req. Count); i++{rsp:= &model. sresponse{} forJ: = Lib. Random (3,5); J <Ten; J + +{rsp. Value= Append (RSP). Value, Lib. Randomstr (lib. Random (3,Ten)))        }        ifERR: = stream. Send (RSP); Err! =Nil {returnErr}//Simulation ProcessTime. Sleep (time. Microsecond * -)    }    returnNilreturnNil}

Hopefully this small example will get you started Go-micro.

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.