腾讯mini项目-【指标监控服务重构】2023-08-23

今日已办

进度和问题汇总

  1. 请求合并
    1. feature/venus trace
    2. feature/venus metric
    3. feature/profile-otel-baserunner-style
    4. bugfix/profile-logger-Sync
    5. feature/profile_otelclient_enable_config
  2. 完成otel 开关
    1. trace-采样
    2. metrice-reader
  3. 已经都在各自服务器运行,并接入了云clickhouse集群,开始准备测试【详细需求】
    1. 测试的用例,并发的数目-【用例拓展-kafka的消息积压】
    2. clickhouse的哪些指标,cpu、内存,耗时等
    3. 以什么形式来输出这个性能对比?(表格or图形)
    4. 指标采集的性能消耗,复杂指标查询的消耗
    5. 对比对象-Jaeger
      1. 存储后端-elasticsearch 【手动部署或者购买】
      2. 收集存储,查询
      3. golang pprof 抓取文件 CPU 占用和耗时,内存-火焰图
      4. 不同方案做对比
    6. ck 的指标
      1. **数据库的延时,(五分钟)入库成功率 **【压测】
      2. 通过指标或者链路耗时,定位哪个环节卡住
      3. 压测 jaeger 数据收集出现问题-【qps】,降低配置,突出优势
      4. 内存和cpu占有,profile 手动收集指标
  4. profile服务器3301的端口
  5. watermill和baserunner的benmark,做得差不多了,修改了publisher用了kafka-client的异步生产者,耗时快了很多
  6. 需要启动其他监控工具(zipkin,jaeger【已经接入,正在尝试连入ck】,Prometheus等来进行对比吗)
  7. 一个优化代码中接入otel-sdk,如何减少显式声明,提高代码的可扩展性
    1. profile 已经将otel逻辑嵌入到baserunner的handler中
    2. venus 待办
    3. profile-watermill 待办

分工

  1. 测试用例 - 1
  2. jaeger - 2
  3. pprof - 1
  4. 测试对比两种方案的 clickhouse 指标
  5. docker-compose拉低配置

watermill-benchmark

代码实现

  1. 先初始化 producer
  2. watermill 初始化并启动 router / baserunner 初始化 consumer
  3. 在 for 循环中同步生产完固定数量的消息【开始计时】
  4. 阻塞等待固定数量的消息被消费,解析,处理,异步推回 kafka 完成【结束计时】
  5. 本机和服务器测试单个topic的100条消息的结果见下列表格
    1. watermill 的性能和资源利用率均好于 baserunner
    2. 核心数多的情况下,优势会更加明显
// Package consumer
// @Author xzx 2023/8/19 14:13:00
package internalimport ("context""fmt"kc "github.com/Kevinello/kafka-client""github.com/ThreeDotsLabs/watermill/message""github.com/ThreeDotsLabs/watermill/message/router/middleware""github.com/ThreeDotsLabs/watermill/message/router/plugin""github.com/bytedance/sonic""github.com/garsue/watermillzap""github.com/google/uuid""github.com/segmentio/kafka-go""go.uber.org/zap""go.uber.org/zap/zapcore""profile/cmd""profile/internal/config"baseconsumer "profile/internal/context/consumer""profile/internal/log""profile/internal/schema""profile/internal/watermill/consumer""profile/internal/watermill/watermillkafka""testing""time"
)// BenchmarkWatermill-16           240           5631314 ns/op         3684370 B/op           37997 allocs/op
// BenchmarkWatermill-16           153           7084305 ns/op         3706966 B/op           38168 allocs/op
// BenchmarkWatermill-16           145           6917486 ns/op         3712511 B/op           38175 allocs/op
func BenchmarkWatermill(b *testing.B) {router := newRouter()go func() {if err := router.Run(context.Background()); err != nil {log.Logger.Error("router run error", zap.Error(err))}}()producer := newProducer()time.Sleep(10 * time.Millisecond)b.ResetTimer()for i := 0; i < b.N; i++ {b.StopTimer()watermillkafka.MessageCount = 0err := publishMessage(producer, 100)if err != nil {break}b.StartTimer()// 阻塞等待消费完成指定数量for {if watermillkafka.MessageCount >= 100 && router.IsRunning() {b.StopTimer()log.Logger.Error("PubSub Count End", zap.Any("count", watermillkafka.MessageCount))break}}}b.StopTimer()router.Close()
}// BenchmarkBaseRunner-16         12         100429542 ns/op         4959836 B/op      42119 allocs/op
// BenchmarkBaseRunner-16         10         100110220 ns/op         4946421 B/op      42132 allocs/op
// BenchmarkBaseRunner-16         10         106747810 ns/op         4942656 B/op      42107 allocs/op
func BenchmarkBaseRunner(b *testing.B) {producer := newProducer()myConsumer, err := kc.NewConsumer(context.Background(),kc.ConsumerConfig{Bootstrap: config.Profile.GetString("kafka.bootstrap"),GroupID:   config.Profile.GetString("kafka.group"),GetTopics: func(broker string) (topics []string, err error) {return []string{"to_analyzer__0.PERF_CRASH","to_analyzer__0.PERF_LAG",}, nil},MessageHandler: cmd.ConsumerDispatchHandler,LogLevel:       int(zapcore.InfoLevel),},)if err != nil {log.Logger.Fatal("create consumer error", zap.Error(err))return}go func() {select {case <-myConsumer.Closed():log.Logger.Info("consumer Closed")return}}()time.Sleep(10 * time.Millisecond)b.ResetTimer()for i := 0; i < b.N; i++ {b.StopTimer()baseconsumer.ConsumeCount = 0err := publishMessage(producer, 100)if err != nil {break}b.StartTimer()// 阻塞等待消费完成指定数量for {if baseconsumer.ConsumeCount >= 100 {log.Logger.Error("PubSub Count End", zap.Any("count", baseconsumer.ConsumeCount))break}}}b.StopTimer()myConsumer.Closed()
}func publishMessage(producer *kc.Producer, nums int) (err error) {var event = &schema.Event{Meta: schema.Meta{AppID:    "1024",Category: "PERF_CRASH",Model:    "xiaomi13",DeviceID: "1b201ff9-5002-4fae-8d22-507a1c1a10b6",Os:       "ios",OsVer:    "13.1",UserID:   "28865194-fd08-480f-957d-ee9f21b32c3c",Version:  "100.24.56.7.19",Arch:     "aarch64",SdkVer:   "5.12.6",Platform: "ios",},Data: schema.Data{Time:         1688491757512,IP:           "119.147.10.203",ID:           "a4b838db-4f34-4da8-a27b-e725477ed336",NetType:      "5G",NetOp:        "CT",BatteryLevel: 92,PageID:       "com.tencent.test.page1",Dimensions: map[string]string{"crashed_thread": "com.tencent.thread1","crash_type":     "native","lose_data":      "true","repeat_occur":   "false",},Values: map[string]int64{"memory_free":  600,"memory_max":   1200,"memory_total": 1600,"remain_disk":  4000,},},VenusData: schema.VenusData{UploadTime: time.Now().UnixMilli(),BackendID:  uuid.NewString(),Country:    "China",Region:     "Guangdong",City:       "Shenzhen",},}topic := fmt.Sprintf("to_analyzer__0.%s", event.Category)messages := make([]kafka.Message, 0, nums)for i := 0; i < nums; i++ {event.UploadTime = time.Now().UnixMilli()event.BackendID = uuid.NewString()bytes, err := sonic.Marshal(event)if err != nil {fmt.Printf("failed to marshal event: %v\n", err)}messages = append(messages, kafka.Message{Topic: topic,Value: bytes,})}if err = producer.WriteMessages(context.Background(), messages...); err != nil {fmt.Printf("failed to write messages: %v\n", err)}return
}func newProducer() *kc.Producer {eventKafkaConfig := &kc.ProducerConfig{Bootstrap:              "127.0.0.1:9092",Async:                  false,AllowAutoTopicCreation: true,Logger:                 &log.LogrLogger,}producer, err := kc.NewProducer(context.Background(), *eventKafkaConfig)if err != nil {panic("cannot connect to kafka with address 127.0.0.1:9092")}return producer
}func newRouter() *message.Router {logger := watermillzap.NewLogger(log.Logger)publisher, subscriber := consumer.NewPubSub(logger)router, err := message.NewRouter(message.RouterConfig{}, logger)if err != nil {log.Logger.Fatal("create router error", zap.Error(err))}router.AddPlugin(plugin.SignalsHandler)router.AddMiddleware(middleware.InstantAck,middleware.Recoverer,)router.AddMiddleware(consumer.UnpackKafkaMessage, consumer.InitPerformanceEvent, consumer.AnalyzeEvent)router.AddHandler("crash", "to_analyzer__0.PERF_CRASH", subscriber, "solar-dev.PERF_CRASH", publisher, consumer.CrashHandler)router.AddHandler("lag", "to_analyzer__0.PERF_LAG", subscriber, "solar-dev.PERF_LAG", publisher, consumer.LagHandler)return router
}

本地测试

BenchmarkWatermill-16BenchmarkBaseRunner-16
240 563,1314 ns/op 368,4370 B/op 3,7997 allocs/op12 1,0042,9542 ns/op 495,9836 B/op 4,2119 allocs/op
153 708,4305 ns/op 370,6966 B/op 3,8168 allocs/op10 1,0011,0220 ns/op 494,6421 B/op 4,2132 allocs/op
145 691,7486 ns/op 371,2511 B/op 3,8175 allocs/op10 1,0674,7810 ns/op 1,0674,7810 B/op 4,2107 allocs/op

服务器上测试

image-20230823202739491

image-20230823204753051

单个topic的100条消息

BenchmarkWatermill-4BenchmarkBaseRunner-4
10 4339,8240 ns/op 363,0762 B/op 3,7820 allocs/op25 4616,7095 ns/op 315,8836 B/op 3,9902 allocs/op
78 4065,2822 ns/op 360,0755 B/op 3,7893 allocs/op26 4330,6776 ns/op 317,8770 B/op 3,9880 allocs/op
100 3549,3863 ns/op 360,5322 B/op 3,7899 allocs/op100 4489,2327 ns/op 316,3158 B/op 3,9775 allocs/op
386 1427,4034 ns/op 358,7454 B/op 3,7876 allocs/op10000 4949,4435 ns/op 319,7664 B/op 3,9874 allocs/op

本地测试单个topic的100条消息

testb.nns/opB/opallocs/op
BenchmarkWatermill-161537084305370696638168
BenchmarkWatermill-161456917486371251138175
BenchmarkBaseRunner-1610100110220494642142132
BenchmarkBaseRunner-161010674781010674781042107

服务器测试单个topic的100条消息

testb.nns/opB/opallocs/op
BenchmarkWatermill-47840652822360075537893
BenchmarkBaseRunner-42643306776317877039880

明日待办

  1. 协助部署 jaeger

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/134716.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SmartSQL 一款开源的数据库文档管理工具

建议直接蓝奏云下载安装 蓝奏云下载&#xff1a;https://wwoc.lanzoum.com/b04dpvcxe 蓝奏云密码&#xff1a;123 项目介绍 SmartSQL 是一款方便、快捷的数据库文档查询、导出工具&#xff01;从最初仅支持 数据库、CHM文档格式开始&#xff0c;通过不断地探索开发、集思广…

【C刷题】day2

一、选择题 1、以下程序段的输出结果是&#xff08; &#xff09; #include<stdio.h> int main() { char s[] "\\123456\123456\t"; printf("%d\n", strlen(s)); return 0; } A: 12 B: 13 C: 16 D: 以上都不对【答案】&#xff1a; A 【解析】…

springboot和vue:二、springboot特点介绍+热部署热更新

springboot特点介绍 能够使用内嵌的Tomcat、Jetty服务器&#xff0c;不需要部署war文件。提供定制化的启动器Starters&#xff0c;简化Maven配置&#xff0c;开箱即用。纯Java配置&#xff0c;没有代码生成&#xff0c;也不需要XML配置。提供了生产级的服务监控方案&#xff0…

Linux Day15:线程安全

一、线程安全方法 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临…

Spring 的注入

目录 一、注入&#xff08;Injection&#xff09; 1、什么是注入 &#xff08;1&#xff09;为什么需要注入 &#xff08;2&#xff09;如何进行注入 2、Spring 注入原理分析&#xff08;简易版&#xff09; 二、Set 注入详解 1、JDK 内置类型 &#xff08;1&#xff09…

CountDownLatch 使用例子和代码流程

目录 CountDownLatch意思理解普通多线程运行Thread.join()实现CountDownLatch实现CountDownLatch流程new CountDownLatch(3)countDown 方法await方法 CountDownLatch意思理解 单词1: countdown 常见释义: 英[ˈkaʊntdaʊn] 美[ˈkaʊntdaʊn] n. 倒数读秒&#xff0c;倒计时(…

推荐一个高质量专栏:「前端面试必备」

文章目录 专栏作者介绍专栏介绍目录&#xff08;前25篇&#xff09;目录&#xff08;后25篇&#xff09;专栏文章部分摘抄JavaScriptVue网络请求和HTTPNode.jswebpackBabelVite微信小程序Vuexuni-appGitECharts前端工程化 写在结尾 专栏作者介绍 &#x1f90d; 前端开发工程师&…

Vulnhub系列靶机---Deathnote: 1死亡笔记

文章目录 信息收集主机发现端口扫描目录扫描dirsearchgobusterdirb扫描 漏洞利用wpscan扫描Hydra爆破 总结 靶机文档&#xff1a;Deathnote: 1 下载地址&#xff1a;Download (Mirror) 难易程度&#xff1a;so Easy 信息收集 主机发现 端口扫描 访问靶机的80端口&#xff0c;报…

Truenas scale 配置 TrueChart zerotier

起源 Official zerotier 总是在系统重启或者服务重启后&#xff0c;会丢失之前配置的IP等信息&#xff0c;使用&#xff0c;转投 TrueChart zerotier 步骤 TrueChart 官方步骤&#xff0c;按这个配置完还是不能使用&#xff0c;需要后续设置。 添加TrueChart步骤到应用库的步…

React TypeScript 定义组件的各种方式

目录 举例说明1. 使用 class 定义2. 使用函数定义2.1 使用普通函数2.2 使用函数组件 举例说明 比如我们要定义一个计数器 Counter&#xff0c;它包含一个 label 和一个 button&#xff0c;计数器的初始值由外部传入&#xff0c;点击 button 计数加 1: 这虽然是个简单组件&…

Python新手入门

文章目录 概要python代码运行结果小结 概要 以下内容为python各种输出语句的语法&#xff01; python代码 # 标准化输出 print("这是标准化输出&#xff01;")# 格式化输出 print("这是第1种%s"%"格式化输出&#xff01;") print("这是第…

智能家居产品公司网站源码,自适应布局设计,带完整演示数据

适合各类智能家居电子产品使用的网站源码&#xff0c;深色大气设计&#xff0c;自适应布局设计&#xff0c;pc手机均可完美适配&#xff0c;带完整演示数据。 独家原创资源。源码是asp开发的&#xff0c;数据库是access&#xff0c;主流的虚拟主机空间都支持asp&#xff0c;直…

冒泡排序及其优化

前言 本文将简单介绍冒泡排序及其优化版本&#xff0c;默认从小到大顺序 什么是冒泡排序 冒泡排序是一种简单且经典的排序算法。 基本思想&#xff1a; 是通过反复交换相邻的未按顺序排列的元素&#xff0c;将最小&#xff08;或最大&#xff09;的元素逐渐“浮”到正确位置…

vscode 下载安装

vscode 下载安装常用插件 vscode 官网&#xff1a; https://code.visualstudio.com/ 点击右上角 Download 进入下载选择页面 选择自己使用操作对应 CPU 架构 下载 本文使用 x86 架构 64位 windows 系统为例 跳转下载页面 自动 开始下载 下载不开始&#xff1f;试试这个直…

lighttpd以及socket和WebSocket编程

综述 本文涉及到下图绿色背景部分的内容&#xff1a; 左侧位于Linux下&#xff0c;其中包括lighttpd和socket程序&#xff1b;右侧是WebSocket程序。两者通过网络交互。 本文介绍lighttpd的基本使用方式&#xff0c;并通过编程完成一个socket服务器与浏览器端的WebSocket客户…

Spring Boot @Value读不到Nacos配置中心的值。(properties配置文件)

读不到配置中心的值&#xff0c; 配置中心的配置文件名字&#xff08;Data ID的值&#xff09;要以.properties结尾。 如果是yaml&#xff0c;就以yaml命名。

Git:Git的一些基本操作

文章目录 基本认识使用方法创建本地仓库配置本地仓库 工作区、暂存区、版本库的概念添加文件版本回退撤销修改删除操作 基本认识 首先要对Git有一个基本的认知&#xff1a; Git本质上是一个版本控制器&#xff0c;可以对一个信息的多个版本进行一些控制&#xff0c;而能对版本…

腾讯mini项目-【指标监控服务重构】2023-08-16

今日已办 v1 验证 StageHandler 在处理消息时是否为单例&#xff0c;【错误尝试】 type StageHandler struct { }func (s StageHandler) Middleware1(h message.HandlerFunc) message.HandlerFunc {return func(msg *message.Message) ([]*message.Message, error) {log.Log…

mac 本地运行 http-proxy-middleware ,请求超时

const http require(http)"/customer": {target: "http://10.10.111.192:8080/",// target: "http://user.jinfu.baohan.com/",changeOrigin: true, // 是否启用跨域// 解决mac 代理超时问题headers: {Connection: "keep-alive"},// …

脚本:python绘制七夕爱心

文章目录 效果脚本Reference 效果 脚本 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 640 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CANVAS_CENTER_Y CANVAS_HEIGHT /…