Write a Microservice via Go-Micro

i’ve learning Go-Micro approximate a month, that i wanna write an article to record what i learned, in case i forgot it, i still can pick up it it by this article, what i wrote about might be inaccurate, i’m very glad that you can correct it.

Architecture

Write a Microservice via Go-Micro - 1

my design about Microservices architecture

what is go-micro

Go-Micro is a pluggable GRPC frameworks, for building Microservices it’s wisely choice, because it’s really easy to working with it, also you can pick up others, but this time i choice Go-Micro to write demonstration code.

how to writing a microservice

project structure

write a simple GRPC service

to write a grpc service with Go-Micro, start with proto file, you should design what interface / datastruct this service provides

in this case i wrote a service named basis, and provide Hello function, and also defined two data structure Request && Response

next, generate Go Code with protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. basis.proto.

now, we can write a service with those Go Code

download consul, run it with ./consul agent -dev, and run your srv with go run main.go, also you can add --registry_address=host:port to specify registry addres and port

write a GRPC client

now to communicate with basis Srv, we need a client, below you can see my code

now run it with go run main.go, also you can add --registry_address=host:port too

add roundrobin plugin into GRPC client

i said Go-Micro is a pluggable before, and roundrobin is a features in Go-Plugins, so you can easyly add it into your client, before we do it, for make sure roundrobin works, add some log into your Srv process function

  1. Srv

  1. Client

then run another srv, then run ./consul monitor, it will show services reigster logs in your cli, below you can see two Srv reigsted in my consul, got different uuid means they are listenning different service port

now execute your client twice, i can sure you both Srv will print Yoooo! i received it in your command line

add ratelimiter / circuitbreaker into GRPC client

before we start write code, i want to talk about what exactly Ratelimter and Circuitbreaker is in Microservices

  • Ratelimiter

Ratelimiter is used to limit the speed of request number increase, to make sure Srv can handler specify number of requests, and slow down the new requests come in speed.

about principle you can take a look here Token bucket && leaky bucket

  • Circuitbreaker

circuit breaker is use to blocking request when Srv is overload or unavailable, circuit breaker got a counter inside, it will record Srv response, after those response over a specific percentage, it will directly return service unavailable message to client, and after a few second, request can access circuit breaker to Srv again, if Srv still not recovering, then do it again until Srv ready to receive request.

now let’s add ratelimiter into our client, for tests we can add time.Sleep into our Srv
* srv

  • client

after this, start your client with go run main.go & make it running on background, after you start over 3 client in background, the first client will return in 1s approximately, but the remaining two clients will take more than time to get the reponse

alright, the next is Circuitbreaker, i’ll use hystrix to achieve Circuitbreaker feature, Go-Micro already packaged hystrix in Go-Plugins, all we have to do is add it into our service’s Init function, set some properties of hystrix or you can use default properties.

still, use go run main.go & run your client twice quickly, the client might return hystrix: timeout, after 2 seconds, run your client again it will truen normal response in one second approximately

tracing your code between Client and Srv

i’m writing demonstration here, but in real project you might have many function calls, some of them are RPC calls, once something wrong, you might hard to deal with it, because in Microservice architecture every service are individual part, code tracing helps to pinpoint failure occur and find what cause poor performance.

before we writing tracing code, we need a Jaeger to collect all of our tracing infos, run jaeger i recommend you start it with docker

docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 -p 9411:9411 jaegertracing/all-in-one:1.8

port 6831/UDP is used to received tracing data, and 16686 is Jaeger Web UI, all tracer infos will displayed graphically in it.

now we have to write a function to init a Tracer, because Srv and Client both depend it, so i wrote a NewTracer function in this case.

  1. tracer.go

  1. Srv

  1. Client

yep, Your Jaeger , if there’s nothing wrong with your code, you might see the calling function infos in that link.

More Example

now i’m using Go-Micro && Angular writing a social blog system at Gitlab as practice, if you’re interesting at it please click HERE

all of the above code you can find it HERE

Leave a Reply

Your email address will not be published. Required fields are marked *