腾讯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.mzph.cn/news/83987.shtml

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

相关文章

创造性地解决冲突

1、冲突的根本原因是矛盾双方存在不可调和的目标冲突。 2、要知己知彼&#xff1a; 知己&#xff1a;就是对自己的问题、需求进行客观定义&#xff0c;说明需求和问题的意义或价值、阐述解决方案和期望效果&#xff1b; 知彼&#xff1a;站在对方立场&#xff0c;深挖对方真…

根据3d框的八个顶点坐标,求他的中心点,长宽高和yaw值(Python)

要从一个3D框的八个顶点求出它的中心点、长、宽、高和yaw值&#xff0c;首先需要明确框的几何形状和坐标点的顺序。通常这样的框是一个矩形体&#xff08;长方体&#xff09;&#xff0c;但其方向并不一定与坐标轴平行。 以下是一个步骤来解决这个问题&#xff1a; 求中心点&a…

Unity Bolt UGUI事件注册方式总结

Bolt插件提供了丰富的事件注册方式&#xff0c;开发者几乎不用编写任何代码就可以完成事件的注册&#xff0c;进行交互。下面是我使用UI事件注册的相关总结。 1、通过UI控件自身拖拽实现事件的注册。 Button的事件注册&#xff1a; 新建一个UnityEvent事件&#xff0c; Butt…

Kafka消费者组重平衡(二)

文章目录 概要重平衡通知机制消费组组状态消费端重平衡流程Broker端重平衡流程 概要 上一篇Kafka消费者组重平衡主要介绍了重平衡相关的概念&#xff0c;本篇主要梳理重平衡发生的流程。 为了更好地观察&#xff0c;数据准备如下&#xff1a; kafka版本&#xff1a;kafka_2.1…

nodejs定时任务

项目需求&#xff1a; 每5秒执行一次&#xff0c;多个定时任务错开&#xff0c;即cron表达式中斜杆前带数字&#xff0c;例如 ‘1/5 * * * * *’定时任务准时&#xff0c;延误低 搜索了nodejs的定时任务&#xff0c;其实不多&#xff0c;找到了以下三个常用的&#xff1a; n…

OpenCV中的HoughLines函数和HoughLinesP函数到底有什么区别?

一、简述 基于OpenCV进行直线检测可以使用HoughLines和HoughLinesP函数完成的。这两个函数之间的唯一区别在于,第一个函数使用标准霍夫变换,第二个函数使用概率霍夫变换(因此名称为 P)。概率版本之所以如此,是因为它仅分析点的子集并估计这些点都属于同一条线的概率。此实…

2D游戏开发和3D游戏开发有什么不同?

2D游戏开发和3D游戏开发是两种不同类型的游戏制作方法&#xff0c;它们之间有一些显著的区别&#xff1a; 1. 图形和视觉效果&#xff1a; 2D游戏开发&#xff1a; 2D游戏通常使用二维图形&#xff0c;游戏世界和角色通常在一个平面上显示。这种类型的游戏具有平面的外观&…

数据仓库模型设计V2.0

一、数仓建模的意义 数据模型就是数据组织和存储方法&#xff0c;它强调从业务、数据存取和使用角度合理存储数据。只有将数据有序的组织和存储起来之后&#xff0c;数据才能得到高性能、低成本、高效率、高质量的使用。 高性能&#xff1a;良好的数据模型能够帮助我们快速查询…

shell脚本命令

Shell命令是在类Unix操作系统中使用的命令行解释器&#xff08;shell&#xff09;中执行的命令。Shell命令可以用于执行系统命令、操作文件、进行文本处理、管理进程等。以下是一些常见的Shell命令&#xff1a; 1. ls&#xff1a;列出当前目录下的文件和文件夹。 2. cd&#x…

界面组件DevExpress WinForms v23.1亮点 - 全新升级HTML CSS模板

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

2020-2023中国高等级自动驾驶产业发展趋势研究-概念界定

1.1 概念界定 自动驾驶发展过程中&#xff0c;中国出现了诸多专注于研发L3级以上自动驾驶的公司&#xff0c;其在业界地位也越来越重要。本报告围绕“高等级自动驾驶” 展开&#xff0c;并聚焦于该技术2020-2023年在中国市场的变化趋势进行研究。 1.1.1 什么是自动驾驶 自动驾驶…

C#中的方法

引言 在C#编程语言中&#xff0c;方法是一种封装了一系列可执行代码的重要构建块。通过方法&#xff0c;我们可以将代码逻辑进行模块化和复用&#xff0c;提高代码的可读性和可维护性。本文将深入探讨C#中的方法的定义、参数传递、返回值、重载、递归等方面的知识&#xff0c;…

小型水库雨水情测报和大坝安全监测解决方案

一、建设背景 我国小型水库数量众多&#xff0c;大多由农村集体经济组织管理&#xff0c;灌溉、供水、防洪、生 态效益突出&#xff0c;是农业生产、农民生活、农村发展和区域防洪的重要基础设施&#xff0c;实施乡 村振兴战略和生态文明建设的重要支撑保障。由于小型水库工程存…

zabbix自定义监控内容案例

一、自定义监控内容 案列&#xff1a;自定义监控客户端服务器登录的人数需求&#xff1a;限制登录人数不超过 3 个&#xff0c;超过 3 个就发出报警信息 1、在客户端创建自定义key 明确需要执行的linux命令 创建zabbix监控项配置文件&#xff0c;用于自定义Key #在zabbix的…

小谈设计模式(3)—策略模式

小谈设计模式&#xff08;3&#xff09;—策略模式 专栏介绍专栏地址专栏介绍 策略模式主要角色环境&#xff08;Context&#xff09;抽象策略&#xff08;Strategy&#xff09;具体策略&#xff08;Concrete Strategy&#xff09;角色总结 核心思想封装算法定义抽象策略使用环…

Selenium Grid 的搭建方法

传统 Selenium Grid 的搭建方法 搭建一个具有 1 个 Node 的 Selenium Grid。那么通常来讲我们需要 2 台机器&#xff0c;其中一台作为 Hub&#xff0c;另外一台作为 Node&#xff0c;并要求这两台机器已经具备了 Java 执行环境。 1.通过官网下载 selenium-server-standalone-…

SpringMVC之JSON数据返回异常处理机制

目录 前言 一、JSON数据返回 1.导入依赖 2.配置spring-mvc.xml 3.使用ResponseBody注解 4.Jackson 4.1.介绍 4.2.常用注解 二、异常处理机制 1.为什么要全局异常处理 2.异常处理思路 3.SpringMVC异常分类 4.综合案例 4.1.异常处理方式一 4.2.异常处理方式二 4.3…

git提示:remote origin already exists

目录 问题场景 问题原因 问题解决 问题场景 在GitLab中新建仓库后&#xff0c;然后将本地项目提交提示&#xff1a;remote origin already exists. 问题原因 error: remote origin already exists. 错误&#xff1a;远程源点已存在&#xff08;翻译&#xff09; 出现该错误的…

AI AIgents时代-(四.)应用上手

HuggingGPT & MetaGPT . &#x1f7e2; HuggingGPT HuggingGPT是一个多模型调用的 Agent 框架&#xff0c;利用 ChatGPT 作为任务规划器&#xff0c;根据每个模型的描述来选择 HuggingFace 平台上可用的模型&#xff0c;最后根据模型的执行结果生成总结性的响应。 这个项…

软件测试 —— 答疑篇

什么是软件测试&#xff1a; 软件测试是不是就是找 bug &#xff1f; 软件测试就是证明软件不存在错误的过程 软件测试就是为了证明程序能够正确运行 刚新买来一部手机&#xff0c;我们要干什么&#xff1f; 一场考试 , 做完一遍题目之后 , 进行一遍检查 , 就是在 "…