jaeger集群集成flink进行链路采样(一):集群搭建

1,193 阅读3分钟

现有业务现状:

1、现有业务集群使用jeager进行数据采集,使用的是AllInOne策略,这种模式下jeager的服务端组件都在一个镜像里面,不适合生成环境,也不适合引入其他组件。

2、虽然在现有的AllInOne模式下把数据存储改为了es,复用了收集日志的es集群,但无用的链路过多,占用了过多的es存储空间,是的es搜索性能下降。

项目架构图

为了加入链路采样和引入其他组件,我先首先要搭建一套健全的jeager集群。

官方集群架构图:

image.png

项目实际采用架构图:

image.png

复用原有ingester组件,统一管理后端db。

集群搭建

1、jeager集群搭建

在k8s里面搭建jeager集群,我采用的方式是jeager operator,具体可以参考www.jaegertracing.io/docs/1.21/o…

按照操作步骤创建好角色和account之后,采用streaming strategy部署jeager集群,这种策略默认情况下只有会有collector、ingester、storage服务,而我们也需要收集我们集群里面的其他服务的日志,需要在默认配置里面加上agent:

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-streaming
  namespace: logging
spec:
  strategy: streaming
  collector:
    options:
      kafka: # <1>
        producer:
          topic: flink-span-dev
          brokers: host:9092
  ingester:
    options:
      kafka: # <1>
        consumer:
          topic: test-tracer
          brokers: host:9092
      ingester:
        deadlockInterval: 0 # <2>
  storage:
    type: elasticsearch
    options:
      es:
        server-urls: http://host:9200
  agent:
    strategy: DaemonSet
    options:
      log-level: debug 

完成启动之后,在k8s里面可以看到Service和pod

image.png

image.png

由于agent是以DaemonSet提供,需要在加一个Service提供给其他ns的服务进行调用

apiVersion: v1
kind: Service
metadata:
  labels:
    app: jaeger
  name: jaeger-agent
  namespace: logging
spec:
  clusterIP: None
  ports:
  - name: agent-zipkin-thrift
    port: 5775
    protocol: UDP
    targetPort: 5775
  - name: agent-compact
    port: 6831
    protocol: UDP
    targetPort: 6831
  - name: agent-binary
    port: 6832
    protocol: UDP
    targetPort: 6832
  selector:
    app: jaeger
    app.kubernetes.io/component: agent
    app.kubernetes.io/instance: simple-streaming
    app.kubernetes.io/managed-by: jaeger-operator
    app.kubernetes.io/name: simple-streaming-agent
    app.kubernetes.io/part-of: jaeger
  sessionAffinity: None
  type: ClusterIP

 到此为止,我们已经搭建了完整的jeager集群并且在collector和ingester中间加入了kafka。

2、flink集群

flink可以使用公司现有flink集群申请资源,在dev环境,我是使用native k8s搭建的的flink session集群进行测试,集群搭建方式参考官方文档:ci.apache.org/projects/fl…

使用flink进行消费:

(这里注意flink消费程序引用的flink版本号一定要和flink集群的版本号一致。)

由于jaeger 的collector发送到kafka的数据使用了protobuf格式,fllink进行消费的时候,需要首先将protobuf格式数据反序列化为java span格式,使用github.com/jaegertraci… 获得proto对应的java文件。

1、kafka consumer配置

kafkaModelSpanConsumer =  new FlinkKafkaConsumer011<>(topics, new ProtoUnMarshalerToModelSpan(), kafkaConsumerConfig());
public class ProtoUnMarshalerToModelSpan extends AbstractDeserializationSchema<Model.Span> {

private static final long serialVersionUID = 7952979116702613945L;

    @Override
    public Model.Span deserialize(byte[] message) throws IOException {
        Model.Span protoSpan = Model.Span.parseFrom(message);
        return protoSpan;
    }
}

2、使用session time窗口,采用process time 对链路进行收集,当sessionTime超过预设的时间,我们可以假定整体链路已经处理完毕,窗口进入处理方法中,针对完整链路,我们可以通过配置好的的异常策略配置(后续完善为基于Broadcast State动态更新配置)进行判断是否为异常链路,异常链路发送到下游,正常链路按配置的系数进行采样。最终将以上分类的数据发送到sink(kafka producer)中。sink中我们需要把span对象转换回protobuf格式数据,使用生成好的jeager java span进行序列化。

3、kafka producer配置 

public class SpanSerialization implements SerializationSchema<Model.Span> {

@Override
    public byte[] serialize(Model.Span element) {
return element.toByteArray();
    }
}

此时数据写回到kafka中,有jeager集群的ingester主键进行消费写入到es当中。

提交的flink集群运行情况:

image.png