现有业务现状:
1、现有业务集群使用jeager进行数据采集,使用的是AllInOne策略,这种模式下jeager的服务端组件都在一个镜像里面,不适合生成环境,也不适合引入其他组件。
2、虽然在现有的AllInOne模式下把数据存储改为了es,复用了收集日志的es集群,但无用的链路过多,占用了过多的es存储空间,是的es搜索性能下降。
项目架构图
为了加入链路采样和引入其他组件,我先首先要搭建一套健全的jeager集群。
官方集群架构图:
项目实际采用架构图:
复用原有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
由于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集群运行情况: