Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[开源自荐] 一个golang 通用 的http grpc 基础框架 #2603

Closed
webws opened this issue Sep 3, 2023 · 1 comment
Closed

[开源自荐] 一个golang 通用 的http grpc 基础框架 #2603

webws opened this issue Sep 3, 2023 · 1 comment

Comments

@webws
Copy link

webws commented Sep 3, 2023

推荐项目

  • 项目地址:https://github.com/webws/go-moda
  • 项目标题:golang 通用的 grpc http 基础开发框架
  • 项目描述:一个api框架,集成了http grpc服务,可以通过代码 理解框架的 配置加载,日志引入,transport的封装

亮点

  • 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

tracing 链路追踪

  • 使用 opentelemetry 实现微服务链路追踪,目前 exporter 支持 jaeger
  • 示例集成了docker 环境,支持 make deploy 同时启动 jaeger,api1,api2,api3,grpc 服务
  • 详细示例请看:tracing_example
  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())
    //...
}
  1. 在代码主动tracing start
  ctx, span := tracing.Start(c.Request().Context(), "api1")
  defer span.End()
  1. 服务之间调用 产生的链路
  • server端: 增加 WithTracing 即可
    //...
    gin, httpSrv := modahttp.NewGinHttpServer(
		modahttp.WithAddress(conf.HttpAddr),
		modahttp.WithTracing(true),
	)
  • client端: 封装了 CallAPI 方法, 已将span ctx 信息注入到请求头
    // ...
    _, err := modahttp.CallAPI(ctx, url, "POST", nil)

截图

pprof 性能分析

启动服务默认开启 pprof 性能分析,浏览器打开 http://localhost:8081/debug/ 查看

可视化分析 gouroutine

go tool pprof http://localhost:8081/debug/pprof/goroutine
(pprof) web

可能提示 需要先安装 graphviz, mac 下可以使用 brew 安装

brew install graphviz

后续更新计划

  • Metrics 集成及示例
  • 引入新的配置加载源 etcd/nacos
  • 引入slog
@521xueweihan
Copy link
Owner

非常感谢您推荐项目。

该项目暂不能收录到 HelloGitHub 月刊中,HelloGitHub 推荐项目审核标准 #271
期待持续完善该项目,后续推荐更多的项目。

再次感谢您对 HelloGitHub 的支持 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants