Today we are going to do a fun Go practice. Start seven different Go Web frameworks simultaneously in one process, using the same set of code.
Why do such boring things?
The main purpose is to introduce the rookie Ninja/RK-boot library.
Which Go Web frameworks start?
We launched the following Go Web frameworks at the same time.
Web framework | Fairly rk – the boot | version |
---|---|---|
gin-gonic/gin | go get github.com/rookie-ninja/rk-boot/gin | V1.2.14 (Stable) |
gRPC | go get github.com/rookie-ninja/rk-boot/grpc | V1.2.18 (Stable) |
labstack/echo | go get github.com/rookie-ninja/rk-boot/echo | V0.0.8 (Stable) |
gogf/gf | go get github.com/rookie-ninja/rk-boot/gf | V0.0.6 (Stable) |
gofiber/fiber | go get github.com/rookie-ninja/rk-boot/fiber | V0.0.4 (Testing) |
zeromicro/go-zero | go get github.com/rookie-ninja/rk-boot/zero | V0.0.2 (Testing) |
gorilla/mux | go get github.com/rookie-ninja/rk-boot/mux | V0.0.2 (Testing) |
Quick start
1. Install
We installed the following dependencies with Go Get.
go get github.com/rookie-ninja/rk-boot/grpc
go get github.com/rookie-ninja/rk-boot/gin
go get github.com/rookie-ninja/rk-boot/echo
go get github.com/rookie-ninja/rk-boot/gf
go get github.com/rookie-ninja/rk-boot/fiber
go get github.com/rookie-ninja/rk-boot/zero
go get github.com/rookie-ninja/rk-boot/mux
Copy the code
2. Create the boot. Yaml
Web framework | port |
---|---|
gRPC | 8081 |
gin-gonic/gin | 8082 |
labstack/echo | 8083 |
gogf/gf | 8084 |
gofiber/fiber | 8085 |
zeromicro/go-zero | 8086 |
gorilla/mux | 8087 |
In addition to specifying the port, we have enabled the following two options:
- CommonService: Provides common apis such as/RK /v1/ HEALTHY.
- LoggingZap: RPC log
---
grpc:
- name: grpc
port: 8081
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
gin:
- name: gin
port: 8082
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
echo:
- name: echo
port: 8083
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
gf:
- name: gf
port: 8084
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
fiber:
- name: fiber
port: 8085
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
zero:
- name: zero
port: 8086
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
mux:
- name: mux
port: 8087
enabled: true
commonService:
enabled: true # Optional, default: false
interceptors:
loggingZap:
enabled: true # Optional, default: false
Copy the code
3. Create a main. Go
All Web frameworks use the handleRequest() function to handle requests.
With the exception of gRPC, we did not use the protocol buffer, because PB has a different protocol. We use grPC-Gateway to simulate.
GrpcEntry default grpc-gateway, grpcentry. HttpMux to grpc-gateway API registration.
// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gofiber/adaptor/v2"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/labstack/echo/v4"
"github.com/rookie-ninja/rk-boot"
"github.com/rookie-ninja/rk-boot/echo"
"github.com/rookie-ninja/rk-boot/fiber"
"github.com/rookie-ninja/rk-boot/gf"
"github.com/rookie-ninja/rk-boot/gin"
"github.com/rookie-ninja/rk-boot/grpc"
"github.com/rookie-ninja/rk-boot/mux"
"github.com/rookie-ninja/rk-boot/zero"
"github.com/tal-tech/go-zero/rest"
"net/http"
)
const handlePath = "/v1/hello"
// Application entrance.
func main(a) {
// Create a new boot instance.
boot := rkboot.NewBoot()
// 6: go-zero @8086, must adds route before bootstrap
rkbootzero.GetZeroEntry("zero").Server.AddRoute(rest.Route{
Method: http.MethodGet,
Path: handlePath,
Handler: handleRequest,
})
// Bootstrap
boot.Bootstrap(context.Background())
// 1: grpc-gateway @8081
rkbootgrpc.GetGrpcEntry("grpc").HttpMux.HandleFunc(handlePath, handleRequest)
// 2: gin @8082
rkbootgin.GetGinEntry("gin").Router.Handle(http.MethodGet, handlePath, gin.WrapF(handleRequest))
// 3: echo @8083
rkbootecho.GetEchoEntry("echo").Echo.GET(handlePath, echo.WrapHandler(http.HandlerFunc(handleRequest)))
// 4: GoFrame @8084
rkbootgf.GetGfEntry("gf").Server.BindHandler(handlePath, ghttp.WrapF(handleRequest))
// 5: Fiber @8085, must call RefreshFiberRoutes()
rkbootfiber.GetFiberEntry("fiber").App.Get(handlePath, adaptor.HTTPHandler(http.HandlerFunc(handleRequest)))
rkbootfiber.GetFiberEntry("fiber").RefreshFiberRoutes()
// 7: mux @8087
rkbootmux.GetMuxEntry("mux").Router.HandleFunc(handlePath, handleRequest)
// Wait for shutdown sig
boot.WaitForShutdownSig(context.Background())
}
// Handle request for all web frameworks
func handleRequest(writer http.ResponseWriter, req *http.Request) {
// 1: get query
name := req.URL.Query().Get("name")
// 2: marshal response
bytes, _ := json.Marshal(&Response{
Message: fmt.Sprintf("Hello %s", name),
})
// 3: write response
writer.WriteHeader(http.StatusOK)
writer.Write(bytes)
}
type Response struct {
Message string `json:"message"`
}
Copy the code
4. Folder structure & go.mod
- Folder structure
.├ ── Go.tempo ├── go.tempo ├─ main. Go 0 directories, 4 filesCopy the code
- Go. The mod file
1.16 the require module github.com/rookie-ninja/rk-demo go (github.com/gin-gonic/gin v1.7.7 github.com/gofiber/adaptor/v2 V2.1.15 github.com/gogf/gf/v2 v2.0.0 - beta github.com/labstack/echo/v4 v4.6.1 github.com/rookie-ninja/rk-boot v1.4.0 Github.com/rookie-ninja/rk-boot/echo v0.0.8 github.com/rookie-ninja/rk-boot/fiber v0.0.4 Github.com/rookie-ninja/rk-boot/gf v0.0.6 github.com/rookie-ninja/rk-boot/gin v1.2.14 Github.com/rookie-ninja/rk-boot/grpc v1.2.18 github.com/rookie-ninja/rk-boot/mux v0.0.2 github.com/rookie-ninja/rk-boot/zero v0.0.2 github.com/tal-tech/go-zero v1.2.4)Copy the code
5. Start the main. Go
$go run main.go 2022-01-03T19:15:14.016+0800 INFO boot/gf_entry.go:1050 Bootstrap gfEntry {"eventId": "264033ff-be9c-4147-871c-e4873ea1510d", "entryName": "Gf"} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: mind. 016473 + 08:00 StartTime = 2022-01-03 T19: now. 016057 + 08:00 elapsedNano = 416178 timezone = CST ids={"eventId":"264033ff-be9c-4147-871c-e4873ea1510d"} app={"appName":"rk","appVersion":"","entryName":"gf","entryType":"GfEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":"*"} payloads={"commonServiceEnabled":true,"commonServicePathPrefix":"/rk/v1/","gfPort":8084} error={} counters={} pairs={} timing={} remoteAddr=localhost operation=Bootstrap resCode=OK eventStatus=Ended EOE ...Copy the code
Call /rk/v1/healthy to determine if the service is started.
$ curl localhost:8081/rk/v1/healthy
{"healthy":true}
$ curl localhost:8082/rk/v1/healthy
{"healthy":true}
$ curl localhost:8083/rk/v1/healthy
{"healthy":true}
$ curl localhost:8084/rk/v1/healthy
{"healthy":true}
$ curl localhost:8085/rk/v1/healthy
{"healthy":true}
$ curl localhost:8086/rk/v1/healthy
{"healthy":true}
$ curl localhost:8087/rk/v1/healthy
{"healthy":true}
Copy the code
6. Verify
We will send /v1/hello requests to each port and look at the RPC logs.
- grpc-gateway@8081 (GRpc-gateway currently generates no RPC logs.)
$ curl "localhost:8081/v1/hello? name=rk-dev" {"message":"Hello rk-dev"}Copy the code
- gin@8082
$ curl "localhost:8082/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: sons. 23983 + 08:00 StartTime = 2022-01-03 T19: the sons. 239805 + 08:00 elapsedNano = 25460 timezone = CST ids={"eventId":"0d284016-f714-4c85-8af8-9715dc9ed35f"} app={"appName":"rk","appVersion":"","entryName":"gin","entryType":"GinEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP / 1.1", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7. 64.1"} error={} counters={} pairs={} timing={} remoteAddr=localhost:54102 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
- echo@8083
$ curl "localhost:8082/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19:19:11. 109838 + 08:00 StartTime = 2022-01-03 T19:19:11. 109817 + 08:00 elapsedNano = 21242 timezone = CST ids={"eventId":"34419c7c-1a78-484f-ba7a-bfca69178b82"} app={"appName":"rk","appVersion":"","entryName":"echo","entryType":"EchoEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP / 1.1", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7. 64.1"} error={} counters={} pairs={} timing={} remoteAddr=localhost:56995 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
- gf@8084
$ curl "localhost:8084/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: this was. 905883 + 08:00 StartTime = 2022-01-03 T19: this was. 905858 + 08:00 elapsedNano = 24703 timezone = CST ids={"eventId":"58bf8706-09ff-434e-b405-d6cdb8dbe8c2"} app={"appName":"rk","appVersion":"","entryName":"gf","entryType":"GfEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP / 1.1", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7. 64.1"} error={} counters={} pairs={} timing={} remoteAddr=localhost:58802 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
- fiber@8085
$ curl "localhost:8085/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: all the 834567 + 08:00 StartTime = 2022-01-03 T19: all the 834425 + 08:00 elapsedNano = 142332 timezone = CST ids={"eventId":"a98a6e9f-6519-4ded-971e-0b6e59f66096"} app={"appName":"rk","appVersion":"","entryName":"fiber","entryType":"FiberEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7.64.1 "} error={} counters={} pairs={} timing={} remoteAddr=127.0.0.1:63237 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
- zero@8086
$ curl "localhost:8086/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: mark. 835415 + 08:00 StartTime = 2022-01-03 T19: mark. 835391 + 08:00 elapsedNano = 24495 timezone = CST ids={"eventId":"a6a53d21-4cf4-4b45-97ca-2b190e438e9c","traceId":"bf7a2359d0813de4388dd11c4f161321"} app={"appName":"rk","appVersion":"","entryName":"zero","entryType":"ZeroEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP / 1.1", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7. 64.1"} error={} counters={} pairs={} timing={} remoteAddr=localhost:65299 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
- mux@8087
$ curl "localhost:8086/v1/hello? name=rk-dev" {"message":"Hello rk-dev"} # RPC log from server side -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- endTime = 2022-01-03 T19: then. 13191 + 08:00 StartTime = 2022-01-03 T19: then. 131889 + 08:00 elapsedNano = 21449 timezone = CST ids={"eventId":"8a0f2db6-8e13-4773-bedd-962060adbe41"} app={"appName":"rk","appVersion":"","entryName":"mux","entryType":"MuxEntry"} Env = {" arch ", "amd64", "az" : "*", "domain" : "*", "hostname" : "lark. Local", "localIP" : "10.8.0.2", "OS" : "Darwin", "realm" : "*", "region ":" * "} Payloads = {" apiMethod ":" GET ", "apiPath" : "/ v1 / hello," "apiProtocol" : "HTTP / 1.1", "apiQuery" : "name = fairly rk - dev", "userAgent" : "curl / 7. 64.1"} error={} counters={} pairs={} timing={} remoteAddr=127.0.0.1:52277 operation=/v1/hello resCode=200 eventStatus=Ended EOECopy the code
Fairly rk – the boot is introduced
Rk-boot is a framework for starting a variety of Web services through YAML. It’s kind of like Spring Boot. By integrating the RK-XXX family of libraries, you can launch a variety of Web frameworks. Of course, users can also customize the RK-XXX library to integrate into the RK-boot.
Fairly rk – highlight the boot
- Start different Web frameworks with YAML files in the same format.
- Even with different frameworks, the format of logging, Metrics, Tracing, etc
- Users can customize YAML files by implementing rkentry.entry.
Web framework supported by RK-boot
Welcome to contribute the new Web framework to the RK-Boot series.
referencedocs & rk-ginAs an example.
The framework | The development status | The installation | Rely on |
---|---|---|---|
Gin | Stable | go get github.com/rookie-ninja/rk-boot/gin | rk-gin |
gRPC | Stable | go get github.com/rookie-ninja/rk-boot/grpc | rk-grpc |
Echo | Stable | go get github.com/rookie-ninja/rk-boot/echo | rk-echo |
GoFrame | Stable | go get github.com/rookie-ninja/rk-boot/gf | rk-gf |
Fiber | Testing | go get github.com/rookie-ninja/rk-boot/fiber | rk-fiber |
go-zero | Testing | go get github.com/rookie-ninja/rk-boot/zero | rk-zero |
GorillaMux | Testing | go get github.com/rookie-ninja/rk-boot/mux | rk-mux |