• golang 通用的 grpc http 基础开发框架


    go-moda

    特性

    • transport: 集成 http(echo、gin)和 grpc。
    • tracing: openTelemetry 实现微务链路追踪
    • pprof: 分析性能
    • config: 通用的配置文件读取模块,支持 toml、yaml 和 json 格式。
    • logger: 日志系统模块,基于 Zap,并支持全局日志和模块日志。

    快速使用

    conf.toml
    http_addr = ":8081"
    grpc_addr = ":8082"
    
    • 1
    • 2
    启用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
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    运行
    go run ./ -c ./conf.toml
    
    • 1
    • 请求 http url http://localhost:8081/helloworld
    • grpc 服务 使用 gRPC 客户端调用 SayHello 方法

    其他服务启用示例

    1. echo http :example_echo
    2. net http :example_echo
    3. grpc example_grpc

    pprof 性能分析

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

    可视化分析 gouroutine

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

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

    brew install graphviz
    
    • 1

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 在代码主动tracing start
      ctx, span := tracing.Start(c.Request().Context(), "api1")
      defer span.End()
    
    • 1
    • 2
    1. 服务之间调用 产生的链路
    • server端: 增加 WithTracing 即可
        //...
        gin, httpSrv := modahttp.NewGinHttpServer(
    		modahttp.WithAddress(conf.HttpAddr),
    		modahttp.WithTracing(true),
    	)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • client端: 封装了 CallAPI 方法, 已将span ctx 信息注入到请求头
        // ...
        _, err := modahttp.CallAPI(ctx, url, "POST", nil)
    		
    
    • 1
    • 2
    • 3

  • 相关阅读:
    vue中使用rem实现动态改变字体大小
    Python150题day12
    【Vue2.x源码系列02】模版编译(AST、Optimize 、Render)
    webpack5 (三)
    [附源码]java毕业设计旅游景点推荐系统
    导图解文 从梦想到财富(41)比起熬夜加班,创业更需要赢在起点
    mfc140u.dll丢失怎么修复?4种亲测有效的方法分享
    技术分享| 基于RTM 实现的呼叫邀请如何添加推送功能?
    python学习 - 设计模式 - 状态模式
    全面总结 Vue 3.0 的新特性!手把手教你如何入门Vue3.0(适合小白的保姆级教程)【尚硅谷vuejs3.0笔记】
  • 原文地址:https://blog.csdn.net/qq_21956483/article/details/132645820