共计 3237 个字符,预计需要花费 9 分钟才能阅读完成。
go-moda
- golang 通用的 grpc http 根底开发框架
- 仓库地址: [https://github.com/webws/go-moda](https://github.com/webws/go-moda
- 仓库始终在更新, 欢送大家吐槽和指导
个性
- transport: 集成 http(echo、gin)和 grpc。
- tracing: openTelemetry 实现微务链路追踪
- pprof: 剖析性能
- config: 通用的配置文件读取模块,反对 toml、yaml 和 json 格局。
-
logger: 日志零碎模块,基于 Zap, 并反对全局日志和模块日志。
疾速应用
conf.toml
http_addr = ":8081" grpc_addr = ":8082" 启用 http(gin) 和 grpc 服务
package main | |
import ( | |
"context" | |
"net/http" | |
"github.com/gin-gonic/gin" | |
app "github.com/webws/go-moda" | |
"github.com/webws/go-moda/config" | |
pbexample "github.com/webws/go-moda/example/pb/example" | |
"github.com/webws/go-moda/logger" | |
modagrpc "github.com/webws/go-moda/transport/grpc" | |
modahttp "github.com/webws/go-moda/transport/http" | |
) | |
var ServerName string | |
type Config struct { | |
HttpAddr string `json:"http_addr" toml:"http_addr"` | |
GrpcAddr string `json:"grpc_addr" toml:"grpc_addr"` | |
} | |
func main() {conf := &Config{} | |
if err := config.NewConfigWithFile("./conf.toml").Load(conf); err != nil {logger.Fatalw("NewConfigWithFile fail", "err", err) | |
} | |
// http server | |
gin, httpSrv := modahttp.NewGinHttpServer(modahttp.WithAddress(conf.HttpAddr), | |
) | |
registerHttp(gin) | |
// grpc server | |
grpcSrv := modagrpc.NewServer(modagrpc.WithServerAddress(conf.GrpcAddr), | |
) | |
grecExample := &ExampleServer{} | |
pbexample.RegisterExampleServiceServer(grpcSrv, grecExample) | |
// app run | |
a := app.New(app.Server(httpSrv, grpcSrv), | |
app.Name(ServerName), | |
) | |
if err := a.Run(); err != nil {logger.Fatalw("app run error", "err", err) | |
} | |
} | |
func registerHttp(g *gin.Engine) {g.GET("/helloworld", func(c *gin.Context) {logger.Debugw("Hello World") | |
c.JSON(http.StatusOK, http.StatusText(http.StatusOK)) | |
}) | |
} | |
type ExampleServer struct {pbexample.UnimplementedExampleServiceServer} | |
func (s *ExampleServer) SayHello(ctx context.Context, req *pbexample.HelloRequest) (*pbexample.HelloResponse, error) {return &pbexample.HelloResponse{Message: "Hello" + req.Name}, nil | |
} |
运行
go run ./ -c ./conf.toml | |
`````` | |
* 申请 http url http://localhost:8081/helloworld | |
* grpc 服务 应用 gRPC 客户端调用 SayHello 办法 | |
其余服务启用示例 | |
1. echo http :[example_echo](https://github.com/webws/go-moda/tree/main/example/echohttp) | |
2. net http :[example_echo](https://github.com/webws/go-moda/blob/main/example/nethttp) | |
3. grpc [example_grpc](https://github.com/webws/go-moda/tree/main/example/grpc) | |
## pprof 性能剖析 | |
启动服务默认开启 pprof 性能剖析,浏览器关上 http://localhost:8081/debug/ 查看 | |
 | |
可视化剖析 gouroutine |
go tool pprof http://localhost:8081/debug/pprof/goroutine
(pprof) web
可能提醒 须要先装置 graphviz, mac 下能够应用 brew 装置
brew install graphviz
 | |
## tracing 链路追踪 | |
* 应用 opentelemetry 实现微服务链路追踪,目前 exporter 反对 jaeger | |
* 示例集成了 docker 环境, 反对 make deploy 同时启动 jaeger,api1,api2,api3,grpc 服务 | |
* 具体示例请看:[tracing_example](https://github.com/webws/go-moda/tree/main/example/tracing/moda_tracing) | |
1. 初始化 jaeger tracing |
import “github.com/webws/go-moda/tracing”
func main(){
//... | |
shutdown, err := tracing.InitJaegerProvider(conf.JaegerUrl, "grpc-server") | |
if err != nil {panic(err) | |
} | |
defer shutdown(context.Background()) | |
//... |
}
2. 在代码被动 tracing start
ctx, span := tracing.Start(c.Request().Context(), “api1”)
defer span.End()
3. 服务之间调用 产生的链路 | |
* server 端: 减少 WithTracing 即可 |
//... | |
gin, httpSrv := modahttp.NewGinHttpServer(modahttp.WithAddress(conf.HttpAddr), | |
modahttp.WithTracing(true), | |
) |
* client 端: 封装了 CallAPI 办法, 已将 span ctx 信息注入到申请头
// ... | |
_, err := modahttp.CallAPI(ctx, url, "POST", nil) |
正文完