prometheus-community-PushProx介绍

  • 1. pushprox 应用场景
  • 2. 架构
  • 3. 部署和测试
    • 3.1. 组件
    • 3.2. proxy 对 client 进行 TLS 认证
      • 3.2.1. 生成支持 SAN 的自签名证书
      • 3.2.2. 启动 pushprox-proxy
      • 3.2.3. 配置 nginx
      • 3.2.4. 启动 client
      • 3.2.5. 启动 prometheus
  • 4. 代码走读
    • 4.1. 代码目录
    • 4.2. client 的代码
    • 4.3. proxy 的代码
  • 5. proxy 和 client 之间如何复用 TCP 连接
    • 5.1 http keepalive
    • 5.2 golang http server 和 client 之间的 keepalive
      • 5.2.1 gin http server
      • 5.2.2 http client
      • 5.2.3 gin http server 和 http client 抓包
  • 6. 参考

1. pushprox 应用场景

监控系统有 pull 和 push 两种模式。pull 模式下,server 侧会主动去找各个 node 获取 metric ,主动权在 server,server需要知悉 node 的信息,可以随时调整收集哪些 node 的哪些 metric,以什么频次去收集。pull 模式比较适合数据中心的场景,prometheus是典型的 pull 模式。 push 模式是由 node 将 metric 上报给 server,node 侧需要配置要上报什么 metric,以什么频次上报给什么 server。push 模式更适合 iot 的场景,open-falcon 是 push 模式。部署监控系统时除了考虑 pull、push 的因素,还会考虑监控系统的生态,比如 k8s 环境下选择 prometheus 会带来较多的便利性。

在使用 prometheus 的情况下,由于 prometheus server 需要能够直接访问到 node。如果 node 是在 NAT 环境下,仍然需要 prometheus server 去收集这些 node 的 metric,就需要使用一些附加的方式,pushprox 就是应用于这种场景。

2. 架构

pushprox 主要由 proxy 和 client 两部分组成,proxy 负责接收来自 prometheus server 的 metric 请求,然后 proxy 将请求信息 proxy 给 client,client 找本地设备获取到 metric 后,将结果返回给 proxy。要求 proxy 部署在 prometheus 能够访问到的地方,client 则部署在需要采集的 node 所在的网络。

  1. 启动 proxy、client
  2. client 使用 http POST 调用 proxy 的 /poll 接口,这一步会建立 client 和 proxy 之间的一个长连接,这个长连接依赖 http1.1 的 KeepAlive 来实现。这条连接建立后表示 client 已经做好准备,可以获取 client 对应的 node(fqdn-x) 的 metric 了。
  3. prometheus 找 proxy 要 fqdn-x 的 metric
  4. proxy 收到请求后会将该次请求作为 第(1)步的 /poll 接口的 response 报文返回给 client
  5. client 收到第(3)步的 scrape 的请求后,新起一个 http 请求找 node(fqdn-x) 请求 metric
  6. node(fqdn-x) 将 metric 返回给 client
  7. client 获取到 node(fqdn-x) 的 metric 后,使用区别 poll 的另一个长连接用于 client 将 metric push 给 proxy。之后 client 有其他的 metric 需要 push 给 proxy 会复用这个长连接。所以,如果没有 第(2)步 prometheus 或其他服务来跟 proxy 要 metric,client 和 proxy 之间只会维持一个 poll 相关的长连接。当有 metric 请求后,client 和 proxy 之间会在维持一个用于 push metric 的长连接。
  8. proxy 收到 第(6)步 client push 的 metric 后,将 metric 返回给 prometheus

我们通常说 HTTP 是无状态的,上面说的长连接主要是居于 http1.1 的 KeepAlive 实现的类似于长连接的效果。具体的连接情况和对应的抓包如下:

# ~ netstat -natp|grep 43.243.130.151
tcp        0      0 192.168.10.212:45922    43.243.130.151:8080     ESTABLISHED 4019233/./pushprox- # 用于 poll
tcp        0      0 192.168.10.212:45930    43.243.130.151:8080     ESTABLISHED 4019233/./pushprox- # 用于 push

3. 部署和测试

3.1. 组件

  1. node_exporter 暴露 node 的一些基础 metric
  2. pushprox-client 和 node_exporter 一起部署在需要收集的 NAT 环境下的 node 上
  3. pushprox-proxy 和 prometheus 都部署在外网。prometheus 可以访问到 pushprox-proxy 的服务。

3.2. proxy 对 client 进行 TLS 认证

由于目前 proxy 和 client 之间没有做认证,client 所在 ip 不确定,proxy 无法针对 client 配置防火墙策略,需要增加 proxy 和 client 之间的认证。

使用 tls 来对 client 进行校验。pushprox-proxy 不支持 tls,需要 nginx 作为反向代理到 pushprox-proxy,然后 nginx 上配置 tls,并且在 nginx 上开启 ssl_verify_client 。pushprox-client 支持 tls 客户端连接到 nginx 。pushprox-client 要求 tls 要支持 SAN(Subject Alternative Name) 是SSL 标准x509 中定义的一个扩展)。所以生成自签名证书的时候需要支持 SAN 。

3.2.1. 生成支持 SAN 的自签名证书

参考 https://github.com/ljq/gen-tlsv3-san-ca 来生成自签名证书

3.2.2. 启动 pushprox-proxy

pushprox-proxy 需要部署在公网的服务器上,而且 pushprox-proxy 要跟每个 client 保持一个长连接,如果 client 比较多, proxy 要考虑负载均衡。

./pushprox-proxy

3.2.3. 配置 nginx

nginx 反向代理到 pushprox-proxy, nginx 上配置 tls

pushprox.conf

upstream prox-backend {server 127.0.0.1:8080;
}server {listen 443 ssl;server_name promprox.xk.com;ssl on;ssl_certificate /opt/xk-self-cert/server.crt;#配置证书位置ssl_certificate_key /opt/xk-self-cert/server.key;#配置秘钥位置ssl_client_certificate /opt/xk-self-cert/ca.crt;#双向认证ssl_verify_client on; #双向认证ssl_session_timeout 5m;ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; #按照这个协议配置ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; #按照这个套件配置ssl_prefer_server_ciphers on;location / {proxy_pass       http://prox-backend/;}
}

3.2.4. 启动 client

pushprox-client 要配置自签名证书中的 ca 和 client crt

./pushprox-client --proxy-url=https://promprox.xk.com --tls.cacert=/opt/xk-self-cert/ca.crt --tls.cert=/opt/xk-self-cert/client.crt --tls.key=/opt/xk-self-cert/client.key

3.2.5. 启动 prometheus

./prometheus --config.file=prometheus-prox.yml
# prometheus-prox.yml# my global config
global:scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:# - alertmanager:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:- job_name: nodeproxy_url: http://43.243.130.151:8080/ # 配置为 proxy 的地址static_configs:- targets: ['ceph-mon2:9100']  # Presuming the FQDN of the client is "client".

4. 代码走读

4.1. 代码目录

代码地址: https://github.com/prometheus-community/PushProx

主要的代码都在 cmd 目录下:

├── client
│   ├── main.go
│   └── main_test.go
└── proxy├── coordinator.go└── main.go

4.2. client 的代码

代码流转:

  1. main()
  2. Coordinator.loop(),这里会循环执行 Coordinator.doPoll,如果调用失败使用 backoff 策略来确定失败后再次调用 doPoll 的频率
  3. Coordinator.doPoll,doPoll 是使用 http POST 调用 proxy 的 poll 接口,如果没有收到 proxy 的 response 报文,doPoll 会 hung 在这边等 proxy 给 response。如果收到 proxy 的 response 报文,表名有 scrape metric 的任务,会新起一个携程执行 Coordinator.doScrape
  4. Coordinator.doScrape 会找 node(fqdn-x) 要到 metric,然后调用 proxy 的 push 接口将 metric push 给 proxy

4.3. proxy 的代码

代码流转:

  1. main()
  2. newHTTPHandler(),这个是处理的路口,http server 的路由在这里配置,执行 poll,push 等接口对应的 handler 函数。proxy 还暴露了一些关于接口调用的 metric,比如pushprox_http_requests_total,pushproxy_proxied_requests_total,在 newHTTPHandler 里面使用了 promhttp.InstrumentHandlerCounter 这样的方式作为 http handlerFunc 的 middleware 在实际的 handler 函数前后插入了一些 metric 打点的逻辑。
  3. httpHandler.handlePoll 用于处理 poll 请求

5. proxy 和 client 之间如何复用 TCP 连接

pushprox 是如何处理 client 和 proxy 的连接,来满足 prometheus metric 获取的低耗时以及一台 proxy 能够支持尽量多的 client。应该说 pushprox 仅仅使用 http 协议的交互来达到 client 和 proxy 之间长连接的效果,然后多个请求复用同一个 tcp 连接,还是可以借鉴的,因为实现起来非常容易。

原本一直认为 HTTP 是无状态的,所以天生就应该是短连接(这边的短连接是指 client 发一个 request 给 server,server 回应一个 response,然后连接关闭,下次再要通信就在发起一个 tcp 连接)的。目前 pushprox 这个 client 和 proxy 的依赖于 http1.1 的长连接使用起来还是比较稳定的,资源消耗也挺小。

5.1 http keepalive

keepalive 在 http 1.0(rfc1945)中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;http 1.1(rfc2068)中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。
使用 keepalive 的好处在 rfc2068 有说明,比如请求一个网页,可能需要有图片、css等多个文件请求,放在一个 tcp 连接里面可以提升效率。
那么如果启用了 keepalive,server 和 client 之前如何知道什么时候该关闭请求呢?比如,client 就找 server 要资源A,然后结束,server 给了 client response 报文后,如果 server 不关闭连接,client 如何知道已经收到了 server 关于资源A的所有内容更应该要关闭连接了呢?目前主要是两种情况:

  1. 如果资源A是静态资源而且比较小能够一次响应给 client,通常 server 侧会在 response 报文的 header 添加 Conent-Length,用来表示 response 报文的大小,client 收到该大小的 response 后就知道已经收到所有内容,可以主动关闭 tcp 连接。

  1. 如果资源A是动态的或者比较大,需要多次分段给 client,这种情况下通常使用 chunk 模式。server 将 response 报文的 “Transfer-Encoding: chunked”,chunk 编码将数据分成一块一块的发送,最后一块由一个标明长度为0的chunk标示结束。关于 chunk 模式可以参考 RFC 2616 。

5.2 golang http server 和 client 之间的 keepalive

我原本以为 golang 实现 http server 和 client 的长连接需要在 client 侧设置 http.Transport 中 DialContext 的 KeepAlive 等相关的值,但是使用 gin 作为 http server,默认的 http client,很容易就能实现这个长连接的效果。

5.2.1 gin http server

func main() {r := gin.Default()r.POST("/echo", func(c *gin.Context) {body, _ := ioutil.ReadAll(c.Request.Body)fmt.Println("---body/--- \r\n " + string(body))time.Sleep(1000000000 * time.Second) # hung 住请求c.JSON(200, gin.H{"msg": "ok",})})r.Run(":8282") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

5.2.2 http client

var server = flag.String("server", "http://127.0.0.1:8282/echo", "http server url")func init() {flag.Parse()
}func main() {client := &http.Client{}doPost(client)
}func doPost(client *http.Client) {resp, _ := client.Post(*server, "application/x-www-form-urlencoded", strings.NewReader("name=moon"))defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(body))
}

5.2.3 gin http server 和 http client 抓包

从上面这张抓包的图可以看出来 http1.1 是如何来实现 keepalive 的,因为 server 侧一直没有给 response 报文,所以 client 一直到等报文,但是这个 tcp 连接并没有超时,依赖的是 tcp 的 keepalive 报文,基本上是每 15s,处在应用层的 http1.1 协议会为了维持住这个 tcp 连接,server 侧会给 client 发 tcp keepalive 报文,这个 15s 是要参考服务器上关于 tcp 连接超时的配置的。

6. 参考

  • https://github.com/prometheus-community/PushProx

prometheus-community-PushProx介绍相关推荐

  1. (一)prometheus与grafana介绍与安装

    #(1)prometheus介绍 prometheus是一款 强大的监控系统和时序系统 采集数据: 在目标主机上安装exporter, exporter组件会在目标处收集监控数据, 并暴露一个http ...

  2. 【Clickhouse】Clickhouse 整合 Prometheus 监控 运行时状态

    1.概述 转载:ClickHouse运行时状态监控 类似:[clickhouse]docker 下 搭建 clickhouse 监控 Clickhouse 在运行时会将一些运行装白保存到系统表中,在对 ...

  3. Prometheus+Grafana监控告警配置

    文章目录 Prometheus介绍 Prometheus及其组件安装 Prometheus安装 PromQL介绍 mysqld_exporter组件安装 node_exporter组件安装 alert ...

  4. 视频教程-Prometheus+Grafana搭建全方位的监控告警系统-Linux

    Prometheus+Grafana搭建全方位的监控告警系统 高级运维工程师.资深DevOps工程师,精通kubernetes容器编排工具,熟练使用linux操作系统,多年线上线下教学经验 韩先超 ¥ ...

  5. Grafana+Prometheus打造运维监控系统(一)-安装篇

    1. Prometheus.Grafana介绍 Prometheus是一个开源的系统监控和报警系统,Grafana 是一个开源的监控数据分析和可视化套件,利用Grafana+Prometheus组合, ...

  6. 开源自主无人机软件平台—Prometheus

    Prometheus,在希腊神话中,是最具智慧的神明之一,希望Prometheus项目能为无人机研发工作带来无限的智慧与光明.同时电影普罗米修斯里面的无人机在黑洞中自由穿越,也是我们在技术层面所追求的 ...

  7. 普罗米修斯监控系统_一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式...

    前言 本系列着重介绍Prometheus以及如何用它和其周边的生态来搭建一套属于自己的实时监控告警平台. 本系列受众对象为初次接触Prometheus的用户,大神勿喷,偏重于操作和实战,但是重要的概念 ...

  8. Prometheus应用监控

    1.主流机器与应用Prometheus,skywalking监控体系分享介绍 应用监控介绍 目前市面上开源应用的APM系统主要有CAT.Zipkin.Pinpoint.SkyWalking. 目前市面 ...

  9. 自定义prometheus exporter实现监控阿里云RDS

    背景 1.Prometheus官网提供的mysql exporter 对于mysql实例只能一个进程监控一个实例,数据库实例很多的情况,不方便管理 2.内部有定制化监控需求,RDS 默认无法实现,比如 ...

  10. python android自动化能做哪些页面_android - python 自动化测试 移动互联网 - SegmentFault...

    批处理ODBC配置 工作需要来回切换ODBC配置,用同一个DSN名称访问不同的数据库. 对于linux的odbc配置在odbc.ini文件里,替换不同的文件就可以切换了. 而windows的配置一直通 ...

最新文章

  1. Pycharm中实现查找和替换
  2. windows下python2.7.14版本的安装
  3. 坑你没商量!盘点Java中最常见的事故现场,你都中过哪些招?
  4. 加减法叫做什么运算_期中备考:数学运算定律、法则与顺序
  5. vc获取当前路径,并且创建文件
  6. [OS复习]存储管理2
  7. 记录爬取信用中国,里面的行政许可内容,行政处罚,守信激励的内容,并以excel形式显示
  8. 超多趣味测评测试微信小程序源码 可插入流量主广告位 无后台
  9. L1-074 两小时学完C语言 (5 分)-PAT 团体程序设计天梯赛 GPLT
  10. 第18章 RS485通信和Modbus协议
  11. 【矩阵论笔记】相似对角化、特征子空间(几何重数和代数重数)
  12. 永远不要使用 Boolean 对象
  13. tiny4412编译出来的zImage不能开机
  14. windows画图常用函数
  15. 死亡细胞1.9最新辅助
  16. python以图搜图api_网络图片搜索-以图搜图【最新版】_自动识别接口_图像识别_数据API-云市场-阿里云...
  17. 科技论文CCF 推荐中文期刊目录2019
  18. 若查找课程表中课程名称是计算机或英语,若查找“课程表”中课程名称是“计算机”或“英语”的记录,应在查询设计视图的“课程名称”列条件行中输入()。...
  19. 文献--Bacterial coexistence driven by motility and spatial competition-模型代码
  20. bootstrap 黑边框表格样式_设置Bootstrap Table表格样式并隔行变色

热门文章

  1. 0016 c/c++语言 二进制转换为十进制
  2. 解决ElementUI列表大数据操作卡顿问题
  3. Linux下终端分屏利器tmux
  4. 三个选择框,当前框选过之后的数据其他两个不能选择
  5. 浪潮服务器内存故障怎么修复,浪潮GS客户端出现内存溢出和存储空间不足的问题说明和解决方案 | 浪潮888博客...
  6. android应用商店代码,仿小米应用商店Android客户端
  7. 利用Log parse 分析Exchange 性能并产生相应报表!(1)-Agent Log!
  8. 如何解析xml报文获取数据集合
  9. ireport导出Excel报表的实现
  10. JSON Shema 校验JSON内容