当前位置: 首页 > news >正文

golang promethus consul 服务发现

软件安装:

所需组件为: consul, promethus, grafana consul, grafana全部装在了本地, promethus运行在docker里面
docker pull consul
docker pull prom/prometheus
docker pull grafana/grafana

brew方式:

brew install grafana          # grafana
brew tap hashicorp/tap    # consul
brew install hashicorp/tap/consul    # consul
brew install prometheus       # prometheus 安装有点问题, 作者采用了docker方式

启动grafana:

brew services start grafana

访问:http://127.0.0.1:3000/
在这里插入图片描述
登录的时候默认用户名密码均为:admin

启动promethus:

docker run -d -p 8091:9090 --name=prometheus_server prom/prometheus   # 主机9090被占用, 临时换成了8091

成功后访问http://127.0.0.1:8091/classic/graph
在这里插入图片描述

consul 前台启动:

consul agent -dev

这种方式只需要 ctrl + c 即可关闭 consul

正常启动:

consul agent -server -ui -bootstrap-expect=1 -data-dir=/Users/xxxxxx/consul_log -node=server-1 -client=0.0.0.0 -bind=192.168.3.241 -datacenter=dc1

启动成功后访问8500端口会出现如下界面:
在这里插入图片描述

自此所有组件启动完成(失败的情况请大家自行Google)

Promethus 配置pull方式

docker exec -it eb6c1878a8dc /bin/sh        #  eb6c1878a8dc 为promethus容器的id
vi /etc/prometheus/prometheus.yml

添加服务发现相关配置:

scrape_configs:
#  - job_name: "prometheus"
#    static_configs:
#      - targets: ["192.168.3.241:22200","192.168.3.241:22201"]

  - job_name: 'prometheus_monitor'
    consul_sd_configs:
      - server: '192.168.3.241:8500'
        services: [prometheus_monitor]

static_configs中的targets为固定拉取部分,在容器化的今天,pod扩展后都需要手动修改很麻烦,采用服务发现的方式来发现节点才是理想的解决方式。services 是程序注册的服务名称,也支持正则的方式,具体请大家自行Google一下。

改完后的配置如下:
在这里插入图片描述

请确保server是可以访问到的地址,包括局域网或公网能否访问consul地址

客户端代码:

package main

import (
	"flag"
	"fmt"
	"github.com/go-basic/uuid"
	consulapi "github.com/hashicorp/consul/api"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net"
	"net/http"
	"time"
)

var (
	commandPort  int
	instanceId   string // 实例Id
	opsProcessed prometheus.Counter
)

const (
	consulAddress = "127.0.0.1:8500"
)

func RecordMetrics() {
	for {
		opsProcessed.Inc()
		time.Sleep(5 * time.Second)
	}
}

func GetLocalIP() string {
	addressList, err := net.InterfaceAddrs()
	if err != nil {
		return ""
	}

	for _, address := range addressList {
		if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
			if ipNet.IP.To4() != nil {
				return ipNet.IP.String()
			}
		}
	}
	return ""
}

func main() {

	flag.IntVar(&commandPort, "command_port", 22200, "command port")
	flag.Parse()

	fmt.Println("command_port: ", commandPort)
	RegisterService()

	opsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "myapp_processed_ops_total",
		Help: "The total number of processed events",
		ConstLabels: map[string]string{
			"instance_id": instanceId,
		},
	})

	go RecordMetrics()
	http.HandleFunc("/", Handler)
	http.Handle("/metrics", promhttp.Handler())
	err := http.ListenAndServe(fmt.Sprintf(":%d", commandPort), nil)
	if err != nil {
		fmt.Println("error: ", err.Error())
	}
}

func RegisterService() {
	// 创建连接consul服务配置
	config := consulapi.DefaultConfig()
	config.Address = consulAddress
	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("consul client error : ", err)
		return
	}

	// 创建注册到consul的服务到
	id := uuid.New()
	instanceId = id
	registration := new(consulapi.AgentServiceRegistration)
	registration.ID = id
	registration.Name = "prometheus_monitor" //根据这个名称来找这个服务
	registration.Port = commandPort
	registration.Address = GetLocalIP()

	// 增加consul健康检查回调函数
	check := new(consulapi.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
	check.Timeout = "5s"                         //超时
	check.Interval = "5s"                        //健康检查频率
	check.DeregisterCriticalServiceAfter = "30s" // 故障检查失败30s后 consul自动将注册服务删除
	registration.Check = check

	// 注册服务到consul
	err = client.Agent().ServiceRegister(registration)
}

func Handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("pong"))
}

启动程序:

go run main.go
go run main.go -command_port 22202

consul结果如下:
在这里插入图片描述
promethus结果如下:
在这里插入图片描述

grafana添加数据源:
在这里插入图片描述
在这里插入图片描述
选择add data source后选择promethus
在这里插入图片描述
填写promethus server的地址,底部有个save and test
在这里插入图片描述
当出现下面这种情况的时候说明数据源可用,不可用的话请检查consul, 检查promethus是否发现节点,以及服务端的 http://xxxxxxx:xxxx/metrics的地址是否能访问且有数据,正常情况如下:

在这里插入图片描述

选中dashboard, 添加一个空的panel
在这里插入图片描述

底部方框输入: myapp_processed_ops_total, 这是我们在代码里面添加的指标名称
在这里插入图片描述
最终显示结果如下
在这里插入图片描述

到此整个流程完成, 在代码里面动态注册服务到consul,promethus server通过consul拿到所有注册组件的地址,然后主动去拉取数据,最后grafana通过进行展示。

相关文章:

  • 五年后端开发,仅考这份面试题和答案,成功涨薪到30k!!!
  • ISE的仿真库编译步骤——基于Omapl138/TMS320C6748+FPGA核心板
  • sql2java-pagehelper:参照Mybatis-PageHelper实现分页查询
  • 质量平台-sonarlint-idea本地配置及使用技巧
  • ansible入门
  • 表单的语法及属性(form)
  • Vue中的方法和事件绑定
  • 阿里首席架构师谈微服务:入门到实战架构
  • 一幅长文细学算法(一)——C++STL
  • 键盘切换不出中文输入法的解决方法
  • 集合的父亲之collection----(单列集合顶级接口)和遍历方式
  • Harbor安装(待补充)
  • python基础(二、基础语法)
  • YOLO系列之yolov2解读(2)
  • 【一生一芯】Chap.0 IC常用网站论坛门户 如何提出一个技术问题 并尝试解决 | 提问的智慧
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • ES6--对象的扩展
  • in typeof instanceof ===这些运算符有什么作用
  • JavaScript 基本功--面试宝典
  • javascript面向对象之创建对象
  • Java小白进阶笔记(3)-初级面向对象
  • js如何打印object对象
  • Netty 4.1 源代码学习:线程模型
  • nginx 配置多 域名 + 多 https
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • SQLServer之索引简介
  • uva 10370 Above Average
  • XForms - 更强大的Form
  • 回顾 Swift 多平台移植进度 #2
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 聊聊hikari连接池的leakDetectionThreshold
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 一文看透浏览器架构
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 正则与JS中的正则
  • 如何用纯 CSS 创作一个货车 loader
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (3)llvm ir转换过程
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (编译到47%失败)to be deleted
  • (二)windows配置JDK环境
  • (二十四)Flask之flask-session组件
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .NET CLR Hosting 简介
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net MySql
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [].slice.call()将类数组转化为真正的数组