Rapid development of microservices
#
0. Why building microservices are so difficultTo build a well working microservice, we need lots of knowledges from different aspects.
basic functionalities
- concurrency control and rate limit, to avoid being brought down by unexpected inbound
- service discovery, make sure new or terminated nodes are detected asap
- load balancing, balance the traffic base on the throughput of nodes
- timeout control, avoid the nodes continue to process the timed out requests
- circuit breaker, load shedding, fail fast, protects the failure nodes to recover asap
advanced functionalities
- authorization, make sure users can only access their own data
- tracing, to understand the whole system and locate the specific problem quickly
- logging, collects data and helps to backtrace problems
- observability, no metrics, no optimization
For any point listed above, we need a long article to describe the theory and the implementation. But for us, the developers, it’s very difficult to understand all the concepts and make it happen in our systems. Although, we can use the frameworks that have been well served busy sites. go-zero is born for this purpose, especially for cloud-native microservice systems.
As well, we always adhere to the idea that prefer tools over conventions and documents. We hope to reduce the boilerplate code as much as possible, and let developers focus on developing the business related code. For this purpose, we developed the tool goctl
.
Let’s take the shorturl microservice as a quick example to demonstrate how to quickly create microservices by using go-zero. After finishing this tutorial, you’ll find that it’s so easy to write microservices!
#
1. What is a shorturl serviceA shorturl service is that it converts a long url into a short one, by well designed algorithms.
Writting this shorturl service is to demonstrate the complete flow of creating a microservice by using go-zero. But algorithms and detail implementations are quite simplified, and this shorturl service is not suitable for production use.
#
2. Architecture of shorturl microservice
- In this tutorial, I only use one rpc service, transform, to demonstrate. It’s not telling that one API Gateway only can call one RPC service, it’s only for simplicity here.
- In production, we should try best to isolate the data belongs to services, that means each service should only use its own database.
#
3. goctl generated code overviewAll modules with green background are generated, and will be enabled when necessary. The modules with red background are handwritten code, which is typically business logic code.
API Gateway
RPC
model
And now, let’s walk through the complete flow of quickly create a microservice with go-zero.
#
4. Get startedinstall etcd, mysql, redis
install protoc-gen-go
install goctl
create the working dir
shorturl
andshorturl/api
in
shorturl
dir, executego mod init shorturl
to initializego.mod
#
5. Write code for API Gatewayuse goctl to generate
api/shorturl.api
for simplicity, the leading
info
block is removed, and the code looks like:the usage of
type
keyword is the same as that in go, service is used to define get/post/head/delete api requests, described below:service shorturl-api {
defines the service name@server
defines the properties that used in server sidehandler
defines the handler nameget /shorten(shortenReq) returns(shortenResp)
defines this is a GET request, the request parameters, and the response parameters
generate the code for API Gateway by using goctl
the generated file structure looks like:
start API Gateway service, listens on port 8888 by default
test API Gateway service
response like:
You can see that the API Gateway service did nothing except returned a zero value. And let’s implement the business logic in rpc service.
you can modify
internal/svc/servicecontext.go
to pass dependencies if neededimplement logic in package
internal/logic
you can use goctl to generate code for clients base on the .api file
till now, the client engineer can work with the api, don’t need to wait for the implementation of server side
#
6. Write code for transform rpc service- under directory
shorturl
create dirrpc
under directory
rpc/transform
createtransform.proto
fileedit the file and make the code looks like:
use goctl to generate the rpc code, execute the following command in
rpc/transofrm
the generated file structure looks like:
just run it, looks like:
you can change the listening port in file
etc/transform.yaml
.
#
7. Modify API Gateway to call transform rpc servicemodify the configuration file
shorturl-api.yaml
, add the following:automatically discover the transform service by using etcd.
modify the file
internal/config/config.go
, add dependency on transform service:modify the file
internal/svc/servicecontext.go
, like below:passing the dependencies among services within ServiceContext.
modify the method
Expand
in the fileinternal/logic/expandlogic.go
, looks like:by calling the method
Expand
oftransformer
to restore the shortened url.modify the file
internal/logic/shortenlogic.go
, looks like:by calling the method
Shorten
oftransformer
to shorten the url.
Till now, we’ve done the modification of API Gateway. All the manually added code are marked.
#
8. Define the database schema, generate the code for CRUD+cacheunder shorturl, create the directory
rpc/transform/model
:mkdir -p rpc/transform/model
under the directory rpc/transform/model create the file called shorturl.sql`, contents as below:
create DB and table
under the directory
rpc/transform/model
execute the following command to genrate CRUD+cache code,-c
means usingredis cache
you can also generate the code from the database url by using
datasource
subcommand instead ofddl
the generated file structure looks like:
#
9. Modify shorten/expand rpc to call crud+cachemodify
rpc/transform/etc/transform.yaml
, add the following:you can use multiple redis as cache. redis node and cluster are both supported.
modify
rpc/transform/internal/config.go
, like below:added the configuration for mysql and redis cache.
modify
rpc/transform/internal/svc/servicecontext.go
, like below:modify
rpc/transform/internal/logic/expandlogic.go
, like below:modify
rpc/shorten/internal/logic/shortenlogic.go
, looks like:till now, we finished modifing the code, all the modified code is marked.
#
10. Call shorten and expand servicescall shorten api
response like:
call expand api
response like:
#
11. BenchmarkBecause benchmarking the write requests depends on the write throughput of mysql, we only benchmarked the expand api. We read the data from mysql and cache it in redis. I chose 100 hot keys hardcoded in shorten.lua to generate the benchmark.
as shown above, in my MacBook Pro, the QPS is like 30K+.
#
12. Full codehttps://github.com/zeromicro/zero-examples/tree/main/shorturl
#
13. ConclusionWe always adhere to prefer tools over conventions and documents.
go-zero is not only a framework, but also a tool to simplify and standardize the building of micoservice systems.
We not only keep the framework simple, but also encapsulate the complexity into the framework. And the developers are free from building the difficult and boilerplate code. Then we get the rapid development and less failure.
For the generated code by goctl, lots of microservice components are included, like concurrency control, adaptive circuit breaker, adaptive load shedding, auto cache control etc. And it’s easy to deal with the busy sites.
If you have any ideas that can help us to improve the productivity, tell me any time! 👏