个人技术分享

接入Prometheus

  • 在 go-micro 生成的模板中, 我们一如既往的完成基础工作之后

  • 进入main.go工作的代码编写,main.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"strconv"
    
    	"github.com/go-micro/plugins/v4/registry/consul"
    	opentracingTool "github.com/go-micro/plugins/v4/wrapper/trace/opentracing"
    
    	"github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus"
    	"github.com/go-micro/plugins/v4/wrapper/ratelimiter/ratelimit"
    	jujuratelimit "github.com/juju/ratelimit"
    
    	"github.com/opentracing/opentracing-go"
    	"go-micro.dev/v4"
    	"go-micro.dev/v4/registry"
    
    	"gitee.com/go-micro-services/common"
    	"gitee.com/go-micro-services/order/domain/repository"
    	"gitee.com/go-micro-services/order/domain/service"
    	"gitee.com/go-micro-services/order/handler"
    	pborder "gitee.com/go-micro-services/order/proto/order"
    
    	"github.com/jinzhu/gorm"
    	_ "github.com/jinzhu/gorm/dialects/mysql"
    )
    
    var (
    	serviceName     = "go.micro.service.order"
    	version         = "latest"
    	host            = "127.0.0.1"
    	port            = 8500
    	address         = host + ":" + strconv.Itoa(port)
    	mysqlConfigPath = "/micro/config/mysql"
    )
    
    func main() {
    	// 1. 指定注册中心
    	consulReg := consul.NewRegistry(
    		registry.Addrs(address),
    	)
    
    	// 2. 从配置中心获取mysql配置并创建处理
    	mysqlConfig, consulConfigErr := common.GetConsulMysqlConfig(address, mysqlConfigPath)
    	if consulConfigErr != nil {
    		log.Fatal(consulConfigErr)
    	}
    	mysqlUrl := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", mysqlConfig.User, mysqlConfig.Pwd, mysqlConfig.Host, mysqlConfig.Port, mysqlConfig.Database)
    	db, dbErr := gorm.Open("mysql", mysqlUrl)
    	if dbErr != nil {
    		log.Fatal(dbErr)
    	}
    	defer db.Close()
    
    	rp := repository.NewOrderRepository(db)
    	// 数据库表初始化,只执行一次, 如果本来就设计好了,则无需下面
    	// rp.InitTable()
    	// db.SingularTable(false) // true 则 表就是单数
    
    	// 3. 链路追踪配置
    	tracer, closer, tracerErr := common.NewTracer("go.micro.service.order", "localhost:6831")
    	if tracerErr != nil {
    		log.Fatal(tracerErr)
    	}
    	defer closer.Close()
    	opentracing.SetGlobalTracer(tracer)
    
    	// 4. 创建服务实例
    	orderDataService := service.NewOrderDataService(rp)
    	// 5.暴露监控地址
    	common.PrometheusBoot(9092)
    
    	// 6. 创建服务和初始化
    	srv := micro.NewService()
    	srv.Init(
    		micro.Name(serviceName),
    		micro.Version(version),
    		micro.Registry(consulReg),
    		// micro.Address("0.0.0.0:8087"), // 暴露的服务地址 这里可用可不用指定
    		micro.WrapHandler(opentracingTool.NewHandlerWrapper(opentracing.GlobalTracer())),       // 绑定链路追踪
    		micro.WrapHandler(ratelimit.NewHandlerWrapper(jujuratelimit.NewBucket(50, 100), true)), // 添加限流
    		micro.WrapHandler(prometheus.NewHandlerWrapper()),                                      // 添加监控
    	)
    
    	// 7. 注册 handler
    	if handlerErr := pborder.RegisterOrderHandler(srv.Server(), &handler.Order{OrderDataService: orderDataService}); handlerErr != nil {
    		log.Fatal(handlerErr)
    	}
    
    	// 8. 运行服务
    	if runErr := srv.Run(); runErr != nil {
    		log.Fatal(runErr)
    	}
    }
    
  • 注意,这里最重要的一行代码:common.PrometheusBoot(9092), 进入看看

    package common
    
    import (
    	"net/http"
    	"strconv"
    
    	"github.com/prometheus/client_golang/prometheus/promhttp"
    	"github.com/prometheus/common/log"
    )
    
    func PrometheusBoot(port int) {
    	http.Handle("/metrics", promhttp.Handler())
    	//启动web 服务
    	go func() {
    		err := http.ListenAndServe("0.0.0.0:"+strconv.Itoa(port), nil)
    		if err != nil {
    			log.Fatal("启动失败")
    		}
    		log.Info("监控启动,端口为:" + strconv.Itoa(port))
    	}()
    }
    
    • http.Handle("/metrics", promhttp.Handler()):
      • 这行代码注册了一个HTTP处理器到/metrics路径上
      • 当HTTP请求访问/metrics时,promhttp.Handler() 会生成并返回Prometheus格式的指标数据
  • 启动服务 $ sudo go run main.go

Prometheus 和 Grafana 监控平台


1 )Prometheus 平台

  • 上面是正常的服务, 如果服务出错,可能如下

选择一项指标后,执行

2 ) Grafana 平台

  • 在已经接入好的 Grafana 监控平台:http://192.168.1.7:3000

可见,已经能够正常监控了

源码地址