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

news/2024/5/18 22:44:01 标签: clickhouse, prometheus, elasticsearch

今日已办

Collector 指标聚合

由于没有找到 Prometheus 官方提供的可以聚合指定时间区间内的聚合函数,所以自己对接Prometheus的api来聚合指定容器的cpu_avg、cpu_99th、mem_avg

实现成功后对接小组成员测试完提供的时间序列和相关容器,将数据记录在表格中

image-20230829135852878

  1. SpringBoot RestController
  2. Jackson json serialization
  3. data aggregation
/**
 * @author xzx
 * @date 2023/8/29
 */
@RestController
@RequestMapping("/prometheus")
public class PrometheusController {

    @GetMapping
    public ResponseResult GetMetrics(@RequestParam String ip,
                                     @RequestParam String containerName,
                                     @RequestParam String startDay,
                                     @RequestParam String startHour,
                                     @RequestParam String startMinute,
                                     @RequestParam String startSecond,
                                     @RequestParam String endDay,
                                     @RequestParam String endHour,
                                     @RequestParam String endMinute,
                                     @RequestParam String endSecond,
                                     @RequestParam int idx) {


        String queryCpu = "sum(irate(container_cpu_usage_seconds_total{name=\"" + containerName + "\"}[5m])) without (cpu)";
        String start = startDay + "T" + startHour + ":" + startMinute + ":" + startSecond + ".000Z";
        String end = endDay + "T" + endHour + ":" + endMinute + ":" + endSecond + ".000Z";
        List<List<Object>> cpuValues = getValues(ip, start, end, queryCpu, idx);

        List<Double> cpuList = new ArrayList<>();
        Double sum = (double) 0;
        for (List<Object> value : cpuValues) {
            if (value.size() == 2) {
                Double v = Convert.toDouble(value.get(1));
                sum += v;
                cpuList.add(v);
            }
        }
        Collections.sort(cpuList);

        String queryMem = "container_memory_usage_bytes{name=\"" + containerName + "\"}";
        List<List<Object>> memValues = getValues(ip, start, end, queryMem, 0);
        long memSum = 0;
        for (List<Object> value : memValues) {
            if (value.size() == 2) {
                memSum += Convert.toLong(value.get(1));
            }
        }

        PrometheusMetricsData data = new PrometheusMetricsData()
                .setCpu95th(cpuList.get(Convert.toInt(0.95 * cpuList.size())) * 100)
                .setCpuAvg(sum / Convert.toDouble(cpuValues.size()) * 100)
                .setMemAvg(memSum / memValues.size());

        return ResponseResult.okResult(data);
    }

    private List<List<Object>> getValues(String ip, String start, String end, String queryCpu, int idx) {
        String body = HttpRequest.get("http://" + ip + "/prometheus/api/v1/query_range?query=" + queryCpu + "&start=" + start + "&end=" + end + "&step=1s")
                .timeout(20000)
                .execute().body();
        PrometheusRespDto prometheusRespDto = JSONUtil.toBean(body, PrometheusRespDto.class);


        List<PromResult> result = prometheusRespDto.getData().getResult();
        List<List<Object>> values = result.get(idx).getValues();

        return values;
    }

}

测试

确定测试方案

我们打算在 10 万到 100万之间摸一个不会丢的量以及合适的并发量,作为不同 collector 测存储和查询的前提

我们能不能固定一个数量,然后使用相同的代码来上报相同的trace(只是可以控制线程睡眠时间)来调整耗时,让两种collector都能完整的上报所有数据,保证不回丢失,最后来计算存储大小

image-20230829205845583

image-20230829205535246

image-20230829210324486

image-20230829210653746

image-20230829211857226

编写测试函数

func TestTraceSpan(t *testing.T) {
	ctx := context.Background()
	res, err := resource.New(ctx,
		resource.WithFromEnv(),
		resource.WithProcess(),
		resource.WithTelemetrySDK(),
		resource.WithHost(),
		resource.WithAttributes(
			attribute.String("service.name", "test-service"),
			attribute.String("library.language", "go"),
		),
	)
	if err != nil {
		return
	}
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	tracerProviderShutDown := otelclient.InitTraceProvider(res, ctx)
	defer tracerProviderShutDown()

	testTracer := otel.Tracer("test_demo", trace.WithInstrumentationAttributes(attribute.String("demo.author", "xzx")))
	group := sync.WaitGroup{}
	for i := 0; i < 50; i++ {
		group.Add(1)
		go func(num int) {
			for j := 0; j < 4000; j++ {
				rootCtx, span := testTracer.Start(ctx, "demo_root_span"+string(rune(num)), trace.WithSpanKind(trace.SpanKindProducer), trace.WithAttributes(attribute.String("user.username", uuid.NewString())))
				for k := 0; k < 4; k++ {
					_, subSpan := testTracer.Start(rootCtx, "demo_sub_span", trace.WithSpanKind(trace.SpanKindInternal))
					if subSpan.IsRecording() {
						subSpan.SetAttributes(attribute.String("user.uuid", uuid.NewString()),
							attribute.Int64("user.ip", int64(uuid.New().ID())))
					}
					time.Sleep(10 * time.Millisecond)
					subSpan.End()
				}
				time.Sleep(time.Millisecond * 41)
				span.End()
			}
			group.Done()
		}(i)
	}
	group.Wait()
}

汇总进度和问题

  1. es 的监控平台的 文档数 和 kibana 的数据条数不一致,最后以 kibana 的 hits 为基准
  2. 测试上报最终的数据丢失,测试不准确,由于并发数太多了,大多数据都存储在内存中,由于超时被丢弃
  3. 官方的 otel-collector 的数据库和表创建耗费时间长
  4. 协助测试组员的记录来聚合容器指标,记录表格内容,完成 trace-collector、metric-collector的测试结果表格
  5. clickhouse的数据**“幻读”**
    1. 存在副本
    2. 同步时间较长,写入后需要一段时间后才能看到另一个节点的数据拷贝
    3. 删除通过SQLDROP Database database_name SYNC 无法drop所有节点的数据库,故删除后一段时间后又会查询到该数据库的数据
  6. 测试周期较长,测试结果的采集不够自动化,测试样例和次数不太丰富,由于前期的测试方案方向和方法不正确,走了很多外路,不过在组员的努力和导师的指导下跌跌撞撞勉强完成测试结果
  7. 。。。

明日待办

  1. PPT制作
  2. 录制Showcase视频
  3. 绘制Showcase表格和图像
  4. 输出测试结果的总结

http://www.niftyadmin.cn/n/5049915.html

相关文章

SSM流程

控制层 调用 服务层 调 dao层 框架搭建后 在 controller&#xff08;控制层&#xff09; 调用service 接口中的service实现类&#xff0c;在service实现类中调用dao接口 在到接口调用 mapper里的方法 id为方法名 Controller //标记当前类为控制层的类 Service 声明服…

【LeetCode-简单题】501. 二叉搜索树中的众数

文章目录 题目方法一&#xff1a;暴力哈希方法二&#xff1a;利用二叉搜索树的特性&#xff08;递归双指针&#xff09; 题目 方法一&#xff1a;暴力哈希 这是针对于普通二叉树的解法 统计number出现次数 然后将次数最大的众数集 取出来 Map<Integer , Integer > map …

《湖科大教书匠计算机网络》学习笔记总目录+思维导图

本篇文章是对《湖科大教书匠计算机网络》所有知识点的笔记总结归档和计算机网络的思维导图 学习视频&#xff1a;计算机网络微课堂&#xff08;湖科大教书匠&#xff09; pdf百度云地址&#xff1a;pdf文档 提取码&#xff1a;yw4y 思维导图 各章节链接 第1章&#xff08…

OpenCV两张图片实现稀疏点云的生成

1 E矩阵 1.1 由F到E E K T ∗ F ∗ K E K^T * F * K EKT∗F∗K E 矩阵可以直接通过之前算好的 F 矩阵与相机内参 K 矩阵获得 Mat E K.t() * F * K;相机内参获得的方式是一个较为复杂的方式&#xff0c;需要使用棋盘进行定位获得&#xff0c;我们这里直接使用了 OpenMVG 提…

VSCode 和 CLion

文章目录 一、VSCode1、文档2、插件3、智能编写4、VSCode 与 C&#xff08;1&#xff09;安装&#xff08;2&#xff09;调试&#xff08;a&#xff09;使用 CMake 进行跨平台编译与调试&#xff08;b&#xff09;launch.json&#xff08;c&#xff09;传参 &#xff08;3&…

解决安装 RabbitMQ 安装不成功的问题

由于RabbitMQ是基于erlang的&#xff0c;所以&#xff0c;在正式安装RabbitMQ之前&#xff0c;需要先安装一下erlang。 1、下载mq https://www.rabbitmq.com/download.html 2、下载erlang&#xff08;点击下载路径根据下载的MQ版本对应下载erl版本&#xff09; https://www.…

CeresPCL ICP精配准(点到点)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 (1)在目标点云P中取点集 p i ∈ P p_i∈P p

Spring Boot中的Binder类

介绍 Spring Boot中的Binder类是一个用于绑定属性的工具类。它可以将配置文件中的属性值绑定到Java对象中&#xff0c;从而方便地进行配置管理。 简单示例 import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.env.Environmen…