解决方案:自媒体采集神器 内设一键文章采集伪原创工具v3.4

优采云 发布时间: 2022-09-27 22:19

  解决方案:自媒体采集神器 内设一键文章采集伪原创工具v3.4

  使用说明:

  打开注册机,随意填写用户名和号码,会得到一个用户名文件夹,里面收录一个jrtj+bjh+qehV3.4.密钥注册码文件。

  

  将计算出来的jrtj+bjh+qehV3.4.key文件移动到主程序目录打开。

  自媒体采集软件、今日头条、百家号、每日快报。

  

  采集速度还可以,也可以按发布时间排序。到达采集的文章基本与发布时间同步,内置一键伪原创。

  注册机和源码都发出去了,大家可以拿来研究一下,如果是小白就拿来玩玩。

  百度网盘提取码:vvaj

  解决方案:调用链追踪系统在伴鱼:OpenTelemetry 最佳实践案例分享

  在理论章节中,我们介绍了Banyu在调用链跟踪领域的研究工作。本章继续介绍Banyu调用链跟踪的实践。在正式介绍之前,先简单说明一下背景:2015年,在Banyu服务器启动的时候,技术团队做出了统一使用Go语言的决定。这一决定的影响主要体现在:

  内部基础架构不需要做跨语言支持技术选型会有轻微语言倾向1.早期实践1.1与Jaeger对接

  2019年,公司内部微服务逐渐增多,调用关系越来越复杂,工程师进行性能分析和排查的难度加大。这时,我们迫切需要一个调用链跟踪系统来帮助我们增强对服务器整体情况的了解。经过调查,我们决定使用Jaeger,这是CNCF孵化的一个同样基于Go语言的项目。当时服务的开发和治理还没有引入上下文,无论进程内调用还是跨进程调用都没有上下文传递。因此,早期引入调用链跟踪的重点是服务和服务治理框架的改造,包括:

  部署:测试环境采用一体机,在线环境采用直入式方案。整个过程前后花了大约一个月时间,我们在2019年Q3推出了第一版调用链追踪系统。随着被广泛采用的prometheus + grafana和ELK,我们终于有了调用链三要素(traces) 、日志(logs)和监控指标(metrics)中微服务集群的可观察性。

  下图是第一版调用链跟踪系统的数据上报路径*敏*感*词*。该服务在容器中运行。通过opentracing sdk埋点,将Jaeger的go-sdk上报给宿主机上的Jaeger-agent,后者进一步上报数据给Jaeger-collector,最后将调用链数据写入ES建立索引,图中的 Jaeger 后端。

  1.遇到的2个问题

  在理论章节中,我们介绍了Jaeger支持三种采样方式:

  这些采样方法都是基于头部的相干采样,我们在理论章节讨论了它们的优缺点。在 Banyu 的生产环境中,使用了限流采样策略:每个进程每秒最多采集 1 个 trace。这种策略虽然节省了资源,但其缺点在在线排查中逐渐暴露出来:

  一个进程收录多个接口:无论是固定概率采样还是限流采样,都会导致小流量接口采集饿死调用链的数据,饿死在线服务的错误是小概率事件,错误请求被采集的概率较小,导致采集到的调用链信息不大,导致问题的调用链丢失。2.调用链路径改造2.1 使用场景

  2020年,我们不断收到业务研发的反馈:能否完成采集trace?

  这促使我们重新思考如何改进调用链跟踪系统。我们做了一个简单的容量估算:目前,Jaeger 每天写入 ES 的数据量接近 100GB/天。如果需要全量采集trace数据,保守假设每个HTTP API服务的平均总QPS为100,那么完全存储全量数据需要10TB/天;乐观假设100名服务器研发人员每天查看1条trace,每条trace的平均大小为1KB,整体信噪比为1/10,000,000。可以看出,这件事本身的ROI是很低的。考虑到未来业务会继续增长,存储这些数据的价值会不断下降,所以放弃了完整的采集计划。退一步想一想:完整的 采集 真的是基本要求吗?事实上,情况并非如此。我们想要的是采集所有“有趣”的痕迹,而不是采集“无趣”的痕迹。

  根据Theory介绍的应用场景,其实第一版调用链追踪系统只支持稳态分析,业务研发迫切需要异常检测。为了支持这两种情况,我们必须求助于基于尾部的相干采样。与头部相干采样决定是否在第一个跨度采样相比,尾部相干采样允许我们在获得(接近)完整的轨迹信息后做出判断。理想情况下,只要能够合理制定采样判断逻辑,我们的调用链跟踪系统就可以采集到所有“有趣”的踪迹,而不是“无趣”的踪迹。

  2.2 架构设计

  自 2017 年以来,Jaeger 团队一直在讨论引入基于尾部的采样的可能性,但尚未得出结论。在与 Jaeger 工程师 jpkrohling 的*敏*感*词*沟通中,对方也确认 Jaeger 目前没有相关的支持计划。因此,我们不得不另谋出路。经过一番研究,我们发现OpenTelemetry刚刚进入CNCF SandBox,它的opentelemetry-collector子项目正好支持我们在现有架构上引入尾相干采样。

  2.2.1 个开放遥测采集器

  整个 OpenTelemetry 项目的目的是统一市场上遥测数据的标准,并提供驱动这些标准实施的组件和工具。 opentelemetry-collector 是这个生态系统的重要组成部分。其架构图如下:

  采集器内部有4个核心组件:

  使用不同的*敏*感*词*、处理器、导出器,我们可以组装一个或多个管道。

  opentelemetry-collector项目分为两部分:主项目opentelemetry-collector和社区贡献项目opentelemetry-collector-contrib,前者负责管理核心逻辑、数据结构和常用的Receiver、Processor、Exporters , Extensions 实现,后者负责接收一些社区贡献的组件。当然,贡献者主要来自可观察性SaaS解决方案提供商,如DataDog、Splunk、LightStep和一些公有云厂商。 opentelemtry-collector项目的插件管理方式使得Receiver、Processor、Exporter的定制开发成本非常低。当我们在做概念验证时,我们基本上可以在一两个小时内开发和测试一个组件。除此之外,opentelemetry-collector-contrib 还提供了开箱即用的尾采样处理器。

  由于opentelemetry-collector是OpenTelemetry团队推动标准实施的重要组成部分,而且OpenTelemetry本身不提供独立的数据存储和索引实施方案,兼容市面上流行的调用链追踪框架,如 Zipkin、Jaeger、OpenCensus,在兼容性上做了很多工作。通过Receivers和Exporters的使用,我们可以用它来代替jaeger-agent,或者放在jaeger-agent和jaeger-collector之间,必要时在jaeger-agent和jaeger-collector之间部署多个collector。另外,如果有一天我们要更换 jaeger-backend,比如新发布的 Grafana Tempo,我们可以轻松做到,在一个 Pipeline 中使用多个 Pipelines 或多个 Exporter 灰度上线,逐步替换。

  2.2.2举报渠道

  在上述研究和现有架构的基础上,我们设计了第二版调用链跟踪架构,如下图所示:

  将jaeger-agent替换为一组opentelemetry-collector,即图中的otel-agent;同时在otel-agent和jaeger-collector之间添加另一组opentelemetry-collector,即图中的otel-collector。 otel-agent采集主机上不同服务上报的trace数据,将打包后的批次发送给otel-collector,otel-collector负责尾部相干采样,继续输出“感兴趣”的trace给jaeger-collector原创架构,负责将数据放入ElasticSearch并建立索引。

  这里还有一个问题需要解决:要实现整个架构的高可用,需要部署多个otel-collector实例。如果使用简单的负载均衡策略,不同的 otel-agent 和单个 otel-agent 将在不同的时间上报。数据可能会随机上报到一个otel-collector实例,这意味着同一trace的不同span不能集中在同一个otel-collector instance上,这将导致同一trace的不同span的决策不一致。也就是说,它不是相干采样;也会导致尾采样时提供给判断的数据不完整。解决方法很简单:让otel-agent根据traceID做负载均衡。

  在研究阶段,我们碰巧看到opentelemetry-collector社区也有这个支持计划,前面提到的工程师jpkrohling正在通过添加loadbalancingexporter来解决。尽管直接使用最前沿的版本存在一定的风险,但我们还是决定尝试一下。在概念验证阶段,我们确实发现了新功能的一些问题,但是通过反馈(#1621) 和贡献(#1677、#1690)),最终结果是一个调用链跟踪系统,它按预期执行尾部相干采样。

  2.3 条抽样规则

  尾部相干采样的数据路径已准备就绪,下一步是确定和实施采样规则。

  2.3.1“有趣”的调用链

  什么是“有趣的”调用链?任何研发在分析和故障排除过程中想要查询的调用链都是“有趣”的调用链。但是,它必须是在代码中实现的确定性规则。根据日常排查经验,我们首先确定了以下三种情况:

  满足任何条件,调用链被认为是“有趣的”。在 Banyu,只要服务打印 ERROR 级别的日志,就会触发报警,研发人员会收到即时消息或电话报警。如果能保证采集到触发告警的调用链数据,研发人员会有更好的排查体验。很大的进步;我们的 DBA 团队认为超过 200ms 的查询请求被判定为慢查询。如果能保证这些请求的调用链,可以极大的方便导致查询慢的请求的研发;对于在线服务,如果延迟太高,用户体验会下降,但到什么程度会导致体验明显下降。我们暂时没有数据支持,所以先设置为1s,可以随时修改阈值。

  当然,以上条件也不是绝对的。我们可以在以后的实践中根据反馈来调整和添加新的规则,比如单个请求引起的数据库和缓存查询次数超过一定的阈值等。

  2.3.2 个采样管道

  

  在第二版系统中,我们期望同时支持稳态分析和异常检测,所以采样过程必须基于概率或限流方法采集部分trace,但还需要遵循上面提出的“有趣”规则 采集 使跟踪的一部分。在撰写本文时,尾采样处理器支持 4 种策略:

  我们可以使用的有 numeric_attribute、string_attribute 和 rate_limiting。

  可以使用 rate_limiting 实现“概率或电流限制采集跟踪的一部分”吗? rate_limiting 只能根据每秒通过的 span 数量来限制电流,但是在高峰期、低峰期和业务阶段,span 的数量是不同的。每个trace的平均span数也会随着微服务组的大小和依赖关系的变化而变化,所以设置spans_per_second会让我们很难合理评估这个参数的最终效果,所以直接使用rate_limiting的方案被拒绝。

  是否可以直接使用numeric_attribute和string_attribute实现“根据规则跟踪的另一部分采集”?跨度中也有布尔标签。以“如果调用链上打印ERROR级别日志”为例,按照规范,我们会记录span.SetTag("error", true),但是tailsamplingprocessor不支持bool_attribute;另外,我们以后可能会有更复杂的组合条件,单靠numeric_attribute和string_attribute是无法实现的。

  经过反复分析,我们最终决定采用Processor的链式结构,将多个Processor组合起来完成采样。管道如下图所示:

  其中probattr负责trace级别的概率抽样,anomaly负责分析每个trace是否符合“有趣”的规则。如果两者中的一个被命中,就会标记trace,即sampling.priority。最后在tailsamplingprocessor上配置一条规则,如下图:

  1

  2

  3

  4

  5

  6

  7

  8

  9

  tail_sampling:

  政策:

  [

  {

  名称:sample_with_high_priority,

  类型:数字属性,

  numeric_attribute: { key: "sampling.priority", min_value: 1, max_value: 1 }

  }

  ]

  这里的sampling.priority是整数类型,当前值只有0和1。按照上面的配置,所有sampling.priority = 1的trace都会是采集。以后可以添加更多 采集 优先级,必要时进行上采样或下采样。

  3.部署实现

  采样规则建立后,整个方案已经跑通了,接下来就是进入部署实施阶段了。

  3.1 在线准备3.1.1 基础库改造

  动态更新 Tracer

  在系统的第一个版本中,每个进程启动时从apollo获取采样配置,并传递给Jaeger sdk,Jaeger sdk用该配置初始化GlobalTracer。 GlobalTracer 会在第一个 trace 出现时决定是否采集,并将这个决定传递给,即 head coherent sampling。在实施新架构时,我们需要 Jaeger sdk 报告所有跟踪数据。为了让这个过程更顺畅,我们对 Jaeger sdk 配置做了两处改动:

  日志库改造

  为了保证必须采用已经打印了ERROR级别日志的调用链,我们还在通用日志库的对应位置标记了带有error标签的span。

  3.1.2 监控看板配置

  opentelemetry-collector 内部使用 OpenCensus sdk 来掩埋许多有用的监控指标,并根据 Open Metrics 规范公开数据。由于指标数量不多,我们已经将大部分指标配置到 Grafana Dashboard 中,包括:

  以下是我们认为在实践中很重要的一些指标:

  xxx_receiver_accepted/refused_spans

  

  这里的 xxx 是指管道中使用的任何*敏*感*词*。这里实际上有两个特定的指标:*敏*感*词*接收到的跨度数和*敏*感*词*拒绝的跨度数。两者可以结合其他指标来分析当前情况下系统的入口流量瓶颈。

  xxx_exporter_send(失败)_spans

  这里的 xxx 指的是任何管道中使用的导出器。这里实际上有两个具体的指标:exporter 成功发送的 span 数量和 exporter 发送失败的 span 数量。两者可以结合其他指标分析当前情况下系统的出口流量瓶颈。

  otelcol_processor_tail_sampling_sampling_trace_dropped_too_early

  介绍上述指标需要简要了解尾采样处理器的工作原理。在分布式环境中,tailsamplingprocessor永远无法判断当前时刻是否已经采集到了trace的所有span,所以需要设置一个超时时间,也就是这里的decision_wait,假设decision_wait = 5s下面。 Trace Data进入处理器后,会被放入两个数据结构中:

  一个固定大小的队列和一个哈希表,它们共同实现了跟踪数据的 LRU 缓存。同时,处理器会按照每秒一个batch来组织所有进入它的trace,内部总共维护5个batch(decision_wait)。每秒取出最旧的batch,判断其中的trace是否符合采样规则,然后传递给后续的处理器:

  如果在做采样决策时发现对应的trace已经被LRU缓存清空,则认为是“trace drop too early”,表示tailsamplingprocessor已经超载。理论上,如果该指标不等于0,则尾部相干采样函数处于异常状态。

  3.2灰度方案

  如上所述,转换的实现需要 Jaeger sdk 报告完整的跟踪。由于“是否上报”的决定是在请求入口服务(即 HTTP 服务)时做出的,并且会随着跨进程调用传播到下游服务,而 Banyu 服务器内部的入口服务已经按照业务,所以灰度的流程可以根据入口服务进行,从低流量低级别的入口服务开始,然后逐步加入高流量和高级别的入口服务,最后启用全默认采样,发现并解决过程中的潜在问题。 .

  3.3 资源消耗优化

  新版架构所需资源与旧版相差不大:

  在逐步上线所有门户服务之前,我们已经做了比较全面的风险评估。启用完整的采集后,主要是增加主机的network i/o。在千兆网卡(约300MB/s)的支持下,增加的i/o量远未达到瓶颈。在实施过程中,业务团队并没有察觉到。但在灰度上线的过程中,我们也发现并解决了几个问题。

  3.3.1 热点服务问题

  请求量因服务而异。个别业务上报量过大会导致不同otel-agent的流量不均衡,并且otel-agent的CPU在高峰期经常会超过警戒线。我们通过增加热点服务实例和减少单个实例的请求量来间接平衡每个otel-agent承载的流量。

  3.3.2 过滤器下推

  在生产环境中,我们默认维护过去 7 天的跟踪数据。在分析 ES 中的索引 jaeger-span-* 的过程中,不出所料,我们看到幂律的存在:

  仔细分析表明,超过 50% 的 span 属于 apolloConfigCenter.*。熟悉apollo开发的人应该都知道,apollo sdk通常通过长轮询从元数据中心拉取配置信息并缓存到本地,而应用层的服务配置则是通过本地缓存获取的。所以其实这里所有的 apolloConfigCenter.* 都只是本地访问,不是跨进程调用,span数据值比较低,可以忽略。所以我们开发了一个处理器,通过正则匹配 spanName 过滤 span,并将其部署到 otel-agent,我们称之为 filter pushdown。部署上线后,ES的索引量下降了50%以上,目前的索引量为每天40-50GB; otel-collector和otel-agent的CPU消耗也降低了近50%。

  3.4 创建 SLO

  在Banyu服务器中,在线故障排除的第一个条目通常是即时消息。告警平台会将引发告警的traceID和日志注入到消息中,并提供链接页面供研发快速查看告警相关的调用链信息以及整个调用链上各个服务打印的日志。基于此,我们制定了新版调用链跟踪系统的SLO:

  名字

  研发相关跟踪数据采集成功率

  SLI 规范

  研发关心的trace数量为采集/研发关心的trace数量

  SLI 实现

  包括跟踪数据在内的服务告警信息数量/服务告警信息数量

  查询

  sum(alertmanager_alert_total{trace_exists="true"})/sum(alertmanager_alert_total)

  目标

  99%

  目前我们刚刚在报警平台中增加了对这个SLI埋点的支持。目前还有一些服务没有升级相关依赖,所以这个指标还不能反映所有服务的情况。我们将继续推进各项服务的全面升级,并根据上述SLO要求新版本的系统。

  4.总结

  在开源项目的帮助下,我们能够以极少的人力解决当前便鱼内部调用链跟踪应用的稳态分析和异常检测需求,同时也为开源项目和社区。调用链跟踪是可观察性平台的重要组成部分。未来,我们将继续专注于遥测数据的整合,为研发提供更全面、更一致的服务观察和分析体验。

  5.参考作者介绍

  郑和,Banyu 技术团队架构师。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线