<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Apache SkyWalking – 博客</title>
    <link>/zh/</link>
    <description>Recent content in 博客 on Apache SkyWalking</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/zh/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Zh: 使用 eBPF 提升 HTTP 可观测性 - L7 指标和追踪</title>
      <link>/zh/ebpf-enhanced-http-observability-l7-metrics-and-tracing/</link>
      <pubDate>Thu, 12 Jan 2023 00:00:00 +0000</pubDate>
      
      <guid>/zh/ebpf-enhanced-http-observability-l7-metrics-and-tracing/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;banner.jpg&#34; alt=&#34;banner&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;Apache SkyWalking 是一个开源应用性能管理系统，帮助用户收集和聚合日志、追踪、指标和事件，并在 UI 上显示。在&lt;a href=&#34;/zh/diagnose-service-mesh-network-performance-with-ebpf/&#34;&gt;上一篇文章&lt;/a&gt;中，我们介绍了如何使用 Apache SkyWalking Rover 分析服务网格环境中的网络性能问题。但是，在商业场景中，用户通常依靠成熟的第 7 层协议（如 HTTP）来进行系统之间的交互。在本文中，我们将讨论如何使用 eBPF 技术来分析第 7 层协议的性能瓶颈，以及如何使用网络采样来增强追踪系统。&lt;/p&gt;
&lt;p&gt;本文将演示如何使用 &lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache SkyWalking&lt;/a&gt; 与 &lt;a href=&#34;https://ebpf.io/what-is-ebpf/&#34;&gt;eBPF&lt;/a&gt; 来增强 HTTP 可观察性中的指标和追踪。&lt;/p&gt;
&lt;h2 id=&#34;http-协议分析&#34;&gt;HTTP 协议分析&lt;/h2&gt;
&lt;p&gt;HTTP 是最常用的 7 层协议之一，通常用于为外部方提供服务和进行系统间通信。在下面的章节中，我们将展示如何识别和分析 HTTP/1.x 协议。&lt;/p&gt;
&lt;h3 id=&#34;协议识别&#34;&gt;协议识别&lt;/h3&gt;
&lt;p&gt;在 HTTP/1.x 中，客户端和服务器通过两端的单个文件描述符（File Descriptor）进行通信。图 1 显示了涉及以下步骤的通信过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connect/Accept：客户端与 HTTP 服务器建立连接，或者服务器接受客户端的连接。&lt;/li&gt;
&lt;li&gt;Read/Write（多次）：客户端或服务器读取和写入 HTTPS 请求和响应。单个请求 - 响应对在每边的同一连接内发生。&lt;/li&gt;
&lt;li&gt;Close：客户端和服务器关闭连接。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了获取 HTTP 内容，必须从此过程的第二步读取它。根据 &lt;a href=&#34;http://rfc-editor.org/rfc/rfc2068.html&#34;&gt;RFC&lt;/a&gt; 定义，内容包含在 4 层协议的数据中，可以通过解析数据来获取。请求和响应对可以相关联，因为它们都在两端的同一连接内发生。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f1.png&#34; alt=&#34;图 1：HTTP 通信时间线。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 1：HTTP 通信时间线。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;http-管线化&#34;&gt;HTTP 管线化&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/HTTP_pipelining&#34;&gt;HTTP 管线化（Pipelining）&lt;/a&gt;是 HTTP/1.1 的一个特性，允许在等待对应的响应的情况下在单个 TCP 连接上发送多个 HTTP 请求。这个特性很重要，因为它确保了服务器端的响应顺序必须与请求的顺序匹配。&lt;/p&gt;
&lt;p&gt;图 2 说明了这是如何工作的，考虑以下情况：HTTP 客户端向服务器发送多个请求，服务器通过按照请求的顺序发送 HTTP 响应来响应。这意味着客户端发送的第一个请求将收到服务器的第一个响应，第二个请求将收到第二个响应，以此类推。&lt;/p&gt;
&lt;p&gt;在设计 HTTP 解析时，我们应该遵循这个原则，将请求数据添加到列表中，并在解析响应时删除第一个项目。这可以确保响应按正确的顺序处理。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f2.png&#34; alt=&#34;图 2： HTTP/1.1 管道。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 2： HTTP/1.1 管道。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;指标&#34;&gt;指标&lt;/h3&gt;
&lt;p&gt;根据前文提到的 HTTP 内容和流程拓扑图的识别，我们可以将这两者结合起来生成进程间的指标数据。&lt;/p&gt;
&lt;p&gt;图 3 显示了目前支持两个进程间分析的指标。基于 HTTP 请求和响应数据，可以分析以下数据：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;指标名称&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;单位&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;请求 CPM（Call Per Minute）&lt;/td&gt;
&lt;td&gt;计数器&lt;/td&gt;
&lt;td&gt;计数&lt;/td&gt;
&lt;td&gt;HTTP 请求计数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;响应状态 CPM (Call Per Minute)&lt;/td&gt;
&lt;td&gt;计数器&lt;/td&gt;
&lt;td&gt;计数&lt;/td&gt;
&lt;td&gt;每个 HTTP 响应状态码的计数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;请求包大小&lt;/td&gt;
&lt;td&gt;计数器 / 直方图&lt;/td&gt;
&lt;td&gt;字节&lt;/td&gt;
&lt;td&gt;请求包大小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;响应包大小&lt;/td&gt;
&lt;td&gt;计数器 / 直方图&lt;/td&gt;
&lt;td&gt;字节&lt;/td&gt;
&lt;td&gt;响应包大小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;客户端持续时间&lt;/td&gt;
&lt;td&gt;计数器 / 直方图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;客户端单个 HTTP 响应的持续时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;服务器持续时间&lt;/td&gt;
&lt;td&gt;计数器 / 直方图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;服务器端单个 HTTP 响应的持续时间&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&#34;f3.png&#34; alt=&#34;图 3：进程到进程指标。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 3：进程到进程指标。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;http-和追踪&#34;&gt;HTTP 和追踪&lt;/h2&gt;
&lt;p&gt;在 HTTP 过程中，如果我们能够从原始数据中解包 HTTP 请求和响应，就可以使用这些数据与现有的追踪系统进行关联。&lt;/p&gt;
&lt;h3 id=&#34;追踪上下文标识&#34;&gt;追踪上下文标识&lt;/h3&gt;
&lt;p&gt;为了追踪多个服务之间的请求流，追踪系统通常在请求进入服务时创建追踪上下文，并在请求 - 响应过程中将其传递给其他服务。例如，当 HTTP 请求发送到另一个服务器时，追踪上下文包含在请求头中。&lt;/p&gt;
&lt;p&gt;图 4 显示了 Wireshark 拦截的 HTTP 请求的原始内容。由 Zipkin Tracing 系统生成的追踪上下文信息可以通过头中的 “X-B3” 前缀进行标识。通过使用 eBPF 拦截 HTTP 头中的追踪上下文，可以将当前请求与追踪系统连接起来。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f4.png&#34; alt=&#34;图 4：Wireshark 中的 HTTP Header 视图。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 4：Wireshark 中的 HTTP Header 视图。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;trace-事件&#34;&gt;Trace 事件&lt;/h3&gt;
&lt;p&gt;我们已经将事件这个概念加入了追踪中。事件可以附加到跨度上，并包含起始和结束时间、标签和摘要，允许我们将任何所需的信息附加到追踪中。&lt;/p&gt;
&lt;p&gt;在执行 eBPF 网络分析时，可以根据请求 - 响应数据生成两个事件。图 5 说明了在带分析的情况下执行 HTTP 请求时发生的情况。追踪系统生成追踪上下文信息并将其发送到请求中。当服务在内核中执行时，我们可以通过与内核空间中的请求 - 响应数据和执行时间交互，为相应的追踪跨度生成事件。&lt;/p&gt;
&lt;p&gt;以前，我们只能观察用户空间的执行状态。现在，通过结合追踪和 eBPF 技术，我们还可以在内核空间获取更多关于当前追踪的信息，如果我们在追踪 SDK 和代理中执行类似的操作，将对目标服务的性能产生较小的影响。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f5.png&#34; alt=&#34;图 5：分析 HTTP 请求和响应的逻辑视图。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 5：分析 HTTP 请求和响应的逻辑视图。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;抽样&#34;&gt;抽样&lt;/h3&gt;
&lt;p&gt;该机制仅在满足特定条件时触发抽样。我们还提供了前 N 条追踪的列表，允许用户快速访问特定追踪的相关请求信息。为了帮助用户轻松识别和分析相关事件，我们提供了三种不同的抽样规则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;慢速追踪&lt;/strong&gt;：当请求的响应时间超过指定阈值时触发抽样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;响应状态 [400,500)&lt;/strong&gt;：当响应状态代码大于或等于 400 且小于 500 时触发抽样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;响应状态 [500,600)&lt;/strong&gt;：当响应状态代码大于或等于 500 且小于 600 时触发抽样。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此外，我们认识到分析时可能并不需要所有请求或响应的原始数据。例如，当试图识别性能问题时，用户可能更感兴趣于请求数据，而在解决错误时，他们可能更感兴趣于响应数据。因此，我们还提供了请求或响应事件的配置选项，允许用户指定要抽样的数据类型。&lt;/p&gt;
&lt;h2 id=&#34;服务网格中的分析&#34;&gt;服务网格中的分析&lt;/h2&gt;
&lt;p&gt;SkyWalking Rover 项目已经实现了 HTTP 协议的分析和追踪关联。当在服务网格环境中运行时它们的表现如何？&lt;/p&gt;
&lt;h3 id=&#34;部署&#34;&gt;部署&lt;/h3&gt;
&lt;p&gt;图 6 演示了 SkyWalking 和 SkyWalking Rover 在服务网格环境中的部署方式。SkyWalking Rover 作为一个 DaemonSet 部署在每台服务所在的机器上，并与 SkyWalking 后端集群通信。它会自动识别机器上的服务并向 SkyWalking 后端集群报告元数据信息。当出现新的网络分析任务时，SkyWalking Rover 会感知该任务并对指定的进程进行分析，在最终将数据报告回 SkyWalking 后端服务之前，收集和聚合网络数据。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f6.png&#34; alt=&#34;图 6：服务网格中的 SkyWalking rover 部署拓扑。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 6：服务网格中的 SkyWalking rover 部署拓扑。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;追踪系统&#34;&gt;追踪系统&lt;/h3&gt;
&lt;p&gt;从版本 9.3.0 开始，SkyWalking 后端完全支持 Zipkin 服务器中的所有功能。因此，SkyWalking 后端可以收集来自 SkyWalking 和 Zipkin 协议的追踪。同样，SkyWalking Rover 可以在 SkyWalking 和 Zipkin 追踪系统中识别和分析追踪上下文。在接下来的两节中，网络分析结果将分别在 SkyWalking 和 Zipkin UI 中显示。&lt;/p&gt;
&lt;h4 id=&#34;skywalking&#34;&gt;SkyWalking&lt;/h4&gt;
&lt;p&gt;当 SkyWalking 执行网络分析时，与&lt;a href=&#34;/zh/diagnose-service-mesh-network-performance-with-ebpf/&#34;&gt;前文中&lt;/a&gt;的 TCP 指标类似，SkyWalking UI 会首先显示进程间的拓扑图。当打开代表进程间流量指标的线的仪表板时，您可以在 “HTTP/1.x” 选项卡中看到 HTTP 流量的指标，并在 “HTTP Requests” 选项卡中看到带追踪的抽样的 HTTP 请求。&lt;/p&gt;
&lt;p&gt;如图 7 所示，选项卡中有三个列表，每个列表对应事件抽样规则中的一个条件。每个列表显示符合预先规定条件的追踪。当您单击追踪列表中的一个项目时，就可以查看完整的追踪。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f7.png&#34; alt=&#34;图 7：Tracing 上下文中的采样 HTTP 请求。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 7：Tracing 上下文中的采样 HTTP 请求。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当您单击追踪列表中的一个项目时，就可以快速查看指定的追踪。在图 8 中，我们可以看到在当前的服务相关的跨度中，有一个带有数字的标签，表示与该追踪跨度相关的 HTTP 事件数。&lt;/p&gt;
&lt;p&gt;由于我们在服务网格环境中，每个服务都涉及与 Envoy 交互。因此，当前的跨度包括 Envoy 的请求和响应信息。此外，由于当前的服务有传入和传出的请求，因此相应的跨度中有事件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f8.png&#34; alt=&#34;图 8：Tracing 详细信息中的事件。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 8：Tracing 详细信息中的事件。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当单击跨度时，将显示跨度的详细信息。如果当前跨度中有事件，则相关事件信息将在时间轴上显示。如图 9 所示，当前跨度中一共有 6 个相关事件。每个事件代表一个 HTTP 请求 / 响应的数据样本。其中一个事件跨越多个时间范围，表示较长的系统调用时间。这可能是由于系统调用被阻塞，具体取决于不同语言中的 HTTP 请求的实现细节。这也可以帮助我们查询错误的可能原因。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f9.png&#34; alt=&#34;图 9：一个 Tracing 范围内的事件。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 9：一个 Tracing 范围内的事件。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;最后，我们可以单击特定的事件查看它的完整信息。如图 10 所示，它显示了一个请求的抽样信息，包括从 HTTP 原始数据中的请求头中包含的 SkyWalking 追踪上下文协议。原始请求数据允许您快速重新请求以解决任何问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f10.png&#34; alt=&#34;图 10：事件的详细信息。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 10：事件的详细信息。&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&#34;zipkin&#34;&gt;Zipkin&lt;/h4&gt;
&lt;p&gt;Zipkin 是世界上广泛使用的分布式追踪系统。SkyWalking 可以作为&lt;a href=&#34;https://zipkin.io/pages/extensions_choices.html&#34;&gt;替代服务器&lt;/a&gt;，提供高级功能。在这里，我们使用这种方式将功能无缝集成到 Zipkin 生态系统中。新事件也将被视为 Zipkin 的标签和注释的一种。&lt;/p&gt;
&lt;p&gt;为 Zipkin 跨度添加事件，需要执行以下操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将每个事件的开始时间和结束时间分别拆分为两个具有规范名称的注释。&lt;/li&gt;
&lt;li&gt;将抽样的 HTTP 原始数据从事件添加到 Zipkin 跨度标签中，使用相同的事件名称用于相应的目的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;图 11 和图 12 显示了同一跨度中的注释和标签。在这些图中，我们可以看到跨度包含至少两个具有相同事件名称和序列后缀的事件（例如，图中的 “Start/Finished HTTP Request/Response Sampling-x”）。这两个事件均具有单独的时间戳，用于表示其在跨度内的相对时间。在标签中，对应事件的数据内容分别由事件名称和序列号表示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f11.png&#34; alt=&#34;图 11：Zipkin span 注释中的事件时间戳。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 11：Zipkin span 注释中的事件时间戳。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f12.png&#34; alt=&#34;图 12：Zipkin span 标签中的事件原始数据。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 12：Zipkin span 标签中的事件原始数据。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;演示&#34;&gt;演示&lt;/h2&gt;
&lt;p&gt;在本节中，我们将演示如何在服务网格中执行网络分析，并完成指标收集和 HTTP 原始数据抽样。要进行操作，您需要一个运行中的 Kubernetes 环境。&lt;/p&gt;
&lt;h3 id=&#34;部署-skywalking-showcase&#34;&gt;部署 SkyWalking Showcase&lt;/h3&gt;
&lt;p&gt;SkyWalking Showcase 包含一套完整的示例服务，可以使用 SkyWalking 进行监控。有关详细信息，请参阅&lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-showcase/next/readme/&#34;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在本演示中，我们只部署了服务、最新发布的 SkyWalking OAP 和 UI。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_OAP_IMAGE&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;apache/skywalking-oap-server:9.3.0
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_UI_IMAGE&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;apache/skywalking-ui:9.3.0
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_ROVER_IMAGE&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;apache/skywalking-rover:0.4.0

&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;FEATURE_FLAGS&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;mesh-with-agent,single-node,elasticsearch,rover
make deploy.kubernetes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;部署完成后，运行下面的脚本启动 SkyWalking UI：&lt;a href=&#34;http://localhost:8080/&#34;&gt;http://localhost:8080/&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl port-forward svc/ui 8080:8080 --namespace default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;启动网络分析任务&#34;&gt;启动网络分析任务&lt;/h3&gt;
&lt;p&gt;目前，我们可以通过单击服务网格面板中的 &lt;strong&gt;Data Plane&lt;/strong&gt; 项和 &lt;strong&gt;Kubernetes&lt;/strong&gt; 面板中的 &lt;strong&gt;Service&lt;/strong&gt; 项来选择要监视的特定实例。&lt;/p&gt;
&lt;p&gt;在图 13 中，我们已在网络分析选项卡中选择了一个具有任务列表的实例。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f13.png&#34; alt=&#34;图 13：数据平面中的网络分析选项卡。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 13：数据平面中的网络分析选项卡。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当我们单击 “开始” 按钮时，如图 14 所示，我们需要为分析任务指定抽样规则。抽样规则由一个或多个规则组成，每个规则都由不同的 URI 正则表达式区分。当 HTTP 请求的 URI 与正则表达式匹配时，将使用该规则。如果 URI 正则表达式为空，则使用默认规则。使用多个规则可以帮助我们为不同的请求配置不同的抽样配置。&lt;/p&gt;
&lt;p&gt;每个规则都有三个参数来确定是否需要抽样：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;最小请求持续时间（毫秒）&lt;/strong&gt;：响应时间超过指定时间的请求将被抽样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在 400 和 499 之间的抽样响应状态代码&lt;/strong&gt;：范围 [400-499) 中的所有状态代码将被抽样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在 500 和 599 之间的抽样响应状态代码&lt;/strong&gt;：范围 [500-599) 中的所有状态码将被抽样。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;抽样配置完成后，我们就可以创建任务了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f14.png&#34; alt=&#34;图 14：创建网络分析任务页面。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 14：创建网络分析任务页面。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;完成&#34;&gt;完成&lt;/h3&gt;
&lt;p&gt;几秒钟后，你会看到页面的右侧出现进程拓扑结构。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f15.png&#34; alt=&#34;图 15：网络分析任务中的流程拓扑。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 15：网络分析任务中的流程拓扑。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当您单击进程之间的线时，您可以查看两个过程之间的数据，它被分为三个选项卡：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;TCP&lt;/strong&gt;：显示与 TCP 相关的指标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP/1.x&lt;/strong&gt;：显示 HTTP 1 协议中的指标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP 请求&lt;/strong&gt;：显示已分析的请求，并根据抽样规则保存到列表中。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;f16.png&#34; alt=&#34;图 16：网络分析任务中的 TCP 指标。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 16：网络分析任务中的 TCP 指标。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f17.png&#34; alt=&#34;图 17：网络分析任务中的 HTTP/1.x 指标。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 17：网络分析任务中的 HTTP/1.x 指标。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f18.png&#34; alt=&#34;图 18：网络分析任务中的 HTTP 采样请求。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 18：网络分析任务中的 HTTP 采样请求。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;在本文中，我们详细介绍了如何在网络分析中分析 7 层 HTTP/1.x 协议，以及如何将其与现有追踪系统相关联。这使我们能够将我们能够观察到的数据从用户空间扩展到内核空间数据。&lt;/p&gt;
&lt;p&gt;在未来，我们将进一步探究内核数据的分析，例如收集 TCP 包大小、传输频率、网卡等信息，并从另一个角度提升分布式追踪。&lt;/p&gt;
&lt;h2 id=&#34;其他资源&#34;&gt;其他资源&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;SkyWalking Github Repo ›&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-rover&#34;&gt;SkyWalking Rover Github Repo ›&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-rover/v0.3.0/readme/&#34;&gt;SkyWalking Rover Documentation ›&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/blog/diagnose-service-mesh-network-performance-with-ebpf/&#34;&gt;Diagnose Service Mesh Network Performance with eBPF blog post &amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/profiling/&#34;&gt;SkyWalking Profiling Documentation &amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/api/x-process-propagation-headers-v3/&#34;&gt;SkyWalking Trace Context Propagation &amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openzipkin/b3-propagation&#34;&gt;Zipkin Trace Context Propagation &amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc2068.html&#34;&gt;RFC - Hypertext Transfer Protocol – HTTP/1.1 &amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 推出 trace-metric 关联功能助力快速根源问题排查</title>
      <link>/zh/boost-root-cause-analysis-quickly-with-skywalking-new-trace-metrics-association-feature/</link>
      <pubDate>Mon, 19 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/boost-root-cause-analysis-quickly-with-skywalking-new-trace-metrics-association-feature/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;banner.jpg&#34; alt=&#34;Banner&#34;&gt;&lt;/p&gt;
&lt;p&gt;现代分布式应用程序工作的可观测性对于了解它们在各种条件下的行为方式以及在出现问题时进行故障排除和解决至关重要。追踪、指标和日志被视为可观测性堆栈的基本部分。Trace 是分布式系统执行的足迹，而 metric 则是用时间轴上的数字衡量系统性能。本质上，它们从两个维度衡量性能。能够快速可视化追踪和相应指标之间的联系，可以快速诊断哪些流程与潜在的异常相关。&lt;a href=&#34;https://skywalking.apache.org/events/release-apache-skywalking-apm-9.3.0/&#34;&gt;SkyWalking 9.3.0&lt;/a&gt; 现在提供了这一强大的新功能。&lt;/p&gt;
&lt;p&gt;SkyWalking 项目从 tracing 开始，从 2018 年开始专注于 100% 基于采样的指标和拓扑分析。当用户面对时间序列指标的异常趋势时，比如折线图上的峰值，或者直方图显示 p95 和 p95 之间的差距较大，直接的问题是，为什么会出现这种情况？SkyWalking 的最新功能之一，trace 与 metric 关联，使得回答这个问题和解决根本原因更加容易。&lt;/p&gt;
&lt;h2 id=&#34;指标是如何生成的&#34;&gt;指标是如何生成的？&lt;/h2&gt;
&lt;p&gt;SkyWalking 提供了三种计算指标的方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据追踪跨度构建的指标，具体取决于跨度的层、种类和标签。&lt;/li&gt;
&lt;li&gt;从日志中提取指标—— 一种基于关键词和标签的指标提取。&lt;/li&gt;
&lt;li&gt;从成熟和主流的指标 / 仪表系统报告的指标，例如 OpenTelemetry、Prometheus 和 Zabbix。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Tracing 追踪应用程序服务之间的请求过程。大多数生成流量和性能相关指标的系统也会生成追踪数据，这些数据来自服务器端基于追踪的聚合或通过客户端 SDK。&lt;/p&gt;
&lt;h2 id=&#34;使用-skywalking-降低追踪索引的传统成本&#34;&gt;使用 SkyWalking 降低追踪索引的传统成本&lt;/h2&gt;
&lt;p&gt;Trace 数据和可视化对于开发人员和运维人员来说都是至关重要的故障排除工具，因为它们在定位问题边界方面非常有帮助。但是，由于传统上很难找到指标和痕迹之间的关联，团队已经将越来越多的标签添加到跨度中，并搜索各种组合。这种增加仪器和搜索的趋势需要增加基础设施投资来支持这种搜索。SkyWalking 的指标和追踪关联功能有助于降低索引和搜索该数据的成本。&lt;/p&gt;
&lt;h2 id=&#34;查找关联的-trace&#34;&gt;查找关联的 trace&lt;/h2&gt;
&lt;p&gt;在寻找 metric 和 trace 之间的关联时，我们处理的指标类型决定了它们与 trace 的关系。让我们回顾一下标准请求*率、错误和持续时间（RED）*指标，看看它是如何工作的。&lt;/p&gt;
&lt;h3 id=&#34;成功率指标&#34;&gt;成功率指标&lt;/h3&gt;
&lt;p&gt;成功率由返回码、RPC 响应码或进程异常决定。当成功率下降时，在这个服务或 Pod 的 trace 中寻找错误是第一个寻找线索的地方。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f1.jpg&#34; alt=&#34;图 1：SkyWalking 9.3.0 仪表板的成功率图表，带有在特定时间查看相关追踪的选项。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 1：SkyWalking 9.3.0 仪表板的成功率图表，带有在特定时间查看相关 trace 的选项。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;从成功率的峰值向下探索，SkyWalking 列出了在这一特定分钟内收集的所有 trace 及其错误状态（图 2）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f2.jpg&#34; alt=&#34;图 2：SkyWalking 显示具有错误状态的相关追踪。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 2：SkyWalking 显示具有错误状态的相关追踪。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;可以从 trace 中找到对 &lt;code&gt;/test&lt;/code&gt; 的请求，并且 span 的标记指示 HTTP 请求的 404 响应代码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f3.jpg&#34; alt=&#34;图 3：显示 URI 不存在的 http://frontend/test 请求的详细视图。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 3：显示 URI 不存在的 http://frontend/test 请求的详细视图。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;通过查看 trace 数据，很明显成功率的下降是由对不存在的 URI 的请求引起的。&lt;/p&gt;
&lt;h3 id=&#34;平均响应时间&#34;&gt;平均响应时间&lt;/h3&gt;
&lt;p&gt;平均响应时间指标提供了服务性能的一般概览。当平均响应时间不稳定时，这通常意味着系统面临严重的性能影响。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f4.jpg&#34; alt=&#34;图 4：SkyWalking 用于搜索相关追踪的查询 UI，显示超过特定持续时间阈值的请求的追踪。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 4：SkyWalking 用于搜索相关 trace 的查询 UI，显示超过特定持续时间阈值的请求的 trace。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当您从该指标向下探索时，该查询条件（图 4）将揭示该特定分钟内服务的最慢 trace。请注意，至少 168ms 作为条件自动添加，以避免扫描数据库中的大量行。&lt;/p&gt;
&lt;h3 id=&#34;apdex&#34;&gt;Apdex&lt;/h3&gt;
&lt;p&gt;Apdex（应用程序性能指数）是根据设定的阈值衡量响应时间的指标。它测量令人满意的响应时间与不令人满意的响应时间的比率（图 5）。响应时间是从资产请求到完成交付回请求者的时间。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f5.jpg&#34; alt=&#34;图 5：Apdex 公式&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 5：Apdex 公式&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;用户定义响应时间容忍阈值 &lt;em&gt;T&lt;/em&gt;。在 &lt;em&gt;T&lt;/em&gt; 或更短时间内处理的所有响应都使用户满意。&lt;/p&gt;
&lt;p&gt;例如，如果 &lt;em&gt;T&lt;/em&gt; 为 1.2 秒，响应在 0.5 秒内完成，则用户会感到满意。所有大于 1.2 秒的响应都会让用户不满意。超过 4.8 秒的响应会让用户感到沮丧。&lt;/p&gt;
&lt;p&gt;当 Apdex 分数下降时，我们需要从两个角度寻找相关的 trace：慢速和错误状态的 trace。SkyWalking 的新相关追踪功能提供了一种直接从 Apdex 图表查看两者（图 6）的快速方法。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f6.jpg&#34; alt=&#34;图 6：显示 Apdex 图中的慢速追踪和错误状态追踪&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 6：显示 Apdex 图中的慢速 trace 和错误状态 trace&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;服务响应时间&#34;&gt;服务响应时间&lt;/h3&gt;
&lt;p&gt;百分位指标百分位图（图 7）提供 p50、p75、p90、p95 和 p99 延迟排名，以衡量服务性能的长尾问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f7.jpg&#34; alt=&#34;图 7：服务响应时间百分位图有助于突出服务性能的长尾问题。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 7：服务响应时间百分位图有助于突出服务性能的长尾问题。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这个百分位数图显示了一个典型的长尾问题。P99 延迟比 P95 慢四倍。当我们使用关联时，我们会看到 P95 - P99 和 P99 - Infinity 之间具有延迟的 trace。&lt;/p&gt;
&lt;p&gt;造成这种长尾现象的请求 trace，就是从那里自动列出来的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f8.jpg&#34; alt=&#34;图 8：用于根据延迟搜索追踪的查询参数。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 8：用于根据延迟搜索 trace 的查询参数。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;是否有更多关联可用&#34;&gt;是否有更多关联可用？&lt;/h2&gt;
&lt;p&gt;SkyWalking 提供的不仅仅是 trace 和 metric 之间的关联，还可以帮助您找到可能的因果关系，避免大海捞针。&lt;/p&gt;
&lt;p&gt;目前，SkyWalking 9.3.0 提供了两种关联：&lt;strong&gt;metric-to-metric&lt;/strong&gt; 关联和 &lt;strong&gt;event-to-metric&lt;/strong&gt; 关联。&lt;/p&gt;
&lt;h3 id=&#34;metric-to-metric-关联&#34;&gt;Metric-to-metric 关联&lt;/h3&gt;
&lt;p&gt;仪表板上有许多指标 —— 这对于全面了解应用程序行为非常有用。在典型的性能问题中，多个指标的峰值会同时受到影响。但是，尝试关联所有这些图表中的峰值可能很困难……&lt;/p&gt;
&lt;p&gt;现在在 SkyWalking 9.3.0 中，当你点击一个图表的峰值时，弹出框可以让你看到相关的指标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f9.jpg&#34; alt=&#34;图 9：SkyWalking 用于查看相关指标的选项。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 9：SkyWalking 用于查看相关指标的选项。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当您选择该选项时，所有关联的指标图表将在所有关联的图表中显示轴指针（垂直虚线），如图 10 所示。这使得将不同图表中的峰值相互关联起来变得更加容易。通常，这些相关的峰值具有相同的根本原因。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f10.jpg&#34; alt=&#34;图 10：轴指针（垂直虚线）显示多个指标图中峰值之间的关联。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 10：轴指针（垂直虚线）显示多个指标图中峰值之间的关联。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;event-to-metric-关联&#34;&gt;Event-to-metric 关联&lt;/h3&gt;
&lt;p&gt;SkyWalking 提供了事件概念来关联可能受基础设施影响的服务性能，例如来自 Kubernetes 的新部署。或者，已通过警报或集成 AIOps 引擎检测到异常。&lt;/p&gt;
&lt;p&gt;事件到指标的关联也是自动的，它可以覆盖指标图上事件的时间范围（蓝色区域）。如果事件区域和峰值匹配，则很可能该事件覆盖了该异常。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f11.jpg&#34; alt=&#34;图 11：SkyWalking 的事件与指标关联视图。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 11：SkyWalking 的事件与指标关联视图。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;skywalking-使查找根本原因变得更加容易和快速&#34;&gt;SkyWalking 使查找根本原因变得更加容易和快速&lt;/h2&gt;
&lt;p&gt;SkyWalking 现在可以轻松找到指标、事件和追踪之间的关联，最终可以确定根本原因并快速解决问题。我们在本文中讨论的关联在 SkyWalking 9.3.0 版本中开箱即用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f12.jpg&#34; alt=&#34;图 12：只需单击圆点即可查看相关追踪和指标关联。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 12：只需单击圆点即可查看相关 trace 和 metric 关联。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;单击任何指标图上的点，如果该指标具有逻辑映射，您将看到一个&lt;em&gt;查看相关 trace&lt;/em&gt; 弹出窗口。&lt;/p&gt;
&lt;h2 id=&#34;结论&#34;&gt;结论&lt;/h2&gt;
&lt;p&gt;在这篇博客中，我们了解了 metric 和 trace 之间新增的关联功能。有了这个新的可视化，现在可以更容易地找到关键 trace 来识别问题的根本原因。SkyWalking 中的关联可以更深入。从 metric 到 trace 的关联并不是诊断系统瓶颈的终点。在下一篇文章中，我们将介绍 eBPF 支持的追踪增强功能，您将看到与网络分析中的追踪跨度相关的 HTTP 请求和响应详细信息。敬请关注。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 如何在 Istio 中使用 SkyWalking 进行分布式追踪？</title>
      <link>/zh/how-to-use-skywalking-for-distributed-tracing-in-istio/</link>
      <pubDate>Wed, 14 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/how-to-use-skywalking-for-distributed-tracing-in-istio/</guid>
      <description>
        
        
        &lt;p&gt;在云原生应用中，一次请求往往需要经过一系列的 API 或后台服务处理才能完成，这些服务有些是并行的，有些是串行的，而且位于不同的平台或节点。那么如何确定一次调用的经过的服务路径和节点以帮助我们进行问题排查？这时候就需要使用到分布式追踪。&lt;/p&gt;
&lt;p&gt;本文将向你介绍：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分布式追踪的原理&lt;/li&gt;
&lt;li&gt;如何选择分布式追踪软件&lt;/li&gt;
&lt;li&gt;在 Istio 中如何使用分布式追踪&lt;/li&gt;
&lt;li&gt;以 Bookinfo 和 SkyWalking 为例说明如何查看分布式追踪数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;分布式追踪基础&#34;&gt;分布式追踪基础&lt;/h2&gt;
&lt;p&gt;分布式追踪是一种用来跟踪分布式系统中请求的方法，它可以帮助用户更好地理解、控制和优化分布式系统。分布式追踪中用到了两个概念：TraceID 和 SpanID。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TraceID 是一个全局唯一的 ID，用来标识一个请求的追踪信息。一个请求的所有追踪信息都属于同一个 TraceID，TraceID 在整个请求的追踪过程中都是不变的；&lt;/li&gt;
&lt;li&gt;SpanID 是一个局部唯一的 ID，用来标识一个请求在某一时刻的追踪信息。一个请求在不同的时间段会产生不同的 SpanID，SpanID 用来区分一个请求在不同时间段的追踪信息；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TraceID 和 SpanID 是分布式追踪的基础，它们为分布式系统中请求的追踪提供了一个统一的标识，方便用户查询、管理和分析请求的追踪信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f1.svg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;下面是分布式追踪的过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当一个系统收到请求后，分布式追踪系统会为该请求分配一个 TraceID，用于串联起整个调用链；&lt;/li&gt;
&lt;li&gt;分布式追踪系统会为该请求在系统内的每一次服务调用生成一个 SpanID 和 ParentID，用于记录调用的父子关系，没有 ParentID 的 Span 将作为调用链的入口；&lt;/li&gt;
&lt;li&gt;每个服务调用过程中都要传递 TraceID 和 SpanID；&lt;/li&gt;
&lt;li&gt;在查看分布式追踪时，通过 TraceID 查询某次请求的全过程；&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;istio-如何实现分布式追踪&#34;&gt;Istio 如何实现分布式追踪&lt;/h2&gt;
&lt;p&gt;Istio 中的分布式追踪是基于数据平面中的 Envoy 代理实现的。服务请求在被劫持到 Envoy 中后，Envoy 在转发请求时会附加大量 Header，其中与分布式追踪相关的有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作为 TraceID：&lt;code&gt;x-request-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用于在 LightStep 追踪系统中建立 Span 的父子关系：&lt;code&gt;x-ot-span-context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用于 Zipkin，同时适用于 Jaeger、SkyWalking，详见 &lt;a href=&#34;https://github.com/openzipkin/b3-propagation&#34;&gt;b3-propagation&lt;/a&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x-b3-traceid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-b3-spanid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-b3-parentspanid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-b3-sampled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-b3-flags&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用于 Datadog：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x-datadog-trace-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-datadog-parent-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-datadog-sampling-priority&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用于 SkyWalking：&lt;code&gt;sw8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用于 AWS X-Ray：&lt;code&gt;x-amzn-trace-id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于这些 Header 的详细用法请参考 &lt;a href=&#34;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers&#34;&gt;Envoy 文档&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;Envoy 会在 Ingress Gateway 中为你产生用于追踪的 Header，不论你的应用程序使用何种语言开发，Envoy 都会将这些 Header 转发到上游集群。但是，你还要对应用程序代码做一些小的修改，才能为使用分布式追踪功能。这是因为应用程序无法自动传播这些 Header，可以在程序中集成分布式追踪的 Agent，或者在代码中手动传播这些 Header。Envoy 会将追踪数据发送到 tracer 后端处理，然后就可以在 UI 中查看追踪数据了。&lt;/p&gt;
&lt;p&gt;例如在 Bookinfo 应用中的 Productpage 服务，如果你查看它的代码可以发现，其中集成了 Jaeger 客户端库，并在 &lt;code&gt;getForwardHeaders (request)&lt;/code&gt; 方法中将 Envoy 生成的 Header 同步给对 Details 和 Reviews 服务的 HTTP 请求：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getForwardHeaders&lt;/span&gt;(request):
    headers &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; {}

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 使用 Jaeger agent 获取 x-b3-* header&lt;/span&gt;
    span &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; get_current_span()
    carrier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; {}
    tracer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;inject(
        span_context&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;context,
        format&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;Format&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;HTTP_HEADERS,
        carrier&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;carrier)

    headers&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;update(carrier)

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 手动处理非 x-b3-* header&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;user&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; session:
        headers[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;end-user&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; session[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;user&amp;#39;&lt;/span&gt;]
    incoming_headers &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; [
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-request-id&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-ot-span-context&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-datadog-trace-id&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-datadog-parent-id&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-datadog-sampling-priority&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;traceparent&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;tracestate&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;x-cloud-trace-context&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;grpc-trace-bin&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;sw8&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;user-agent&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;cookie&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;authorization&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;jwt&amp;#39;&lt;/span&gt;,
    ]

    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;for&lt;/span&gt; ihdr &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; incoming_headers:
        val &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;headers&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;get(ihdr)
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; val &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#999&#34;&gt;None&lt;/span&gt;:
            headers[ihdr] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; val

    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; headers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关于 Istio 中分布式追踪的常见问题请见 &lt;a href=&#34;https://istio.io/latest/zh/about/faq/#distributed-tracing&#34;&gt;Istio 文档&lt;/a&gt; 。&lt;/p&gt;
&lt;h2 id=&#34;分布式追踪系统如何选择&#34;&gt;分布式追踪系统如何选择&lt;/h2&gt;
&lt;p&gt;分布式追踪系统的原理类似，市面上也有很多这样的系统，例如 &lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache SkyWalking&lt;/a&gt; 、&lt;a href=&#34;https://github.com/jaegertracing/jaeger&#34;&gt;Jaeger&lt;/a&gt; 、&lt;a href=&#34;https://github.com/openzipkin/zipkin/&#34;&gt;Zipkin&lt;/a&gt; 、&lt;a href=&#34;https://lightstep.com/&#34;&gt;LightStep&lt;/a&gt; 、&lt;a href=&#34;https://github.com/pinpoint-apm/pinpoint&#34;&gt;Pinpoint&lt;/a&gt; 等。我们将选择其中三个，从多个维度进行对比。之所以选择它们是因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它们是当前最流行的开源分布式追踪系统；&lt;/li&gt;
&lt;li&gt;都是基于 OpenTracing 规范；&lt;/li&gt;
&lt;li&gt;都支持与 Istio 及 Envoy 集成；&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;类别&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Apache SkyWalking&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Jaeger&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Zipkin&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;实现方式&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;基于语言的探针、服务网格探针、eBPF agent、第三方指标库（当前支持 Zipkin）&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;基于语言的探针&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;基于语言的探针&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;数据存储&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;ES、H2、MySQL、TiDB、Sharding-sphere、BanyanDB&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;ES、MySQL、Cassandra、内存&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;ES、MySQL、Cassandra、内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;支持语言&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Java、Rust、PHP、NodeJS、Go、Python、C++、.NET、Lua&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Java、Go、Python、NodeJS、C#、PHP、Ruby、C++&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Java、Go、Python、NodeJS、C#、PHP、Ruby、C++&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;发起者&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;个人&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Uber&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Twitter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;治理方式&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Apache Foundation&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;CNCF&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;CNCF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;版本&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;9.3.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1.39.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;2.23.19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;Star 数量&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;20.9k&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;16.8k&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;15.8k&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;分布式追踪系统对比表（数据截止时间 2022-12-07）&lt;/p&gt;
&lt;p&gt;虽然 Apache SkyWalking 的 Agent 支持的语言没有 Jaeger 和 Zipkin 多，但是 SkyWalking 的实现方式更丰富，并且与 Jaeger、Zipkin 的追踪数据兼容，开发更为活跃，且为国人开发，中文资料丰富，是构建遥测平台的最佳选择之一。&lt;/p&gt;
&lt;h2 id=&#34;实验&#34;&gt;实验&lt;/h2&gt;
&lt;p&gt;参考 &lt;a href=&#34;https://istio.io/latest/docs/tasks/observability/distributed-tracing/skywalking/&#34;&gt;Istio 文档&lt;/a&gt; 来安装和配置 Apache SkyWalking。&lt;/p&gt;
&lt;h3 id=&#34;环境说明&#34;&gt;环境说明&lt;/h3&gt;
&lt;p&gt;以下是我们实验的环境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes 1.24.5&lt;/li&gt;
&lt;li&gt;Istio 1.16&lt;/li&gt;
&lt;li&gt;SkyWalking 9.1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;安装-istio&#34;&gt;安装 Istio&lt;/h3&gt;
&lt;p&gt;安装之前可以先检查下环境是否有问题:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ istioctl experimental precheck
✔ No issues found when checking the cluster. Istio is safe to install or upgrade!
  To get started, check out https://istio.io/latest/docs/setup/getting-started/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后安装 Istio 同时配置发送追踪信息的目的地为 SkyWalking：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 初始化 Istio Operator&lt;/span&gt;
istioctl operator init
&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 安装 Istio 并配置使用 SkyWalking&lt;/span&gt;
kubectl apply -f - &lt;span style=&#34;color:#d14&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;apiVersion: install.istio.io/v1alpha1
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;kind: IstioOperator
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;metadata:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  namespace: istio-system
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  name: istio-with-skywalking
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;spec:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  meshConfig:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;    defaultProviders:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;      tracing:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;      - &amp;#34;skywalking&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;    enableTracing: true
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;    extensionProviders:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;    - name: &amp;#34;skywalking&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;      skywalking:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;        service: tracing.istio-system.svc.cluster.local
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;        port: 11800
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;部署-apache-skywalking&#34;&gt;部署 Apache SkyWalking&lt;/h3&gt;
&lt;p&gt;Istio 1.16 支持使用 Apache SkyWalking 进行分布式追踪，执行下面的代码安装 SkyWalking：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/extras/skywalking.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它将在 &lt;code&gt;istio-system&lt;/code&gt; 命名空间下安装：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/v9.3.0/en/concepts-and-designs/backend-overview/&#34;&gt;SkyWalking OAP&lt;/a&gt; (Observability Analysis Platform) ：用于接收追踪数据，支持 SkyWalking 原生数据格式，Zipkin v1 和 v2 以及 Jaeger 格式。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/v9.3.0/en/ui/readme/&#34;&gt;UI&lt;/a&gt; ：用于查询分布式追踪数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于 SkyWalking 的详细信息请参考 &lt;a href=&#34;https://skywalking.apache.org/docs/main/v9.3.0/readme/&#34;&gt;SkyWalking 文档&lt;/a&gt; 。&lt;/p&gt;
&lt;h3 id=&#34;部署-bookinfo-应用&#34;&gt;部署 Bookinfo 应用&lt;/h3&gt;
&lt;p&gt;执行下面的命令安装 bookinfo 示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl label namespace default istio-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打开 SkyWalking UI：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;istioctl dashboard skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SkyWalking 的 General Service 页面展示了 bookinfo 应用中的所有服务。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f2.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;你还可以看到实例、端点、拓扑、追踪等信息。例如下图展示了 bookinfo 应用的服务拓扑。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f3.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;SkyWalking 的追踪视图有多种显示形式，如列表、树形、表格和统计。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f4.jpg&#34; alt=&#34;img&#34;&gt;SkyWalking 通用服务追踪支持多种显示样式&lt;/p&gt;
&lt;p&gt;为了方便我们检查，将追踪的采样率设置为 100%：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl apply -f - &lt;span style=&#34;color:#d14&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;apiVersion: telemetry.istio.io/v1alpha1
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;kind: Telemetry
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;metadata:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  name: mesh-default
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  namespace: istio-system
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;spec:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  tracing:
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;  - randomSamplingPercentage: 100.00
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;卸载&#34;&gt;卸载&lt;/h3&gt;
&lt;p&gt;在实验完后，执行下面的命令卸载 Istio 和 SkyWalking：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;samples/bookinfo/platform/kube/cleanup.sh
istioctl unintall --purge
kubectl delete namespace istio-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;bookinfo-demo-追踪信息说明&#34;&gt;Bookinfo demo 追踪信息说明&lt;/h2&gt;
&lt;p&gt;在 Apache SkyWalking UI 中导航到 General Service 分页，查看最近的 &lt;code&gt;istio-ingressgateway&lt;/code&gt; 服务的追踪信息，表视图如下所示。图中展示了此次请求所有 Span 的基本信息，点击每个 Span 可以查看详细信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f5.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;切换为列表视图，可以看到每个 Span 的执行顺序及持续时间，如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f6.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;你可能会感到困惑，为什么这么简单的一个应用会产生如此多的 Span 信息？因为我们为 Pod 注入了 Envoy 代理之后，每个服务间的请求都会被 Envoy 拦截和处理，如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f7.svg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;整个追踪流程如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f8.svg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;图中给每一个 Span 标记了序号，并在括号里注明了耗时。为了便于说明我们将所有 Span 汇总在下面的表格中。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;序号&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;方法&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;总耗时（ms）&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;组件耗时（ms）&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;当前服务&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;190&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;istio-ingressgateway&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Outbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;2&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;190&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;istio-ingressgateway&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Ingress -&amp;gt; Productpage 网络传输&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;3&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;189&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Inbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;4&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;188&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;21&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;应用内部处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;5&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/details/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;8&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Outbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;6&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/details/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;7&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;3&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Productpage -&amp;gt; Details 网络传输&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;7&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/details/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;4&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;details&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Inbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;8&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/details/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;4&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;4&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;details&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;应用内部&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;9&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/reviews/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;159&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Outbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;10&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/reviews/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;159&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;14&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;productpage&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Productpage -&amp;gt; Reviews 网络传输&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;11&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/reviews/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;145&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;reviews&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Inbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;12&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/reviews/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;144&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;109&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;reviews&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;应用内部处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;13&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/ratings/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;35&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;2&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;reviews&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Outbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;14&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/ratings/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;33&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;16&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;reviews&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Reviews -&amp;gt; Ratings 网络传输&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;15&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/ratings/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;17&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;ratings&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Envoy Inbound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;16&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/ratings/0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;16&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;16&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;ratings&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;应用内部处理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;从以上信息可以发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本次请求总耗时 190ms；&lt;/li&gt;
&lt;li&gt;在 Istio sidecar 模式下，每次流量在进出应用容器时都需要经过一次 Envoy 代理，每次耗时在 0 到 2 ms；&lt;/li&gt;
&lt;li&gt;在 Pod 间的网络请求耗时在 1 到 16ms 之间；&lt;/li&gt;
&lt;li&gt;将耗时做多的调用链 Ingress Gateway -&amp;gt; Productpage -&amp;gt; Reviews -&amp;gt; Ratings 上的所有耗时累计 182 ms，小于请求总耗时 190ms，这是因为数据本身有误差，以及 Span 的开始时间并不一定等于父 Span 的结束时间，如果你在 SkyWalking 的追踪页面，选择「列表」样式查看追踪数据（见图 2）可以更直观的发现这个问题；&lt;/li&gt;
&lt;li&gt;我们可以查看到最耗时的部分是 Reviews 应用，耗时 109ms，因此我们可以针对该应用进行优化；&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;只要对应用代码稍作修改就可以在 Istio 很方便的使用分布式追踪功能。在 Istio 支持的众多分布式追踪系统中，&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;Apache SkyWalking&lt;/a&gt; 是其中的佼佼者。它不仅支持分布式追踪，还支持指标和日志收集、报警、Kubernetes 和服务网格监控，&lt;a href=&#34;https://skywalking.apache.org/zh/diagnose-service-mesh-network-performance-with-ebpf/&#34;&gt;使用 eBPF 诊断服务网格性能&lt;/a&gt; 等功能，是一个功能完备的云原生应用分析平台。本文中为了方便演示，将追踪采样率设置为了 100%，在生产使用时请根据需要调整采样策略（采样百分比），防止产生过多的追踪日志。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;如果您不熟悉服务网格和 Kubernetes 安全性，我们在 &lt;a href=&#34;https://tetr8.io/academy&#34;&gt;Tetrate Academy&lt;/a&gt; 提供了一系列免费在线课程，可以让您快速了解 Istio 和 Envoy。&lt;/p&gt;
&lt;p&gt;如果您正在寻找一种快速将 Istio 投入生产的方法，请查看 &lt;a href=&#34;https://tetr8.io/tid&#34;&gt;Tetrate Istio Distribution (TID)&lt;/a&gt;。TID 是 Tetrate 的强化、完全上游的 Istio 发行版，具有经过 FIPS 验证的构建和支持。这是开始使用 Istio 的好方法，因为您知道您有一个值得信赖的发行版，有一个支持您的专家团队，并且如果需要，还可以选择快速获得 FIPS 合规性。&lt;/p&gt;
&lt;p&gt;一旦启动并运行 Istio，您可能需要更简单的方法来管理和保护您的服务，而不仅仅是 Istio 中可用的方法，这就是 Tetrate Service Bridge 的用武之地。您可以&lt;a href=&#34;https://tetr8.io/tsb&#34;&gt;在这里&lt;/a&gt;详细了解 Tetrate Service Bridge 如何使服务网格更安全、更易于管理和弹性，或&lt;a href=&#34;https://tetr8.io/contact&#34;&gt;联系我们进行快速演示&lt;/a&gt;。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 如何在 AWS EKS 和 RDS/Aurora 上运行 Apache SkyWalking</title>
      <link>/zh/2022-12-13-how-to-run-apache-skywalking-on-aws-eks-rds/</link>
      <pubDate>Tue, 13 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-12-13-how-to-run-apache-skywalking-on-aws-eks-rds/</guid>
      <description>
        
        
        &lt;h2 id=&#34;介绍&#34;&gt;介绍&lt;/h2&gt;
&lt;p&gt;Apache SkyWalking 是一个开源的 APM 工具，用于监控分布式系统和排除故障，特别是为微服务、云原生和基于容器（Docker、Kubernetes、Mesos）的架构而设计。它提供分布式跟踪、服务网格可观测性、指标聚合和可视化以及警报。&lt;/p&gt;
&lt;p&gt;在本文中，我将介绍如何在 AWS EKS 和 RDS/Aurora 上快速设置 Apache SkyWalking，以及几个示例服务，监控服务以观察 SkyWalking 本身。&lt;/p&gt;
&lt;h2 id=&#34;先决条件&#34;&gt;先决条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS 账号&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html&#34;&gt;AWS CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.terraform.io/downloads.html&#34;&gt;Terraform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/#kubectl&#34;&gt;kubectl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们可以使用 AWS Web 控制台或 CLI 来创建本教程所需的所有资源，但是当出现问题时，它可能过于繁琐且难以调试。因此，在本文中，我将使用 Terraform 创建所有 AWS 资源、部署 SkyWalking、示例服务和负载生成器服务 (Locust)。&lt;/p&gt;
&lt;h2 id=&#34;架构&#34;&gt;架构&lt;/h2&gt;
&lt;p&gt;演示架构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    subgraph AWS
        subgraph EKS
          subgraph istio-system namespace
              direction TB
              OAP[[SkyWalking OAP]]
              UI[[SkyWalking UI]]
            Istio[[istiod]]
          end
          subgraph sample namespace
              Service0[[Service0]]
              Service1[[Service1]]
              ServiceN[[Service ...]]
          end
          subgraph locust namespace
              LocustMaster[[Locust Master]]
              LocustWorkers0[[Locust Worker 0]]
              LocustWorkers1[[Locust Worker 1]]
              LocustWorkersN[[Locust Worker ...]]
          end
        end
        RDS[[RDS/Aurora]]
    end
    OAP --&amp;gt; RDS
    Service0 -. telemetry data -.-&amp;gt; OAP
    Service1 -. telemetry data -.-&amp;gt; OAP
    ServiceN -. telemetry data -.-&amp;gt; OAP
    UI --query--&amp;gt; OAP
    LocustWorkers0 -- traffic --&amp;gt; Service0
    LocustWorkers1 -- traffic --&amp;gt; Service0
    LocustWorkersN -- traffic --&amp;gt; Service0
    Service0 --&amp;gt; Service1 --&amp;gt; ServiceN
    LocustMaster --&amp;gt; LocustWorkers0
    LocustMaster --&amp;gt; LocustWorkers1
    LocustMaster --&amp;gt; LocustWorkersN
    User --&amp;gt; LocustMaster
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如架构图所示，我们需要创建以下 AWS 资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EKS 集群&lt;/li&gt;
&lt;li&gt;RDS 实例或 Aurora 集群&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;听起来很简单，但背后有很多东西，比如 VPC、子网、安全组等。你必须正确配置它们以确保 EKS 集群可以连接到 RDS 实例 / Aurora 集群，否则 SkyWalking 不会不工作。幸运的是，Terraform 可以帮助我们自动创建和销毁所有这些资源。&lt;/p&gt;
&lt;p&gt;我创建了一个 Terraform 模块来创建本教程所需的所有 AWS 资源，您可以在 &lt;a href=&#34;https://github.com/kezhenxu94/oap-load-test/tree/main/aws&#34;&gt;GitHub 存储库&lt;/a&gt;中找到它。&lt;/p&gt;
&lt;h2 id=&#34;创建-aws-资源&#34;&gt;创建 AWS 资源&lt;/h2&gt;
&lt;p&gt;首先，我们需要将 GitHub 存储库克隆 &lt;code&gt;cd&lt;/code&gt; 到文件夹中：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;git clone https://github.com/kezhenxu94/oap-load-test.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，我们需要创建一个文件 &lt;code&gt;terraform.tfvars&lt;/code&gt; 来指定 AWS 区域和其他变量：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cat &amp;gt; terraform.tfvars &lt;span style=&#34;color:#d14&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;aws_access_key = &amp;#34;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;aws_secret_key = &amp;#34;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;cluster_name   = &amp;#34;skywalking-on-aws&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;region         = &amp;#34;ap-east-1&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;db_type        = &amp;#34;rds-postgresql&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果您已经配置了 AWS CLI，则可以跳过 &lt;code&gt;aws_access_key&lt;/code&gt; 和 &lt;code&gt;aws_secret_key&lt;/code&gt; 变量。要使用 RDS postgresql 安装 SkyWalking，请将 &lt;code&gt;db_type&lt;/code&gt; 设置为 &lt;code&gt;rds-postgresql&lt;/code&gt;，要使用 Aurora postgresql 安装 SkyWalking，请将 &lt;code&gt;db_type&lt;/code&gt; 设置为 &lt;code&gt;aurora-postgresql&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;您可以配置许多其他变量，例如标签、示例服务计数、副本等，您可以在 variables.tf 中找到&lt;a href=&#34;https://github.com/kezhenxu94/oap-load-test/blob/main/aws/variables.tf&#34;&gt;它们&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;然后，我们可以运行以下命令来初始化 Terraform 模块并下载所需的提供程序，然后创建所有 AWS 资源：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;terraform init
terraform apply -var-file&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;terraform.tfvars
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;键入 &lt;code&gt;yes&lt;/code&gt; 以确认所有 AWS 资源的创建，或将标志 &lt;code&gt;-auto-approve&lt;/code&gt; 添加到 &lt;code&gt;terraform apply&lt;/code&gt; 以跳过确认：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;terraform apply -var-file&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;terraform.tfvars -auto-approve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在你需要做的就是等待所有 AWS 资源的创建完成，这可能需要几分钟的时间。您可以在 AWS Web 控制台查看创建进度，也可以查看 EKS 集群内部服务的部署进度。&lt;/p&gt;
&lt;h2 id=&#34;产生流量&#34;&gt;产生流量&lt;/h2&gt;
&lt;p&gt;除了创建必要的 AWS 资源外，Terraform 模块还将 SkyWalking、示例服务和 Locust 负载生成器服务部署到 EKS 集群。&lt;/p&gt;
&lt;p&gt;您可以访问 Locust Web UI 以生成到示例服务的流量：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;open http://&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$(&lt;/span&gt;kubectl get svc -n locust -l &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;locust-master -o &lt;span style=&#34;color:#008080&#34;&gt;jsonpath&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;{.items[0].status.loadBalancer.ingress[0].hostname}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;:8089
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;该命令将浏览器打开到 Locust web UI，您可以配置用户数量和孵化率以生成流量。&lt;/p&gt;
&lt;h2 id=&#34;观察-skywalking&#34;&gt;观察 SkyWalking&lt;/h2&gt;
&lt;p&gt;您可以访问 SkyWalking Web UI 来观察示例服务。&lt;/p&gt;
&lt;p&gt;首先需要将 SkyWalking UI 端口转发到本地：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl -n istio-system port-forward &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$(&lt;/span&gt;kubectl -n istio-system get pod -l &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking -l &lt;span style=&#34;color:#008080&#34;&gt;component&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;ui -o name&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; 8080:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后在浏览器中打开 http://localhost:8080 访问 SkyWalking web UI。&lt;/p&gt;
&lt;h2 id=&#34;观察-rdsaurora&#34;&gt;观察 RDS/Aurora&lt;/h2&gt;
&lt;p&gt;您也可以访问 RDS/Aurora web 控制台，观察 RDS/Aurora 实例 / Aurora 集群的性能。&lt;/p&gt;
&lt;h2 id=&#34;试验结果&#34;&gt;试验结果&lt;/h2&gt;
&lt;h3 id=&#34;测试-1使用-eks-和-rds-postgresql-的-skywalking&#34;&gt;测试 1：使用 EKS 和 RDS PostgreSQL 的 SkyWalking&lt;/h3&gt;
&lt;h4 id=&#34;服务流量&#34;&gt;服务流量&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/postgresql/test1-cpm-locust.png&#34; alt=&#34;Service Traffic Locust&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-cpm.png&#34; alt=&#34;Service Traffic SW&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;rds-性能&#34;&gt;RDS 性能&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/postgresql/test1-postgresql-1.png&#34; alt=&#34;RDS Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-postgresql-2.png&#34; alt=&#34;RDS Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-postgresql-3.png&#34; alt=&#34;RDS Performance&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;skywalking-性能&#34;&gt;SkyWalking 性能&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/postgresql/test1-so11y-1.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-so11y-2.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-so11y-3.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-so11y-4.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/postgresql/test1-so11y-5.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;测试-2使用-eks-和-aurora-postgresql-的-skywalking&#34;&gt;测试 2：使用 EKS 和 Aurora PostgreSQL 的 SkyWalking&lt;/h3&gt;
&lt;h4 id=&#34;服务流量-1&#34;&gt;服务流量&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/aurora/test1-cpm-locust.png&#34; alt=&#34;Service Traffic Locust&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-cpm-skywalking.png&#34; alt=&#34;Service Traffic SW&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;rds-性能-1&#34;&gt;RDS 性能&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/aurora/test1-postgresql-1.png&#34; alt=&#34;RDS Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-postgresql-2.png&#34; alt=&#34;RDS Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-postgresql-3.png&#34; alt=&#34;RDS Performance&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;skywalking-性能-1&#34;&gt;SkyWalking 性能&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;./outputs/aurora/test1-so11y-1.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-so11y-2.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-so11y-3.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-so11y-4.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;
&lt;img src=&#34;./outputs/aurora/test1-so11y-5.png&#34; alt=&#34;SkyWalking Performance&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;清理&#34;&gt;清理&lt;/h2&gt;
&lt;p&gt;完成演示后，您可以运行以下命令销毁所有 AWS 资源：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;terraform destroy -var-file&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;terraform.tfvars -auto-approve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 基于 ShardingSphere-Proxy 的 MySQL-Sharding 分库分表的存储特性介绍</title>
      <link>/zh/skywalking-shardingsphere-proxy/</link>
      <pubDate>Fri, 02 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/skywalking-shardingsphere-proxy/</guid>
      <description>
        
        
        &lt;p&gt;Apache SkyWalking 作为一个分布式系统的应用性能监控工具，它观察服务网格中的指标、日志、痕迹和事件。其中 SkyWalking OAP 高性能的数据流处理架构能够实时处理庞大的数据流量，但是这些海量数据的存储更新和后续查询对后端存储系统带来了挑战。&lt;/p&gt;
&lt;p&gt;SkyWalking 默认已经提供了多种存储支持包括 H2、OpenSearch、ElasticSearch、MySQL、TiDB、PostgreSQL、BanyanDB。其中 MySQL 存储提供的是针对单机和单表的存储方式（MySQL 的集群能力需要自己选型提供），在面对高流量的业务系统时，监控数据的存储存在较大压力，同时影响查询性能。&lt;/p&gt;
&lt;p&gt;在 MySQL 存储基础上 SkyWalking v9.3.0 提供了一种新的存储方式 MySQL-Sharding，它提供了基于 &lt;a href=&#34;https://shardingsphere.apache.org/document/5.1.2/cn/quick-start/shardingsphere-proxy-quick-start/&#34;&gt;ShardingSphere-Proxy&lt;/a&gt; 的分库分表特性，而分库分表是关系型数据库面对大数据量处理的成熟解决方案。&lt;/p&gt;
&lt;h2 id=&#34;部署架构&#34;&gt;部署架构&lt;/h2&gt;
&lt;p&gt;SkyWalking 使用 ShardingSphere-Proxy 的部署方式如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;arch.jpg&#34; alt=&#34;部署架构&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SkyWalking OAP 由直连数据库的方式变成只与 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;ShardingSphere-Proxy&lt;/a&gt; 进行交互；&lt;/li&gt;
&lt;li&gt;每一个 MySQL 节点暴露的连接都是一个数据源，由 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;ShardingSphere-Proxy&lt;/a&gt; 进行统一管理；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;ShardingSphere-Proxy&lt;/a&gt; 会根据配置建立一个虚拟逻辑数据库，根据 OAP 提供的分库分表规则进行库表分片和路由；&lt;/li&gt;
&lt;li&gt;SkyWalking OAP 负责生成分库分表规则并且像操作 MySQL 一样对虚拟逻辑库执行 DDL 和 DML；&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;适用场景&#34;&gt;适用场景&lt;/h2&gt;
&lt;p&gt;希望使用 MySQL 作为存储，随着业务规模的增长，单表模式已经无法满足性能需要。&lt;/p&gt;
&lt;h2 id=&#34;skywalking-分库分表逻辑&#34;&gt;SkyWalking 分库分表逻辑&lt;/h2&gt;
&lt;p&gt;分库分表逻辑通过注解 &lt;code&gt;@SQLDatabase.Sharding&lt;/code&gt; 对 SkyWalking 中的数据模型 Model 进行定义：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@interface&lt;/span&gt; Sharding &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  ShardingAlgorithm &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;shardingAlgorithm&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
  String &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;dataSourceShardingColumn&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;default&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
  String &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tableShardingColumn&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;default&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;shardingAlgorithm&lt;/code&gt;：表分片算法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;dataSourceShardingColumn&lt;/code&gt;：分库键&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tableShardingColumn&lt;/code&gt;：分表键&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SkyWalking 根据注解 &lt;code&gt;@SQLDatabase.Sharding&lt;/code&gt; 选择分库键、分表键以及表分片算法对每个表动态生成分片规则通过 DistSQL 操作 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt; 执行规则定义 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt; 根据规则定义进行数据分片。&lt;/p&gt;
&lt;h3 id=&#34;分库方式&#34;&gt;分库方式&lt;/h3&gt;
&lt;p&gt;SkyWalking 对于分库采用统一的方式，路由目标库的数字后缀使用分库键的哈希值取模需要分库的数据库数量，所以路由目标库为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ds_{dataSourceShardingColumn.hashcode() % dataSourceList.size()}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;例如我们有 &lt;code&gt;dataSourceList = ds_0...ds_n&lt;/code&gt;，如果&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{dataSourceShardingColumn.hashcode() % dataSourceList.size() = 2}&lt;/code&gt; 那么所有数据将会路由到 &lt;code&gt;ds_2&lt;/code&gt; 这个数据源节点上。&lt;/p&gt;
&lt;h3 id=&#34;分表方式&#34;&gt;分表方式&lt;/h3&gt;
&lt;p&gt;由于 TTL 机制的存在，分表算法主要根据时间的日期进行分片，分片表的数量是根据 TTL 每天一个表：&lt;/p&gt;
&lt;p&gt;分片表名 = 逻辑表名_时间序列（日期）：&lt;code&gt;{tableName =logicTableName_timeSeries}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;为保证在 TTL 有效期内的数据能够被写入和查询，时间序列将生成当前日期&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{timeSeries = currentDate - TTL +1...currentDate + 1}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;例如：如果 &lt;code&gt;TTL=3, currentDate = 20220907&lt;/code&gt;，则分片表为:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;logicTableName_20220905
logicTableName_20220906
logicTableName_20220907
logicTableName_20220908
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SkyWalking 提供了多种不同的分表算法用于不同的数据模型：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;算法名称&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;分片说明&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;分片键时间精度要求&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;典型应用数据模型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;NO_SHARDING&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;不做任何表分片，保持单表模式&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;/&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;数据量小无需分片的数据模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;TIME_RELATIVE_ID_SHARDING_ALGORITHM&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;使用 ID 列中的 &lt;code&gt;time_bucket&lt;/code&gt; 按天分片&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;time_bucket&lt;/code&gt; 的精度可以是同一表中的秒、分、小时和天&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;各类 Metrics 指标&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;TIME_SEC_RANGE_SHARDING_ALGORITHM&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;使用 &lt;code&gt;time_bucket&lt;/code&gt; 列按天分片&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;time_bucket&lt;/code&gt; 的精度必须是秒&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;SegmentRecordLogRecord&lt;/code&gt; 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;TIME_MIN_RANGE_SHARDING_ALGORITHM&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;使用 &lt;code&gt;time_bucket&lt;/code&gt; 列按天分片&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;time_bucket&lt;/code&gt; 的精度必须是分钟&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;EndpointTraffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;TIME_BUCKET_SHARDING_ALGORITHM&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;使用 &lt;code&gt;time_bucket&lt;/code&gt; 列按天分片&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;time_bucket&lt;/code&gt; 的精度可以是同一个表中的秒、分、小时和天&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Service、Instance、Endpoint 调用关系等如 &lt;code&gt;ServiceRelationServerSideMetrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;ttl-机制&#34;&gt;TTL 机制&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对于进行分片的表根据 TTL 直接删除 &lt;code&gt;deadline&lt;/code&gt; &amp;gt;= &lt;code&gt;timeSeries&lt;/code&gt; 的物理表 &lt;code&gt;{deadline = new DateTime().plusDays(-ttl)}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;TTL 定时器在根据当前日期删除过期表的同时也会根据新日期更新分片规则，通知 ShardingSphere-Proxy 创建新的分片表&lt;/li&gt;
&lt;li&gt;对于单表的延续之前的方式，删除 deadline &amp;gt;= &lt;code&gt;time_bucket&lt;/code&gt; 的行记录&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;分片数据存储示例&#34;&gt;分片数据存储示例&lt;/h2&gt;
&lt;p&gt;下面以 segment（Record 类型）和 &lt;code&gt;service_resp_time&lt;/code&gt;（Metrics 类型）两个为例说明数据存储的逻辑和物理分布。这里假设 MySQL 为 &lt;code&gt;ds_0&lt;/code&gt; 和 &lt;code&gt;ds_1&lt;/code&gt; 两个节点。&lt;/p&gt;
&lt;p&gt;注意：以下的存储表结构仅为简化后的存储示例，不表示 SkyWalking 真实的表结构。&lt;/p&gt;
&lt;h3 id=&#34;segment&#34;&gt;segment&lt;/h3&gt;
&lt;p&gt;分片配置为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, dataSourceShardingColumn = service_id, tableShardingColumn = time_bucket)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;逻辑库表结构和实际库表如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f1.jpg&#34; alt=&#34;逻辑表结构和实际库表 1&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;service_resp_time&#34;&gt;service_resp_time&lt;/h3&gt;
&lt;p&gt;分片配置为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_RELATIVE_ID_SHARDING_ALGORITHM, tableShardingColumn = id, dataSourceShardingColumn = entity_id)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;逻辑库表结构和实际库表如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f2.jpg&#34; alt=&#34;逻辑表结构和实际库表 2&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;如何使用&#34;&gt;如何使用&lt;/h2&gt;
&lt;p&gt;你可以选择手动或使用 Docker 来运行 Demo。&lt;/p&gt;
&lt;h3 id=&#34;手动部署&#34;&gt;手动部署&lt;/h3&gt;
&lt;p&gt;这里以单节点 SkyWalking OAP 和 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy 5.1.2&lt;/a&gt; 部署为例，集群部署请参考其他相关文档。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;准备好 MySQL 集群&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部署安装并配置 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conf/server.yaml&lt;/code&gt;，&lt;code&gt;props.proxy-hint-enabled&lt;/code&gt; 必须为 &lt;code&gt;true&lt;/code&gt;，完整配置可参考&lt;a href=&#34;https://github.com/wankai123/skywalking-mysql-sharding-demo/blob/main/shardingsphere-proxy/conf/server.yaml&#34;&gt;这里&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conf/config-sharding.yaml&lt;/code&gt;，配置逻辑数据库和 &lt;code&gt;dataSources&lt;/code&gt; 列表，&lt;code&gt;dataSource&lt;/code&gt; 的名称必须以 &lt;code&gt;ds_&lt;/code&gt;为前缀，并且从 &lt;code&gt;ds_0&lt;/code&gt; 开始，完整配置可参考&lt;a href=&#34;https://github.com/wankai123/skywalking-mysql-sharding-demo/blob/main/shardingsphere-proxy/conf/config-sharding.yaml&#34;&gt;这里&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部署安装并配置 SkyWalking OAP：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置 OAP 环境变量 &lt;code&gt;${SW_STORAGE:mysql-sharding}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;根据实际部署情况配置连接信息： &lt;code&gt;${SW_JDBC_URL}&lt;/code&gt; &lt;code&gt;${SW_DATA_SOURCE_USER}&lt;/code&gt; &lt;code&gt;${SW_DATA_SOURCE_PASSWORD}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：连接信息需对应 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt; 虚拟数据库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt; 中 &lt;code&gt;conf/config-sharding.yaml&lt;/code&gt; 配置的数据源名称配置在 &lt;code&gt;${SW_JDBC_SHARDING_DATA_SOURCES}&lt;/code&gt; 中，用 &lt;code&gt;,&lt;/code&gt; 分割&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动 MySQL 集群&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动 &lt;a href=&#34;https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy&#34;&gt;Shardingsphere-Proxy&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动 SkyWalking OAP&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;使用-docker-运行-demo&#34;&gt;使用 Docker 运行 Demo&lt;/h3&gt;
&lt;p&gt;GitHub 资源库提供了一个基于 Docker 完整可运行的 demo：&lt;a href=&#34;https://github.com/wankai123/skywalking-mysql-sharding-demo&#34;&gt;skywalking-mysql-sharding-demo&lt;/a&gt;，可以快速尝试实际运行效果。&lt;/p&gt;
&lt;p&gt;其中部署包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;oap 服务 1 个，Metrics 和 Record 数据的 TTL 均设为 2 天&lt;/li&gt;
&lt;li&gt;sharding-proxy 服务 1 个版本为 5.1.2，对外端口为 13307，创建的逻辑库名称为 swtest&lt;/li&gt;
&lt;li&gt;mysql 服务 2 个，对外端口分别为 3306，3307，在 sharding-proxy 的 &lt;code&gt;conf/config-sharding.yaml&lt;/code&gt; 中配置为 &lt;code&gt;ds_0&lt;/code&gt; 和 &lt;code&gt;ds_1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;provider 服务 1 个（模拟业务程序用于验证 trace 和 metrics 等数据），对外端口为 9090&lt;/li&gt;
&lt;li&gt;consumer 服务 1 个（模拟业务程序用于验证 trace 和 metrics 等数据），对外端口为 9092&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将 Demo 程序获取到本地后，在 skywalking-mysql-sharding-demo 目录下直接运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意：初次启动由于拉取镜像和新建所有表可能需要一定的时间。&lt;/p&gt;
&lt;p&gt;所有服务启动完成之后可以通过数据库工具查看 &lt;code&gt;sharding-proxy&lt;/code&gt; 逻辑表创建情况，以及两个 MySQL 库中实际的物理分片表创建情况。也可以连接 &lt;code&gt;sharding-proxy&lt;/code&gt; 逻辑库 &lt;code&gt;swtest&lt;/code&gt; 查看数据查询路由情况，如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;PREVIEW
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;FROM&lt;/span&gt; SEGMENT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;显示结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sql.jpg&#34; alt=&#34;查询结果&#34;&gt;&lt;/p&gt;
&lt;p&gt;Demo 提供的模拟业务程序可以通过请求 consumer 服务模拟业务请求，用于验证各类型数据分布：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;curl http://127.0.0.1:9092/info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;在这篇文章中我们详细介绍了 SkyWalking  基于 ShardingSphere-Proxy 的 MySQL-Sharding 存储特性的部署架构、适应场景、核心分库分表逻辑以及 TTL 机制，并提供了运行后的数据存储示例和详细部署配置步骤以便大家快速理解上手。SkyWalking 提供了多种存储方式以供选择，如果你目前的需求如本文所述，欢迎使用该新特性。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 使用 eBPF 诊断服务网格网络性能</title>
      <link>/zh/diagnose-service-mesh-network-performance-with-ebpf/</link>
      <pubDate>Tue, 27 Sep 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/diagnose-service-mesh-network-performance-with-ebpf/</guid>
      <description>
        
        
        &lt;p&gt;本文将展示如何利用 &lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache SkyWalking&lt;/a&gt; 与 &lt;a href=&#34;https://ebpf.io/what-is-ebpf/&#34;&gt;eBPF&lt;/a&gt;，使服务网格下的网络故障排除更加容易。&lt;/p&gt;
&lt;p&gt;Apache SkyWalking 是一个分布式系统的应用性能监控工具。它观察服务网格中的指标、日志、痕迹和事件，并使用这些数据来生成 pod 和服务的依赖图。这个依赖关系图可以帮助你快速系统，尤其是在出现问题的时候。&lt;/p&gt;
&lt;p&gt;然而，在排除 SkyWalking 服务拓扑中的网络问题时，确定错误的实际位置有时候并不容易。造成这种困难的原因有两个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;通过 Envoy sidecar 的流量并不容易观察&lt;/strong&gt;：来自 Envoy 的&lt;a href=&#34;https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto&#34;&gt;访问日志服务（ALS）&lt;/a&gt;的数据显示了服务之间的流量（sidecar-to-sidecar），但没有关于 Envoy sidecar 和它代理的服务之间的通信指标。如果没有这些信息，就很难理解 sidecar 的影响。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺乏来自传输层（OSI 第 4 层）通信的数据&lt;/strong&gt;：由于服务通常使用应用层（OSI 第 7 层）协议，如 HTTP，可观测性数据通常被限制在应用层通信中。然而，根本原因可能实际上是在传输层，而传输层对可观测性工具来说通常是不透明的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;获取 Envoy-to-service 和传输层通信的指标，可以更容易诊断服务问题。为此，SkyWalking 需要收集和分析 Kubernetes pod 内进程之间的传输层指标 —— 这项任务很适合 eBPF。我们调查了为此目的使用 eBPF 的情况，并在下面介绍了我们的结果和演示。&lt;/p&gt;
&lt;h2 id=&#34;用-ebpf-监控-kubernetes-网络&#34;&gt;用 eBPF 监控 Kubernetes 网络&lt;/h2&gt;
&lt;p&gt;eBPF 起源于 Extended Berkeley Packet Filter，是一种通用的机制，可以在 Linux 内核中注入和运行自己的代码，是监测 Kubernetes Pod 中网络流量的优秀工具。在接下来的几节中，我们将概述如何使用 eBPF 进行网络监控，作为介绍 &lt;a href=&#34;https://github.com/apache/skywalking-rover&#34;&gt;Skywalking Rover&lt;/a&gt; 的背景，这是一个由 eBPF 驱动的指标收集器和分析器，用于诊断 CPU 和网络性能。&lt;/p&gt;
&lt;h3 id=&#34;应用程序和网络如何相互作用&#34;&gt;应用程序和网络如何相互作用&lt;/h3&gt;
&lt;p&gt;应用程序和网络之间的互动一般可分为以下步骤，从较高的抽象层次到较低的抽象层次：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f0.svg&#34; alt=&#34;抽象层次&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户代码&lt;/strong&gt;：应用程序代码使用应用程序堆栈中的高级网络库，在网络上交换数据，如发送和接收 HTTP 请求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络库&lt;/strong&gt;：当网络库收到网络请求时，它与语言 API 进行交互以发送网络数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语言 API&lt;/strong&gt;：每种语言都提供了一个操作网络、系统等的 API。当收到一个请求时，它与系统的 API 进行交互。在 Linux 中，这个 API 被称为系统调用（syscalls）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux API&lt;/strong&gt;：当 Linux 内核通过 API 收到请求时，它与套接字进行通信以发送数据，这通常更接近于 OSI 第四层协议，如 TCP、UDP 等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Socket Ops&lt;/strong&gt;：向 / 从网卡发送或接收数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们的假设是，eBPF 可以监控网络。有两种方法可以实现拦截：&lt;strong&gt;用户空间（uprobe）或内核空间（kprobe）&lt;/strong&gt;。下表总结了两者的区别。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;uprobe&lt;/td&gt;
&lt;td&gt;• 获取更多与应用相关的上下文，例如当前请求是 HTTP 还是 HTTPS。&lt;/br&gt; • 请求和响应可以通过一个方法来截获。&lt;/td&gt;
&lt;td&gt;• 数据结构可能是不稳定的，所以更难获得所需的数据。&lt;/br&gt; • 不同语言/库版本的实现可能不同。&lt;/br&gt; • 在没有&lt;a href=&#34;https://en.wikipedia.org/wiki/Symbol_table&#34;&gt;符号表&lt;/a&gt;的应用程序中不起作用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kprobe&lt;/td&gt;
&lt;td&gt;• 可用于所有语言。&lt;/br&gt; • 数据结构和方法很稳定，不需要太多调整。&lt;/br&gt; • 更容易与底层数据相关联，如获得 TCP 的目标地址、OSI 第四层协议指标等。&lt;/td&gt;
&lt;td&gt;• 一个单一的请求和响应可能被分割成多个 probe。&lt;/br&gt; • 对于有状态的请求，上下文信息不容易得到。例如 HTTP/2 中的头压缩。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;对于一般的网络性能监控，我们选择使用 kprobe（拦截系统调用），原因如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;它可用于用任何编程语言编写的应用程序，而且很稳定，所以可以节省大量的开发 / 适应成本。&lt;/li&gt;
&lt;li&gt;它可以与系统层面的指标相关联，这使得故障排除更加容易。&lt;/li&gt;
&lt;li&gt;由于一个请求和响应被分割成多个 probe，我们可以利用技术将它们关联起来。&lt;/li&gt;
&lt;li&gt;对于背景信息，它通常用于 OSI 第七层协议网络分析。因此，如果我们只是监测网络性能，那么它们可以被忽略。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;kprobes-和网络监控&#34;&gt;Kprobes 和网络监控&lt;/h3&gt;
&lt;p&gt;按照 &lt;a href=&#34;http://linasm.sourceforge.net/docs/syscalls/network.php&#34;&gt;Linux 文档中的网络系统调用&lt;/a&gt;，我们可以通过两类拦截方法实现网络监控：&lt;strong&gt;套接字操作&lt;/strong&gt;和&lt;strong&gt;发送 / 接收&lt;/strong&gt;方法。&lt;/p&gt;
&lt;h4 id=&#34;套接字操作&#34;&gt;套接字操作&lt;/h4&gt;
&lt;p&gt;当接受或与另一个套接字连接时，我们可以得到以下信息：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;连接信息&lt;/strong&gt;：包括来自连接的远程地址，这有助于我们了解哪个 pod 被连接。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;连接统计&lt;/strong&gt; ：包括来自套接字的基本指标，如往返时间（&lt;a href=&#34;https://en.wikipedia.org/wiki/Round-trip_delay&#34;&gt;RTT&lt;/a&gt;）、TCP 的丢包数等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;套接字和文件描述符（&lt;a href=&#34;https://en.wikipedia.org/wiki/File_descriptor&#34;&gt;FD&lt;/a&gt;）的映射&lt;/strong&gt;：包括 Linux 文件描述符和套接字对象之间的关系。在通过 Linux 文件描述符发送和接收数据时，它很有用。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;发送--接收&#34;&gt;发送 / 接收&lt;/h4&gt;
&lt;p&gt;与发送或接收数据有关的接口是性能分析的重点。它主要包含以下参数：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Socket 文件描述符&lt;/strong&gt;：当前操作对应的套接字的文件描述符。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缓冲区&lt;/strong&gt;：发送或接收的数据，以字节数组形式传递。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于上述参数，我们可以分析以下数据：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;字节&lt;/strong&gt;：数据包的大小，以字节为单位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协议&lt;/strong&gt;：根据缓冲区的数据进行协议分析，如 HTTP、MySQL 等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行时间&lt;/strong&gt;：发送 / 接收数据所需的时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在这一点上（图 1），我们可以分析出连接的整个生命周期的以下步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;连接 / 接受&lt;/strong&gt;：当连接被创建时。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转化&lt;/strong&gt;：在连接上发送和接收数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关闭&lt;/strong&gt;：当连接被关闭时。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;f1.svg&#34; alt=&#34;图 1&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 1&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;协议和-tls&#34;&gt;协议和 TLS&lt;/h3&gt;
&lt;p&gt;上一节描述了如何使用发送或接收缓冲区数据来分析连接。例如，遵循 &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc2068.html#section-4.1&#34;&gt;HTTP/1.1 消息规范&lt;/a&gt;来分析连接。然而，这对 TLS 请求 / 响应不起作用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f2.svg&#34; alt=&#34;图 2&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 2&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当使用 TLS 时，Linux 内核在用户空间中传输加密的数据。在上图中，应用程序通常通过第三方库（如 OpenSSL）传输 SSL 数据。对于这种情况，Linux API 只能得到加密的数据，所以它不能识别任何高层协议。为了在 eBPF 内部解密，我们需要遵循以下步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;通过 uprobe 读取未加密的数据&lt;/strong&gt;：兼容多种语言，使用 uprobe 来捕获发送前或接收后没有加密的数据。通过这种方式，我们可以获得原始数据并将其与套接字联系起来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与套接字关联&lt;/strong&gt;：我们可以将未加密的数据与套接字关联。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;openssl-用例&#34;&gt;OpenSSL 用例&lt;/h4&gt;
&lt;p&gt;例如，发送 / 接收 SSL 数据最常见的方法是使用 OpenSSL 作为共享库，特别是 &lt;a href=&#34;https://www.openssl.org/docs/man1.1.1/man3/SSL_read.html&#34;&gt;SSL_read&lt;/a&gt; 和 &lt;a href=&#34;https://www.openssl.org/docs/man1.1.1/man3/SSL_write.html&#34;&gt;SSL_write&lt;/a&gt; 方法，以提交缓冲区数据与套接字。&lt;/p&gt;
&lt;p&gt;按照&lt;a href=&#34;https://www.openssl.org/docs/man1.1.1/man7/ssl.html&#34;&gt;文档&lt;/a&gt;，我们可以截获这两种方法，这与 Linux 中的 API 几乎相同。OpenSSL 中 SSL 结构的源代码显示， &lt;a href=&#34;https://github.com/openssl/openssl/blob/9eae491721209f302a9a475bffd271370e8bcb8f/crypto/bio/bio_local.h#L115-L125&#34;&gt;Socket FD&lt;/a&gt; 存在于 &lt;a href=&#34;https://github.com/openssl/openssl/blob/9eae491721209f302a9a475bffd271370e8bcb8f/ssl/ssl_local.h#L1068-L1083&#34;&gt;SSL 结构的 BIO 对象&lt;/a&gt;中，我们可以通过 offset 得到它。&lt;/p&gt;
&lt;p&gt;综上所述，通过对 OpenSSL 工作原理的了解，我们可以在一个 eBPF 函数中读取未加密的数据。&lt;/p&gt;
&lt;h2 id=&#34;skywalking-rover-基于-ebpf-的指标收集器和分析器&#34;&gt;SkyWalking Rover—— 基于 eBPF 的指标收集器和分析器&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking-rover&#34;&gt;SkyWalking Rover&lt;/a&gt; 在 SkyWalking 生态系统中引入了 eBPF 网络分析功能。目前已在 Kubernetes 环境中得到支持，所以必须在 Kubernetes 集群内部署。部署完成后，SkyWalking Rover 可以监控特定 Pod 内所有进程的网络。基于监测数据，SkyWalking 可以生成进程之间的拓扑关系图和指标。&lt;/p&gt;
&lt;h3 id=&#34;拓扑结构图&#34;&gt;拓扑结构图&lt;/h3&gt;
&lt;p&gt;拓扑图可以帮助我们了解同一 Pod 内的进程之间以及进程与外部环境（其他 Pod 或服务）之间的网络访问情况。此外，它还可以根据线路的流动方向来确定流量的数据方向。&lt;/p&gt;
&lt;p&gt;在下面的图 3 中，六边形内的所有节点都是一个 Pod 的内部进程，六边形外的节点是外部关联的服务或 Pod。节点由线连接，表示节点之间的请求或响应方向（客户端或服务器）。线条上标明了协议，它是 HTTP (S)、TCP 或 TCP (TLS)。另外，我们可以在这个图中看到，Envoy 和 Python 应用程序之间的线是双向的，因为 Envoy 拦截了所有的应用程序流量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f3.jpg&#34; alt=&#34;图 3&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 3&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;度量&#34;&gt;度量&lt;/h3&gt;
&lt;p&gt;一旦我们通过拓扑结构认识到进程之间的网络调用关系，我们就可以选择一个特定的线路，查看两个进程之间的 TCP 指标。&lt;/p&gt;
&lt;p&gt;下图（图4）显示了两个进程之间网络监控的指标。每行有四个指标。左边的两个是在客户端，右边的两个是在服务器端。如果远程进程不在同一个 Pod 中，则只显示一边的指标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f4.jpg&#34; alt=&#34;图 4&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 4&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;有以下两种度量类型。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;计数器（Counter）&lt;/strong&gt;：记录一定时期内的数据总数。每个计数器包含以下数据。
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;计数&lt;/strong&gt;：执行次数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字节&lt;/strong&gt;：数据包大小，以字节为单位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行时间&lt;/strong&gt;：执行时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;柱状图（Histogram）&lt;/strong&gt;：记录数据在桶中的分布。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于上述数据类型，暴露了以下指标：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;单位&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;计数器和柱状图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;套接字写计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;计数器和柱状图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;套接字读计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write RTT&lt;/td&gt;
&lt;td&gt;计数器和柱状图&lt;/td&gt;
&lt;td&gt;微秒&lt;/td&gt;
&lt;td&gt;套接字写入往返时间（RTT）计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect&lt;/td&gt;
&lt;td&gt;计数器和柱状图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;套接字连接/接受另一个服务器/客户端的计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Close&lt;/td&gt;
&lt;td&gt;计数器和柱状图&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;有其他套接字的计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retransmit&lt;/td&gt;
&lt;td&gt;计数器&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;套接字重发包计数器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop&lt;/td&gt;
&lt;td&gt;计数器&lt;/td&gt;
&lt;td&gt;毫秒&lt;/td&gt;
&lt;td&gt;套接字掉包计数器。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;演示&#34;&gt;演示&lt;/h2&gt;
&lt;p&gt;在本节中，我们将演示如何在服务网格中执行网络分析。要跟上进度，你需要一个正在运行的 Kubernetes 环境。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：所有的命令和脚本都可以&lt;a href=&#34;https://github.com/mrproliu/skywalking-network-profiling-demo&#34;&gt;在这个 GitHub 资源库中&lt;/a&gt;找到。&lt;/p&gt;
&lt;h3 id=&#34;安装-istio&#34;&gt;安装 Istio&lt;/h3&gt;
&lt;p&gt;Istio是最广泛部署的服务网格，并附带一个完整的演示应用程序，我们可以用来测试。要安装 Istio 和演示应用程序，请遵循以下步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用演示配置文件安装 Istio。&lt;/li&gt;
&lt;li&gt;标记 default 命名空间，所以当我们要部署应用程序时，Istio 会自动注入 Envoy 的 sidecar 代理。&lt;/li&gt;
&lt;li&gt;将 bookinfo 应用程序部署到集群上。&lt;/li&gt;
&lt;li&gt;部署流量生成器，为应用程序生成一些流量。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;ISTIO_VERSION&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;1.13.1

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 安装 istio&lt;/span&gt;
istioctl install -y --set &lt;span style=&#34;color:#008080&#34;&gt;profile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo
kubectl label namespace default istio-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 部署 bookinfo 应用程序&lt;/span&gt;
kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/networking/destination-rule-all.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/networking/virtual-service-all-v1.yaml

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 产生流量&lt;/span&gt;
kubectl apply -f https://raw.githubusercontent.com/mrproliu/skywalking-network-profiling-demo/main/resources/traffic-generator.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;安装-skywalking&#34;&gt;安装 SkyWalking&lt;/h3&gt;
&lt;p&gt;下面将安装 SkyWalking 所需的存储、后台和用户界面。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;git clone https://github.com/apache/skywalking-kubernetes.git
&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; skywalking-kubernetes
&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; chart
helm dep up skywalking
helm -n istio-system install skywalking skywalking &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set &lt;span style=&#34;color:#008080&#34;&gt;fullnameOverride&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set elasticsearch.minimumMasterNodes&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set elasticsearch.imageTag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;7.5.1 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.replicas&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set ui.image.repository&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;apache/skywalking-ui &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set ui.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;9.2.0 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;9.2.0 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.envoy.als.enabled&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.image.repository&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;apache/skywalking-oap-server &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.storageType&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;elasticsearch &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt; --set oap.env.SW_METER_ANALYZER_ACTIVE_FILES&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;network-profiling&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;安装-skywalking-rover&#34;&gt;安装 SkyWalking Rover&lt;/h3&gt;
&lt;p&gt;SkyWalking Rover 部署在 Kubernetes 的每个节点上，它自动检测 Kubernetes 集群中的服务。网络剖析功能已经在 SkyWalking Rover 的 0.3.0 版本中发布。当网络监控任务被创建时，SkyWalking Rover 会将数据发送到 SkyWalking 后台。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl apply -f https://raw.githubusercontent.com/mrproliu/skywalking-network-profiling-demo/main/resources/skywalking-rover.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;启动网络分析任务&#34;&gt;启动网络分析任务&lt;/h3&gt;
&lt;p&gt;一旦所有部署完成，我们必须在 SkyWalking UI 中为服务的特定实例创建一个网络分析任务。&lt;/p&gt;
&lt;p&gt;要打开 SkyWalking UI，请运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl port-forward svc/skywalking-ui 8080:80 --namespace istio-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;目前，我们可以通过点击服务网格面板中的&lt;strong&gt;数据平面&lt;/strong&gt;项目和 &lt;strong&gt;Kubernetes&lt;/strong&gt; 面板中的服务项目来选择我们想要监控的特定实例。&lt;/p&gt;
&lt;p&gt;在下图中，我们选择了一个实例，在网络剖析标签里有一个任务列表。当我们点击启动按钮时，SkyWalking Rover 开始监测这个实例的网络。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f5.jpg&#34; alt=&#34;图 5&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 5&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;完成&#34;&gt;完成&lt;/h3&gt;
&lt;p&gt;几秒钟后，你会看到页面的右侧出现进程拓扑结构。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f6.jpg&#34; alt=&#34;图 6&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 6&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当你点击进程之间的线时，你可以看到两个进程之间的 TCP 指标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f7.jpg&#34; alt=&#34;图 7&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;图 7&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;在这篇文章中，我们详细介绍了一个使服务网格故障排除困难的问题：网络堆栈中各层之间缺乏上下文。这些情况下，当现有的服务网格 /envoy 不能时，eBPF 开始真正帮助调试 / 生产。然后，我们研究了如何将 eBPF 应用于普通的通信，如 TLS。最后，我们用 SkyWalking Rover 演示了这个过程的实现。&lt;/p&gt;
&lt;p&gt;目前，我们已经完成了对 OSI 第四层（主要是 TCP）的性能分析。在未来，我们还将介绍对 OSI 第 7 层协议的分析，如 HTTP。&lt;/p&gt;
&lt;h2 id=&#34;开始使用-istio&#34;&gt;开始使用 Istio&lt;/h2&gt;
&lt;p&gt;开始使用服务网格，&lt;a href=&#34;https://istio.tetratelabs.io/&#34;&gt;Tetrate Istio Distro&lt;/a&gt; 是安装、管理和升级 Istio 的最简单方法。它提供了一个经过审查的 Istio 上游发布，由 Tetrate 为特定平台进行测试和优化，加上一个 CLI，方便获取、安装和配置多个 Istio 版本。Tetrate Istio Distro 还为 FedRAMP 环境提供 &lt;a href=&#34;https://www.tetrate.io/blog/tetrate-istio-distro-achieves-fips-certification/&#34;&gt;FIPS 认证的 Istio 构建&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;对于需要以统一和一致的方式在复杂的异构部署环境中保护和管理服务和传统工作负载的企业，我们提供 &lt;a href=&#34;https://www.tetrate.io/tetrate-service-bridge/&#34;&gt;Tetrate Service Bridge&lt;/a&gt;，这是我们建立在 Istio 和 Envoy 上的旗舰工作负载应用连接平台。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.tetrate.io/contact/&#34;&gt;联系我们以了解更多&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;其他资源&#34;&gt;其他资源&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;SkyWalking Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-rover&#34;&gt;SkyWalking Rover Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-rover/v0.3.0/readme/&#34;&gt;SkyWalking Rover 文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/blog/2022-07-05-pinpoint-service-mesh-critical-performance-impact-by-using-ebpf/&#34;&gt;通过使用 eBPF 博文准确定位服务网格关键性能影响&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=yUF5qRk4rYY&#34;&gt;Apache SkyWalking 与本地 eBPF 代理的介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ebpf.io/what-is-ebpf#hook-overview&#34;&gt;eBPF hook概述&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking on the way - 平安健康千亿级的全链路追踪系统的建设与实践</title>
      <link>/zh/2022-08-30-pingan-jiankang/</link>
      <pubDate>Tue, 30 Aug 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-08-30-pingan-jiankang/</guid>
      <description>
        
        
        &lt;img src=&#34;pic1.png&#34;&gt;
&lt;h3 id=&#34;目录&#34;&gt;目录&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;开篇&lt;/li&gt;
&lt;li&gt;为什么需要全链路监控&lt;/li&gt;
&lt;li&gt;为什么选择SkyWalking&lt;/li&gt;
&lt;li&gt;预研&lt;/li&gt;
&lt;li&gt;POC&lt;/li&gt;
&lt;li&gt;优化&lt;/li&gt;
&lt;li&gt;未来&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;1开篇&#34;&gt;1、开篇&lt;/h3&gt;
&lt;p&gt;自从SkyWalking开始在公司推广，时不时会在排查问题的人群中听到这样的话：“你咋还没接SkyWalking？接入后，一眼就看出是哪儿的问题了&amp;hellip;&amp;quot;，正如同事所说的，在许多情况下，SkyWalking就是这么秀。作为实践者，我非常感谢SkyWalking，因为这款国产全链路监控产品给公司的的伙伴们带来了实实在在的帮助；也特别感谢公司的领导和同事们，正因为他们的支持和帮助，才让这套SkyWalking（V8.5.0）系统从起初的有用进化到现在的好用；&lt;strong&gt;从几十亿的Segment储能上限、几十秒的查询耗时，优化到千亿级的Segment储能、毫秒级的查询耗时&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;小提示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SkyWalking迭代速度很快，公司使用的是8.5.0版本，其新版本的性能肯定有改善。&lt;/li&gt;
&lt;li&gt;Segment是SkyWalking中提出的概念，表示一次请求在某个服务内的执行链路片段的合集，一个请求在多个服务中先后产生的Segment串起来构成一个完整的Trace，如下图所示：&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&#34;pic2.png&#34;&gt;
&lt;p&gt;SkyWalking的这次实践，截止到现在有一年多的时间，回顾总结一下这段历程中的些许积累和收获，愿能反哺社区，给有需求的道友提供个案例借鉴；也希望能收获到专家们的指导建议，把项目做得更好。因为安全约束，要把有些内容和谐掉，但也努力把这段历程中那些**靓丽的风景，**尽可能完整的呈现给大家。&lt;/p&gt;
&lt;h3 id=&#34;2为什么需要全链路监控&#34;&gt;2、为什么需要全链路监控&lt;/h3&gt;
&lt;p&gt;随着微服务架构的演进，单体应用按照服务维度进行拆分，组织架构也随之演进以横向、纵向维度拆分；一个业务请求的执行轨迹，也从单体应用时期一个应用实例内一个接口，变成多个服务实例的多个接口；对应到组织架构，可能跨越多个BU、多个Owner。虽然微服务架构高内聚低耦合的优势是不言而喻的，但是低耦合也有明显的副作用，它在现实中给跨部门沟通、协作带来额外的不可控的开销；因此开发者尤其是终端业务侧的架构师、管理者，特别需要一些可以帮助理解系统拓扑和用于分析性能问题的工具，便于在架构调整、性能检测和发生故障时，缩减沟通协作方面的精力和时间耗费，快速定位并解决问题。&lt;/p&gt;
&lt;p&gt;我所在的&lt;strong&gt;平安健康互联网股份有限公司&lt;/strong&gt;（文中简称公司），是微服务架构的深度实践者。公司用互联网技术搭建医疗服务平台，致力于&lt;strong&gt;构筑专业的医患桥梁，提供专业、全面、高品质、一站式企业健康管理服务&lt;/strong&gt;。为了进一步提高系统服务质量、提升问题响应效率，部门在21年结合自身的一些情况，决定对现行的全链路监控系统进行升级，目的与以下网络中常见的描述基本一致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快速发现问题&lt;/li&gt;
&lt;li&gt;判断故障影响范围&lt;/li&gt;
&lt;li&gt;梳理服务依赖并判断依赖的合理性&lt;/li&gt;
&lt;li&gt;分析链路性能并实施容量规划&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3为什么选择skywalking&#34;&gt;3、为什么选择SkyWalking&lt;/h3&gt;
&lt;p&gt;在做技术选型时，网络中搜集的资料显示，谷歌的 Dapper系统，算是链路追踪领域的始祖。受其公开论文中提出的概念和理念的影响，一些优秀的企业、个人先后做出不少非常nice的产品，有些还在社区开源共建，如：韩国的Pinpoint，Twitter的Zipkin，Uber的Jaeger及中国的SkyWalking 等，我司选型立项的过程中综合考虑的因素较多，这里只归纳一下SkyWalking吸引我们的2个优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;产品的完善度高：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;java生态，功能丰富&lt;/li&gt;
&lt;li&gt;社区活跃，迭代迅速&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;链路追踪、拓扑分析的能力强：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件丰富，探针无侵入。&lt;/li&gt;
&lt;li&gt;采用先进的&lt;strong&gt;流式拓扑分析&lt;/strong&gt;设计&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;“好东西不需要多说,实际行动告诉你“，这句话我个人非常喜欢，关于SkyWalking的众多的优点，网络上可以找到很多，此处先不逐一比较、赘述了。&lt;/p&gt;
&lt;h3 id=&#34;4预研&#34;&gt;4、预研&lt;/h3&gt;
&lt;p&gt;当时最新版本8.5.0，梳理分析8.x的发布记录后，评估此版本的核心功能是蛮稳定的，于是基于此版本开始了SkyWalking的探索之旅。当时的认知是有限的，串行思维模型驱使我将关注的问题聚焦在&lt;strong&gt;架构原理是怎样&lt;/strong&gt;、&lt;strong&gt;有什么副作用&lt;/strong&gt;这2个方面：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;架构和原理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent端 主要关注 Java Agent的机制、SkyWalking Agent端的配置、插件的工作机制、数据采集及上报的机制。&lt;/li&gt;
&lt;li&gt;服务端 主要关注 角色和职责、模块和配置、数据接收的机制、指标构建的机制、指标聚合的机制及指标存储的机制。&lt;/li&gt;
&lt;li&gt;存储端 主要关注 数据量，存储架构要求以及资源评估。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;副作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能干扰&lt;/li&gt;
&lt;li&gt;性能损耗&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;41-架构和原理&#34;&gt;4.1 架构和原理&lt;/h4&gt;
&lt;p&gt;SkyWalking社区很棒，官网文档和官方出版的书籍有较系统化的讲解，因为自己在APM系统以及Java Agent方面有一些相关的经验沉淀，通过在这两个渠道的学习，对Agent端和OAP(服务端)很快便有了较系统化的认知。在做系统架构选型时，评估数据量会比较大（成千上万的JVM实例数，每天采集的Segment数量可能是50-100亿的级别），所以传输通道选择Kafka、存储选择Elasticsearch，如此简易版的架构以及数据流转如下图所示：&lt;/p&gt;
&lt;img src=&#34;pic3.png&#34;&gt;
&lt;p&gt;这里有几处要解释一下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Agent上报数据给OAP端，有grpc通道和kafka通道，当时就盲猜grpc通道可能撑不住，所以选择kafka通道来削峰；kafka通道是在8.x里加入的。&lt;/li&gt;
&lt;li&gt;千亿级的数据用ES来做存储肯定是可以的。&lt;/li&gt;
&lt;li&gt;图中L1聚合的意思是：SkyWalking OAP服务端 接收数据后，构建metric并完成metric 的Level-1聚合，这里简称L1聚合。&lt;/li&gt;
&lt;li&gt;图中L2聚合的意思是：服务端 基于metric的Level-1聚合结果，再做一次聚合，即Level-2聚合，这里简称L2聚合。后续把纯Mixed角色的集群拆成了两个集群。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;42-副作用&#34;&gt;4.2 副作用&lt;/h4&gt;
&lt;p&gt;对于质量团队和接入方来说，他们最关注的问题是，接入SkyWalking后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否对应用有功能性干扰&lt;/li&gt;
&lt;li&gt;在运行期能带来哪些性能损耗&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两个问题从3个维度来得到答案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;网络资料显示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent带来的性能损耗在5%以内&lt;/li&gt;
&lt;li&gt;未搜到功能性干扰相关的资料（盲猜没有这方面问题）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现机制评估：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;字节码增强机制是JVM提供的机制，SkyWalking使用的字节码操控框架ByteBuddy也是成熟稳定的；通过自定义ClassLoader来加载管理插件类，不会产生冲突和污染。&lt;/li&gt;
&lt;li&gt;Agent内插件开发所使用的AOP机制是基于模板方法模式实现的，风控很到位，即使插件的实现逻辑有异常也不影响用户逻辑的执行；&lt;/li&gt;
&lt;li&gt;插件采集数据跟上报逻辑之间用了一个&lt;strong&gt;轻量级的无锁环形队列&lt;/strong&gt;进行解耦，算是一种保护机制；这个队列在MPSC场景下性能还不错；队列采用满时丢弃的策略，不会有积压阻塞和OOM。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;性能测试验证&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试的老师针对dubbo、http 这两种常规RPC通信场景，进行压力测试和稳定性测试，结果与网络资料描述一致，符合预期。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;5poc&#34;&gt;5、POC&lt;/h3&gt;
&lt;p&gt;在POC阶段，接入几十个种子应用，在非生产环境试点观察，同时完善插件补全链路，对接公司的配置中心，对接发布系统，完善自监控.全面准备达到推广就绪状态。&lt;/p&gt;
&lt;h4 id=&#34;51-对接发布系统&#34;&gt;5.1 对接发布系统&lt;/h4&gt;
&lt;p&gt;为了对接公司的发布系统，方便系统的发布，将SkyWalking应用拆分为4个子应用：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;应用&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;介绍&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;Webapp&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Skywalking的web端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;Agent&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Skywalking的Agent端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;OAP-Receiver&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;skywakling的服务端，角色是Mixed或Receiver&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;OAP-Aggregator&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;skywalking的服务端，角色是Aggregator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这里有个考虑，暂定先使用纯Mixed角色的单集群，有性能问题时就试试 Receiver+Aggregator双角色集群模式，最终选哪种视效果而定。&lt;/p&gt;
&lt;p&gt;SkyWalking Agent端是基于Java Agent机制实现的，采用的是启动挂载模式；启动挂载需在启动脚本里加入挂载Java Agent的逻辑，发布系统实现这个功能需要注意2点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;启动脚本挂载SkyWalking Agent的环节，尽量让用户无感知。&lt;/li&gt;
&lt;li&gt;发布系统在挂载Agent的时候，给Agent指定应用名称和所属分组信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SkyWalking Agent的发布和升级也由发布系统来负责；Agent的升级采用了灰度管控的方案，控制的粒度是应用级和实例级两种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;按照应用灰度，可给应用指定使用什么版本的Agent&lt;/li&gt;
&lt;li&gt;按照应用的实例灰度，可给应用指定其若干实例使用什么版本的Agent&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;52-完善插件补全链路&#34;&gt;5.2 完善插件补全链路&lt;/h4&gt;
&lt;p&gt;针对公司OLTP技术栈，量身定制了插件套，其中大部分在开源社区的插件库中有，缺失的部分通过自研快速补齐。&lt;/p&gt;
&lt;p&gt;这些插件给各组件的核心环节埋点，采集数据上报给SkyWalking后，Web端的【追踪】页面就能勾勒出丰满完美的请求执行链路；这对架构师理解真实架构，测试同学验证逻辑变更和分析性能损耗，开发同学精准定位问题都非常的有帮助。这里借官方在线Demo的截图一用（抱歉后端程序员，五毛特效都没做出来，丰满画面还请自行脑补）&lt;/p&gt;
&lt;img src=&#34;pic4.png&#34;&gt;
&lt;p&gt;&lt;strong&gt;友情小提示&lt;/strong&gt;：移除不用的插件对程序编译打包和减少应用启动耗时很有帮助。&lt;/p&gt;
&lt;h4 id=&#34;53压测稳测&#34;&gt;5.3压测稳测&lt;/h4&gt;
&lt;p&gt;测试的老师，针对SkyWalking Agent端的插件套，设计了丰富的用例，压力测试和稳定性测试的结果都符合预期；每家公司的标准不尽一致，此处不再赘述。&lt;/p&gt;
&lt;h4 id=&#34;54-对接自研的配置中心&#34;&gt;5.4 对接自研的配置中心&lt;/h4&gt;
&lt;p&gt;把应用中繁杂的配置交给配置中心来管理是非常必要的，配置中心既能提供启动时的静态配置，又能管理运行期的动态配置，而且外部化配置的机制特别容易满足容器场景下应用的无状态化要求。啰嗦一下，举2个例子：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;调优时，修改参数的值不用来一遍开发到测试再到生产的发布。&lt;/li&gt;
&lt;li&gt;观测系统状态，修改日志配置后不需要来一遍开发到测试再到生产的发布。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Skywaling在外接配置中心这块儿，适配了市面中主流的配置中心产品。而公司的配置中心是自研的，需要对接一下，得益于SkyWalking提供的模块化管理机制，只用扩展一个模块即可。&lt;/p&gt;
&lt;p&gt;在POC阶段，梳理服务端各模块的功能，能感受到其配置化做的不错，配置项很丰富，管控的粒度也很细；在POC阶段几乎没有变动，除了对Webapp模块的外部化配置稍作改造，与配置中心打通以便在配置中心管理 Webapp模块中Ribbon和Hystrix的相关配置。&lt;/p&gt;
&lt;h4 id=&#34;55完善自监控&#34;&gt;5.5完善自监控&lt;/h4&gt;
&lt;p&gt;自监控是说监控SkyWalking系统内各模块的运转情况：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;组件&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;监控方案&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;kafka&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;kafka-manager&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;它俩是老搭档了&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;Agent端&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Skywalking&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Agent端会发心跳信息给服务端，可在Web端看到Agent的信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;OAP集群&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;prometheus&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;指标还算丰富，感觉缺的可以自己补充&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;ES集群&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;prometheus&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;指标还算丰富&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;完善自监控后的架构如下图所示：&lt;/p&gt;
&lt;img src=&#34;pic5.png&#34;&gt;
&lt;h4 id=&#34;56-自研native端sdk&#34;&gt;5.6 自研Native端SDK&lt;/h4&gt;
&lt;p&gt;公司移动端的应用很核心，也要使用链路追踪的功能，社区缺了这块，于是基于SkyWalking的协议，移动端的伙伴们自研了一套SDK，弥补了Native端链路数据的缺失，也在后来的秒开页面指标统计中发挥了作用。随着口口相传，不断有团队提出需求、加入建设，所以也在持续迭代中；内容很多，这里先不展开。&lt;/p&gt;
&lt;h4 id=&#34;57-小结&#34;&gt;5.7 小结&lt;/h4&gt;
&lt;p&gt;POC阶段数据量不大，主要是发现系统的各种功能性问题，查缺补漏。&lt;/p&gt;
&lt;h3 id=&#34;6优化&#34;&gt;6、优化&lt;/h3&gt;
&lt;p&gt;SkyWalking的正式推广采用的是城市包围农村的策略；公司的核心应用作为第一批次接入，这个策略有几个好处：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;核心应用的监管是重中之重，优先级默认最高。&lt;/li&gt;
&lt;li&gt;核心应用的上下游应用，会随着大家对SkyWalking依赖的加深，而逐步自主接入。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当然安全是第一位的，无论新系统多好、多厉害，其引入都需遵守安全稳定的前提要求。既要安全又要快速还要方便，于是基于之前Agent灰度接入的能力，在发布系统中增加应用Owner&lt;strong&gt;自助式灰度接入和快速卸载&lt;/strong&gt;SkyWalking Agent的能力，即应用负责人可自主选择哪个应用接入，接入几个实例，倘若遇到问题仅通过重启即可完成快速卸载；这个能力在推广的前期发挥了巨大的作用；毕竟安全第一，信任也需逐步建立。&lt;/p&gt;
&lt;p&gt;随着应用的接入、使用，我们也逐渐遇到了一些问题，这里按照时间递增的顺序将问题和优化效果快速的介绍给大家，更多技术原理的内容计划在【SkyWalking(v8.5.0)调优系列】补充。开始之前有几个事项要说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;下文中提到的数字仅代表我司的情况，标注的Segment数量是处理这个问题的那段时间的情况，并不是说达到这个数量才开始出现这个现象。&lt;/li&gt;
&lt;li&gt;这些数值以及当时的现象，受到宿主机配置、Segment数据的大小、存储处理能力等多种因素的影响；请关注调整的过程和效果，不必把数字和现象对号入座哈。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;61-启动耗时&#34;&gt;6.1 启动耗时：&lt;/h4&gt;
&lt;h5 id=&#34;问题&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;有同事反馈应用启动变慢，排查发现容器中多数应用启动的总耗时，在接入SkyWalking前是2秒，接入后变成了16秒以上，公司很多核心应用的实例数很多，这样的启动损耗对它们的发布影响太大。&lt;/p&gt;
&lt;h5 id=&#34;优化&#34;&gt;优化：&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;记录启动耗时并随着其他启动数据上报到服务端，方便查看对比。&lt;/li&gt;
&lt;li&gt;优化Kafka Reporter的启动过程，将启动耗时减少了3-4秒。&lt;/li&gt;
&lt;li&gt;优化类匹配和增强环节（重点）后，容器中的应用启动总耗时从之前16秒以上降低到了3秒内。&lt;/li&gt;
&lt;li&gt;梳理Kafka 启动和上报的过程中，顺带调整了Agent端的数据上报到kafka的分区选择策略，将一个JVM实例中的数据全部发送到同一个的分区中，如此在L1层的聚合就完成了JVM实例级的Metric聚合，需注意调整Kafka分片数来保证负载均衡。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;62-kafka积压-6亿segment天&#34;&gt;6.2 kafka积压-6亿segment/天&lt;/h4&gt;
&lt;h5 id=&#34;问题-1&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;SkyWalking OAP端消费慢，导致Kafka中Segment积压。未能达到能用的目标。&lt;/p&gt;
&lt;h5 id=&#34;优化-1&#34;&gt;优化：&lt;/h5&gt;
&lt;p&gt;从SkyWalking OAP端的监控指标中没有定位出哪个环节的问题，把服务端单集群拆为双集群，即把 Mixed角色的集群 ，修改为 Receiver 角色（接收和L1聚合）的集群 ，并加入 Aggregation角色（L2聚合）的集群，调整成了双集群模式，数据流传如下图所示：&lt;/p&gt;
&lt;img src=&#34;pic6.png&#34;&gt;
&lt;h4 id=&#34;63-kafka积压-8亿segment天&#34;&gt;6.3 kafka积压-8亿segment/天&lt;/h4&gt;
&lt;h5 id=&#34;问题-2&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;SkyWalking OAP端消费慢，导致Kafka中Segment积压，监控指标能看出是在ES存储环节慢，未能达到能用的目标。&lt;/p&gt;
&lt;h5 id=&#34;优化-2&#34;&gt;优化：&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;优化segment保存到ES的批处理过程，调整BulkProcessor的线程数和批处理大小。&lt;/li&gt;
&lt;li&gt;优化metrics保存到ES的批处理过程，调整批处理的时间间隔、线程数、批处理大小以及刷盘时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;64-kafka积压-20亿segment天&#34;&gt;6.4 kafka积压-20亿segment/天&lt;/h4&gt;
&lt;h5 id=&#34;问题-3&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;Aggregation集群的实例持续Full GC，Receiver集群通过grpc 给Aggregation集群发送metric失败。未能达到能用的目标。&lt;/p&gt;
&lt;h5 id=&#34;优化-3&#34;&gt;优化：&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;增加ES节点、分片，效果不明显。&lt;/li&gt;
&lt;li&gt;ES集群有压力，但无法精准定位出是什么数据的什么操作引发的。采用分治策略，尝试将数据拆分，从OAP服务端读写逻辑调整，将ES单集群拆分为 trace集群 和 metric集群；之后对比ES的监控指标明确看出是metric集群读写压力太大。&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&#34;pic7.png&#34;&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;优化Receiver集群metric的L1聚合，完成1分钟的数据聚合后，再提交给Aggregation集群做L2聚合。&lt;/li&gt;
&lt;li&gt;Aggregation集群metric的L2 聚合是基于db实现的，会有 空读-写-再读-累加-更新写 这样的逻辑，每次写都会有读，调整逻辑是：提升读的性能，优化缓存机制减少读的触发；调整间隔，避免触发累加和更新。&lt;/li&gt;
&lt;li&gt;将metric批量写ES操作调整成BulkProcessor。&lt;/li&gt;
&lt;li&gt;ES的metric集群 使用SSD存储，增加节点数和分片数。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这一次的持续优化具有里程碑式的意义，Kafka消费很快，OAP各机器的Full GC没了，ES的各方面指标也很稳定；接下来开始优化查询，提升易用性。&lt;/p&gt;
&lt;h4 id=&#34;65-trace查询慢-25亿segment天&#34;&gt;6.5 trace查询慢-25亿segment/天&lt;/h4&gt;
&lt;h5 id=&#34;问题-4&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;Web端【追踪】页中的查询都很慢，仅保存了15天的数据，按照traceId查询耗时要20多秒，按照条件查询trace列表的耗时更糟糕；这给人的感受就是“一肚子墨水倒不出来”，未能达到好用的目标。&lt;/p&gt;
&lt;h5 id=&#34;优化-4&#34;&gt;优化：&lt;/h5&gt;
&lt;p&gt;ES查询优化方面的信息挺多，但通过百度筛选出解决此问题的有效方案，就要看咱家爱犬的品类了；当时搜集整理了并尝试了N多优化条款，可惜没有跟好运偶遇，结论是颜值不可靠。言归正传，影响读写性能的基本要素有3个：读写频率，数据规模，硬件性能；trace的情况从这三个维度来套一套模板：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;要素&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;trace的情况&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;读写频率&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;宏观来看是写多读少的状况&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;数据规模&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;按照每天50亿个segment来算，半个月是750亿，1个月是1500亿。&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;硬件性能&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;普通硬盘速度一般&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这个分析没有得出具有指导意义的结论，读写频率这里粒度太粗，用户的使用情况跟时间也有紧密的关系，情况大概是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当天的数据是读多写多（当天不断有新数据写入，基于紧急响应的需求，问题出现时可能是近实时的排查处理）。&lt;/li&gt;
&lt;li&gt;前一天的数据是读多写少（一般也会有问题隔天密集上报的情况，0点后会有前一天数据延迟到达的情况）。&lt;/li&gt;
&lt;li&gt;再早的话无新数据写入，数据越早被读的概率也越小。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于以上分析，增加时间维度并细化更多的参考因素后，分析模型变成了这样：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;要素&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;当天&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;当天-1&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;当天-2 ~ 当天-N&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;写频率&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;多&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;少&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;读（查询）频率&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;多&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;多&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;少&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;读响应速度要求&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;快&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;快&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;慢点也行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;数据规模&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;50亿&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;50亿&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;50亿* (N-2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;宿主机性能要求&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;次高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;硬盘速度要求&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高(SSD)&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高(SSD)&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;次高(机械)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;硬件成本&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;高&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;次高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;期望成本&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;低&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;低&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;从上表可以看出，整体呈现出hot-warm数据架构的需求之势，近1-2天为hot数据，之前的为warm数据；恰好ES7提供了hot-warm架构支持，按照hot-warm改造后架构如下图所示：&lt;/p&gt;
&lt;img src=&#34;pic8.png&#34;&gt;
&lt;ol&gt;
&lt;li&gt;恰逢公司ES中台调优版的ES发布，其内置的ZSTD压缩算法 空间压缩效果非常显著。&lt;/li&gt;
&lt;li&gt;对 trace集群进行hot-warm架构调整，查询耗时从20多秒变成了2-3秒，效果是非常明显的。&lt;/li&gt;
&lt;li&gt;从查询逻辑进一步调整，充分利用ES的数据分片、路由机制，把全量检索调整为精准检索，即降低检索时需要扫描的数据量，把2-3秒优化到毫秒。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这里要炫一个5毛特效，这套机制下，Segment数据即使是保留半年的，按照TraceId查询的耗时也是毫秒。&lt;/p&gt;
&lt;p&gt;至此完成了&lt;strong&gt;查询千亿级Trace数据只要毫秒级耗时&lt;/strong&gt;的阶段性优化。&lt;/p&gt;
&lt;h4 id=&#34;66-仪表盘和拓扑查询慢&#34;&gt;6.6 仪表盘和拓扑查询慢&lt;/h4&gt;
&lt;h5 id=&#34;问题-5&#34;&gt;问题：&lt;/h5&gt;
&lt;p&gt;Web端的【拓扑】页，在开始只有几十个应用的时候，虽然很慢，但还是能看到数据，随着应用增多后，【拓扑】页面数据请求一直是超时(配置的60s超时)的，精力有限，先通过功能降级把这个页面隐藏了；【仪表盘】的指标查询也非常的慢，未能达到好用的目标。&lt;/p&gt;
&lt;h5 id=&#34;优化-5&#34;&gt;优化：&lt;/h5&gt;
&lt;p&gt;Web端的【仪表盘】页和【拓扑】页是对SkyWalking里metric数据的展现，metric数据同trace数据一样满足hot-warm的特征。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;metric集群采用hot-warm架构调整，之后仪表盘中的查询耗时也都减小为毫秒级。&lt;/li&gt;
&lt;li&gt;【拓扑】页接口依然是超时(60s)，对拓扑这里做了几个针对性的调整：
&lt;ul&gt;
&lt;li&gt;把内部的循环调用合并，压缩调用次数。&lt;/li&gt;
&lt;li&gt;去除非必要的查询。&lt;/li&gt;
&lt;li&gt;拆分隔离通用索引中的数据，避免互相干扰。&lt;/li&gt;
&lt;li&gt;全量检索调整为精准检索，即降低检索时需要扫描的数据量。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;至此完成了&lt;strong&gt;拓扑页数据查询毫秒级耗时&lt;/strong&gt;的阶段性优化。&lt;/p&gt;
&lt;h4 id=&#34;67-小结&#34;&gt;6.7 小结&lt;/h4&gt;
&lt;p&gt;SkyWalking调优这个阶段，恰逢上海疫情封城，既要为生存抢菜，又要翻阅学习着各种ES原理、调优的文档资料，一行一行反复的品味思考SkyWalking相关的源码，尝试各种方案去优化它，梦中都在努力提升它的性能。疫情让很多人变得焦虑烦躁，但以我的感受来看在系统的性能压力下疫情不值一提。&lt;strong&gt;凡事贵在坚持&lt;/strong&gt;，时间搞定了诸多困难，调优的效果是很显著的。&lt;/p&gt;
&lt;p&gt;可能在&lt;em&gt;业务价值驱动&lt;/em&gt;的价值观中这些技术优化不产生直接业务价值，顶多是五毛特效，但从其他维度来看它价值显著：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对个人来说，技术有提升。&lt;/li&gt;
&lt;li&gt;对团队来说，实战练兵提升战力，团队协作加深友情；特别感谢ES中台这段时间的鼎力支持！&lt;/li&gt;
&lt;li&gt;对公司来说，易用性的提升将充分发挥SkyWalking的价值，在问题发生时，给到同事们切实、高效的帮助，使得问题可以被快速响应；须知战争拼的是保障。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这期间其实也是有考虑过其他的2个方案的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用降低采样率的兜底方案；但为了得到更准确的指标数据，以及后续其他的规划而坚持了全采样。&lt;/li&gt;
&lt;li&gt;采用ClickHouse优化存储；因为公司有定制优化的ES版本，所以就继续在ES上做存储优化，刚好借此机会验证一下。后续【全链路结构化日志】的存储会使用ClickHouse。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个章节将内容聚焦在落地推广时期技术层面的准备和调优，未描述团队协调、推广等方面的情况；因每个公司情况不同，所以并未提及；但其实对多数公司来说，有些项目的推广比技术本身可能难度更大，这个项目也遇到过一些困难，PM去推广是既靠能力又靠颜值， 以后有机会再与大家探讨。&lt;/p&gt;
&lt;h3 id=&#34;7未来&#34;&gt;7、未来&lt;/h3&gt;
&lt;p&gt;H5、Native以及后端应用都在持续接入中，相应的SDK也在不断的迭代；目前正在基于已建立的链路通道，完善【全链路业务状态追踪】和【全链路结构化日志追踪】，旨在给运营、客服、运维、开发等服务在一线的同事们提供多视角一站式的观测平台，全方位提升系统服务质量、提高问题响应速度。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 阿里云 - 可观测技术峰会 2022 - More than Tracing Logging Metrics</title>
      <link>/zh/2022-06-23-more-than-tracing-logging-metrics/</link>
      <pubDate>Thu, 23 Jun 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-06-23-more-than-tracing-logging-metrics/</guid>
      <description>
        
        
        



&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1Cg411X71x&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: Apache ShenYu (incubating)插件实现原理和可观测性实践</title>
      <link>/zh/2022-05-08-apache-shenyuincubating-integrated-skywalking-practice-observability/</link>
      <pubDate>Sun, 08 May 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-05-08-apache-shenyuincubating-integrated-skywalking-practice-observability/</guid>
      <description>
        
        
        &lt;h3 id=&#34;目录&#34;&gt;目录&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;#1.-SkyWalking%E5%92%8CShenYu%E4%BB%8B%E7%BB%8D&#34;&gt;SkyWalking和ShenYu介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#2.-ApacheShenYu%E6%8F%92%E4%BB%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86&#34;&gt;ApacheShenYu插件实现原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#3.-%E7%BB%99gRPC%E6%8F%92%E4%BB%B6%E5%A2%9E%E5%8A%A0%E6%B3%9B%E5%8C%96%E8%B0%83%E7%94%A8%E8%BF%BD%E8%B8%AA%E5%B9%B6%E4%BF%9D%E6%8C%81%E5%85%BC%E5%AE%B9&#34;&gt;给gRPC插件增加泛化调用追踪并保持兼容&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#4.-ShenYu%E7%BD%91%E5%85%B3%E5%8F%AF%E8%A7%82%E6%B5%8B%E6%80%A7%E5%AE%9E%E8%B7%B5&#34;&gt;ShenYu网关可观测性实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#5.-%E6%80%BB%E7%BB%93&#34;&gt;总结&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;1skywalking和shenyu介绍&#34;&gt;1.SkyWalking和ShenYu介绍&lt;/h2&gt;
&lt;h3 id=&#34;11-skywalking&#34;&gt;1.1 SkyWalking&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/hutaishi/skywalking&#34;&gt;SkyWalking&lt;/a&gt;是一个针对微服务、分布式系统、云原生的应用性能监控(APM)和可观测性分析平台(OAP),
拥有强大的功能，提供了多维度应用性能分析手段，包含分布式拓扑图、应用性能指标、分布式链路追踪、日志关联分析和告警。同时还拥有非常丰富的生态。广泛应用于各个公司和开源项目。&lt;/p&gt;
&lt;h3 id=&#34;12-apache-shenyu-incubating&#34;&gt;1.2 Apache ShenYu (incubating)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/incubator-shenyu&#34;&gt;Apache ShenYu (incubating)&lt;/a&gt;是一个高性能，多协议，易扩展，响应式的API网关。
兼容各种主流框架体系，支持热插拔，用户可以定制化开发，满足用户各种场景的现状和未来需求，经历过大规模场景的锤炼。
支持丰富的协议：&lt;code&gt;Http&lt;/code&gt;、&lt;code&gt;Spring Cloud&lt;/code&gt;、&lt;code&gt;gRPC&lt;/code&gt;、&lt;code&gt;Dubbo&lt;/code&gt;、&lt;code&gt;SOFARPC&lt;/code&gt;、&lt;code&gt;Motan&lt;/code&gt;、&lt;code&gt;Tars&lt;/code&gt;等等。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;shenyu-arch.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;2apacheshenyu插件实现原理&#34;&gt;2.ApacheShenYu插件实现原理&lt;/h2&gt;
&lt;p&gt;ShenYu的异步和以往接触的异步有一点不一样，是一种全链路异步，每一个插件的执行都是异步的，并且线程切换并不是单一固定的情况(和各个插件实现有关)。
网关会发起各种协议类型的服务调用，现有的SkyWalking插件发起服务调用的时候会创建ExitSpan(同步或异步).  网关接收到请求会创建异步的EntrySpan。
异步的EntrySpan需要和同步或异步的ExitSpan串联起来，否则链路会断。
串联方案有2种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;快照传递&lt;/strong&gt;： 将创建EntrySpan之后的快照通过某种方式传递到创建ExitSpan的线程中。&lt;br&gt;
目前这种方式应用在异步的WebClient插件中，该插件能接收异步快照。ShenYu代理Http服务或SpringCloud服务便是通过快照传递实现span串联。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LocalSpan中转&lt;/strong&gt;：
其它RPC类插件不像异步WebClient那样可以接收快照实现串联。尽管你可以改动其它RPC插件让其接收快照实现串联，但不推荐也没必要，
因为可以通过在创建ExitSpan的线程中，创建一个LocalSpan就可以实现和ExitSpan串联，然后将异步的EntrySpan和LocalSpan通过&lt;code&gt;快照传递&lt;/code&gt;的方式串联。这样实现完全可以不改动原先插件的代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;span连接如下图所示:&lt;br&gt;
&lt;img src=&#34;span-connect.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;也许你会问是否可以在一个通用的插件里面创建LocalSpan,而不是ShenYu RPC插件分别创建一个？
答案是不行，因为需要保证LocalSpan和ExitSpan在同一个线程，而ShenYu是全链路异步. 在实现上创建LocalSpan的代码是复用的。&lt;/p&gt;
&lt;h2 id=&#34;3-给grpc插件增加泛化调用追踪并保持兼容&#34;&gt;3. 给gRPC插件增加泛化调用追踪并保持兼容&lt;/h2&gt;
&lt;p&gt;现有的SkyWalking gRPC插件只支持通过存根的方式发起的调用。而对于网关而言并没有proto文件，网关采取的是泛化调用(不通过存根)，所以追踪rpc请求，你会发现链路会在网关节点断掉。
在这种情况下，需要让gRPC插件支持泛化调用，而同时需要保持兼容，不影响原先的追踪方式。实现上通过判断请求参数是否是动态消息(DynamicMessage)，如果不是则走原先通过存根的追踪逻辑，
如果是则走泛化调用追踪逻辑。另外的兼容则是在gRPC新旧版本的差异，以及获取服务端IP各种情况的兼容，感兴趣的可以看看源码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;grpc-generic-call.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;4-shenyu网关可观测性实践&#34;&gt;4. ShenYu网关可观测性实践&lt;/h2&gt;
&lt;p&gt;上面讲解了SkyWalking ShenYu插件的实现原理，下面部署应用看下效果。SkyWalking功能强大，除了了链路追踪需要开发插件外，其它功能强大功能开箱即用。
这里只描述链路追踪和应用性能剖析部分，如果想体验SkyWalking功能的强大，请参考&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;SkyWalking官方文档&lt;/a&gt;。&lt;br&gt;
版本说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;skywalking-java: &lt;code&gt;8.11.0-SNAPSHOT&lt;/code&gt;源码构建。说明：shenyu插件会在8.11.0版本发布，可能会在5月或6月初步发布它。Java代理正处于常规发布阶段。&lt;/li&gt;
&lt;li&gt;skywalking: &lt;code&gt;9.0.0&lt;/code&gt; V9 版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用法说明:&lt;br&gt;
SkyWalking的设计非常易用，配置和激活插件请参考官方文档。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/readme/&#34;&gt;SkyWalking Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-java/latest/readme/&#34;&gt;SkyWalking Java Agent Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;41-向网关发起请求&#34;&gt;4.1 向网关发起请求&lt;/h3&gt;
&lt;p&gt;通过&lt;code&gt;postman&lt;/code&gt;客户端或者其它方式向网关发起各种服务请求&lt;/p&gt;
&lt;h3 id=&#34;42-请求拓扑图&#34;&gt;4.2 请求拓扑图&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;topology.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&#34;topology2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;43-请求链路以grpc为例&#34;&gt;4.3 请求链路(以gRPC为例)&lt;/h3&gt;
&lt;h4 id=&#34;正常链路&#34;&gt;正常链路：&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;grpc-ok.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;异常链路&#34;&gt;异常链路：&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;grpc-error.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;点击链路节点变可以看到对应的节点信息和异常信息&lt;/p&gt;
&lt;h4 id=&#34;服务提供者span&#34;&gt;服务提供者span&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;grpc-error-span.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;网关请求span&#34;&gt;网关请求span&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;gateway-error-span.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;44-服务指标监控&#34;&gt;4.4 服务指标监控&lt;/h3&gt;
&lt;p&gt;服务指标监控
&lt;img src=&#34;overview.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;45-网关后台指标监控&#34;&gt;4.5 网关后台指标监控&lt;/h3&gt;
&lt;h4 id=&#34;数据库监控&#34;&gt;数据库监控:&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;database.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;线程池和连接池监控&#34;&gt;线程池和连接池监控&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;img.png&#34; alt=&#34;img.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;46-jvm监控&#34;&gt;4.6 JVM监控&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;jvm.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;47-接口分析&#34;&gt;4.7 接口分析&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;endpoint.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;48-异常日志和异常链路分析&#34;&gt;4.8 异常日志和异常链路分析&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x/&#34;&gt;日志配置见官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;日志监控
&lt;img src=&#34;log-trace.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;异常日志对应的分布式链路追踪详情
&lt;img src=&#34;log-trace-detail.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;5-总结&#34;&gt;5. 总结&lt;/h2&gt;
&lt;p&gt;SkyWalking在可观测性方面对指标、链路追踪、日志有着非常全面的支持，功能强大，简单易用，专为大型分布式系统、微服务、云原生、容器架构而设计，拥有丰富的生态。
使用SkyWalking为Apache ShenYu (incubating)提供强大的可观测性支持，让ShenYu如虎添翼。最后，如果你对高性能响应式网关感兴趣，可以关注
&lt;a href=&#34;https://github.com/apache/incubator-shenyu&#34;&gt;Apache ShenYu (incubating)&lt;/a&gt; 。
同时感谢SkyWalking这么优秀的开源软件对行业所作的贡献。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 如何使用java探针注入器?</title>
      <link>/zh/2022-04-19-how-to-use-the-java-agent-injector/</link>
      <pubDate>Tue, 19 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-04-19-how-to-use-the-java-agent-injector/</guid>
      <description>
        
        
        &lt;h3 id=&#34;目录&#34;&gt;目录&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;#1.-%E4%BB%8B%E7%BB%8D&#34;&gt;介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#2.-%E4%B8%BB%E8%A6%81%E7%89%B9%E7%82%B9&#34;&gt;主要特点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#3.-%E5%AE%89%E8%A3%85SWCK&#34;&gt;安装SWCK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#4.-%E9%83%A8%E7%BD%B2demo%E5%BA%94%E7%94%A8&#34;&gt;部署demo应用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#5.-%E9%AA%8C%E8%AF%81%E6%B3%A8%E5%85%A5%E5%99%A8&#34;&gt;验证注入器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#6.-%E7%BB%93%E6%9D%9F%E8%AF%AD&#34;&gt;结束语&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;1-介绍&#34;&gt;1. 介绍&lt;/h2&gt;
&lt;h3 id=&#34;11-swck-是什么&#34;&gt;1.1 SWCK 是什么？&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck&#34;&gt;SWCK&lt;/a&gt;是部署在 Kubernetes 环境中，为 Skywalking 用户提供服务的平台，用户可以基于该平台使用、升级和维护 SkyWalking 相关组件。&lt;/p&gt;
&lt;p&gt;实际上，SWCK 是基于 &lt;a href=&#34;https://book.kubebuilder.io/&#34;&gt;kubebuilder&lt;/a&gt; 开发的Operator，为用户提供自定义资源（ CR ）以及管理资源的控制器（ Controller ），所有的自定义资源定义（CRD）如下所示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#javaagent&#34;&gt;JavaAgent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#oap&#34;&gt;OAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#ui&#34;&gt;UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#storage&#34;&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#satellite&#34;&gt;Satellite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#fetcher&#34;&gt;Fetcher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;12-java-探针注入器是什么&#34;&gt;1.2 java 探针注入器是什么？&lt;/h3&gt;
&lt;p&gt;对于 java 应用来说，用户需要将 java 探针注入到应用程序中获取元数据并发送到 Skywalking 后端。为了让用户在 Kubernetes 平台上更原生地使用 java 探针，我们提供了 java 探针注入器，该注入器能够将 java 探针通过 sidecar 方式注入到应用程序所在的 pod 中。 java 探针注入器实际上是一个&lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/&#34;&gt;Kubernetes Mutation Webhook控制器&lt;/a&gt;，如果请求中存在 &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/&#34;&gt;annotations&lt;/a&gt; ，控制器会拦截 pod 事件并将其应用于 pod 上。&lt;/p&gt;
&lt;h2 id=&#34;2-主要特点&#34;&gt;2. 主要特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;透明性&lt;/strong&gt;。用户应用一般运行在普通容器中而 java 探针则运行在初始化容器中，且两者都属于同一个 pod 。该 pod 中的每个容器都会挂载一个共享内存卷，为 java 探针提供存储路径。在 pod 启动时，初始化容器中的 java 探针会先于应用容器运行，由注入器将其中的探针文件存放在共享内存卷中。在应用容器启动时，注入器通过设置 JVM 参数将探针文件注入到应用程序中。用户可以通过这种方式实现 java 探针的注入，而无需重新构建包含 java 探针的容器镜像。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可配置性&lt;/strong&gt;。注入器提供两种方式配置 java 探针：全局配置和自定义配置。默认的全局配置存放在 &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/configmap/&#34;&gt;configmap&lt;/a&gt; 中，用户可以根据需求修改全局配置，比如修改 &lt;code&gt;backend_service&lt;/code&gt; 的地址。此外，用户也能通过 annotation 为特定应用设置自定义的一些配置，比如不同服务的 &lt;code&gt;service_name&lt;/code&gt; 名称。详情可见  &lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/java-agent-injector.md&#34;&gt;java探针说明书&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可观察性&lt;/strong&gt;。每个 java 探针在被注入时，用户可以查看名为 &lt;code&gt;JavaAgent&lt;/code&gt; 的 CRD 资源，用于观测注入后的 java 探针配置。详情可见 &lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/javaagent.md&#34;&gt;JavaAgent说明&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-安装swck&#34;&gt;3. 安装SWCK&lt;/h2&gt;
&lt;p&gt;在接下来的几个步骤中，我们将演示如何从0开始搭建单机版的 Kubernetes 集群，并在该平台部署0.6.1版本的 SWCK。&lt;/p&gt;
&lt;h3 id=&#34;31-工具准备&#34;&gt;3.1 工具准备&lt;/h3&gt;
&lt;p&gt;首先，你需要安装一些必要的工具，如下所示：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://kind.sigs.k8s.io&#34;&gt;kind&lt;/a&gt;，用于创建单机版 Kubernetes集群。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/&#34;&gt;kubectl&lt;/a&gt;，用于和Kubernetes 集群交互。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;32-搭建单机版-kubernetes集群&#34;&gt;3.2 搭建单机版 Kubernetes集群&lt;/h3&gt;
&lt;p&gt;在安装完 &lt;a href=&#34;http://kind.sigs.k8s.io&#34;&gt;kind&lt;/a&gt; 工具后，可通过如下命令创建一个单机集群。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意！如果你的终端配置了代理，在运行以下命令之前最好先关闭代理，防止一些意外错误的发生。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kind create cluster --image&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;kindest/node:v1.19.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在集群创建完毕后，可获得如下的pod信息。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get pod -A                          
NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
kube-system          coredns-f9fd979d6-57xpc                      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m16s
kube-system          coredns-f9fd979d6-8zj8h                      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m16s
kube-system          etcd-kind-control-plane                      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m23s
kube-system          kindnet-gc9gt                                1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m16s
kube-system          kube-apiserver-kind-control-plane            1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m23s
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m23s
kube-system          kube-proxy-6zbtb                             1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m16s
kube-system          kube-scheduler-kind-control-plane            1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m23s
local-path-storage   local-path-provisioner-78776bfc44-jwwcs      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          7m16s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;33-安装证书管理器cert-manger&#34;&gt;3.3 安装证书管理器(cert-manger)&lt;/h3&gt;
&lt;p&gt;SWCK 的证书都是由证书管理器分发和验证，需要先通过如下命令安装&lt;a href=&#34;https://cert-manager.io/docs/&#34;&gt;证书管理器cert-manger&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证 cert-manger 是否安装成功。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get pod -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-7dd5854bb4-slcmd              1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          73s
cert-manager-cainjector-64c949654c-tfmt2   1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          73s
cert-manager-webhook-6bdffc7c9d-h8cfv      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          73s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;34-安装swck&#34;&gt;3.4 安装SWCK&lt;/h3&gt;
&lt;p&gt;java 探针注入器是 SWCK 中的一个组件，首先需要按照如下步骤安装 SWCK：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;输入如下命令获取 SWCK 的 yaml 文件并部署在 Kubernetes 集群中。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ curl -Ls https://archive.apache.org/dist/skywalking/swck/0.6.1/skywalking-swck-0.6.1-bin.tgz | tar -zxf - -O ./config/operator-bundle.yaml | kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;检查 SWCK 是否正常运行。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get pod -n skywalking-swck-system
NAME                                                  READY   STATUS    RESTARTS   AGE
skywalking-swck-controller-manager-7f64f996fc-qh8s9   2/2     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          94s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;35-安装-skywalking-组件--oapserver-和-ui&#34;&gt;3.5 安装 Skywalking 组件 — OAPServer 和 UI&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;default&lt;/code&gt; 命名空间中部署 OAPServer 组件和 UI 组件。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl apply -f https://raw.githubusercontent.com/apache/skywalking-swck/master/operator/config/samples/default.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;查看 OAPServer 组件部署情况。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get oapserver
NAME      INSTANCES   RUNNING   ADDRESS
default   &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;           &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;         default-oap.default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;查看 UI 组件部署情况。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get ui
NAME      INSTANCES   RUNNING   INTERNALADDRESS      EXTERNALIPS   PORTS
default   &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;           &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;         default-ui.default                 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;80&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;4-部署demo应用&#34;&gt;4. 部署demo应用&lt;/h2&gt;
&lt;p&gt;在第3个步骤中，我们已经安装好 SWCK 以及相关的 Skywalking 组件，接下来按照全局配置以及自定义配置两种方式，通过两个 java 应用实例，分别演示如何使用 SWCK 中的 java 探针注入器。&lt;/p&gt;
&lt;h3 id=&#34;41-设置全局配置&#34;&gt;4.1 设置全局配置&lt;/h3&gt;
&lt;p&gt;当 SWCK 安装完成后，默认的全局配置就会以 configmap 的形式存储在系统命令空间中，可通过如下命令查看。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$  kubectl get configmap skywalking-swck-java-agent-configmap -n skywalking-swck-system -oyaml
apiVersion: v1
data:
  agent.config: |-
    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# The service name in UI&lt;/span&gt;
    agent.service_name&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_NAME&lt;/span&gt;:&lt;span style=&#34;color:#008080&#34;&gt;Your_ApplicationName&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Backend service addresses.&lt;/span&gt;
    collector.backend_service&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_COLLECTOR_BACKEND_SERVICES&lt;/span&gt;:&lt;span style=&#34;color:#008080&#34;&gt;127&lt;/span&gt;.0.0.1:&lt;span style=&#34;color:#008080&#34;&gt;11800&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Please refer to https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configurations/#table-of-agent-configuration-properties to get more details.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 &lt;code&gt;kind&lt;/code&gt; 创建的 Kubernetes 集群中， SkyWalking 后端地址和 configmap 中指定的地址可能不同，我们需要使用真正的 OAPServer 组件的地址 &lt;code&gt;default-oap.default&lt;/code&gt; 来代替默认的 &lt;code&gt;127.0.0.1&lt;/code&gt; ，可通过修改 configmap 实现。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl edit configmap skywalking-swck-java-agent-configmap -n skywalking-swck-system
configmap/skywalking-swck-java-agent-configmap edited

$ kubectl get configmap skywalking-swck-java-agent-configmap -n skywalking-swck-system -oyaml
apiVersion: v1
data:
  agent.config: |-
    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# The service name in UI&lt;/span&gt;
    agent.service_name&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_NAME&lt;/span&gt;:&lt;span style=&#34;color:#008080&#34;&gt;Your_ApplicationName&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Backend service addresses.&lt;/span&gt;
    collector.backend_service&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_COLLECTOR_BACKEND_SERVICES&lt;/span&gt;:&lt;span style=&#34;color:#008080&#34;&gt;default&lt;/span&gt;-oap.default:&lt;span style=&#34;color:#008080&#34;&gt;11800&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Please refer to https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configurations/#table-of-agent-configuration-properties to get more details.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;42-设置自定义配置&#34;&gt;4.2 设置自定义配置&lt;/h3&gt;
&lt;p&gt;在实际使用场景中，我们需要使用 Skywalking 组件监控不同的 java 应用，因此不同应用的探针配置可能有所不同，比如应用的名称、应用需要使用的插件等。为了支持自定义配置，注入器提供 annotation 来覆盖默认的全局配置。接下来我们将分别以基于 &lt;code&gt;spring boot&lt;/code&gt; 以及 &lt;code&gt;spring cloud gateway&lt;/code&gt; 开发的两个简单java应用为例进行详细说明，你可以使用这两个应用的&lt;a href=&#34;https://github.com/dashanji/swck-spring-cloud-k8s-demo&#34;&gt;源代码&lt;/a&gt;构建镜像。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# build the springboot and springcloudgateway image&lt;/span&gt; 
$ git clone https://github.com/dashanji/swck-spring-cloud-k8s-demo 
$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; swck-spring-cloud-k8s-demo &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# check the image&lt;/span&gt;
$ docker images
REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
gateway        v0.0.1    51d16251c1d5   &lt;span style=&#34;color:#099&#34;&gt;48&lt;/span&gt; minutes ago   723MB
app            v0.0.1    62f4dbcde2ed   &lt;span style=&#34;color:#099&#34;&gt;48&lt;/span&gt; minutes ago   561MB

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# load the image into the cluster&lt;/span&gt;
$ kind load docker-image app:v0.0.1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; kind load docker-image gateway:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;43-部署-spring-boot-应用&#34;&gt;4.3 部署 spring boot 应用&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建 &lt;code&gt;springboot-system&lt;/code&gt; 命名空间。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl create namespace springboot-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;给 &lt;code&gt;springboot-system&lt;/code&gt; 命名空间打上标签使能 java 探针注入器。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl label namespace springboot-system swck-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;接下来为 spring boot 应用对应的部署文件 &lt;code&gt;springboot.yaml&lt;/code&gt; ，其中使用了 annotation 覆盖默认的探针配置，比如 &lt;code&gt;service_name&lt;/code&gt; ，将其覆盖为 &lt;code&gt;backend-service&lt;/code&gt; 。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是，在使用 annotation 覆盖探针配置之前，需要增加 &lt;code&gt;strategy.skywalking.apache.org/agent.Overlay: &amp;quot;true&amp;quot;&lt;/code&gt; 来使覆盖生效。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-springboot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;springboot-system&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-springboot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;template&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;swck-java-agent-injected&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# enable the java agent injector&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-springboot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;strategy.skywalking.apache.org/agent.Overlay&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# enable the agent overlay&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;agent.skywalking.apache.org/agent.service_name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;backend-service&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;springboot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;IfNotPresent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;app:v0&lt;span style=&#34;color:#099&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;java&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;args&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/app.jar&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;---&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;springboot-system&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ClusterIP&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;8085&lt;/span&gt;-tcp&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;8085&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TCP&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;8085&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-springboot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;在 &lt;code&gt;springboot-system&lt;/code&gt; 命名空间中部署 &lt;code&gt;spring boot&lt;/code&gt; 应用。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl apply -f springboot.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;查看部署情况。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get pod -n springboot-system
NAME                               READY   STATUS    RESTARTS   AGE
demo-springboot-7c89f79885-dvk8m   1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          11s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;通过 &lt;code&gt;JavaAgent&lt;/code&gt; 查看最终注入的 java 探针配置。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get javaagent -n springboot-system
NAME                            PODSELECTOR           SERVICENAME       BACKENDSERVICE
app-demo-springboot-javaagent   &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo-springboot   backend-service   default-oap.default:11800
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;44-部署-spring-cloud-gateway-应用&#34;&gt;4.4 部署 spring cloud gateway 应用&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建 &lt;code&gt;gateway-system&lt;/code&gt; 命名空间。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl create namespace gateway-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;给 &lt;code&gt;gateway-system&lt;/code&gt; 命名空间打上标签使能 java 探针注入器。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl label namespace gateway-system swck-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;接下来为 spring cloud gateway 应用对应的部署文件 &lt;code&gt;springgateway.yaml&lt;/code&gt; ，其中使用了 annotation 覆盖默认的探针配置，比如 &lt;code&gt;service_name&lt;/code&gt; ，将其覆盖为 &lt;code&gt;gateway-service&lt;/code&gt; 。此外，在使用 &lt;code&gt;spring cloud gateway&lt;/code&gt; 时，我们需要在探针配置中添加 &lt;code&gt;spring cloud gateway&lt;/code&gt; 插件。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是，在使用 annotation 覆盖探针配置之前，需要增加 &lt;code&gt;strategy.skywalking.apache.org/agent.Overlay: &amp;quot;true&amp;quot;&lt;/code&gt; 来使覆盖生效。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway-system&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;template&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;swck-java-agent-injected&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;strategy.skywalking.apache.org/agent.Overlay&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;agent.skywalking.apache.org/agent.service_name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gateway-service&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;     
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;optional.skywalking.apache.org&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;cloud-gateway-3.x&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# add spring cloud gateway plugin&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway:v0&lt;span style=&#34;color:#099&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;java&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;args&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/gateway.jar&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;---&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;service-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway-system&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ClusterIP&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;9999&lt;/span&gt;-tcp&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;9999&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TCP&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;9999&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;app&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;在 &lt;code&gt;gateway-system&lt;/code&gt; 命名空间中部署 &lt;code&gt;spring cloud gateway&lt;/code&gt; 应用。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl apply -f springgateway.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;查看部署情况。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get pod -n gateway-system
NAME                           READY   STATUS    RESTARTS   AGE
demo-gateway-758899c99-6872s   1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          15s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;通过 &lt;code&gt;JavaAgent&lt;/code&gt; 获取最终注入的java探针配置。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get javaagent -n gateway-system
NAME                         PODSELECTOR        SERVICENAME       BACKENDSERVICE
app-demo-gateway-javaagent   &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo-gateway   gateway-service   default-oap.default:11800
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;5-验证注入器&#34;&gt;5. 验证注入器&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;当完成上述步骤后，我们可以查看被注入pod的详细状态，比如被注入的&lt;code&gt;agent&lt;/code&gt;容器。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# get all injected pod&lt;/span&gt;
$ kubectl get pod -A -lswck-java-agent-injected&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;true&lt;/span&gt;
NAMESPACE           NAME                               READY   STATUS    RESTARTS   AGE
gateway-system      demo-gateway-5bb77f6d85-lt4z7      1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          69s
springboot-system   demo-springboot-7c89f79885-lkb5j   1/1     Running   &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;          75s

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# view detailed state of the injected pod [demo-springboot]&lt;/span&gt;
$ kubectl describe pod -l &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo-springboot -n springboot-system
...
Events:
  Type   Reason   Age                From                           Message
  ----   ------  ----                ----                           -------
  ...
  Normal Created  91s  kubelet,kind-control-plane Created  container inject-skywalking-agent
  Normal Started  91s  kubelet,kind-control-plane Started  container inject-skywalking-agent
  ...
  Normal Created  90s  kubelet,kind-control-plane Created  container springboot
  Normal Started  90s  kubelet,kind-control-plane Started  container springboot

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# view detailed state of the injected pod [demo-gateway]&lt;/span&gt; 
$ kubectl describe pod -l &lt;span style=&#34;color:#008080&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo-gateway -n gateway-system
...
Events:
  Type   Reason   Age            From                         Message
  ----   ------  ----            ----                         -------
  ...
  Normal Created 2m20s kubelet,kind-control-plane Created container inject-skywalking-agent
  Normal Started 2m20s kubelet,kind-control-plane Started container inject-skywalking-agent
  ...
  Normal Created 2m20s kubelet,kind-control-plane Created container gateway
  Normal Started 2m20s kubelet,kind-control-plane Started container gateway
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;现在我们可以将服务绑定在某个端口上并通过 web 浏览器查看采样数据。首先，我们需要通过以下命令获取&lt;code&gt;gateway&lt;/code&gt;服务和&lt;code&gt;ui&lt;/code&gt;服务的信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl get service service-gateway -n gateway-system
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;S&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;    AGE
service-gateway   ClusterIP   10.99.181.145   &amp;lt;none&amp;gt;        9999/TCP   9m19s

$ kubectl get service default-ui
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;S&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;   AGE
default-ui   ClusterIP   10.111.39.250   &amp;lt;none&amp;gt;        80/TCP    82m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;接下来分别启动2个终端将&lt;code&gt;service-gateway&lt;/code&gt; 以及 &lt;code&gt;default-ui&lt;/code&gt; 绑定到本地端口上，如下所示：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl port-forward service/service-gateway -n gateway-system 9999:9999
Forwarding from 127.0.0.1:9999 -&amp;gt; &lt;span style=&#34;color:#099&#34;&gt;9999&lt;/span&gt;
Forwarding from &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;::1&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;:9999 -&amp;gt; &lt;span style=&#34;color:#099&#34;&gt;9999&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ kubectl port-forward service/default-ui 8090:80                     
Forwarding from 127.0.0.1:8090 -&amp;gt; &lt;span style=&#34;color:#099&#34;&gt;8080&lt;/span&gt;
Forwarding from &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;::1&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;:8090 -&amp;gt; &lt;span style=&#34;color:#099&#34;&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;使用以下命令通过&lt;code&gt;spring cloud gateway&lt;/code&gt; 网关服务暴露的端口来访问 &lt;code&gt;spring boot&lt;/code&gt; 应用服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;for&lt;/span&gt; i in &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;1..10&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;do&lt;/span&gt; curl http://127.0.0.1:9999/gateway/hello &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#0086b3&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;done&lt;/span&gt;
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;我们可以在 web 浏览器中输入 &lt;code&gt;http://127.0.0.1:8090&lt;/code&gt; 来访问探针采集到的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;dashboard.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;所有服务的拓扑图如下所示。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;topology.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;7&#34;&gt;
&lt;li&gt;查看 &lt;code&gt;gateway-service&lt;/code&gt; 网关服务的 trace 信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://lh3.googleusercontent.com/KAJruPRGjzjmX3S0xOu_3CoWetbcTwMQZIcCLtpkOKy1Z3CQFnz_hO6o4pheLiWwNGAr-xfM71NtsgxWo1nHfkGoYRfUF6fY6yHsYI4aAfEJ0y09Gm_tysQir1tn0SNxuVciCjl4&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;8&#34;&gt;
&lt;li&gt;查看 &lt;code&gt;backend-service&lt;/code&gt; 应用服务的 trace 信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://lh5.googleusercontent.com/zani4DhZmsrKN0N2GLgcjyFg6NBteduWwTNuwXvh7OOONjBhBwnCEuOLNpWa3iaZiPIeG36p-vlk2Fex2lvXJxv4YgBYmvl480U7_FBbtXjduJhsMdTBdvaBN_C2HRpZbdwWzerJ&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;6-结束语&#34;&gt;6. 结束语&lt;/h2&gt;
&lt;p&gt;如果你的应用部署在 Kubernetes 平台中，且需要 Skywalking 提供监控服务， SWCK 能够帮助你部署、升级和维护 Kubernetes 集群中的 Skywalking 组件。除了本篇博客外，你还可以查看 &lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/operator.md#operator-usage-guide&#34;&gt;SWCK文档&lt;/a&gt; 以及 &lt;a href=&#34;https://github.com/apache/skywalking-swck/blob/master/docs/java-agent-injector.md&#34;&gt;java探针注入器文档&lt;/a&gt; 获取更多的信息。如果你觉得这个项目好用，请给 &lt;a href=&#34;https://github.com/apache/skywalking-swck&#34;&gt;SWCK&lt;/a&gt; 一个star! 如果你有任何疑问，欢迎在&lt;a href=&#34;https://github.com/apache/skywalking/issues&#34;&gt;Issues&lt;/a&gt;或者&lt;a href=&#34;https://github.com/apache/skywalking/discussions&#34;&gt;Discussions&lt;/a&gt;中提出。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: Apache SkyWalking 2022 峰会</title>
      <link>/zh/2022-04-18-meeting/</link>
      <pubDate>Mon, 18 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-04-18-meeting/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;https://img-blog.csdnimg.cn/9dfd03251da64946becdf67f6a10ead7.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Apache SkyWalking 是中国首个，也是目前唯一的个人开源的 Apache 顶级项目。&lt;/p&gt;
&lt;p&gt;作为一个针对分布式系统的应用性能监控 APM 和可观测性分析平台， SkyWalking 提供了媲美商业APM/监控的功能。&lt;/p&gt;
&lt;p&gt;CSDN云原生系列在线峰会第4期，特邀SkyWalking创始人、Apache基金会首位中国董事、Tetrate创始工程师吴晟担任出品人，推出SkyWalking峰会。&lt;/p&gt;
&lt;p&gt;SkyWalking峰会在解读SkyWalking v9新特性的同时，还将首发解密APM的专用数据库BanyanDB，以及分享SkyWalking在原生eBPF探针、监控虚拟机和Kubernetes、云原生函数计算可观测性等方面的应用实践。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;峰会议程：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;14:00-14:30 开场演讲：SkyWalking v9解析 &lt;br&gt;吴晟  Tetrate 创始工程师、Apache 基金会首位中国董事&lt;/p&gt;
&lt;p&gt;14:30-15:00 首发解密：APM的专用数据库BanyanDB&lt;br&gt;高洪涛 Tetrate 创始工程师&lt;/p&gt;
&lt;p&gt;15:00-15:30 SkyWalking 原生eBPF探针展示&lt;br&gt;刘晗 Tetrate 工程师&lt;/p&gt;
&lt;p&gt;15:30-16:00 Apache SkyWalking MAL实践-监控虚拟机和Kubernetes&lt;br&gt;万凯 Tetrate 工程师&lt;/p&gt;
&lt;p&gt;16:00-16:30 SkyWalking助力云原生函数计算可观测&lt;br&gt;霍秉杰 青云科技 资深架构师&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://img-blog.csdnimg.cn/f98f2935c5404d5cb718123e73908fa5.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;峰会视频&#34;&gt;峰会视频&lt;/h2&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1Qu411z7wh&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: 将 Apache SkyWalking 与源代码集成</title>
      <link>/zh/2022-04-14-integrating-skywalking-with-source-code/</link>
      <pubDate>Thu, 14 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-04-14-integrating-skywalking-with-source-code/</guid>
      <description>
        
        
        &lt;p&gt;&lt;sub&gt;Read this post in original language: &lt;a href=&#34;https://skywalking.apache.org/blog/2022-04-14-integrating-skywalking-with-source-code/&#34;&gt;English&lt;/a&gt;&lt;/sub&gt;&lt;/p&gt;
&lt;h2 id=&#34;介绍&#34;&gt;介绍&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;最具影响力的技术是那些消失的技术。他们交织在日常生活中，直到二者完全相融。 - 马克韦瑟&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;马克韦瑟在 1980 年代后期预言，影响最深远的技术是那些消失在空气中的技术。&lt;/p&gt;
&lt;p&gt;“当人们足够熟知它，就不会再意识到它。”&lt;/p&gt;
&lt;p&gt;正如韦瑟所说，这种消失的现象不只源于技术，更是人类的心理。
正是这种经验使我们能够摆脱对底层的考量，进入更高层次的思考。
一旦我们不再被平凡的细枝末节所阻碍，我们就可以自如地专注于新的目标。&lt;/p&gt;
&lt;p&gt;随着 APM(应用性能管理系统) 变得越来越普遍，这种认识变得更加重要。随着更多的应用程序开始使用 APM 部署，底层源代码抽象表示的数量也在同步增加。
虽然这为组织内的许多非开发角色提供了巨大的价值，但它确实也对开发人员提出了额外的挑战 -
他们必须将这些表示转化为可操作的概念（即源代码）。
对此，韦瑟相当简洁的总结道,“就像不应要求汽车机械师在不查看引擎的情况下工作一样，我们不应要求程序员在不访问源代码的情况下工作”。&lt;/p&gt;
&lt;p&gt;尽管如此，APM 收集更多信息只是为了产生充足的新抽象表示。
在本文中，我们将介绍开源实时编码平台 &lt;a href=&#34;https://github.com/sourceplusplus/live-platform&#34;&gt;Source++&lt;/a&gt; 中的一个新概念，旨在让开发人员更直观地监控生产应用程序。&lt;/p&gt;
&lt;h2 id=&#34;实时查看&#34;&gt;实时查看&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我们尚且不理解在收集了数百个指标之后，是什么让程序更容易理解、修改、重复使用或借用。
我不认为我们能够通过原理程序本身而到它们的抽象接口中找到答案。答案就在源代码之中。 - 马克韦瑟&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;随着 APM 从“有了更好”转变为“必须拥有”，有一个基本特性阻碍了它们的普及。
它们必须从意识中消失。作为开发人员，我们不应急于打开浏览器以更好地理解底层源代码，答案就在源代码中。
相反，我们应该改进我们的工具，以便源代码直观地告诉我们需要了解的内容。
想想如果失败的代码总是表明它是如何以及为什么失败的，生活会多么简单。这就是 Source++ 背后的理念。&lt;/p&gt;
&lt;p&gt;在我们的上一篇博客中，我们讨论了不间断断点 &lt;a href=&#34;https://skywalking.apache.org/blog/2021-12-06-extend-skywalking-with-nbb/&#34;&gt;Extending Apache SkyWalking&lt;/a&gt;。
我们介绍了一个名为 &lt;strong&gt;Live Instruments&lt;/strong&gt;(实时埋点) 的概念，开发人员可以使用它轻松调试实时生产应用程序，而无需离开他们的开发环境。
而今天，我们将讨论如何通过一个名为 &lt;strong&gt;Live Views&lt;/strong&gt;（实时查看）的新概念将现有部署的 SkyWalking 集成到您的 IDE 中。
与专为调试实时应用程序而设计的 Live Instruments (实时埋点) 不同，Live Views（实时查看）旨在提高对应用程序的理解和领悟。
这将通过输入到 Live Command Palette (实时命令面板) 中的各种命令来完成。&lt;/p&gt;
&lt;h3 id=&#34;实时命令面板&#34;&gt;实时命令面板&lt;/h3&gt;
&lt;p&gt;Live Command Palette (LCP) 是一个当前上下文场景下的命令行面板，这个组件包含在 &lt;a href=&#34;https://github.com/sourceplusplus/interface-jetbrains&#34;&gt;Source++ JetBrains 插件中&lt;/a&gt;，它允许开发人员从 IDE 中直接控制和对实时应用程序发起查询。&lt;/p&gt;
&lt;p&gt;LCP 通过键盘快捷键 (&lt;code&gt;Ctrl+Shift+S&lt;/code&gt;) 打开，允许开发人员轻松了解与他们当前正在查看的源代码相关的运行指标。&lt;/p&gt;
&lt;p&gt;目前 LCP 支持以下实时查看命令：&lt;/p&gt;
&lt;h4 id=&#34;命令viewoverviewactivitytraceslogs--查看-总览活动追踪日志&#34;&gt;命令：&lt;code&gt;view&lt;/code&gt;（overview/activity/traces/Logs）- 查看 总览/活动/追踪/日志&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;view&lt;/code&gt; 查看命令会展示一个与当前源码的实时运维数据关联的弹窗。
这些命令允许开发人员查看根据相关指标过滤的传统 SkyWalking 的运维数据。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;view_command.gif&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;命令watch-log---实时监听日志&#34;&gt;命令：&lt;code&gt;watch log&lt;/code&gt; - 实时监听日志&lt;/h4&gt;
&lt;p&gt;本日志命令允许开发人员实时跟踪正在运行的应用程序的每一条日志。
通过此命令开发人员无需手动查阅大量日志就可以查找特定日志语句的实例。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;watch_log_command.gif&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;命令showhide-quick-stats-显示隐藏快速统计&#34;&gt;命令：(show/hide) quick stats （显示/隐藏）快速统计&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;show quick stats&lt;/code&gt; 显示快速统计命令显示实时端点指标，以便快速了解端点的活动。
使用此命令，开发人员可以快速评估端点的状态并确定端点是否按预期正常运行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;show_quick_stats_command.gif&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;未来的工作&#34;&gt;未来的工作&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;好工具是无形的。我所指的无形，是指这个工具不会侵入你的意识；
你专注于任务，而不是工具。
眼镜就是很好的工具——你看的是世界，而不是眼镜。 - 马克韦瑟&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source++ 旨在扩展 SkyWalking，使 SkyWalking 本身变得无需感知。
为此，我们计划支持自定义的开发人员命令。
开发人员将能够构建自定义命令，以及与团队共享的命令。
这些命令将识别上下文、类型和条件，从而允许广泛的操作。
随着更多命令的添加，开发人员将能够洞悉 SkyWalking 所提供的所有功能，同时专注于最重要的源码。&lt;/p&gt;
&lt;p&gt;如果您觉得这些功能有用，请考虑尝试使用 Source++。
您可以通过 &lt;a href=&#34;https://plugins.jetbrains.com/plugin/12033-source-&#34;&gt;JetBrains Marketplace&lt;/a&gt;
或直接从您的 JetBrains IDE 安装插件。
如果您有任何疑问，&lt;a href=&#34;https://github.com/sourceplusplus/interface-jetbrains/issues&#34;&gt;请到这提 issue&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;欢迎随时反馈！&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 在无人驾驶领域的实践</title>
      <link>/zh/2022-04-13-skywalking-in-autonomous-driving/</link>
      <pubDate>Wed, 13 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-04-13-skywalking-in-autonomous-driving/</guid>
      <description>
        
        
        &lt;p&gt;随着无人驾驶在行业的不断发展和技术的持续革新，规范化、常态化的真无人运营逐渐成为事实标准，而要保障各个场景下的真无人业务运作，一个迫切需要解决的现状就是业务链路长，出现问题难以定位。本文由此前于 KubeSphere 直播上的分享整理而成，主要介绍 SkyWalking 的基本概念和使用方法，以及在无人驾驶领域的一系列实践。&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1qY41137ZT&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;


&lt;h2 id=&#34;行业背景&#34;&gt;行业背景&lt;/h2&gt;
&lt;p&gt;驭势科技（UISEE）是国内领先的无人驾驶公司。致力于为全行业、全场景提供 AI 驾驶服务,做赋能出行和物流新生态的 AI 驾驶员。早在三年前， 驭势科技已在机场和厂区领域实现了“去安全员” 无人驾驶常态化运营的重大突破，落地“全场景、真无人、全天候”的自动驾驶技术，并由此迈向大规模商用。要保证各个场景下没有安全员参与的业务运作，我们在链路追踪上做了一系列实践。&lt;/p&gt;
&lt;p&gt;对于无人驾驶来说，从云端到车端的链路长且复杂，任何一层出问题都会导致严重的后果；然而在如下图所示的链路中，准确迅速地定位故障服务并不容易，经常遇到多个服务层层排查的情况。我们希望做到的事情，就是在出现问题以后，能够尽快定位到源头，从而快速解决问题，以绝后患。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./uisee-arch.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;前提条件&#34;&gt;前提条件&lt;/h2&gt;
&lt;h3 id=&#34;skywalking-简介&#34;&gt;SkyWalking 简介&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;./skywalking-arch.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;Apache SkyWalking&lt;/a&gt; 是一个开源的可观察性平台，用于收集、分析、聚集和可视化来自服务和云原生基础设施的数据。SkyWalking 通过简单的方法，提拱了分布式系统的清晰视图，甚至跨云。它是一个现代的 APM（Application Performence Management），专门为云原生、基于容器的分布式系统设计。它在逻辑上被分成四个部分。探针、平台后端、存储和用户界面。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;探针&lt;/strong&gt;收集数据并根据 SkyWalking 的要求重新格式化（不同的探针支持不同的来源）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;平台后端&lt;/strong&gt;支持数据聚合、分析以及从探针接收数据流的过程，包括 Tracing、Logging、Metrics。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储系统&lt;/strong&gt;通过一个开放/可插拔接口容纳 SkyWalking 数据。用户可以选择一个现有的实现，如 ElasticSearch、H2、MySQL、TiDB、InfluxDB，或实现自定义的存储。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI&lt;/strong&gt;是一个高度可定制的基于网络的界面，允许 SkyWalking 终端用户可视化和管理 SkyWalking 数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;综合考虑了对各语言、各框架的支持性、可观测性的全面性以及社区环境等因素，我们选择了 SkyWalking 进行链路追踪。&lt;/p&gt;
&lt;h3 id=&#34;链路追踪简介&#34;&gt;链路追踪简介&lt;/h3&gt;
&lt;p&gt;关于链路追踪的基本概念，可以参看吴晟老师翻译的 &lt;a href=&#34;https://link.segmentfault.com/?enc=q1lzCJRhfh95RIedPCDqGw%3D%3D.b%2BljJx4TgV4x%2BL8GhbAFQBIcNDkcjjdwXDSg8sC%2FVstKogfnXaU6Gi2pYyp4ib%2BOL4VKmRmMhysiLsRyw2gvFDhsryXKVeddg5djhaqM01s%3D&#34;&gt;OpenTracing 概念和术语&lt;/a&gt; 以及 &lt;a href=&#34;https://opentelemetry.io/&#34;&gt;OpenTelemetry&lt;/a&gt;。在这里，择取几个重要的概念供大家参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trace&lt;/strong&gt;：代表一个潜在的分布式的存在并行数据或者并行执行轨迹的系统。一个 Trace 可以认为是多个 Span 的有向无环图（DAG）。简单来说，在微服务体系下，一个 Trace 代表从第一个服务到最后一个服务经历的一系列的服务的调用链。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;./trace.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Span&lt;/strong&gt;：在服务中埋点时，最需要关注的内容。一个 Span 代表系统中具有开始时间和执行时长的逻辑运行单元。举例来说，在一个服务发出请求时，可以认为是一个 Span 的开始；在这个服务接收到上游服务的返回值时，可以认为是这个 Span 的结束。Span 之间通过嵌套或者顺序排列建立逻辑因果关系。在 SkyWalking 中，Span 被区分为：
&lt;ul&gt;
&lt;li&gt;LocalSpan：服务内部调用方法时创建的 Span 类型&lt;/li&gt;
&lt;li&gt;EntrySpan：请求进入服务时会创建的 Span 类型（例如处理其他服务对于本服务接口的调用）&lt;/li&gt;
&lt;li&gt;ExitSpan：请求离开服务时会创建的 Span 类型（例如调用其他服务的接口）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TraceSegment&lt;/strong&gt;：SkyWalking 中的概念，介于 Trace 和 Span 之间，是一条 Trace 的一段，可以包含多个 Span。一个 TraceSegment 记录了一个线程中的执行过程，一个 Trace 由一个或多个 TraceSegment 组成，一个 TraceSegment 又由一个或多个 Span 组成。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SpanContext&lt;/strong&gt;：代表跨越进程上下文，传递到下级 Span 的状态。一般包含 Trace ID、Span ID 等信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Baggage&lt;/strong&gt;：存储在 SpanContext 中的一个键值对集合。它会在一条追踪链路上的所有 Span 内全局传输，包含这些 Span 对应的 SpanContext。Baggage 会随着 Trace 一同传播。
&lt;ul&gt;
&lt;li&gt;SkyWalking 中，上下文数据通过名为 &lt;code&gt;sw8&lt;/code&gt; 的头部项进行传递，值中包含 8 个字段，由 &lt;code&gt;-&lt;/code&gt; 进行分割（包括 Trace ID，Parent Span ID 等等）&lt;/li&gt;
&lt;li&gt;另外 SkyWalking 中还提供名为 &lt;code&gt;sw8-correlation&lt;/code&gt; 的扩展头部项，可以传递一些自定义的信息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;快速上手&#34;&gt;快速上手&lt;/h2&gt;
&lt;p&gt;以 Go 为例，介绍如何使用 SkyWalking 在服务中埋点。&lt;/p&gt;
&lt;h3 id=&#34;部署&#34;&gt;部署&lt;/h3&gt;
&lt;p&gt;我们选择使用 Helm Chart 在 Kubernetes 中进行部署。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SKYWALKING_RELEASE_NAME&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking  &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# change the release name according to your scenario&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SKYWALKING_RELEASE_NAMESPACE&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;default  &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# change the namespace to where you want to install SkyWalking&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;REPO&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking

helm repo add &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;REPO&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt; https://apache.jfrog.io/artifactory/skywalking-helm                                
helm install &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SKYWALKING_RELEASE_NAME&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;REPO&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/skywalking -n &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;SKYWALKING_RELEASE_NAMESPACE&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  --set oap.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;8.8.1 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  --set oap.storageType&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;elasticsearch &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  --set ui.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;8.8.1 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  --set elasticsearch.imageTag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;6.8.6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;埋点&#34;&gt;埋点&lt;/h3&gt;
&lt;p&gt;部署完以后，需要在服务中进行埋点，以生成 Span 数据：主要的方式即在服务的入口和出口创建 Span。在代码中，首先我们会创建一个 Reporter，用于向 SkyWalking 后端发送数据。接下来，我们需要创建一个名为 &lt;code&gt;&amp;quot;example&amp;quot;&lt;/code&gt; 的 Tracer 实例。此时，我们就可以使用 Tracer 实例来创建 Span。 在 Go 中，主要利用 &lt;code&gt;context.Context&lt;/code&gt; 来创建以及传递 Span。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;github.com/SkyAPM/go2sky&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// configure to export to OAP server
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;r, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; reporter.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;NewGRPCReporter&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;oap-skywalking:11800&amp;#34;&lt;/span&gt;)
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nil&lt;/span&gt; {
    log.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Fatalf&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;new reporter error %v \n&amp;#34;&lt;/span&gt;, err)
}
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;defer&lt;/span&gt; r.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Close&lt;/span&gt;()
tracer, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; go2sky.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;NewTracer&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt;, go2sky.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;WithReporter&lt;/span&gt;(r))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;服务内部&#34;&gt;服务内部&lt;/h4&gt;
&lt;p&gt;在下面的代码片段中，通过 &lt;code&gt;context.background()&lt;/code&gt; 生成的 Context 创建了一个 Root Span，同时在创建该 Span 的时候，也会产生一个跟这 个 Span 相关联的 Context。利用这个新的 Context，就可以创建一个与 Root Span 相关联的 Child Span。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// create root span
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;span, ctx, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateLocalSpan&lt;/span&gt;(context.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Background&lt;/span&gt;())
&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// create sub span w/ context above
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;subSpan, newCtx, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateLocalSpan&lt;/span&gt;(ctx)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;服务间通信&#34;&gt;服务间通信&lt;/h4&gt;
&lt;p&gt;在服务内部，我们会利用 Context 传的递来进行 Span 的创建。但是如果是服务间通信的话，这也是链路追踪最为广泛的应用场景，肯定是没有办法直接传递 Context 参数的。这种情况下，应该怎么做呢？一般来说，SkyWalking 会把 Context 中与当前 Span 相关的键值对进行编码，后续在服务通信时进行传递。例如，在 HTTP 协议中，一般利用请求头进行链路传递。再例如 gRPC 协议，一般想到的就是利用 Metadata 进行传递。&lt;/p&gt;
&lt;p&gt;在服务间通信的时候，我们会利用 EntrySpan 和 ExitSpan 进行链路的串联。以 HTTP 请求为例，在创建 EntrySpan 时，会从请求头中获取到 Span 上下文信息。而在 ExitSpan 中，则在请求中注入了上下文。这里的上下文是经过了 SkyWalking 编码后的字符串，以便在服务间进行传递。除了传递 Span 信息，也可以给 Span 打上 Tag 进行标记。例如，记录 HTTP 请求的方法，URL 等等，以便于后续数据的可视化。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;//Extract context from HTTP request header `sw8`
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;span, ctx, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateEntrySpan&lt;/span&gt;(r.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Context&lt;/span&gt;(), &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/api/login&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(key &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;) (&lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;, &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;error&lt;/span&gt;) {
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; r.Header.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Get&lt;/span&gt;(key), &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nil&lt;/span&gt;
})

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// Some operation
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;...&lt;/span&gt;

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// Inject context into HTTP request header `sw8`
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;span, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateExitSpan&lt;/span&gt;(req.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Context&lt;/span&gt;(), &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/service/validate&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;tomcat-service:8080&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(key, value &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;error&lt;/span&gt; {
		req.Header.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Set&lt;/span&gt;(key, value)
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nil&lt;/span&gt;
})

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// tags
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;span.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Tag&lt;/span&gt;(go2sky.TagHTTPMethod, req.Method)
span.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Tag&lt;/span&gt;(go2sky.TagURL, req.URL.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;String&lt;/span&gt;())
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是，我们可能也会用到一些不那么常用的协议，比如说 MQTT 协议。在这些情况下，应该如何传递上下文呢？关于这个问题，我们在自定义插件的部分做了实践。&lt;/p&gt;
&lt;h4 id=&#34;ui&#34;&gt;UI&lt;/h4&gt;
&lt;p&gt;经过刚才的埋点以后，就可以在 SkyWalking 的 UI 界面看到调用链。SkyWalking 官方提供了一个 Demo 页面，有兴趣可以一探究竟：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;UI &lt;a href=&#34;http://demo.skywalking.apache.orgUsername&#34;&gt;http://demo.skywalking.apache.org&lt;/a&gt;&lt;br&gt;
Username &lt;em&gt;skywalking&lt;/em&gt;   Password &lt;em&gt;skywalking&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;./skywalking-ui.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;插件体系&#34;&gt;插件体系&lt;/h2&gt;
&lt;p&gt;如上述埋点的方式，其实是比较麻烦的。好在 SkyWalking 官方提供了很多插件，一般情况下，直接接入插件便能达到埋点效果。SkyWalking 官方为多种语言都是提供了丰富的插件，对一些主流框架都有插件支持。由于我们部门使用的主要是 Go 和 Python 插件，下文中便主要介绍这两种语言的插件。同时，由于我们的链路复杂，用到的协议较多，不可避免的是也需要开发一些自定义插件。下图中整理了 Go 与 Python 插件的主要思想，以及我们开发的各框架协议自定义插件的研发思路。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./plugins.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;官方插件&#34;&gt;官方插件&lt;/h3&gt;
&lt;h4 id=&#34;go--gin-插件&#34;&gt;Go · Gin 插件&lt;/h4&gt;
&lt;p&gt;Gin 是 Go 的 Web 框架，利用其中间件，可以进行链路追踪。由于是接收请求，所以需要在中间件中，创建一个 EntrySpan，同时从请求头中获取 Span 的上下文的信息。获取到上下文信息以后，还需要再进行一步操作：把当前请求请求的上下文 &lt;code&gt;c.Request.Context()&lt;/code&gt;, 设置成为刚才创建完 EntrySpan 时生成的 Context。这样一来，这个请求的 Context 就会携带有 Span 上下文信息，可以用于在后续的请求处理中进行后续传递。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Middleware&lt;/span&gt;(engine &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gin.Engine, tracer &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;go2sky.Tracer) gin.HandlerFunc {
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(c &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gin.Context) {
		span, ctx, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateEntrySpan&lt;/span&gt;(c.Request.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Context&lt;/span&gt;(), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getOperationName&lt;/span&gt;(c), &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(key &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;) (&lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;, &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;error&lt;/span&gt;) {
			&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; c.Request.Header.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Get&lt;/span&gt;(key), &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nil&lt;/span&gt;
		})
        &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// some operation
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;		c.Request = c.Request.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;WithContext&lt;/span&gt;(ctx)
		c.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Next&lt;/span&gt;()
		span.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;End&lt;/span&gt;()
	}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;python--requests&#34;&gt;Python · requests&lt;/h4&gt;
&lt;p&gt;Requests 插件会直接修改 Requests 库中的&lt;code&gt;request&lt;/code&gt;函数，把它替换成 SkyWalking 自定义的&lt;code&gt;_sw_request&lt;/code&gt;函数。在这个函数中，创建了 ExitSpan，并将 ExitSpan 上下文注入到请求头中。在服务安装该插件后，实际调用 Requests 库进行请求的时候，就会携带带有上下文的请求体进行请求。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;install&lt;/span&gt;():
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;requests&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;import&lt;/span&gt; Session
    _request &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; Session&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;request
    
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;_sw_request&lt;/span&gt;(this: Session, method, url, other params&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;...&lt;/span&gt;):
        span &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; get_context()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;new_exit_span(op&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;url_param&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;path &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, peer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;url_param&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;netloc,
                                         component&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;Component&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;Requests)

        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;with&lt;/span&gt; span:
            carrier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;inject()
            span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;layer &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; Layer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;Http

            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; headers &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#999&#34;&gt;None&lt;/span&gt;:
                headers &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; {}
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; carrier:
                headers[item&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;key] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; item&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;val

                span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;tag(TagHttpMethod(method&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;upper()))
                span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;tag(TagHttpURL(url_param&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;geturl()))

                res &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; _request(this, method, url, , other params&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;...&lt;/span&gt;n)
                &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# some operation&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; res
                        
    Session&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;request &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; _sw_request
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;自定义插件&#34;&gt;自定义插件&lt;/h3&gt;
&lt;h4 id=&#34;go--gorm&#34;&gt;Go · Gorm&lt;/h4&gt;
&lt;p&gt;Gorm 框架是 Go 的 ORM 框架。我们自己在开发的时候经常用到这个框架，因此希望能对通过 Gorm 调用数据库的链路进行追踪。&lt;/p&gt;
&lt;p&gt;Gorm 有自己的插件体系，会在数据库的操作前调用&lt;code&gt;BeforeCallback&lt;/code&gt;函数，数据库的操作后调用&lt;code&gt;AfterCallback&lt;/code&gt;函数。于是在&lt;code&gt;BeforeCallback&lt;/code&gt;中，我们创建 ExitSpan，并在&lt;code&gt;AfterCallback&lt;/code&gt;里结束先前在&lt;code&gt;BeforeCallback&lt;/code&gt;中创建的 ExitSpan。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt; (s &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;SkyWalking) &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;BeforeCallback&lt;/span&gt;(operation &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(db &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gorm.DB) {
    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// some operation
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(db &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gorm.DB) {
        tableName &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; db.Statement.Table
        operation &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; fmt.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Sprintf&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;%s/%s&amp;#34;&lt;/span&gt;, tableName, operation)
        
        span, err &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; tracer.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;CreateExitSpan&lt;/span&gt;(db.Statement.Context, operation, peer, &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(key, value &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;error&lt;/span&gt; {
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nil&lt;/span&gt;
        })
        &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// set span from db instance&amp;#39;s context to pass span
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;        db.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Set&lt;/span&gt;(spanKey, span)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;需要注意的是，因为 Gorm 的插件分为 Before 与 After 两个 Callback，所以需要在两个回调函数间传递 Span，这样我们才可以在&lt;code&gt;AfterCallback&lt;/code&gt;中结束当前的 Span。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt; (s &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;SkyWalking) &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;AfterCallback&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(db &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gorm.DB) {
    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// some operation
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;func&lt;/span&gt;(db &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;gorm.DB) {
        &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// get span from db instance&amp;#39;s context
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;        spanInterface, _ &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; db.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;Get&lt;/span&gt;(spanKey)
        span, ok &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:=&lt;/span&gt; spanInterface.(go2sky.Span)
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; !ok {
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt;
        }
        
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;defer&lt;/span&gt; span.&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;End&lt;/span&gt;()
        &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;// some operation 
&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;&lt;/span&gt;    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;python--mqtt&#34;&gt;Python · MQTT&lt;/h4&gt;
&lt;p&gt;在 IoT 领域，MQTT 是非常常用的协议，无人驾驶领域自然也相当依赖这个协议。&lt;/p&gt;
&lt;p&gt;以 Publish 为例，根据官方插件的示例，我们直接修改 paho.mqtt 库中的&lt;code&gt;publish&lt;/code&gt;函数，改为自己定义的&lt;code&gt;_sw_publish&lt;/code&gt;函数。在自定义函数中，创建 ExitSpan，并将上下文注入到 MQTT 的 Payload 中。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;install&lt;/span&gt;():
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;paho.mqtt.client&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;import&lt;/span&gt; Client
    
    _publish &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; Client&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;publish
    Client&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;publish &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; _sw_publish_func(_publish)
    
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;_sw_publish_func&lt;/span&gt;(_publish):
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;_sw_publish&lt;/span&gt;(this, topic, payload&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#999&#34;&gt;None&lt;/span&gt;, qos&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, retain&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#999&#34;&gt;False&lt;/span&gt;, properties&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#999&#34;&gt;None&lt;/span&gt;):
            &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# some operation&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;with&lt;/span&gt; get_context()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;new_exit_span(op&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;EMQX/Topic/&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; topic &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/Producer&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;,
                                       peer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;peer) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;as&lt;/span&gt; span:
                carrier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;inject()
                span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;layer &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; Layer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;MQ
                span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;component &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; Component&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;RabbitmqProducer
                payload &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; {} &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; payload &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#999&#34;&gt;None&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;else&lt;/span&gt; json&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;loads(payload)
                payload[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;headers&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; {}
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; carrier:
                    payload[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;headers&amp;#39;&lt;/span&gt;][item&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;key] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; item&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;val
              &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ...&lt;/span&gt;
                                    
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; _sw_publish
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可能这个方式不是特别优雅：因为我们目前使用 MQTT 3.1 版本，此时尚未引入 Properties 属性（类似于请求头）。直到 MQTT 5.0，才对此有相关支持。我们希望在升级到 MQTT 5.0 以后，能够将上下文注入到 Properties 中进行传递。&lt;/p&gt;
&lt;h2 id=&#34;无人驾驶领域的实践&#34;&gt;无人驾驶领域的实践&lt;/h2&gt;
&lt;p&gt;虽然这些插件基本上涵盖了所有的场景，但是链路追踪并不是只要接入插件就万事大吉。在一些复杂场景下，尤其无人驾驶领域的链路追踪，由于微服务架构中涉及的语言环境、中间件种类以及业务诉求通常都比较丰富，导致在接入全链路追踪的过程中，难免遇到各种主观和客观的坑。下面选取了几个典型例子和大家分享。&lt;/p&gt;
&lt;h3 id=&#34;问题一kong-网关的插件链路接入&#34;&gt;&lt;strong&gt;【问题一】Kong 网关的插件链路接入&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;我们的请求在进入服务之前，都会通过 API 网关 Kong，同时我们在 Kong 中定义了一个自定义权限插件，这个插件会调用权限服务接口进行授权。如果只是单独单纯地接入 SkyWalking Kong  插件，对于权限服务的调用无法在调用链中体现。所以我们的解决思路是，直接地在权限插件里进行埋点，而不是使用官方的插件，这样就可以把对于权限服务的调用也纳入到调用链中。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./kong.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;问题二-context-传递&#34;&gt;【问题二】 Context 传递&lt;/h3&gt;
&lt;p&gt;我们有这样一个场景：一个服务，使用 Gin Web 框架，同时在处理 HTTP 请求时调用上游服务的 gRPC 接口。起初以为只要接入 Gin 的插件以及 gRPC 的插件，这个场景的链路就会轻松地接上。但是结果并不如预期。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./context.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;最后发现，Gin 提供一个 Context&lt;code&gt;c&lt;/code&gt;；同时对于某一个请求，可以通过&lt;code&gt;c.Request.Context()&lt;/code&gt;获取到请求的 Context&lt;code&gt;reqCtx&lt;/code&gt;，二者不一致；接入 SkyWalking 提供的 Gin 插件后，修改的是&lt;code&gt;reqCtx&lt;/code&gt;，使其包含 Span 上下文信息；而现有服务，在 gRPC 调用时传入的 Context 是&lt;code&gt;c&lt;/code&gt;，所以一开始 HTTP -&amp;gt; gRPC 无法连接。最后通过一个工具函数，复制了&lt;code&gt;reqCtx&lt;/code&gt;的键值对到&lt;code&gt;c&lt;/code&gt;后，解决了这个问题。&lt;/p&gt;
&lt;h3 id=&#34;问题三官方-pythonredis-插件-pubsub-断路&#34;&gt;【问题三】官方 Python·Redis 插件 Pub/Sub 断路&lt;/h3&gt;
&lt;p&gt;由于官方提供了 Python ·Redis 插件，所以一开始认为，安装了 Redis 插件，对于一切 Redis 操作，都能互相连接。但是实际上，对于 Pub/Sub 操作，链路会断开。&lt;/p&gt;
&lt;p&gt;查看代码后发现，对于所有的 Redis 操作，插件都创建一个 ExitSpan；也就是说该插件其实仅适用于 Redis 作缓存等情况；但是在我们的场景中，需要进行 Pub/Sub 操作。这导致两个操作都会创建 ExitSpan，而使链路无法相连。通过改造插件，在 Pub 时创建 ExitSpan，在 Sub 时创建 EntrySpan 后，解决该问题。&lt;/p&gt;
&lt;h3 id=&#34;问题四mqtt-broker-的多种-databridge-接入&#34;&gt;&lt;strong&gt;【问题四】MQTT Broker 的多种 DataBridge 接入&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;一般来说，对 MQTT 的追踪链路是 Publisher -&amp;gt; Subscriber，但是在我们的使用场景中，存在 MQTT broker 接收到消息后，通过规则引擎调用其他服务接口这种特殊场景。这便不是 Publisher -&amp;gt; Subscriber，而是 Publisher -&amp;gt; HTTP。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./data-bridge.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;我们希望能够从 MQTT  Payload 中取出 Span 上下文，再注入到 HTTP 的请求头中。然而规则引擎调用接口时，没有办法自定义请求头，所以我们最后的做法是，约定好参数名称，将上下文放到请求体中，在服务收到请求后，从请求体中提取 Context。&lt;/p&gt;
&lt;h3 id=&#34;问题五tracing-与-logging-如何结合&#34;&gt;&lt;strong&gt;【问题五】Tracing 与 Logging 如何结合&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;很多时候，只有 Tracing 信息，对于问题排查来说可能还是不充分的，我们非常的期望也能够把 Tracing 和 Logging 进行结合。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./logging.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;如上图所示，我们会把所有服务的 Tracing 的信息发送到 SkyWalking，同时也会把这个服务产生的日志通过 Fluent Bit 以及 Fluentd 发送到 ElasticSearch。对于这种情况，我们只需要在日志中去记录 Span 的上下文，比如记录 Trace ID 或者 Span ID 等，就可以在 Kibana 里面去进行对于 Trace ID 的搜索，来快速的查看同一次调用链中的日志。&lt;/p&gt;
&lt;p&gt;当然，SkyWalking 它本身也提供了自己的日志收集和分析机制，可以利用 Fluentd 或者 Fluent Bit 等向 SkyWalking 后端发送日志（我们选用了 Fluentd）。当然，像 SkyWalking 后端发送日志的时候，也要符合其&lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/en/protocols/log-data-protocol/&#34;&gt;日志协议&lt;/a&gt;，即可在 UI 上查看相应日志。&lt;/p&gt;
&lt;p&gt;本文介绍了 SkyWalking 的使用方法、插件体系以及实践踩坑等，希望对大家有所帮助。总结一下，SkyWalking 的使用的确是有迹可循的，一般来说我们只要接入插件，基本上可以涵盖大部分的场景，达到链路追踪的目的。但是也要注意，很多时候需要具体问题具体分析，尤其是在链路复杂的情况下，很多地方还是需要根据不同场景来进行一些特殊处理。&lt;/p&gt;
&lt;p&gt;最后，我们正在使用的 FaaS 平台 &lt;a href=&#34;https://openfunction.dev&#34;&gt;OpenFunction&lt;/a&gt; 近期也接入了 SkyWalking 作为其 &lt;a href=&#34;https://openfunction.dev/docs/best-practices/skywalking-solution-for-openfunction/&#34;&gt;链路追踪的解决方案&lt;/a&gt;：&lt;/p&gt;
&lt;div style=&#39;padding:0.1em; background-color:#e8f7ff; color:black; padding:1em; border: 1px solid #abd2da;&#39; markdown=&#34;1&#34;&gt;
&lt;p&gt;OpenFunction 提供了插件体系，并预先定义了 SkyWalking &lt;code&gt;pre&lt;/code&gt;/&lt;code&gt;post&lt;/code&gt; 插件；编写函数时，用户无需手动埋点，只需在 OpenFunction 配置文件中简单配置，即可开启 SkyWalking 插件，达到链路追踪的目的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./of-topology.png&#34; alt=&#34;image.png&#34;&gt;  &lt;img src=&#34;./of-tracing.png&#34; alt=&#34;image.png&#34;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;在感叹 OpenFunction 动作迅速的同时，也能够看到 SkyWalking 已成为链路追踪领域的首要选择之一。&lt;/p&gt;
&lt;h1 id=&#34;参考资料&#34;&gt;参考资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;OpenTracing 文档：&lt;a href=&#34;https://wu-sheng.gitbooks.io/opentracing-io/content/pages/spec.html&#34;&gt;https://wu-sheng.gitbooks.io/opentracing-io/content/pages/spec.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking 文档：&lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/readme/&#34;&gt;https://skywalking.apache.org/docs/main/latest/readme/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking GitHub：&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;https://github.com/apache/skywalking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking go2sky GitHub：&lt;a href=&#34;https://github.com/SkyAPM/go2sky&#34;&gt;https://github.com/SkyAPM/go2sky&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking Python GitHub：&lt;a href=&#34;https://github.com/apache/skywalking-python&#34;&gt;https://github.com/apache/skywalking-python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking Helm Chart：&lt;a href=&#34;https://github.com/apache/skywalking-kubernetes&#34;&gt;https://github.com/apache/skywalking-kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SkyWalking Solution for OpenFunction &lt;a href=&#34;https://openfunction.dev/docs/best-practices/skywalking-solution-for-openfunction/&#34;&gt;https://openfunction.dev/docs/best-practices/skywalking-solution-for-openfunction/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: [视频] SkyWalking 8.7.0 源码分析</title>
      <link>/zh/2022-03-25-skywalking-source-code-analyzation/</link>
      <pubDate>Fri, 25 Mar 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-03-25-skywalking-source-code-analyzation/</guid>
      <description>
        
        
        &lt;p&gt;如果要讨论提高自己系统设计能力的方式，我想大多数人都会选择去阅读优秀开源项目的源代码。近年来我参与了多个监控服务的开发工作，并在工作中大量地使用了 SkyWalking 并对其进行二次开发。在这个过程中，我发现 SkyWalking 天然的因其国产的身份，整套源代码地组织和设计非常符合国人的编程思维。由此我录制了本套课程，旨在和大家分享我的一些浅薄的心得和体会。&lt;/p&gt;
&lt;p&gt;本套课程分为两个阶段，分别讲解 Agent 端和 OAP 端地设计和实现。每个阶段的内容都是以启动流程作为讲解主线，逐步展开相关的功能模块。除了对 SKyWalking 本身内容进行讲解，课程还针对 SKyWalking 使用到的一些较为生僻的知识点进行了补充讲解（如 synthetic、NBAC 机制、自定义类加载器等），以便于大家更清晰地掌握课程内容。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1dy4y1V7ck/&#34;&gt;SkyWalking8.7.0 源码分析 - 视频课程直达链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;目前课程已更新完 Agent 端的讲解，目录如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;01-开篇和源码环境准备&lt;/li&gt;
&lt;li&gt;02-Agent 启动流程&lt;/li&gt;
&lt;li&gt;03-Agent 配置加载流程&lt;/li&gt;
&lt;li&gt;04-自定义类加载器 AgentClassLoader&lt;/li&gt;
&lt;li&gt;05-插件定义体系&lt;/li&gt;
&lt;li&gt;07-插件加载&lt;/li&gt;
&lt;li&gt;06-定制 Agent&lt;/li&gt;
&lt;li&gt;08-什么是 synthetic&lt;/li&gt;
&lt;li&gt;09-NBAC 机制&lt;/li&gt;
&lt;li&gt;10-服务加载&lt;/li&gt;
&lt;li&gt;11-witness 组件版本识别&lt;/li&gt;
&lt;li&gt;12-Transform 工作流程&lt;/li&gt;
&lt;li&gt;13-静态方法插桩&lt;/li&gt;
&lt;li&gt;14-构造器和实例方法插桩&lt;/li&gt;
&lt;li&gt;15-插件拦截器加载流程(非常重要)&lt;/li&gt;
&lt;li&gt;16-运行时插件效果的字节码讲解&lt;/li&gt;
&lt;li&gt;17-JDK 类库插件工作原理&lt;/li&gt;
&lt;li&gt;18-服务-GRPCChanelService&lt;/li&gt;
&lt;li&gt;19-服务-ServiceManagementClient&lt;/li&gt;
&lt;li&gt;20-服务-CommandService&lt;/li&gt;
&lt;li&gt;21-服务-SamplingService&lt;/li&gt;
&lt;li&gt;22-服务-JVMService&lt;/li&gt;
&lt;li&gt;23-服务-KafkaXxxService&lt;/li&gt;
&lt;li&gt;24-服务-StatusCheckService&lt;/li&gt;
&lt;li&gt;25-链路基础知识&lt;/li&gt;
&lt;li&gt;26-链路 ID 生成&lt;/li&gt;
&lt;li&gt;27-TraceSegment&lt;/li&gt;
&lt;li&gt;28-Span 基本概念&lt;/li&gt;
&lt;li&gt;29-Span 完整模型&lt;/li&gt;
&lt;li&gt;30-StackBasedTracingSpan&lt;/li&gt;
&lt;li&gt;31-ExitSpan 和 LocalSpan&lt;/li&gt;
&lt;li&gt;32-链路追踪上下文 TracerContext&lt;/li&gt;
&lt;li&gt;33-上下文适配器 ContextManager&lt;/li&gt;
&lt;li&gt;34-DataCarrier-Buffer&lt;/li&gt;
&lt;li&gt;35-DataCarrier-全解&lt;/li&gt;
&lt;li&gt;36-链路数据发送到 OAP&lt;/li&gt;
&lt;/ul&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1dy4y1V7ck&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: 我眼中的 The Apache Way</title>
      <link>/zh/2022-03-14-the-apache-community/</link>
      <pubDate>Sun, 13 Mar 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-03-14-the-apache-community/</guid>
      <description>
        
        
        &lt;p&gt;大约二十年前我刚开始进入互联网的世界的时候，支撑起整个网络的基础设施，就包括了 Apache 软件基金会（ASF）治下的软件。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://httpd.apache.org/&#34;&gt;Apache Httpd&lt;/a&gt; 是开启这个故事的软件，巅峰时期有超过七成的市场占有率，即使是在今天 NGINX 等新技术蓬勃发展的时代，也有三成左右的市场占有率。由 Linux、Apache Httpd、MySQL 和 PHP 组成的 LAMP 技术栈，是开源吞噬软件应用的第一场大型胜利。&lt;/p&gt;
&lt;p&gt;我从 2018 年参与 &lt;a href=&#34;https://flink.apache.org/&#34;&gt;Apache Flink&lt;/a&gt; 开始正式直接接触到成立于 1999 年，如今已经有二十年以上历史的 &lt;a href=&#34;https://www.apache.org/&#34;&gt;Apache 软件基金会&lt;/a&gt;，并在一年后的 2019 年成为 Apache Flink 项目 Committer 队伍的一员，2020 年成为 &lt;a href=&#34;https://curator.apache.org/&#34;&gt;Apache Curator&lt;/a&gt; 项目 PMC（项目管理委员会）的一员。今年，经由&lt;a href=&#34;https://github.com/WillemJiang&#34;&gt;姜宁&lt;/a&gt;老师推荐，成为了 &lt;a href=&#34;https://www.apache.org/foundation/members.html&#34;&gt;Apache Members&lt;/a&gt; 之一，也就是 Apache 软件基金会层面的正式成员。&lt;/p&gt;
&lt;p&gt;我想系统性地做一个开源案例库已经很久了。无论怎么分类筛选优秀的开源共同体，The Apache Community 都是无法绕开的。然而，拥有三百余个开源软件项目的 Apache 软件基金会，并不是一篇文章就能讲清楚的案例。本文也没有打算写成一篇长文顾及方方面面，而是启发于自己的新角色，回顾过去近五年在 Apache Community 当中的经历和体验，简单讨论 Apache 的理念，以及这些理念是如何落实到基金会组织、项目组织以及每一个参与者的日常生活事务当中的。&lt;/p&gt;
&lt;p&gt;不过，尽管对讨论的对象做了如此大幅度的缩减，由我自己来定义什么是 Apache 的理念未免也太容易有失偏颇。幸运的是，Apache Community 作为优秀的开源共同体，当然做到了我在&lt;a href=&#34;https://tisonkun.org/2022/02/10/value-creation/&#34;&gt;《共同创造价值》&lt;/a&gt;一文中提到的回答好“我能为你做什么”以及“我应该怎么做到”的问题。Apache Community 的理念之一就是 Open Communications 即开放式讨论，由此产生的公开材料以及基于公开材料整理的文档汗牛充栋。这既是研究 Apache Community 的珍贵材料，也为还原和讨论一个真实的 Apache Community 提出了不小的挑战。&lt;/p&gt;
&lt;p&gt;无论如何，本文将以 Apache 软件基金会在 2020 年发布的纪录片 &lt;a href=&#34;https://www.youtube.com/watch?v=JUt2nb0mgwg&#34;&gt;Trillions and Trillions Served&lt;/a&gt; 为主线，结合其他文档和文字材料来介绍 Apache 的理念。&lt;/p&gt;
&lt;h2 id=&#34;以人为本&#34;&gt;以人为本&lt;/h2&gt;
&lt;p&gt;纪录片一开始就讲起了 Apache Httpd 项目的历史，当初的 Apache Group 是基于一个源代码共享的 Web Server 建立起来的邮件列表上的一群人。软件开发当初的印象如同科学研究，因此交流源码在近似科学共同体的开源共同体当中是非常自然的。&lt;/p&gt;
&lt;p&gt;如同 ASF 的联合创始人 Brian Behlendorf 所说，每当有人解决了一个问题或者实现了一个新功能，他出于一种朴素的分享精神，也就是“为什么不把补丁提交回共享的源代码当中呢”的念头，基于开源软件的协作就这样自然发生了。纪录片中有一位提到，她很喜欢 Apache 这个词和 a patchy software 的谐音，共享同一个软件的补丁（patches）就是开源精神最早诞生的形式。&lt;/p&gt;
&lt;p&gt;这是 Apache Community 的根基，我们将会看到这种朴素精神经过发展形成了一个怎样的共同体，在共同体的发展过程当中，这样的根基又是如何深刻地影响了 Apache 理念的方方面面。&lt;/p&gt;
&lt;p&gt;Apache Group 的工作模式还有一个重要的特征，那就是每个人都是基于自己的需求修复缺陷或是新增功能，在邮件列表上交流和提交补丁的个人，仅仅只是代表他个人，而没有一个“背后的组织”或者“背后的公司”。因此，ASF 的 &lt;a href=&#34;https://www.apache.org/foundation/how-it-works.html&#34;&gt;How it Works&lt;/a&gt; 文档中一直强调，在基金会当中的个体，都只是个体（individuals），或者称之为志愿者（volunteers）。&lt;/p&gt;
&lt;p&gt;我在某公司的分享当中提到过，商业产品可以基于开源软件打造，但是当公司的雇员出现在社群当中的时候，他应该保持自己志愿者的身份。这就像是开源软件可以被用于生产环境或者严肃场景，例如航空器的发射和运行离不开 Linux 操作系统，但是开源软件本身是具有免责条款的。商业公司或专业团队提供服务保障，而开源软件本身是 AS IS 的。同样，社群成员本人可以有商业公司雇员的身份，但是他在社群当中，就是一个志愿者。&lt;/p&gt;
&lt;p&gt;毫无疑问，这种论调当即受到了质疑，因为通常的认知里，我就是拿了公司的钱，就是因为在给这家公司打工，才会去关注这个项目，你非要说我是一个志愿者，我还就真不是一个志愿者，你怎么说？&lt;/p&gt;
&lt;p&gt;其实这个问题，同样在 How it Works 文档中已经有了解答。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All participants in ASF projects are volunteers and nobody (not even members or officers) is paid directly by the foundation to do their job. There are many examples of committers who are paid to work on projects, but never by the foundation itself. Rather, companies or institutions that use the software and want to enhance it or maintain it provide the salary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我当时基于这样的认识，给到质疑的回答是，如果你不想背负起因为你是员工，因此必须响应社群成员的 issue 或 PR 等信息，那么你可以试着把自己摆在一个 volunteer 的角度来观察和参与社群。实际上，你并没有这样的义务，即使公司要求你必须回答，那也是公司的规定，而不是社群的要求。如果你保持着这样的认识和心态，那么社群于你而言，才有可能是一个跨越职业生涯不同阶段的归属地，而不是工作的附庸。&lt;/p&gt;
&lt;p&gt;社群从来不会从你这里索取什么，因为你的参与本身也是自愿的。其他社群成员会感谢你的参与，并且如果相处得好，这会是一个可爱的去处。社群不是你的敌人，不要因为公司下达了离谱的社群指标而把怒火发泄在社群和社群成员身上。压力来源于公司，作为社群成员的你本来可以不用承受这些。&lt;/p&gt;
&lt;p&gt;Apache Community 对个体贡献者组成社群这点有多么重视呢？只看打印出来不过 10 页 A4 纸的 How it Works 文档，volunteer 和 individuals 两个词加起来出现了 19 次。&lt;a href=&#34;https://www.apache.org/theapacheway/index.html&#34;&gt;The Apache Way&lt;/a&gt; 文档中强调的社群特征就包括了 Independence 一条，唯一并列的另一个是经常被引用的 Community over code 原则。甚至，有一个专门的 &lt;a href=&#34;https://community.apache.org/projectIndependence.html&#34;&gt;Project independence&lt;/a&gt; 文档讨论了 ASF 治下的项目如何由个体志愿者开发和维护，又为何因此是中立和非商业性的。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.apache.org/foundation/how-it-works.html#hats&#34;&gt;INDIVIDUALS COMPOSE THE ASF&lt;/a&gt; 集中体现了 ASF 以人为本的理念。实际上，不止上面提到的 Independence 强调了社群成员个体志愿者的属性，Community over code 这一原则也在强调 ASF 关注围绕开源软件聚集起来的人，包括开发者、用户和其他各种形式的参与者。人是维持社群常青的根本，在后面具体讨论 The Apache Way 的内容的时候还会展开。&lt;/p&gt;
&lt;h2 id=&#34;上善若水&#34;&gt;上善若水&lt;/h2&gt;
&lt;p&gt;众所周知，&lt;a href=&#34;https://www.apache.org/licenses/LICENSE-2.0&#34;&gt;Apache License 2.0&lt;/a&gt; (APL-2.0) 是所谓的&lt;a href=&#34;https://en.wikipedia.org/wiki/Permissive_software_license&#34;&gt;宽容式软件协议&lt;/a&gt;。也就是说，不同于 &lt;a href=&#34;https://www.gnu.org/licenses/gpl-3.0.en.html&#34;&gt;GPL 3.0&lt;/a&gt; 这样的 Copyleft 软件协议要求衍生作品需要以相同的条款发布，其中包括开放源代码和自由修改从而使得软件源代码总是可以获取和修改的，Apache License 在协议内容当中仅保留了著作权和商标，并要求保留软件作者的任何声明（NOTICE）。&lt;/p&gt;
&lt;p&gt;ASF 在软件协议上的理念是赋予最大程度的使用自由，鼓励用户和开发者参与到共同体当中来，鼓励与上游共同创造价值，共享补丁。“鼓励”而不是“要求”，是 ASF 和自由软件基金会（Free Software Foundation, FSF）最主要的区别。&lt;/p&gt;
&lt;p&gt;这一倾向可以追溯到 Apache Group 建立的基础。Apache Httpd 派生自伊利诺伊大学的 NCSA Httpd 项目，由于使用并开发这个 web server 的人以邮件列表为纽带聚集在一起，通过交换补丁来开发同一个项目。在项目的发起人 Robert McCool 等大学生毕业以后，Apache Group 的发起人们接过这个软件的维护和开发工作。当时他们看到的软件协议，就是一个 MIT License 精神下的宽容式软件协议。自然而然地，Apache Group 维护 Apache Httpd 的时候，也就继承了这个协议。&lt;/p&gt;
&lt;p&gt;后来，Apache Httpd 打下了 web server 的半壁江山，也验证了这一模式的可靠性。虽然有些路径依赖的嫌疑，但是 ASF 凭借近似“上善若水”的宽容理念，在二十年间成功创造了数以百亿计美元价值的三百多个软件项目。&lt;/p&gt;
&lt;p&gt;纪录片中 ASF 的元老 Ted Dunning 提到，在他早期创造的软件当中，他会在宽容式软件协议之上，添加一个商用的例外条款。这就像是著名开源领域律师 Heather Meeker 起草的 &lt;a href=&#34;https://commonsclause.com/&#34;&gt;The Commons Clause&lt;/a&gt; 附加条款。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;附加 The Commons Clause 条款的软件都不是符合 OSD 定义的开源软件，也不再是原来的协议了。NebulaGraph 曾经在附加 The Commons Clause 条款的情况下声称自己是 APL-2.0 协议许可的软件，当时的 ASF 董事吴晟就提 issue (&lt;a href=&#34;https://github.com/vesoft-inc/nebula/issues/3247&#34;&gt;vesoft-inc/nebula#3247&lt;/a&gt;) 指出这一问题。NebulaGraph 于是删除了所有 The Commons Clause 的字样，保证无误地以 APL-2.0 协议许可该软件。&lt;/p&gt;
&lt;p&gt;Ted Dunning 随后提到，这样的附加条款实际上严重影响了软件的采用。他意识到自己实际上并不想为此打官司，因此加上这样的条款对他而言是毫无意义的。Ted Dunning 于是去掉了附加条款，而这使得使用他的软件的条件能够简单的被理解，从而需要这些软件的用户能够大规模的采用。“水利万物而不争”，反而是不去强迫和约束用户行为的做法，为软件赢得了更多贡献。&lt;/p&gt;
&lt;p&gt;我仍然很敬佩采用 GPL 系列协议发布高质量软件的开发者，Linux 和 GCC 这样的软件的成功改变了世人对软件领域的自由的认识。然而，FSF 自己也认识到需要提出修正的 LGPL 来改进应用程序以外的软件的发布和采用，例如基础库。&lt;/p&gt;
&lt;p&gt;APL-2.0 的思路与之不同，它允许任何人以任何形式使用、修改和分发软件，因此 ASF 治下的项目，以及 Linux Foundation 治下采用 APL-2.0 的项目，以及更多个人或组织采用 APL-2.0 的项目，共同构成了强大的开源软件生态，涵盖了应用软件，基础库，开发工具和框架等等各个方面。事实证明，“鼓励”而不是“要求”用户秉持 upstream first 的理念，尽可能参与到开源共同体并交换知识和补丁，共同创造价值，是能够制造出高质量的软件，构建出繁荣的社群和生态的。&lt;/p&gt;
&lt;h2 id=&#34;匠人精神&#34;&gt;匠人精神&lt;/h2&gt;
&lt;p&gt;Apache Community 关注开发者的需要。&lt;/p&gt;
&lt;p&gt;Apache Group 成立 ASF 的原因，是在 Apache Httpd 流行起来以后，商业公司和社会团体开始寻求和这个围绕项目形成的群体交流。然而，缺少一个正式的法律实体让组织之间的往来缺乏保障和流程。因此，如同纪录片当中提到的，ASF 成立的主要原因，是为了支撑 Apache Httpd 项目。只不过当初的创始成员们很难想到的是，ASF 最终支撑了数百个开源项目。&lt;/p&gt;
&lt;p&gt;不同于 Linux Foundation 是行业联盟，主要目的是为了促进其成员的共同商业利益，ASF 主要服务于开发者，由此支撑开源项目的开发以及开源共同体的发展。&lt;/p&gt;
&lt;p&gt;举例来说，进入 ASF 孵化器的项目都能够在 &lt;a href=&#34;https://infra.apache.org/&#34;&gt;ASF Infra&lt;/a&gt; 的支持下运行自己的 apache.org 域名的网站，将代码托管在 ASF 仓库中上，例如 &lt;a href=&#34;https://gitbox.apache.org/repos/asf&#34;&gt;Apache GitBox Repositories&lt;/a&gt; 和 &lt;a href=&#34;https://github.com/apache/&#34;&gt;Apache GitHub Organization&lt;/a&gt; 等。这些仓库上运行着自由取用的开发基础设施，例如持续集成和持续发布的工具和资源等等。ASF 还维护了自己的邮件列表和文件服务器等一系列资源，以帮助开源项目建立起自己的共同体和发布自己的构件。&lt;/p&gt;
&lt;p&gt;反观 Linux Foundation 的主要思路，则是关注围绕项目聚集起来的供应商，以行业联盟的形式举办联合市场活动扩大影响，协调谈判推出行业标准等等。典型地，例如 CNCF 一直致力于定义云上应用开发的标准，容器虚拟化技术的标准。上述 ASF Infra 关注的内容和资源，则大多需要项目开发者自己解决，这些开发者往往主要为一个或若干个供应商工作，他们解决的方式通常也是依赖供应商出力。&lt;/p&gt;
&lt;p&gt;当然，上面的对比只是为了说明区别，并无优劣之分，也不相互对立。ASF 的创始成员 Brian Behlendorf 同时是 Linux Foundation 下 Open Source Security Foundation 的经理，以及 Hyperledger 的执行董事。&lt;/p&gt;
&lt;p&gt;ASF 关注开发者的需要，体现出 Apache Community 及其成员对开发者的人文关怀。纪录片中谈到 ASF 治下项目的开发体验时，几乎每个人的眼里都有光。他们谈论着匠人精神，称赞知识分享，与人合作，以及打磨技艺的愉快经历。实际上，要想从 Apache 孵化器中成功毕业，相当部分的 mentor 关注的是围绕开源软件形成的共同体，能否支撑开源软件长久的发展和采用，这其中就包括共同体成员是否能够沉下心来做技术，而不是追求花哨的数字指标和人头凑数。&lt;/p&gt;
&lt;p&gt;讲几个具体的开发者福利。&lt;/p&gt;
&lt;p&gt;每个拥有 @apache.org 邮箱的人，即成为 ASF 治下项目 Committer 或 ASF Member 的成员，JetBrains 会提供免费的全家桶订阅授权码。我从 2019 年成为 Apache Flink 项目的 Committer 以后，已经三年沉浸在 IDEA 和 CLion 的包容下，成为彻底使用 IDE 主力开发的程序员了。&lt;/p&gt;
&lt;p&gt;Apache GitHub Organization 下的 GitHub Actions 资源是企业级支持，这部分开销也是由 ASF 作为非营利组织募资和运营得到的资金支付的。基本上，如果你的项目成为 Apache 孵化器项目或顶级项目，那么和 GitHub Actions 集成的 CI 体验是非常顺畅的。Apache SkyWalking 只算主仓库就基于 GitHub Actions 运行了十多个端到端测试作业，Apache Pulsar 也全面基于 GitHub Actions 集成了自己的 CI 作业。&lt;/p&gt;
&lt;p&gt;提到匠人精神，一个隐形的开发者福利，其实是 ASF 的成员尤其是孵化器的 mentor 大多是经验非常丰富的开发者。软件开发不只是写代码，Apache Community 成员之间相互帮助，能够帮你跟上全世界最前沿的开发实践。如何提问题，如何做项目管理，如何发布软件，这些平日里在学校在公司很难有机会接触的知识和实践机会，在 Apache Community 当中只要你积极承担责任，都是触手可得的。&lt;/p&gt;
&lt;p&gt;当然，如何写代码也是开发当中最常交流的话题。我深入接触 Maven 开始于跟 Flink Community 的 Chesnay Schepler 的交流。我对 Java 开发的理解，分布式系统开发的知识，很大程度上也得到了 Apache Flink 和 Apache ZooKeeper 等项目的成员的帮助，尤其是 Till Rohrmann 和 Enrico Olivelli 几位。上面提到的 Ted Dunning 开始攻读博士的时候，我还没出生。但是我在项目当中用到 ZooKeeper 的 multi 功能并提出疑问和改进想法的时候，也跟他有过一系列的讨论。&lt;/p&gt;
&lt;p&gt;谈到技艺就会想起人，这也是 ASF 一直坚持以人为本带来的社群风气。&lt;/p&gt;
&lt;p&gt;我跟姜宁老师在一年前认识，交流 The Apache Way 期间萌生出相互认同。姜宁老师在 Apache 孵化器当中帮助众多项目理解 The Apache Way 并予以实践，德高望重。在今年的 ASF Members 年会当中，姜宁老师也被推举为 ASF Board 的一员。&lt;/p&gt;
&lt;p&gt;我跟吴晟老师在去年认识。他经常会强调开发者尤其是没有强烈公司背景的开发者的视角，多次提到这些开发者是整个开源生态的重要组成部分。他作为 PMC Chair 的 Apache SkyWalking 项目相信“没有下一个版本的计划，只知道会有下一个版本”，这是最佳实践的传播，也是伴随技术的文化理念的传播。SkyWalking 项目出于自己需要，也出于为开源世界添砖加瓦的动机创建的 &lt;a href=&#34;https://github.com/apache/skywalking-eyes&#34;&gt;SkyWalking Eyes&lt;/a&gt; 项目，被广泛用在不止于 ASF 治下项目，而是整个开源世界的轻量级的软件协议审计和 License Header 检查上。&lt;/p&gt;
&lt;p&gt;主要贡献在 Apache APISIX 的琚致远同学今年也被推选成为 Apache Members 的一员。他最让我印象深刻的是在 APISIX 社群当中积极&lt;a href=&#34;https://lists.apache.org/thread/40spln9t62dz8dlwf0xg174g131t89fq&#34;&gt;讨论社群建设的议题&lt;/a&gt;，以及作为 APISIX 发布的 GSoC 项目的 mentor 帮助在校学生接触开源，实践开源，锻炼技艺。巧合的是，他跟我年龄相同，于是我痛失 Youngest Apache Member 的噱头，哈哈。&lt;/p&gt;
&lt;p&gt;或许，参与 Apache Community 就是这样的一种体验。并不是什么复杂的叙事，只是找到志同道合的人做出好的软件。我希望能够为提升整个软件行业付出自己的努力，希望我（参与）制造的软件创造出更大的价值，这里的人看起来大都也有相似的想法，这很好。仅此而已。&lt;/p&gt;
&lt;p&gt;原本还想聊聊 The Apache Way 的具体内容，还有介绍 Apache Incubator 这个保持 Apache Community 理念常青，完成代际传承的重要机制，但是到此为止似乎也很好。Apache Community 的故事和经验很难用一篇文章讲完，这两个话题就留待以后再写吧。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: Cyborg Flow X SkyWalking: 生产环境全链路压测</title>
      <link>/zh/2022-01-18-cyborg-flow/</link>
      <pubDate>Tue, 18 Jan 2022 00:00:00 +0000</pubDate>
      
      <guid>/zh/2022-01-18-cyborg-flow/</guid>
      <description>
        
        
        &lt;p&gt;随着业务与用户量的持续发展，系统的瓶颈也逐渐出现。尤其在一些节假日、突发的营销活动中，访问量激增可能会导致系统性能下降，甚至造成系统瘫痪。
全链路压测可以很好的帮助我们预先演练高峰流量，从而提前模拟出系统的执行情况，帮助我们预估系统容量。当流量真正来临时，也可以更从容面对。
Apache SkyWalking 联合 Apache APISIX 及 Apache ShardingSphere，三大顶级开源社区通力合作，共同打造生产级可用的全链路压测解决方案，CyborgFlow。&lt;/p&gt;
&lt;h2 id=&#34;介绍&#34;&gt;介绍&lt;/h2&gt;
&lt;p&gt;CyborgFlow 是一款面向生产级可用的全链路压测解决方案。总共由三个组件组成，如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;components.png&#34; alt=&#34;components&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flow Gateway: 压测流量网关。当流量到达该组件时，则会将请求认定为压测流量，并将压测流量标识传递至上游服务。&lt;/li&gt;
&lt;li&gt;Database Shadow: 数据库中间件。当数据库中间件感知到当前流量为压测流量时，则会将数据库操作路由至影子表中进行操作。&lt;/li&gt;
&lt;li&gt;Agent/Dashboard: 分布式监控系统。与业务系统紧密结合，当感知到压测请求后，自动将其标识传递至上游，无需业务代码改造。并且利用分析能力，构建Dashboard来便于查看流量情况。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以此，便覆盖了单个请求的完整生命周期，在网关层构建压测标识，到业务系统透传标识，最终将请求与影子表交互。同时整个流程拥有完整的监控分析。&lt;/p&gt;
&lt;h2 id=&#34;原理&#34;&gt;原理&lt;/h2&gt;
&lt;p&gt;依托于三大社区合作，让这一切变得简单易用。下图为全链路压测系统的运行原理，橙色和蓝色分别代表正常流量和压测流量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;theory.png&#34; alt=&#34;theory&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;flow-gateway&#34;&gt;Flow Gateway&lt;/h3&gt;
&lt;p&gt;Flow Gateway 作为压测流量网关，主要负责接收流量，并传递压测流量表示至上游。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;添加 &lt;a href=&#34;https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/skywalking.md&#34;&gt;skywalking插件&lt;/a&gt; 构建链路入口。&lt;/li&gt;
&lt;li&gt;依据 &lt;a href=&#34;https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/proxy-rewrite.md&#34;&gt;proxy-rewrite插件&lt;/a&gt; 将压测流量标识注入到上游的请求头中。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;agentdashboard&#34;&gt;Agent/Dashboard&lt;/h3&gt;
&lt;p&gt;该组件中则分为两部分内容说明。&lt;/p&gt;
&lt;h4 id=&#34;agent&#34;&gt;Agent&lt;/h4&gt;
&lt;p&gt;Agent与业务程序拥有相同生命周期，负责压测流量标识在各个业务系统之间传递，并与 Database Shadow 交互。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SkyWalking Agent通过读取从Flow Gateway传递的压测流量标识，利用 &lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/en/protocols/skywalking-cross-process-correlation-headers-protocol-v1/&#34;&gt;透传协议&lt;/a&gt; 将该标识在应用之间传递。&lt;/li&gt;
&lt;li&gt;当准备进行数据库调用时，则通过判断是否包含压测流量标识来决定是否SQL调用时追加压测流量标识(&lt;code&gt;/* cyborg-flow: true */&lt;/code&gt;)。&lt;/li&gt;
&lt;li&gt;当检测到当前请求包含压测流量标识后，将该数据与Trace绑定，用于Dashboard数据分析。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;dashboard&#34;&gt;Dashboard&lt;/h4&gt;
&lt;p&gt;Dashboard 用于压测过程进行中的监控数据分析，并最终以图表的方式进行展示。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;接收来自Agent中上报的Trace数据，并依据&lt;code&gt;OAL&lt;/code&gt;中的Tag过滤器(&lt;code&gt;.filter(tags contain &amp;quot;cyborg-flow:true&amp;quot;)&lt;/code&gt;)来生成压测与非压测的指标数据。&lt;/li&gt;
&lt;li&gt;利用指标数据便可以在Dashboard中创建图表进行观察。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;database-shadow&#34;&gt;Database Shadow&lt;/h3&gt;
&lt;p&gt;Database Shadow 作为 Proxy 在业务程序与数据库中间完成数据交互，当检测到压测流量时则会将SQL传递至影子表中处理。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检测下游传递的数据库语句中是否包含压测流量标识(&lt;code&gt;/* cyborg-flow: true */&lt;/code&gt;)，存在时则将SQL交给由用户配置的影子表中处理。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;快速上手&#34;&gt;快速上手&lt;/h2&gt;
&lt;p&gt;下面将带你快速将Cyborg Flow集成至你的项目中。相关组件的下载请至 &lt;a href=&#34;https://github.com/SphereEx/CyborgFlow/releases/tag/v0.1.0&#34;&gt;Github Release&lt;/a&gt; 中下载，目前已发布 0.1.0 版本。&lt;/p&gt;
&lt;h3 id=&#34;部署-database-shadow&#34;&gt;部署 Database Shadow&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;解压缩&lt;strong&gt;cyborg-database-shadow.tar.gz&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;conf/config-shadow.yaml&lt;/code&gt; 文件中的业务数据库与影子数据库配置为自身业务中的配置。&lt;/li&gt;
&lt;li&gt;启动 Database Shadow服务，启动脚本位于&lt;code&gt;bin/start.sh&lt;/code&gt;中。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如需了解更详细的部署参数配置，请参考 &lt;a href=&#34;https://github.com/SphereEx/CyborgFlow/blob/main/cyborg-database-shadow/README_ZH.md#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B&#34;&gt;官方文档&lt;/a&gt; 。&lt;/p&gt;
&lt;h3 id=&#34;部署-cyborg-dashboard&#34;&gt;部署 Cyborg Dashboard&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;解压缩&lt;strong&gt;cyborg-dashboard.tar.gz&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;启动后端与UI界面服务，用于链路数据解析与界面展示，启动脚本位于&lt;code&gt;bin/startup.sh&lt;/code&gt;中。&lt;/li&gt;
&lt;li&gt;接下来就可以通过打开浏览器并访问&lt;code&gt;http://localhost:8080/&lt;/code&gt;，此页面为Cyborg Dashboard界面，由于目前尚未部署任何业务程序，所以暂无任何数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如需了解更详细的部署参数配置，请参考 &lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/en/setup/backend/backend-setup/&#34;&gt;后端服务&lt;/a&gt; 与 &lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/en/setup/backend/ui-setup/&#34;&gt;UI界面服务&lt;/a&gt; 的安装文档。&lt;/p&gt;
&lt;h3 id=&#34;部署-cyborg-agent-到业务程序中&#34;&gt;部署 Cyborg Agent 到业务程序中&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;解压缩&lt;strong&gt;cyborg-agent.tar.gz&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;修改&lt;code&gt;config/agent.config&lt;/code&gt;中的&lt;code&gt;collector.backend_service&lt;/code&gt;为 Cyborg Dashboard 中后端地址(默认为&lt;code&gt;11800&lt;/code&gt;端口)，用于将监控数据上报至 Cyborg Dashboard 。&lt;/li&gt;
&lt;li&gt;修改业务程序中与数据库的链接，将其更改为 Database Shadow 中的配置。默认访问端口为&lt;code&gt;3307&lt;/code&gt;，用户名密码均为&lt;code&gt;root&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;当程序启动时，增加该参数到启动命令中：&lt;code&gt;-jar path/to/cyborg-agent/skywalking-agent.jar&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如需了解更详细的部署参数配置，请参考 &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme/&#34;&gt;Agent安装文档&lt;/a&gt; 。&lt;/p&gt;
&lt;h3 id=&#34;部署-flow-gateway&#34;&gt;部署 Flow Gateway&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;参考 &lt;a href=&#34;https://github.com/SphereEx/CyborgFlow/blob/main/cyborg-flow-gateway/README_ZH.md#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B%E5%9F%BA%E4%BA%8E-centos-7&#34;&gt;Flow Gateway 快速开始&lt;/a&gt; 进行下载 Apache APISIX 并配置相关插件。&lt;/li&gt;
&lt;li&gt;基于 &lt;a href=&#34;https://apisix.apache.org/zh/docs/apisix/getting-started#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E5%88%9B%E5%BB%BA%E8%B7%AF%E7%94%B1&#34;&gt;APISIX 创建路由文档&lt;/a&gt; 进行路由创建。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;完成&#34;&gt;完成！&lt;/h3&gt;
&lt;p&gt;最后，通过Flow Gateway访问业务系统资源，便完成了一次压测流量请求。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;压测流量最终访问至影子表进行数据操作。&lt;/li&gt;
&lt;li&gt;如下图所示，通过观察 Cyborg Dashboard 便可以得知压测与非压测请求的执行情况。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;traffic.png&#34; alt=&#34;traffic&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;在本文中，我们详细介绍了Cyborg Flow中的各个组件的功能、原理，最终搭配快速上手来快速将该系统与自己的业务系统结合。
如果在使用中有任何问题，欢迎来&lt;a href=&#34;https://github.com/SphereEx/CyborgFlow/discussions&#34;&gt;共同讨论&lt;/a&gt;。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: Chaos Mesh X SkyWalking: 可观测的混沌工程</title>
      <link>/zh/2021-11-29-better-observability-for-chaos-engineering/</link>
      <pubDate>Mon, 29 Nov 2021 00:00:00 +0000</pubDate>
      
      <guid>/zh/2021-11-29-better-observability-for-chaos-engineering/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://github.com/chaos-mesh/chaos-mesh&#34;&gt;Chaos Mesh&lt;/a&gt; 是&lt;strong&gt;一个开源的云原生混沌工程&lt;/strong&gt;平台，借助 Chaos Mesh，用户可以很方便地对服务注入异常故障，并配合 Chaos Dashboard 实现对整个混沌实验运行状况的监测 。然而，对混沌实验运行情况的监控并不能告诉我们应用服务性能的变化。从系统可观测性的角度来说，我们可能无法单纯通过混沌实验的动态了解故障的全貌，这也阻碍了我们对系统和故障的进一步了解，调试。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache SkyWalking&lt;/a&gt; 是一个开源的 APM (Application Performance Monitor) 系统，可以对云原生服务提供监控、跟踪、诊断等功能。SkyWalking &lt;a href=&#34;https://skywalking.apache.org/docs/main/latest/en/concepts-and-designs/event/#how-to-configure-alarms-for-events&#34;&gt;支持&lt;/a&gt;收集 Event（事件），可在 Dashboard 中查看分布式系统中发生了哪些事件，并可以直观地观测到不同 Event 对服务性能造成的影响，和 Chaos Mesh 结合使用，便可为混沌实验造成的服务影响提供监控。&lt;/p&gt;
&lt;p&gt;本教程将分享如何通过将 SkyWalking 和 Chaos Mesh 结合，运用 Event 信息监控，实时了解混沌实验对应用服务性能造成的影响。&lt;/p&gt;
&lt;h2 id=&#34;准备工作&#34;&gt;准备工作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建 Skywalking 集群，具体可以参考 &lt;a href=&#34;https://github.com/apache/skywalking-kubernetes#install&#34;&gt;SkyWalking Readme&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;部署 Chaos Mesh，推荐使用 &lt;a href=&#34;https://chaos-mesh.org/docs/production-installation-using-helm/&#34;&gt;helm 安装&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;安装 Java 测试工具 &lt;a href=&#34;https://jmeter.apache.org/index.html&#34;&gt;JMeter&lt;/a&gt; （其他工具亦可，仅用于增加服务负载）&lt;/li&gt;
&lt;li&gt;如果仅作为 Demo 使用，可以参考 &lt;a href=&#34;https://github.com/chaos-mesh/chaos-mesh-on-skywalking&#34;&gt;chaos-mesh-on-skywalking&lt;/a&gt; 这个仓库进行配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;step-1---访问-skywalking-集群&#34;&gt;Step 1 - 访问 SkyWalking 集群&lt;/h2&gt;
&lt;p&gt;安装 SkyWalking 后，就可以访问它的UI了，但因为还没有服务进行监控，这里还需要添加服务并进行 Agent 埋点设置。本文选用轻量级微服务框架 Spring Boot 作为埋点对象搭建一个简易 Demo 环境。&lt;/p&gt;
&lt;p&gt;可以参考 &lt;a href=&#34;https://github.com/chaos-mesh/chaos-mesh-on-skywalking&#34;&gt;chaos-mesh-on-skywalking&lt;/a&gt; 仓库中的 &lt;a href=&#34;https://github.com/chaos-mesh/chaos-mesh-on-skywalking/blob/master/demo-deployment.yaml&#34;&gt;demo-deployment.yaml &lt;/a&gt;文件创建。之后使用 &lt;code&gt;kubectl apply -f demo-deployment.yaml -n skywalking&lt;/code&gt; 进行部署。部署成功后即可在SkyWalking-UI 中看到实时监控的服务信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：因为 Spring Boot 的端口也是8080，在端口转发时要避免和 **SkyWalking **的端口冲突，比如使用 &lt;code&gt;kubectl port-forward svc/spring-boot-skywalking-demo 8079:8080 -n skywalking&lt;/code&gt; 。&lt;/p&gt;
&lt;h2 id=&#34;step-2---部署-skywalking-kubernetes-event-exporter&#34;&gt;Step 2 - 部署 SkyWalking Kubernetes Event Exporter&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking-kubernetes-event-exporter&#34;&gt;SkyWalking Kubernetes Event Exporter&lt;/a&gt; 可以用来监控和过滤 Kubernetes 集群中的 Event ，通过设置过滤条件筛选出需要的 Event，并将这些 Event 发送到 SkyWalking 后台， 这样就可以通过 SkyWalking 观察到你的 Kubernetes 集群中的Event 何时影响到服务的各项指标了。如果想要一条命令部署，可以参考此&lt;a href=&#34;https://github.com/chaos-mesh/chaos-mesh-on-skywalking/blob/master/exporter-deployment.yaml&#34;&gt;配置&lt;/a&gt;创建 yaml 文件 ，设置 filters 和 exporters 的参数后，使用 &lt;code&gt;kubectl apply&lt;/code&gt; 进行部署。&lt;/p&gt;
&lt;h2 id=&#34;step-3---使用-jmeter-对服务加压&#34;&gt;Step 3 - 使用 JMeter 对服务加压&lt;/h2&gt;
&lt;p&gt;为了达到更好的观察效果，需要先对 Spring Boot 增加服务负载，本文选择使用 JMeter 这一使用广泛的 Java 压力测试工具来对服务加压。&lt;/p&gt;
&lt;h3 id=&#34;通过-jmeter-对-localhost8079-进行压测添加5个线程持续进行加压&#34;&gt;通过 JMeter 对 &lt;code&gt;localhost:8079&lt;/code&gt; 进行压测，添加5个线程持续进行加压。&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;1.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;2.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;通过 SkyWalking Dashboard 可以看到，目前访问成功率为100%，服务负载大约在5300 CPM (Calls Per Minute）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;3.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;step-4---chaos-mesh-注入故障观察效果&#34;&gt;Step 4 - Chaos Mesh 注入故障，观察效果&lt;/h2&gt;
&lt;p&gt;做好了这些准备工便可以使用 Chaos Dashboard 进行压力场景模拟，并在实验进程中观察服务性能的变化。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;4.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;以下使用不同 Stress Chaos 配置，观测对应服务性能变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CPU 负载10%，内存负载128 MB 。&lt;/p&gt;
&lt;p&gt;混沌实验开始和结束的时间点标记可以通过右侧开关显示在在图表中，将鼠标移至短线出可以看到是实验的 Applied 或 Recovered。可以看到两个绿色短线之间的时间段里，服务处理调用的的性能降低，为4929 CPM，在实验结束后，性能恢复正常。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;5.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU load 增加到50%，发现服务负载进一步降低至4307 CPM。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;6.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;极端情况下 CPU 负载达到100%，服务负载降至无混沌实验时的40% 。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;7.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为 Linux 系统下的进程调度并不会让某个进程一直占据 CPU，所以即使实在 CPU 满载的极端情况下，该部署的 Spring Boot Demo 仍可以处理40%的访问请求。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结&lt;/h2&gt;
&lt;p&gt;通过 SkyWalking 与 Chaos Mesh 的结合，我们可以清晰的观察到服务在何时受到混沌实验的影响，在注入混沌后服务的表现性能又将如何。SkyWalking 与 Chaos Mesh 的结合使得我们轻松地观察到了服务在各种极端情况下的表现，增强了我们对服务的信心。&lt;/p&gt;
&lt;p&gt;Chaos Mesh 在 2021 年成长了许多。为了更多地了解用户在实践混沌工程方面的经验，以便持续完善和提升对用户的支持，社区发起了 Chaos Mesh 用户问卷调查，点击【阅读原文】参与调查，谢谢！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.surveymonkey.com/r/X78WQPC&#34;&gt;https://www.surveymonkey.com/r/X78WQPC&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;欢迎大家加入 Chaos Mesh 社区，加入 CNCF Slack (slack.cncf.io) 底下的 Chaos Mesh 频道: project-chaos-mesh，一起参与到项目的讨论与开发中来！大家在使用过程发现 Bug 或缺失什么功能，也可以直接在 GitHub (&lt;a href=&#34;https://github.com/chaos-mesh&#34;&gt;https://github.com/chaos-mesh&lt;/a&gt;) 上提 Issue 或 PR。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: [视频] SkyWalking Day 2021 演讲视频</title>
      <link>/zh/skywalking-day-2021/</link>
      <pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate>
      
      <guid>/zh/skywalking-day-2021/</guid>
      <description>
        
        
        &lt;p&gt;时间：2021 年 6 月 26 日&lt;/p&gt;
&lt;p&gt;地点：北京市海淀区西格玛大厦 B1 多功能厅&lt;/p&gt;
&lt;p&gt;视频回放：见 &lt;a href=&#34;https://space.bilibili.com/390683219/channel/detail?cid=190669&#34;&gt;Bilibili&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;apache-skywalking-landscapehttpswwwbilibilicomvideobv1hv411w7sr&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1HV411W7sr&#34;&gt;Apache SkyWalking Landscape&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;吴晟 Sheng Wu. Tetrate Founding Engineer, Apache Software Foundation board director. SkyWalking founder.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SkyWalking 2020-2021 年发展和后续计划&lt;/p&gt;
&lt;h4 id=&#34;微服务可观测性分析平台的探索与实践httpswwwbilibilicomvideobv15g411u7nh&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV15g411u7nh&#34;&gt;微服务可观测性分析平台的探索与实践&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;凌若川 腾讯高级工程师&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可观测性分析平台作为云原生时代微服务系统基础组件，开放性与性能是决定平台价值的核心要素。 复杂微服务应用场景与海量多维链路数据，对可观测性分析平台在开放性设计和各环节高性能实现带来诸多挑战。 本次分享中将重点梳理腾讯云微服务团队在构建云原生可观测性分析平台过程中遇到的挑战，介绍我们在架构设计与实现方面的探索与实践。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;云原生时代微服务可观测性平台面临的性能与可用性挑战&lt;/li&gt;
&lt;li&gt;腾讯云在构建高性能微服务可观测性分析平台的探索与实践&lt;/li&gt;
&lt;li&gt;微服务可观测性分析平台架构的下一阶段演进方向展望&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;banyandb-数据模型背后的逻辑httpswwwbilibilicomvideobv1eo4y1c7kj&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1Eo4y1C7KJ&#34;&gt;BanyanDB 数据模型背后的逻辑&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;高洪涛 Hongtao Gao. Tetrate SRE, SkyWalking PMC, Apache ShardingSphere PMC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BanyanDB 作为为处理 Apache SkyWalking 产生的 trace，log 和 metric 的数据而特别设计的数据库，其背后数据模型的抉择是非常与众不同的。 在本次分享中，我将根据 RUM 猜想来讨论为什么 BanyanDB 使用的数据模型对于 APM 数据而言是更加高效和可靠的。&lt;/p&gt;
&lt;p&gt;通过本次分享，观众可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;理解数据库设计的取舍&lt;/li&gt;
&lt;li&gt;了解 BanyanDB 的数据模型&lt;/li&gt;
&lt;li&gt;认识到该模型对于 APM 类数据有特定的优势&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;apache-skywalking-如何做前端监控httpswwwbilibilicomvideobv1fl411w7xe&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1FL411W7XE&#34;&gt;Apache SkyWalking 如何做前端监控&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;范秋霞 Qiuxia Fan，Tetrate FE SRE，SkyWalking PMC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apache SkyWalking 对前端进行了监控与跟踪，分别有 Metric, Log, Trace 三部分。本次分享我会介绍页面性能指标的收集与计算，同时用案列进行分析，也会讲解 Log 的采集方法以及 Source Map 错误定位的实施。最后介绍浏览器端 Requets 的跟踪方法。&lt;/p&gt;
&lt;p&gt;通过本次分享，观众可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;了解页面的性能指标以及收集计算方法&lt;/li&gt;
&lt;li&gt;了解前端如何做错误日志收集&lt;/li&gt;
&lt;li&gt;如何对页面请求进行跟踪以及跟踪的好处&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;一名普通工程师该如何正确的理解开源精神httpswwwbilibilicomvideobv1bh411h7re&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1Bh411h7RE&#34;&gt;一名普通工程师，该如何正确的理解开源精神？&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;王晔倞 Yeliang Wang. API7 Partner / Product VP.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;开源精神，那也许是一种给于和获取的平衡，有给于才能有获取，有获取才会有给于的动力。无需指责别人只会获取，我们应该懂得开源是一种创造方式，一个没有创造欲和创造力的人加入开源也是无用的。&lt;/p&gt;
&lt;p&gt;通过本次分享，观众可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为什么国内一些程序员会对开源产生误解？&lt;/li&gt;
&lt;li&gt;了解 “开源≠自由≠非商业” 的来龙去脉。&lt;/li&gt;
&lt;li&gt;一名普通工程师，如何高效地向开源社区做贡献？&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;可观测性技术生态和-opentelemetry-原理及实践httpswwwbilibilicomvideobv1nu4y1v7lx&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1NU4y1V7LX&#34;&gt;可观测性技术生态和 OpenTelemetry 原理及实践&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;陈一枭 腾讯. OpenTelemetry docs-cn maintainer、Tencent OpenTelemetry OTeam 创始人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;综述云原生可观测性技术生态，介绍 OpenTracing，OpenMetrics，OpenTelemetry 等标准演进。介绍 OpenTelemetry 存在价值意义，介绍 OpenTelemetry 原理及其整体生态规划。介绍腾讯在 OpenTelemetry 方面的实践。&lt;/p&gt;
&lt;p&gt;本次分享内容如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;云原生可观测性技术简介&lt;/li&gt;
&lt;li&gt;OpenTelemetry 及其它规范简介&lt;/li&gt;
&lt;li&gt;OpenTelemetry 原理&lt;/li&gt;
&lt;li&gt;OpenTelemetry 在腾讯的应用及实践&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;apache-skywalking-事件采集系统更快定位故障httpswwwbilibilicomvideobv1nu4y1v7lx&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1NU4y1V7LX&#34;&gt;Apache SkyWalking 事件采集系统更快定位故障&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;柯振旭 Zhenxu Ke，Tetrate SRE, Apache SkyWalking PMC. Apache Incubator PMC. Apache Dubbo committer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过本次分享，听众可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;了解 SkyWalking 的事件采集系统；&lt;/li&gt;
&lt;li&gt;了解上报事件至 SkyWalking 的多种方式；&lt;/li&gt;
&lt;li&gt;学习如何利用 SkyWalking 采集的事件结合 metrics，分析目标系统的性能问题；&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;可观测性自动注入技术原理探索与实践httpswwwbilibilicomvideobv13b4y1t78h&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV13B4y1T78H&#34;&gt;可观测性自动注入技术原理探索与实践&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;詹启新 Tencnet OpenTelemetry Oteam PMC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在可观测领域中自动注入已经成为重要的组成部分之一，其优异简便的使用方式并且可同时覆盖到链路、指标、日志，大大降低了接入成本及运维成本，属于友好的一种接入方式； 本次分享将介绍 Java 中的字节码注入技术原理，及在可观测领域的应用实践&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;常用的自动注入技术原理简介&lt;/li&gt;
&lt;li&gt;介绍可观测性在 Java 落地的要点&lt;/li&gt;
&lt;li&gt;opentelemetry-java-instrumentation 的核心原理及实现&lt;/li&gt;
&lt;li&gt;opentelemetry 自动注入的应用实践&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;如何利用-apache-apisix-提升-nginx-的可观测性httpswwwbilibilicomvideobv1864y1q71f&#34;&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV1864y1Q71f&#34;&gt;如何利用 Apache APISIX 提升 Nginx 的可观测性&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;金卫 Wei Jin, API7 Engineer Apache SkyWalking committer. Apache apisix-ingress-controller Founder. Apache APISIX PMC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在云原生时代，动态和可观测性是 API 网关的标准特性。Apache APISIX 不仅覆盖了 Nginx 的传统功能，在可观测性上也和 SkyWalking 深度合作，大大提升了服务治理能力。本次分享会介绍如何无痛的提升 Nginx 的可观测性和 APISIX 在未来可观测性方面的规划。&lt;/p&gt;
&lt;p&gt;通过本次分享，观众可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;通过 Apache APISIX 实现观测性的几种手段.&lt;/li&gt;
&lt;li&gt;了解 Apache APISIX 高效且易用的秘诀.&lt;/li&gt;
&lt;li&gt;结合 Apache skywalking 进一步提升可观测性.&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: [视频] 大咖说开源 第二季 第4期 | Apache软件基金会20年</title>
      <link>/zh/2021-05-09-summer-2021-asf20/</link>
      <pubDate>Sun, 09 May 2021 00:00:00 +0000</pubDate>
      
      <guid>/zh/2021-05-09-summer-2021-asf20/</guid>
      <description>
        
        
        



&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1BQ4y1o7rA&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: [视频] 开放原子开源基金会2020年度峰会 - Educate community Over Support community</title>
      <link>/zh/2021-01-21-educate-community/</link>
      <pubDate>Wed, 20 Jan 2021 00:00:00 +0000</pubDate>
      
      <guid>/zh/2021-01-21-educate-community/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;第一节：开篇介绍&lt;/li&gt;
&lt;li&gt;第二节：数字游戏（Number Game）&lt;/li&gt;
&lt;li&gt;第三节：社区原则（Community “Principles”）&lt;/li&gt;
&lt;li&gt;第四节：基金会原则（For public good）&lt;/li&gt;
&lt;li&gt;第五节：一些不太好的事情&lt;/li&gt;
&lt;/ul&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV125411E7GK&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: 暑期 2020 活动学生（张可）心得分享</title>
      <link>/zh/2020-12-20-summer2020-activity-sharing2/</link>
      <pubDate>Sun, 20 Dec 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-12-20-summer2020-activity-sharing2/</guid>
      <description>
        
        
        &lt;p&gt;今年暑假期间我参加了开源软件供应链点亮计划—暑期 2020 的活动，在这个活动中，我主要参加了 Apache SkyWalking 的 Python Agent 的开发，最终项目顺利结项并获得了”最具潜力奖“，今天我想分享一下我参与这个活动以及开源社区的感受与收获。&lt;/p&gt;
&lt;h2 id=&#34;缘起&#34;&gt;缘起&lt;/h2&gt;
&lt;p&gt;其实我在参加暑期 2020 活动之前就听说过 SkyWalking 了。我研究生的主要研究方向是微服务和云原生，组里的学长们之前就在使用 SkyWalking 进行一些研究工作，也是通过他们，我了解到了 OpenTracing, SkyWalking 等与微服务相关的 Tracing 工具以及 APM 等，当时我就在想如果有机会可以深度参加这些开源项目就好了。 巧的是，也正是在差不多的时候，本科的一个学长发给了我暑期 2020 活动的链接，我在其中惊喜的发现了 SkyWalking 项目。&lt;/p&gt;
&lt;p&gt;虽然说想要参与 SkyWalking 的开发，但是真的有了机会我却有一些不自信——这可是 Star 上万的 Apache 顶级项目。万幸的是在暑期 2020 活动中，每一个社区都提供了很多题目以供选择，想参与的同学可以提前对要做的事情有所了解，并可以提前做一些准备。我当时也仔细地浏览了项目列表，最终决定申请为 Python Agent 支持 Flask 或 Django 埋点的功能。当时主要考虑的是，我对 Python 语言比较熟悉，同时也有使用 Flask 等 web 框架进行开发的经验，我认为应该可以完成项目要求。为了能让心里更有底一些，我阅读了 Python Agent 的源码，写下了对项目需要做的工作的理解，并向项目的导师柯振旭发送了自荐邮件，最终被选中去完成这个项目。&lt;/p&gt;
&lt;h2 id=&#34;过程&#34;&gt;过程&lt;/h2&gt;
&lt;p&gt;被选中后我很激动，也把这份激动化作了参与开源的动力。我在进一步阅读源码，搭建本地环境后，用了三周左右的时间完成了 Django 项目的埋点插件的开发，毕竟我选择的项目是一个低难度的项目，而我在 Python web 方面也有一些经验。在这之后，我的导师和我进行了沟通，在我表达了想要继续做贡献的意愿之后，他给我建议了一些可以进一步进行贡献的方向，我也就继续参与 Python Agent 的开发。接下来，我陆续完成了 PyMongo 埋点插件, 插件版本检查机制, 支持使用 kafka 协议进行数据上报等功能。在提交了暑期 2020 活动的结项申请书后，我又继续参与了在端到端测试中增加对百分位数的验证等功能。&lt;/p&gt;
&lt;p&gt;在整个过程中，我遇到过很多问题，包括对问题认识不够清晰，功能的设计不够完善等等，但是通过与导师的讨论以及 Code Review，这些问题最终都迎刃而解了。此外他还经常会和我交流项目进一步发展方向，并给我以鼓励和肯定，在这里我想特别感谢我的导师在整个项目过程中给我的各种帮助。&lt;/p&gt;
&lt;h2 id=&#34;收获&#34;&gt;收获&lt;/h2&gt;
&lt;p&gt;参加暑期 2020 的活动带给我了很多收获，主要有以下几点：&lt;/p&gt;
&lt;p&gt;第一是让我真正参与到了开源项目中。在之前我只向在项目代码或文档中发现的 typo 发起过一些 Pull Request，但是暑期 2020 活动通过列出项目 ＋ 导师指导的方式，明确了所要做的事情，并提供了相应的指导，降低了参与开源的门槛，使得我们学生可以参与到项目的开发中来。&lt;/p&gt;
&lt;p&gt;第二是对我的专业研究方向也有很多启发，我的研究方向就是微服务与云原生相关，通过参与到 SkyWalking 的开发中使得我可以更好地理解研究问题中的一些概念，也让我更得心应手得使用 SkyWalking 来解决一些实际的问题。&lt;/p&gt;
&lt;p&gt;第三是通过参与 SkyWalking Python Agent 以及其他部分的开发，我的贡献得到了社区的承认，并在最近被邀请作为 Committer 加入了社区，这对我而言是很高的认可，也提升了我的自信心。&lt;/p&gt;
&lt;p&gt;​	&lt;img src=&#34;committer.png&#34; alt=&#34;committer&#34;&gt;&lt;/p&gt;
&lt;p&gt;第四点就是我通过这个活动认识了不少新朋友，同时也开拓了我的视野，使得我对于开源项目与开源社区有了很多新的认识。&lt;/p&gt;
&lt;h2 id=&#34;建议&#34;&gt;建议&lt;/h2&gt;
&lt;p&gt;最后同样是我对想要参与开源社区，想要参与此类活动的同学们的一些建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;虽然奖金很吸引人，但是还是希望大家能抱着长期为项目进行贡献的心态来参与开源项目，以这样的心态参与开源可以让你更好地理解开源社区的运作方式，也可以让你更有机会参与完成激动人心的功能，你在一个东西上付出的时间精力越多，你能收获的往往也越多。&lt;/li&gt;
&lt;li&gt;在申请项目的时候，可以提前阅读一下相关功能的源码，并结合自己的思考去写一份清晰明了的 proposal ，这样可以帮助你在申请人中脱颖而出。&lt;/li&gt;
&lt;li&gt;在开始着手去完成一个功能之前，首先理清思路，并和自己的导师或了解这一部分的人进行沟通与确认，从而尽量避免在错误的方向上浪费太多时间。&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 暑期2020活动心得分享</title>
      <link>/zh/2020-12-19-summer2020-activity-sharing/</link>
      <pubDate>Sat, 19 Dec 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-12-19-summer2020-activity-sharing/</guid>
      <description>
        
        
        &lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;我是一个热爱编程、热爱技术的人，⼀直以来都向往着能参与到开源项⽬中锻炼⾃⼰，但当我面对庞大而复杂的项目代码时，却感到手足无措，不知该从何开始。⽽此次的“开源软件供应链点亮计划-暑期2020”活动则正好提供了这样⼀个机会：清晰的任务要求、开源社区成员作为导师提供指导以及一笔丰厚的奖金，让我顺利地踏上了开源这条道路。&lt;/p&gt;
&lt;h2 id=&#34;回顾&#34;&gt;回顾&lt;/h2&gt;
&lt;p&gt;在“暑期2020”活动的这两个多月里，我为 SkyWalking 的命令行工具实现了一个 dashboard，此外在阅读项目源码的过程中，还发现并修复了几个 bug。到活动结束时，我共提交了11个 PR，贡献了两千多行改动，对 SkyWalking CLI 项目的贡献数量排名第二，还获得了“最具潜力奖”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;award.png&#34; alt=&#34;award&#34;&gt;&lt;/p&gt;
&lt;p&gt;我觉得之所以能够如此顺利地完成这个项⽬主要有两个原因。一方面，我选择的 SkyWalking CLI 项⽬当时最新的版本号为0.3.0，还处于起步阶段，代码量相对较少，⽽且项⽬结构非常清晰，文档也较为详细，这对于我理解整个项⽬⾮常有帮助，从⽽能够更快地上⼿。另一方面，我的项目导师非常认真负责，每次我遇到问题，导师都会及时地为我解答，然后我提交的 PR 也能够很快地被 review。⽽且导师不时会给予我肯定的评论与⿎励，这极⼤地提⾼了我的成就感，让我更加积极地投⼊到下⼀阶段的⼯作，形成⼀个正向的循环。&lt;/p&gt;
&lt;h2 id=&#34;收获&#34;&gt;收获&lt;/h2&gt;
&lt;p&gt;回顾整个参与过程，觉得自己收获颇多：&lt;/p&gt;
&lt;p&gt;首先，我学习到了很多可能在学校里接触不到的新技术，了解了开源项目是如何进行协作，开源社区是如何运转治理的，以及开源文化、Apache way 等知识，仿佛进入了一个崭新而精彩的世界。&lt;/p&gt;
&lt;p&gt;其次，我的编程能力得到了锻炼。因为开源项目对于代码的质量有较高的要求，因此我会在编程时有意识地遵守相关的规范，培养良好的编码习惯。然后在导师的 code review 中也学习到了一些编程技巧。&lt;/p&gt;
&lt;p&gt;此外，参与开源为我的科研带来了不少灵感。因为我的研究方向是智能软件工程，旨在将人工智能技术应用在软件工程的各个环节中，这需要我在实践中发现实际问题。而开源则提供了这样一个窗口，让我足不出户即可参与到软件项目的设计、开发、测试和发布等环节。&lt;/p&gt;
&lt;p&gt;最后也是本次活动最大的一个收获，我的贡献得到了社区的认可，被提名成为了 SkyWalking 社区的第一位学生 committer。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;committer.png&#34; alt=&#34;committer&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;建议&#34;&gt;建议&lt;/h2&gt;
&lt;p&gt;最后，对于将来想要参加此类活动的同学，附上我的一些建议：&lt;/p&gt;
&lt;p&gt;第一，选择活跃、知名的社区。社区对你的影响将是极其深远的，好的社区意味着成熟的协作流程、良好的氛围、严谨的代码规范，以及有更大几率遇到优秀的导师，这些对于你今后在开源方面的发展都是非常有帮助的。&lt;/p&gt;
&lt;p&gt;第二，以兴趣为导向来选择项目，同时要敢于走出舒适区。我最初在选择项目时，初步确定了两个，一个是低难度的 Python 项目，另一个是中等难度的 Go 项目。当时我很纠结：因为我对 Python 语言比较熟悉，选择一个低难度的项目是比较稳妥的，但是项目的代码我看的并不是很懂，具体要怎么做我完全没有头绪；而 Go 项目是一个命令行工具，我对这个比较感兴趣，且有一个大致的思路，但是我对 Go 语言并不是很熟悉，实践经验为零。最后凭借清晰具体的 proposal 我成功申请到了 Go 项目并顺利地完成了，还在实践中快速掌握了一门新的编程语言。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;step_out_of_your_comfort_zone.png&#34; alt=&#34;step_out_of_your_comfort_zone&#34;&gt;&lt;/p&gt;
&lt;p&gt;这次的“暑期2020”活动虽已圆满结束，但我的开源之路才刚刚开始。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking报警发送到钉钉群</title>
      <link>/zh/2020-12-13-skywalking-alarm/</link>
      <pubDate>Sun, 13 Dec 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-12-13-skywalking-alarm/</guid>
      <description>
        
        
        &lt;p&gt;这篇文章暂时不讲告警策略, 直接看默认情况下激活的告警目标以及钉钉上的告警效果&lt;/p&gt;
&lt;p&gt;SkyWalking内置了很多默认的告警策略, 然后根据告警策略生成告警目标, 我们可以很容易的在界面上看到&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;image-20201213163408221.png&#34; alt=&#34;image-20201213163408221&#34;&gt;&lt;/p&gt;
&lt;p&gt;当我们想去让这些告警目标通知到我们时, 由于SkyWalking目前版本(8.3)已经自带了, 只需要简单配置一下即可&lt;/p&gt;
&lt;p&gt;我们先来钉钉群中创建机器人并勾选加签&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;image-20201213164116760.png&#34; alt=&#34;image-20201213164116760&#34;&gt;&lt;/p&gt;
&lt;p&gt;然后再修改告警部分的配置文件, 如果你是默认的配置文件(就像我一样), 你可以直接执行以下命令, 反之你也可以手动修改configs/alarm-settings.yml文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tee &amp;lt;your_skywalking_path&amp;gt;/configs/alarm-settings.yml &amp;lt;&amp;lt;-&#39;EOF&#39;
dingtalkHooks:
  textTemplate: |-
    {
      &amp;quot;msgtype&amp;quot;: &amp;quot;text&amp;quot;,
      &amp;quot;text&amp;quot;: {
        &amp;quot;content&amp;quot;: &amp;quot;Apache SkyWalking Alarm: \n %s.&amp;quot;
      }
    }
  webhooks:
    - url: https://oapi.dingtalk.com/robot/send?access_token=&amp;lt;access_token&amp;gt;
      secret: &amp;lt;加签值&amp;gt;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最终效果如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;image-20201213164145494.png&#34; alt=&#34;image-20201213164145494&#34;&gt;&lt;/p&gt;
&lt;p&gt;参考文档:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md&#34;&gt;https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/uKPlK&#34;&gt;https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/uKPlK&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;谢谢观看, 后续我会在SkyWalking告警这块写更多实战文章&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 使用 SkyWalking 和 Envoy 访问日志服务对服务网格进行观察</title>
      <link>/zh/observe-service-mesh-with-skywalking-and-envoy-access-log-service/</link>
      <pubDate>Thu, 03 Dec 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/observe-service-mesh-with-skywalking-and-envoy-access-log-service/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/canyonhorseshoe.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如果你正在寻找在 Mixer 方案以外观察服务网格的更优解，本文正符合你的需要。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache Skywalking&lt;/a&gt;&lt;/strong&gt;︰特别为微服务、云原生和容器化（Docker、Kubernetes、Mesos）架构而设计的 APM（应用性能监控）系统。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.envoyproxy.io/docs/envoy/latest/api-v2/service/accesslog/v2/als.proto&#34;&gt;Envoy 访问日志服务&lt;/a&gt;&lt;/strong&gt;︰访问日志服务（ALS）是 Envoy 的扩展组件，会将所有通过 Envoy 的请求的详细访问日志发送出来。&lt;/p&gt;
&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;Apache SkyWalking 一直通过 Istio Mixer 的适配器，支持服务网格的可观察性。不过自从 v1.5 版本，由于 Mixer 在大型集群中差强人意的表现，Istio 开始弃用 Mixer。Mixer 的功能现已迁至 Envoy 代理，并获 Istio 1.7 版本支持。&lt;/p&gt;
&lt;p&gt;在去年的中国 &lt;a href=&#34;https://kccncosschn19eng.sched.com/event/NroB/observability-in-service-mesh-powered-by-envoy-and-apache-skywalking-sheng-wu-lizan-zhou-tetrate&#34;&gt;KubeCon&lt;/a&gt; 中，&lt;a href=&#34;https://github.com/wu-sheng&#34;&gt;吴晟&lt;/a&gt;和&lt;a href=&#34;https://github.com/lizan&#34;&gt;周礼赞&lt;/a&gt;基于 Apache SkyWalking 和 Envoy ALS，发布了新的方案：不再受制于 Mixer  带来的性能影响，也同时保持服务网格中同等的可观察性。这个方案最初是由吴晟、&lt;a href=&#34;https://github.com/hanahmily&#34;&gt;高洪涛&lt;/a&gt;、周礼赞和 &lt;a href=&#34;https://github.com/dio&#34;&gt;Dhi Aurrahman&lt;/a&gt; 在 Tetrate.io 实现的。&lt;/p&gt;
&lt;p&gt;如果你正在寻找在 Mixer 方案之外，为你的服务网格进行观察的最优解，本文正是你当前所需的。在这个教程中，我们会解释此方案的运作逻辑，并将它实践到 bookinfo 应用上。&lt;/p&gt;
&lt;h3 id=&#34;运作逻辑&#34;&gt;运作逻辑&lt;/h3&gt;
&lt;p&gt;从可观察性的角度来说，Envoy 一般有两种部署模式︰Sidecar 和路由模式。 Envoy 代理可以代表多项服务（见下图之 1），或者当它作为 Sidecar 时，一般是代表接收和发送请求的单项服务（下图之 2 和 3）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-2.25.17-PM.png&#34; alt=&#34;Envoy 作为前端代理和 Sidecar 的部署实例&#34;&gt;&lt;/p&gt;
&lt;p&gt;在两种模式中，ALS 发放的日志都会带有一个节点标记符。该标记符在路由模式时，以 &lt;code&gt;router~&lt;/code&gt; （或 &lt;code&gt;ingress~&lt;/code&gt;）开头，而在 Sidecar 代理模式时，则以 &lt;code&gt;sidecar~&lt;/code&gt; 开头。&lt;/p&gt;
&lt;p&gt;除了节点标记符之外，这个方案［1］所采用的访问日志也有几个值得一提的字段︰&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;downstream_direct_remote_address&lt;/strong&gt;︰此字段是下游的&lt;strong&gt;直接远程地址&lt;/strong&gt;，用作接收来自用户的请求。&lt;strong&gt;注意&lt;/strong&gt;︰它永远是对端实体的地址，即使远程地址是从 &lt;code&gt;x-forwarded-for header&lt;/code&gt;、代理协议等推断出来的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;downstream_remote_address&lt;/strong&gt;︰远程或原始地址，用作接收来自用户的请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;downstream_local_address&lt;/strong&gt;︰本地或目标地址，用作接收来自用户的请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;upstream_remote_address&lt;/strong&gt;︰上游的远程或目标地址，用作处理本次交换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;upstream_local_address&lt;/strong&gt;︰上游的本地或原始地址，用作处理本次交换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;upstream_cluster&lt;/strong&gt;︰&lt;strong&gt;upstream_remote_address&lt;/strong&gt; 所属的上游集群。&lt;/p&gt;
&lt;p&gt;我们会在下面详细讲解各个字段。&lt;/p&gt;
&lt;h3 id=&#34;sidecar&#34;&gt;Sidecar&lt;/h3&gt;
&lt;p&gt;当 Envoy 作为 Sidecar 的时候，会搭配服务一起部署，并代理来往服务的传入或传出请求。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代理传入请求&lt;/strong&gt;︰在此情况下，Envoy 会作为服务器端的 Sidecar，以 &lt;code&gt;inbound|portNumber|portName|Hostname[or]SidecarScopeID&lt;/code&gt; 格式设定 &lt;code&gt;upstream_cluster&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-2.37.49-PM.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;SkyWalking 分析器会检查 &lt;code&gt;downstream_remote_address&lt;/code&gt; 是否能够找到对应的 Kubernetes 服务。&lt;/p&gt;
&lt;p&gt;如果在此 IP（和端口）中有一个服务（例如服务 B）正在运行，那我们就会建立起服务对服务的关系（即服务 B → 服务 A），帮助建立拓扑。再配合访问日志中的 &lt;code&gt;start_time&lt;/code&gt; 和 &lt;code&gt;duration&lt;/code&gt; 两个字段，我们就可以获得延迟的指标数据了。&lt;/p&gt;
&lt;p&gt;如果没有任何服务可以和 &lt;code&gt;downstream_remote_address&lt;/code&gt; 相对应，那请求就有可能来自网格以外的服务。由于 SkyWalking 无法识别请求的服务来源，在没有源服务的情况下，它简单地根据&lt;a href=&#34;https://wu-sheng.github.io/STAM/&#34;&gt;拓扑分析方法&lt;/a&gt;生成数据。拓扑依然可以准确地建立，而从服务器端侦测出来的指标数据也依然是正确的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代理传出请求&lt;/strong&gt;︰在此情况下，Envoy 会作为客户端的 Sidecar，以 &lt;code&gt;outbound|&amp;lt;port&amp;gt;|&amp;lt;subset&amp;gt;|&amp;lt;serviceFQDN&amp;gt;&lt;/code&gt; 格式设定 &lt;code&gt;upstream_cluster&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog//2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-2.43.16-PM.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;客户端的侦测相对来说比代理传入请求容易。如果 &lt;code&gt;upstream_remote_address&lt;/code&gt; 是另一个 Sidecar 或代理的话，我们只需要获得它相应的服务名称，便可生成拓扑和指标数据。否则，我们没有办法理解它，只能把它当作 UNKNOWN 服务。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;代理角色&#34;&gt;代理角色&lt;/h3&gt;
&lt;p&gt;当 Envoy 被部署为前端代理时，它是独立的服务，并不会像 Sidecar 一样，代表任何其他的服务。所以，我们可以建立客户端以及服务器端的指标数据。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-2.46.56-PM.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;演示范例&#34;&gt;演示范例&lt;/h2&gt;
&lt;p&gt;在本章，我们会使用典型的 bookinfo 应用，来演示 Apache SkyWalking 8.3.0+ （截至 2020 年 11 月 30 日的最新版本）如何与 Envoy ALS 合作，联手观察服务网格。&lt;/p&gt;
&lt;h3 id=&#34;安装-kubernetes&#34;&gt;安装 Kubernetes&lt;/h3&gt;
&lt;p&gt;在 Kubernetes 和虚拟机器（VM）的环境下，SkyWalking 8.3.0 均支持 Envoy ALS 的方案。在本教程中，我们只会演示在 Kubernetes 的情境，至于 VM 方案，请耐心期待我们下一篇文章。所以在进行下一步之前，我们需要先安装 Kubernetes。&lt;/p&gt;
&lt;p&gt;在本教程中，我们会使用 &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;Minikube&lt;/a&gt; 工具来快速设立本地的 Kubernetes（v1.17 版本）集群用作测试。要运行所有必要组件，包括 bookinfo 应用、SkyWalking OAP 和 WebUI，集群需要动用至少 4GB 内存和 2 个 CPU 的核心。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
minikube start --memory&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; --cpus&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，运行 &lt;code&gt;kubectl get pods --namespace=kube-system --watch&lt;/code&gt;，检查所有 Kubernetes 的组件是否已准备好。如果还没，在进行下一步前，请耐心等待准备就绪。&lt;/p&gt;
&lt;h3 id=&#34;安装-istio&#34;&gt;安装 Istio&lt;/h3&gt;
&lt;p&gt;Istio 为配置 Envoy 代理和实现访问日志服务提供了一个非常方便的方案。内建的配置设定档为我们省去了不少手动的操作。所以，考虑到演示的目的，我们会在本教程全程使用 Istio。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;ISTIO_VERSION&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;1.7.1

curl -L https://istio.io/downloadIstio | sh - 

sudo mv &lt;span style=&#34;color:#008080&#34;&gt;$PWD&lt;/span&gt;/istio-&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/bin/istioctl /usr/local/bin/

istioctl  install --set &lt;span style=&#34;color:#008080&#34;&gt;profile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo

kubectl label namespace default istio-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，运行 &lt;code&gt;kubectl get pods --namespace=istio-system --watch&lt;/code&gt;，检查 Istio 的所有组件是否已准备好。如果还没，在进行下一步前，请耐心等待准备就绪。&lt;/p&gt;
&lt;h3 id=&#34;启动访问日志服务&#34;&gt;启动访问日志服务&lt;/h3&gt;
&lt;p&gt;演示的设定档没有预设启动 ALS，我们需要重新配置才能够启动 ALS。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
istioctl  manifest install &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set meshConfig.enableEnvoyAccessLogService&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set meshConfig.defaultConfig.envoyAccessLogService.address&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking-oap.istio-system:11800
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;范例指令 &lt;code&gt;--set meshConfig.enableEnvoyAccessLogService=true&lt;/code&gt; 会在网格中启动访问日志服务。正如之前提到，ALS 本质上是一个会发放请求日志的 gRPC 服务。配置 &lt;code&gt;meshConfig.defaultConfig.envoyAccessLogService.address=skywalking-oap.istio-system:11800&lt;/code&gt; 会告诉这个gRPC 服务往哪里发送日志，这里是往 &lt;code&gt;skywalking-oap.istio-system:11800&lt;/code&gt; 发送，稍后我们会部署 SkyWalking ALS 接收器到这个地址。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;︰&lt;/p&gt;
&lt;p&gt;你也可以在安装 Istio 时启动 ALS，那就不需要在安装后重新启动 Istio︰&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
istioctl install --set &lt;span style=&#34;color:#008080&#34;&gt;profile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
               --set meshConfig.enableEnvoyAccessLogService&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
               --set meshConfig.defaultConfig.envoyAccessLogService.address&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;skywalking-oap.istio-system:11800

kubectl label namespace default istio-injection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;部署-apache-skywalking&#34;&gt;部署 Apache SkyWalking&lt;/h3&gt;
&lt;p&gt;SkyWalking 社区提供了 Helm Chart ，让你更轻易地在 Kubernetes 中部署 SkyWalking 以及其依赖服务。 Helm Chart 可以在 &lt;a href=&#34;https://github.com/apache/skywalking-kubernetes&#34;&gt;GitHub 仓库&lt;/a&gt;找到。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Install Helm&lt;/span&gt;

curl -sSLO https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz

sudo tar xz -C /usr/local/bin --strip-components&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; linux-amd64/helm -f helm-v3.0.0-linux-amd64.tar.gz

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Clone SkyWalking Helm Chart&lt;/span&gt;

git clone https://github.com/apache/skywalking-kubernetes

&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; skywalking-kubernetes/chart

git reset --hard dd749f25913830c47a97430618cefc4167612e75

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Update dependencies&lt;/span&gt;

helm dep up skywalking

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Deploy SkyWalking&lt;/span&gt;

helm -n istio-system install skywalking skywalking &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.storageType&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set ui.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;8.3.0 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.image.tag&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;8.3.0-es7 &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.replicas&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.env.SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;k8s-mesh &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.env.JAVA_OPTS&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;-Dmode=&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set oap.envoy.als.enabled&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;
        --set elasticsearch.enabled&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们在 &lt;code&gt;istio-system&lt;/code&gt; 的命名空间内部署 SkyWalking，使 SkyWalking OAP 服务可以使用地址 &lt;code&gt;skywalking-oap.istio-system:11800&lt;/code&gt; 访问，在上一步中，我们曾告诉过 ALS 应往此处发放它们的日志。&lt;/p&gt;
&lt;p&gt;我们也在 SkyWalking OAP 中启动 ALS 分析器︰&lt;code&gt;oap.env.SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS=k8s-mesh&lt;/code&gt;。分析器会对访问日志进行分析，并解析日志中的 IP 地址和 Kubernetes 中的真实服务名称，以建立拓扑。&lt;/p&gt;
&lt;p&gt;为了从 Kubernetes 集群处获取元数据（例如 Pod IP 和服务名称），以识别相应的 IP 地址，我们还会设定 &lt;code&gt;oap.envoy.als.enabled=true&lt;/code&gt;，用来申请一个对元数据有访问权的 &lt;code&gt;ClusterRole&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;POD_NAME&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$(&lt;/span&gt;kubectl get pods -A -l &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;app=skywalking,release=skywalking,component=ui&amp;#34;&lt;/span&gt; -o name&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#0086b3&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;$POD_NAME&lt;/span&gt;

kubectl -n istio-system port-forward &lt;span style=&#34;color:#008080&#34;&gt;$POD_NAME&lt;/span&gt; 8080:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在到你的浏览器上访问 &lt;a href=&#34;http://localhost:8080/&#34;&gt;http://localhost:8080&lt;/a&gt;。你应该会看到 SkyWalking 的 Dashboard。 Dashboard 现在应该是空的，但稍后部署应用和生成流量后，它就会被填满。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-3.01.03-PM.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;部署-bookinfo-应用&#34;&gt;部署 Bookinfo 应用&lt;/h3&gt;
&lt;p&gt;运行︰&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;ISTIO_VERSION&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;1.7.1

kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/platform/kube/bookinfo.yaml

kubectl apply -f https://raw.githubusercontent.com/istio/istio/&lt;span style=&#34;color:#008080&#34;&gt;$ISTIO_VERSION&lt;/span&gt;/samples/bookinfo/networking/bookinfo-gateway.yaml

kubectl &lt;span style=&#34;color:#0086b3&#34;&gt;wait&lt;/span&gt; --for&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;condition&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;Ready pods --all --timeout&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;1200s

minikube tunnel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在到你的浏览器上进入 &lt;a href=&#34;http://localhost/productpage&#34;&gt;http://localhost/productpage&lt;/a&gt;。你应该会看到典型的 bookinfo 应用画面。重新整理该页面几次，以生成足够的访问日志。&lt;/p&gt;
&lt;h3 id=&#34;完成了&#34;&gt;完成了！&lt;/h3&gt;
&lt;p&gt;这样做，你就成功完成设置了！再查看 SkyWalking 的 WebUI，你应该会看到 bookinfo 应用的拓扑，以及它每一个单独服务的指标数据。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-3.05.24-PM.png&#34; alt=&#34;&#34;&gt;
&lt;img src=&#34;../../blog/2020-12-03-obs-service-mesh-with-sw-and-als/Screen-Shot-2020-12-02-at-3.11.55-PM.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;疑难解答&#34;&gt;疑难解答&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;检查所有 pod 的状态︰&lt;code&gt;kubectl get pods -A&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;SkyWalking OAP 的日志︰&lt;code&gt;kubectl -n istio-system logs -f $(kubectl get pod -A -l &amp;quot;app=skywalking,release=skywalking,component=oap&amp;quot; -o name)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;SkyWalking WebUI 的日志︰&lt;code&gt;kubectl -n istio-system logs -f $(kubectl get pod -A -l &amp;quot;app=skywalking,release=skywalking,component=ui&amp;quot; -o name)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;确保 WebUI 右下方的时区设定在 &lt;code&gt;UTC +0&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;自定义服务器名称&#34;&gt;自定义服务器名称&lt;/h2&gt;
&lt;p&gt;SkyWalking 社区在 ALS 方案的 8.3.0 版本中，作出了许多改善。你现在可以在映射 IP 地址时，决定如何用 &lt;code&gt;service&lt;/code&gt; 和 &lt;code&gt;pod&lt;/code&gt; 变量去自定义服务器的名称。例如，将 &lt;code&gt;K8S_SERVICE_NAME_RULE&lt;/code&gt; 设置为 &lt;code&gt;${service.metadata.name}-${pod.metadata.labels.version}&lt;/code&gt;，就可以使服务名称带上版本的标签，类似 &lt;code&gt;reviews-v1&lt;/code&gt;、&lt;code&gt;reviews-v2&lt;/code&gt; 和 &lt;code&gt;reviews- v3&lt;/code&gt;，而不再是单个服务 &lt;code&gt;review&lt;/code&gt;［2］。&lt;/p&gt;
&lt;h2 id=&#34;在-vm-上使用-als&#34;&gt;在 VM 上使用 ALS&lt;/h2&gt;
&lt;p&gt;Kubernetes 很受欢迎，可是 VM 呢？正如我们之前所说，为了替 IP 找到对应的服务，SkyWalking 需要对 Kubernetes 集群有访问权，以获得服务的元数据和 Pod 的 IP。可是在 VM 环境中，我们并没有来源去收集这些元数据。&lt;/p&gt;
&lt;p&gt;在下一篇文章，我们会介绍另外一个 ALS 分析器，它是建立于 Envoy 的元数据交换机制。有了这个分析器，你就可以在 VM 环境中观察服务网格了。万勿错过！&lt;/p&gt;
&lt;p&gt;如果你希望在 ALS 方案或是混合式网格可观察性上获得商业支持，&lt;a href=&#34;https://www.tetrate.io/tetrate-service-bridge/&#34;&gt;TSB&lt;/a&gt; 会是一个好选项。&lt;/p&gt;
&lt;p&gt;额外资源&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KubeCon 2019 的录影&lt;a href=&#34;https://www.youtube.com/watch?v=tERm39ju9ew&#34;&gt;视频&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;在&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;官方网站&lt;/a&gt;上获得更多有关 SkyWalking 的最新消息吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如有任何问题或反馈，发送邮件至 &lt;a href=&#34;mailto:learn@tetrate.io&#34;&gt;learn@tetrate.io&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Apache SkyWalking 创始人吴晟和 SkyWalking 的核心贡献者柯振旭都是 Tetrate 的工程师。 Tetrate 的内容创造者编辑与贡献于本文章。 Tetrate 帮助企业采用开源服务网格工具，包括 Istio、Envoy 和 Apache SkyWalking，让它们轻松管理微服务，在任何架构上运行服务网格，以至现代化他们的应用。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;［1］&lt;a href=&#34;https://github.com/envoyproxy/envoy/blob/549164c42cae84b59154ca4c36009e408aa10b52/generated_api_shadow/envoy/data/accesslog/v2/accesslog.proto&#34;&gt;https://github.com/envoyproxy/envoy/blob/549164c42cae84b59154ca4c36009e408aa10b52/generated_api_shadow/envoy/data/accesslog/v2/accesslog.proto&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;［2］&lt;a href=&#34;https://github.com/apache/skywalking/pull/5722&#34;&gt;https://github.com/apache/skywalking/pull/5722&lt;/a&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: [视频] PyCon China 2020 - Python 微服务应用性能监控</title>
      <link>/zh/2020-11-30-pycon/</link>
      <pubDate>Mon, 30 Nov 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-11-30-pycon/</guid>
      <description>
        
        
        &lt;p&gt;Python 作为一门功能强大的编程语言，被广泛的应用于计算机行业之中； 在微服务系统架构盛行的今天，Python 以其丰富的软件生态和灵活的语言特性在服务端编程领域也占有重要的一席之地。  本次分享将阐述 Apache SkyWalking 在微服务架构中要解决的问题，展示如何使用 Apache SkyWalking 来近乎自动化地监控 Python 后端应用服务，并对 Apache SkyWalking 的 Python 语言探针的实现技术进行解读。&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1Ry4y167b6&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: [视频] SkyWalking DevCon 2020</title>
      <link>/zh/2020-11-23-devcon/</link>
      <pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-11-23-devcon/</guid>
      <description>
        
        
        &lt;h1 id=&#34;活动介绍&#34;&gt;活动介绍&lt;/h1&gt;
&lt;p&gt;Apache SkyWalking 2020 开发者线下活动，社区创始人，PMC成员和Committer会亲临现场，和大家交流和分享项目中的使用经验。
以及邀请Apache Local Community 北京的成员一起分享Apache文化和Apache之道。&lt;/p&gt;
&lt;h1 id=&#34;日程安排&#34;&gt;日程安排&lt;/h1&gt;
&lt;h2 id=&#34;开场演讲&#34;&gt;开场演讲&lt;/h2&gt;
&lt;p&gt;09：30-09：50   SkyWalking&amp;rsquo;s 2019-2020 and beyond&lt;/p&gt;
&lt;p&gt;吴晟，Tetrate.io创始工程师，Apache SkyWalking创始人&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1ay4y16755&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;


&lt;hr&gt;
&lt;h2 id=&#34;上午&#34;&gt;上午&lt;/h2&gt;
&lt;p&gt;09：55-10：30   贝壳全链路跟踪实践&lt;/p&gt;
&lt;p&gt;赵禹光，赵禹光，贝壳找房监控技术负责人，Apache SkyWalking PMC成员&lt;/p&gt;
&lt;p&gt;10：35-11：15   SkyWalking在百度爱番番部门实践&lt;/p&gt;
&lt;p&gt;刘嘉鹏，百度，SkyWalking contributor&lt;/p&gt;
&lt;p&gt;11：15-11：55   非计算机背景的同学如何贡献开源&lt;/p&gt;
&lt;p&gt;缘于一位本科在读的社会学系的同学的问题，这让我反思我们开源community的定位和Open的程度，于是，适兕从生产、分发、消费的软件供应的角度，根据涉及到的角色，然后再反观现代大学教育体系的专业，进一步对一个开源项目和community需要的专业背景多样性进行一个阐述和探究。并以ALC Beijing为例进行一个事例性的说明。&lt;/p&gt;
&lt;p&gt;适兕，开源布道师，ALC Beijing member，开源之道主创，开源社教育组成员。&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV12v411t7yt&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;


&lt;hr&gt;
&lt;h2 id=&#34;下午&#34;&gt;下午&lt;/h2&gt;
&lt;p&gt;13：30-14：10   如何从 Apache SkyWalking 社区学习 Apache Way&lt;/p&gt;
&lt;p&gt;温铭，支流科技联合创始人＆CEO，Apache APISIX 项目 VP， Apache SkyWalking Committer&lt;/p&gt;
&lt;p&gt;14：10-14：50   Apache SkyWalking 在小米公司的应用&lt;/p&gt;
&lt;p&gt;宋振东，小米公司小米信息技术部 skywalking 研发负责人&lt;/p&gt;
&lt;p&gt;14：50-15：30   Istio全生命周期监控&lt;/p&gt;
&lt;p&gt;高洪涛，Tetrate.io创始工程师，Apache SkyWalking PMC成员&lt;/p&gt;
&lt;p&gt;15：30-15：45   茶歇&lt;/p&gt;
&lt;p&gt;15：45-16：25  针对HikariCP数据库连接池的监控&lt;/p&gt;
&lt;p&gt;张鑫 Apache SkyWalking PMC 成员&lt;/p&gt;
&lt;p&gt;16：25-17：00   SkyWalking 与 Nginx 的优化实践&lt;/p&gt;
&lt;p&gt;王院生 深圳支流科技创始人兼 CTO，Apache APISIX 创始人 &amp;amp; PMC成员&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1xZ4y1G7D7&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: 亲临百人盛况的Apache SkyWalking 2020 DevCon，看见了什么？</title>
      <link>/zh/2020-11-21-what-do-we-see-at-the-apache-skywalking-2020-devcon-event/</link>
      <pubDate>Sat, 21 Nov 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-11-21-what-do-we-see-at-the-apache-skywalking-2020-devcon-event/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者: 赵禹光&lt;/li&gt;
&lt;li&gt;原文链接: &lt;a href=&#34;https://mp.weixin.qq.com/s/5wYCYiP8oKs7V6BR1lyKxg&#34;&gt;亲临百人盛况的Apache SkyWalking 2020 DevCon，看见了什么？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020 年 10 月 29 日&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;活动现场&#34;&gt;活动现场&lt;/h3&gt;
&lt;p&gt;2020年11月14日Apache SkyWalking 2020 DevCon由贝壳找房和tetrate赞助，Apache SkyWalking、云原生、Apache APISIX、Apache Pulsar 和 ALC Beijing 五大社区合作，在贝壳找房一年级会议室盛大举行，本次活动主要面对Apache SkyWalking的使用者、开发者和潜在用户。线上线下共有230多人报名。经统计，实际参加活动人数超过130人，近60%的人愿意抽出自己的休息时间，来交流学习Apache SkyWalking和开源文化。不难看见，在可预见的未来，中国的开源项目很快将进入下一个维度，那必定是更广的社区人员参与，更高技术知识体现，更强的线上稳定性和及时修复能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;hdsk.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;活动历程&#34;&gt;活动历程：&lt;/h3&gt;
&lt;h4 id=&#34;0930-0950-skywalkings-2019-2020-and-beyond&#34;&gt;09：30-09：50 SkyWalking&amp;rsquo;s 2019-2020 and beyond&lt;/h4&gt;
&lt;p&gt;吴晟老师本次分享：回顾2020年度SkyWalking发布的重要的新特性，出版的《Apache SkyWalking实战》图书，社区的进展，开源爱好者如何参与SkyWalking建设，和已知社区在主导的SkyWalking2021年孵化中的新特性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ws.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;0955-1030-贝壳全链路跟踪实践&#34;&gt;09：55-10：30 贝壳全链路跟踪实践&lt;/h4&gt;
&lt;p&gt;赵禹光老师（作者）本次分享：回顾了贝壳找房2018年至今，贝壳找房的全链路跟踪项目与SkyWalking的渊源，分享了SkyWalking在实践中遇到的问题，和解决方案。以及SkyWalking近10%的Committer都曾经或正在贝壳人店平台签中研发部，工作过的趣事。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;zyg.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1035-1115-刘嘉鹏老师分享-skywalking在百度爱番番部门实践&#34;&gt;10：35-11：15 刘嘉鹏老师分享 SkyWalking在百度爱番番部门实践&lt;/h4&gt;
&lt;p&gt;刘嘉鹏老师本次分享：回顾了百度爱番番部门在使用SkyWalking的发展历程&amp;amp;现状，CRM SAAS产品在近1年使用SkyWalking实践经验，以及如何参与SkyWalking的贡献，并成为的Apache Committer。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ljp.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1115-1155-适兕老师分享-非计算机背景的同学如何贡献开源&#34;&gt;11：15-11：55 适兕老师分享 非计算机背景的同学如何贡献开源&lt;/h4&gt;
&lt;p&gt;适兕是国内很有名的开源布道师，本次分享从生产、分发、消费的软件供应的角度，根据涉及到的角色，然后再反观现代大学教育体系的专业，进一步对一个开源项目和community需要的专业背景多样性进行一个阐述和探究。并以ALC Beijing为例进行一个事例性的说明，非计算机背景的同学如何贡献开源。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;js.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1330-1410-如何从-apache-skywalking-社区学习-apache-way&#34;&gt;13：30-14：10 如何从 Apache SkyWalking 社区学习 Apache Way&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;wm.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1410-1450-apache-skywalking-在小米公司的应用&#34;&gt;14：10-14：50 Apache SkyWalking 在小米公司的应用&lt;/h4&gt;
&lt;p&gt;宋振东老师是小米信息技术部分布式链路追踪系统研发负责人，分别以小米公司，业务开发、架构师、SRE、Leader和QA等多个视角，回顾了SkyWalking在小米公司的应用实践。从APM的产品选型到实际落地，对其他公司准备使用SkyWalking落地，非常有借鉴意义。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;szd.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1450-1530-istio全生命周期监控&#34;&gt;14：50-15：30 Istio全生命周期监控&lt;/h4&gt;
&lt;p&gt;高洪涛老师本次分享了SkyWalking和可观测云原生等非常前沿的知识布道，其中有，云原生在Logging、Metrics和Tracing的相关知识，Istio，K8S等方面的实践。对一些公司在前沿技术的落地，非常有借鉴意义。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ght.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1545-1625-针对hikaricp数据库连接池的监控&#34;&gt;15：45-16：25 针对HikariCP数据库连接池的监控&lt;/h4&gt;
&lt;p&gt;张鑫老师本次分享了，以一个SkyWalking无法Tracing的实际线上故障的故事出发，讲述如何定位，和补充SkyWalking插件的不足，并将最后的实践贡献到社区。对大家参与开源很有帮助。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;zx.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;1625-1700-skywalking-与-nginx-的优化实践&#34;&gt;16：25-17：00 SkyWalking 与 Nginx 的优化实践&lt;/h4&gt;
&lt;p&gt;王院生老师本次分享SkyWalking社区和APISIX社区合作，在Nginx插件的实践过程，对社区之间的如何开展合作，非常有借鉴意义，院生老师的工作&amp;amp;开源态度，很好的诠释Geek精神，也是我们互联网从业者需要学习恪守的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;wys.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;apache-skywalking-2020-devcon-讲师ppt&#34;&gt;Apache SkyWalking 2020 DevCon 讲师PPT&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/alc-beijing/alc-site/blob/master/content/images/What_do_we_see_at_the_Apache_SkyWalking_2020_DevCon_event/ppt&#34;&gt;Apache SkyWalking 2020 DevCon 讲师 PPT&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;skywalking-后续发展计划&#34;&gt;SkyWalking 后续发展计划&lt;/h3&gt;
&lt;p&gt;正如吴晟老师所说：No plan, open to the community，Apache SkyWalking是没有RoadMap。社区的后续发展，依赖于每个人在社区的贡献。与其期待，不如大胆设想，将自己的设计按照Apache Way贡献到SkyWalking，你就是下一个Apache SkyWalking Commiter，加入Member of SkyWalking大家庭，让社区因为你，而更加有活力。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 8.2.0 中的新特性: 浏览器端监控; 使用标签查询; 指标分析语言</title>
      <link>/zh/2020-10-29-skywalking8-2-release/</link>
      <pubDate>Thu, 29 Oct 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-10-29-skywalking8-2-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5gnaa2ij31lb0u0jum.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作者: 柯振旭, 吴晟, 高洪涛, Tevah Platt. tetrate.io&lt;/li&gt;
&lt;li&gt;原文链接: &lt;a href=&#34;https://www.tetrate.io/blog/whats-new-with-apache-skywalking-8-2-browser-monitoring-and-more/&#34;&gt;What&amp;rsquo;s new with Apache SkyWalking 8.2? Browser monitoring and more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020 年 10 月 29 日&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apache SkyWalking，一个可观测性平台，也是一个开源的应用性能监视器（APM）项目，今日宣布 8.2 发行版全面可用。该发行版拓展了核心功能，并将其监控边界拓展到浏览器端。&lt;/p&gt;
&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;
&lt;p&gt;SkyWalking 是一个观测平台和 APM 工具。它可以选择性的与 Service Mesh 协同工作，为微服务、云原生和基于容器的应用提供自动的指标。该项目是全球社区支持的 Apache 顶级项目，阿里巴巴、华为、腾讯、百度、字节跳动等许多公司都在使用。&lt;/p&gt;
&lt;h3 id=&#34;浏览器端监控&#34;&gt;浏览器端监控&lt;/h3&gt;
&lt;p&gt;APM 可以帮助 SRE 和工程团队诊断系统故障，也能在系统异常缓慢之前优化它。但它是否足以让用户总是满意呢？&lt;/p&gt;
&lt;p&gt;在 8.2.0 版本中， SkyWalking 将它的监控边界拓展到了浏览器端，比如 Chrome ，或者 Chrome 和后端服务之间的网络。这样，我们不仅可以像以前一样监控浏览器发送给后端服务的与请求，还能看到前端的渲染速度、错误日志等信息——这些信息是获取最终用户体验的最有效指标。（目前此功能尚未拓展到物联网设备中，但这项功能使得 SkyWalking 向着这个方向前进了一步）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5go0t43j30zk0m8tdb.jpg&#34; alt=&#34;SkyWalking 8.2.0 Browser Side Monitoring: Overview&#34;&gt;&lt;/p&gt;
&lt;p&gt;此外，SkyWalking浏览器监视也提供以下数据:
PV（page views，页面浏览量）， UV（unique visitors，独立访客数），浏览量前 N 的页面（Top N Page Views）等。这些数据可以为产品队伍优化他们的产品提供线索。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5gnpi0dj30zk0m843n.jpg&#34; alt=&#34;SkyWalking 8.2.0 Browser Side Monitoring: Pages&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;按标签-tag-查询链路数据&#34;&gt;按标签 (tag) 查询链路数据&lt;/h3&gt;
&lt;p&gt;在 SkyWalking 的 Span 数据模型中，已经有了许多被索引并可供用户查询的重要字段。但出于性能考虑，使用 Span 标签查询链路数据的功能直到现在才正式提供。在 SkyWalking 8.2.0 中，我们允许用户查询被特定标签标记的链路，这非常有用。SRE 工程师可以在生产环境中运行测试，将其打上仿真流量的标签，并稍后通过该标签查找它。&lt;/p&gt;
&lt;h3 id=&#34;指标分析语言&#34;&gt;指标分析语言&lt;/h3&gt;
&lt;p&gt;在 8.2.0 中，仪表系统提供了一项名为MAL（Meter Analysis Language，指标分析语言）的强大分析语言。该语言允许用户在 OAP 流系统中分析并聚合（aggregate）指标数据。
表达式的结果可以被 Agent 分析器或 OpenTelemetry/Prometheus 分析器获取。&lt;/p&gt;
&lt;h3 id=&#34;复合警报规则&#34;&gt;复合警报规则&lt;/h3&gt;
&lt;p&gt;警报是及时发现系统失效的有效方式。一个常见的问题是，为了避免错过任何可能的问题，我们通常会配置过多的触发器（triggers）。没有人喜欢半夜被警报叫醒，结果只是因为触发系统太敏感。这种警报很嘈杂并毫无帮助。&lt;/p&gt;
&lt;p&gt;在 8.2.0 版本中，用户选择可以配置考虑了多个度量维度的复合警报规则。使用复合报警规则，我们可以根据需要添加尽可能多的指标来更精确地判断是否存在真正的问题，或者只是一个偶发的小问题。&lt;/p&gt;
&lt;p&gt;一些常见的情况，如 &lt;code&gt;成功率 &amp;lt; 90% 但只有 1~2 个请求&lt;/code&gt;，现在可以通过复合规则解决，如&lt;code&gt;流量(即每分钟调用数) &amp;gt; n &amp;amp;&amp;amp; 成功率 &amp;lt; m%&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;其它值得注意的功能增强&#34;&gt;其它值得注意的功能增强&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;agent-toolkit SDK 公开了某些 API，供用户发送自定义指标。&lt;/li&gt;
&lt;li&gt;Agent &lt;code&gt;exclude_plgins&lt;/code&gt; 配置允许您排除某些插件（plugins）; &lt;code&gt;mount&lt;/code&gt; 配置使您能够加载一套新的插件。&lt;/li&gt;
&lt;li&gt;社区贡献了超过 10 个新 Agent 插件。&lt;/li&gt;
&lt;li&gt;报警系统原生支持发送消息到 Slack，企业微信，钉钉。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;附加资源&#34;&gt;附加资源&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;阅读更多关于&lt;a href=&#34;https://github.com/apache/skywalking/blob/v8.2.0/CHANGES.md&#34;&gt;SkyWalkng 8.2 发行版重点&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在&lt;a href=&#34;https://twitter.com/ASFSkyWalking&#34;&gt;推特&lt;/a&gt;上获取更多关于 SkyWalking 的更新。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;apache-skywalking-devcon-报名信息&#34;&gt;Apache SkyWalking DevCon 报名信息&lt;/h3&gt;
&lt;p&gt;Apache SkyWalking DevCon 2020 开始报名了。
2020 年 11 月 14 日，欢迎大家&lt;a href=&#34;https://www.huodongxing.com/event/3567284406200&#34;&gt;来线下参加活动和交流&lt;/a&gt;, 或者&lt;a href=&#34;https://www.itdks.com/Home/Act/apply?id=5392&amp;amp;mUid=57437&#34;&gt;报名观看线上直播&lt;/a&gt;。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: [视频] Apache SkyWalking Cloud on Kubernetes</title>
      <link>/zh/2020-10-25-coscon20-swck/</link>
      <pubDate>Sun, 25 Oct 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-10-25-coscon20-swck/</guid>
      <description>
        
        
        &lt;h3 id=&#34;高洪涛&#34;&gt;高洪涛&lt;/h3&gt;
&lt;p&gt;美国ServiceMesh服务商tetrate创始工程师。原华为软件开发云技术专家。目前为Apache SkyWalking核心贡献者，参与该开源项目在软件开发云的商业化进程。曾任职当当网系统架构师，开源达人，曾参与Apache ShardingSphere，Elastic-Job等知名开源项目。对分布式数据库，容器调度，微服务，ServicMesh等技术有深入的了解。&lt;/p&gt;
&lt;h3 id=&#34;议题简介&#34;&gt;议题简介&lt;/h3&gt;
&lt;p&gt;定制化Operator模式在面向Kubernetes的云化平台建构中变得越来越流行。Apache SkyWalking社区已经开始尝试使用Operator模式去构建基于Kubernetes平台的PaaS云组件。本次分享给将会给听众带来该项目的初衷，实现与未来演进等相关内容。分享的内容包含：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;项目动机与设计理念&lt;/li&gt;
&lt;li&gt;核心功能展示，包含SkyWalking核心组件的发布，更新与维护。&lt;/li&gt;
&lt;li&gt;观测ServiceMesh，包含于Istio的自动集成。&lt;/li&gt;
&lt;li&gt;目前的工作进展和对未来的规划。&lt;/li&gt;
&lt;/ol&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1ia411c7Hc&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: [视频] 云原生学院 - 后分布式追踪时代的性能问题定位——方法级性能剖析</title>
      <link>/zh/2020-08-13-cloud-native-academy/</link>
      <pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-08-13-cloud-native-academy/</guid>
      <description>
        
        
        &lt;h2 id=&#34;吴晟&#34;&gt;吴晟&lt;/h2&gt;
&lt;p&gt;吴晟，Apache 基金会会员，Apache SkyWalking 创始人、项目 VP 和 PMC 成员，Apache 孵化器 PMC 成员，Apache ShardingSphere PMC成员，Apache APISIX PMC 成员，Apache ECharts (incubating) 和Apache DolphinScheduler (incubating) 孵化器导师，Zipkin 成员和贡献者。&lt;/p&gt;
&lt;h2 id=&#34;分享大纲&#34;&gt;分享大纲&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;分布式追踪兴起的背景&lt;/li&gt;
&lt;li&gt;SkyWalking和其他分布式追踪的异同&lt;/li&gt;
&lt;li&gt;定位问题的流程和方法&lt;/li&gt;
&lt;li&gt;性能剖析的由来、用途和优势&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;听众收获&#34;&gt;听众收获&lt;/h2&gt;
&lt;p&gt;听众能够全面的了解分布式追踪的技术背景，和技术原理。以及为什么这些年，分布式追踪和基于分布式追踪的APM系统，Apache SkyWalking，得到了广泛的使用、集成，甚至云厂商的支持。同时，除了针对追踪数据，我们应该关注更多的是，如何利用其产生的监控数据，定位系统的性能问题。以及它有哪些短板，应该如何弥补。&lt;/p&gt;




&lt;div class=&#34;bilibili-container&#34;&gt;&lt;iframe id=&#34;biliplayer&#34; src=&#34;//player.bilibili.com/player.html?bvid=BV1D541187kC&amp;page=1&#34; scrolling=&#34;no&#34; border=&#34;0&#34; frameborder=&#34;no&#34; framespacing=&#34;0&#34; allowfullscreen=&#34;true&#34; loading=&#34;lazy&#34;&gt; &lt;/iframe&gt;&lt;/div&gt;



      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 为超大规模而生</title>
      <link>/zh/2020-08-11-observability-at-scale-skywalking-it-is/</link>
      <pubDate>Tue, 11 Aug 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-08-11-observability-at-scale-skywalking-it-is/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者：吴晟&lt;/li&gt;
&lt;li&gt;翻译：董旭 金蝶医疗&lt;/li&gt;
&lt;li&gt;原文链接：&lt;a href=&#34;https://www.tetrate.io/blog/observability-at-scale-skywalking-it-is/&#34;&gt;Tetrate.io blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SkyWalking做为Apache的顶级项目，是一个开源的APM和可观测性分析平台，它解决了21世纪日益庞大、分布式和异构的系统的问题。它是为应对当前系统管理所面临的困难而构建的：就像大海捞针，SkyWalking可以在服务依赖复杂且多语言环境下，获取服务对应的指标，以及完整而有意义的性能视图。&lt;/p&gt;
&lt;p&gt;SkyWalking是一个非常全面的平台，无论你的微服务是否在服务网格(Service Mesh)架构下，它都可以提供高性能且一致性的监控。&lt;/p&gt;
&lt;p&gt;让我们来看看，SkyWalking是如何解决大规模集群的可观测性问题，并从一个纯粹的链路跟踪系统，发展成为一个每天分析百亿级跟踪数据，功能丰富的可观测性平台。&lt;/p&gt;
&lt;h3 id=&#34;为超大规模而生&#34;&gt;为超大规模而生&lt;/h3&gt;
&lt;p&gt;SkyWalking的诞生，时间要追溯到2015年，当时它主要应用于监控顶级电信公司（例如：中国联通和中国移动）的第一代分布式核心系统。2013-2014年，这些电信公司计划用分布式系统取代传统的单体架构应用。从诞生那天开始，SkyWalking首要的设计目标，就是能够支持超大型分布式系统，并具有很好可扩展性。那么支撑超大规模系统要考虑什么呢？&lt;/p&gt;
&lt;h3 id=&#34;拉取vs推送&#34;&gt;拉取vs推送&lt;/h3&gt;
&lt;p&gt;与数据流向息息相关的：拉取模式和推送模式。Agent（客户端）收集数据并将其推送到后端，再对数据进一步分析，我们称之为“推送”模式。究竟应该使用拉取还是推送？这个话题已经争论已久。关键因素取决于可观测性系统的目标，即：在Agent端花最小的成本，使其适配不同类型的可观测性数据。&lt;/p&gt;
&lt;p&gt;Agent收集数据后，可以在短时间内发送出去。这样，我们就不必担心本地缓存压力过大。举一个典型的例子，任意服务都可以轻松地拥有数百个甚至数千个端点指标（如：HTTP的URI，gRPC的服务）。那么APM系统就必须具有分析这些数量庞大指标的能力。&lt;/p&gt;
&lt;p&gt;此外，度量指标并不是可观测性领域中的唯一关注点，链路跟踪和日志也很重要。在生产环境下，SkyWalking为了能提供100%采样率的跟踪能力，数据推送模式是唯一可行的解决方案。&lt;/p&gt;
&lt;p&gt;SkyWalking即便使用了推送模式，同时也可进行数据拉取。在最近的8.x的发版本中，SkyWalking支持从已经集成Prometheus的服务中获取终端用户的数据，避免重复工程建设，减少资源浪费。另外，比较常见的是基于MQ的传输构建拉取模式，Kafka消费者就是一个比较典型的例子。SkyWalking的Agent端使用推送模式，OAP服务器端使用拉取模式。&lt;/p&gt;
&lt;p&gt;结论：SkyWalking的推送模式是原生方式，但拉取式模式也适用于某些特殊场景。&lt;/p&gt;
&lt;h3 id=&#34;度量指标分析并不仅仅是数学统计&#34;&gt;度量指标分析并不仅仅是数学统计&lt;/h3&gt;
&lt;p&gt;度量指标依赖于数学理论和计算。Percentile（百分位数）是用于反映响应时间的长尾效应。服务具备合理的平均响应时间和成功率，说明服务的服务等级目标(SLO）很好。除此之外，分布式跟踪还为跟踪提供了详细的信息，以及可分析的高价值指标。&lt;/p&gt;
&lt;p&gt;运维团队（OPS）和系统稳定性（SRE）团队通过服务拓扑图，用来观察网络情况（当做NOC dashboard使用）、确认系统数据流。SkyWalking依靠trace（跟踪数据），使用&lt;a href=&#34;https://wu-sheng.github.io/STAM/&#34;&gt;STAM（Streaming Topology Analysis Method）&lt;/a&gt;方法进行分析拓扑结构。在服务网格环境下，使用ALS（Envoy Access Log Service）进行拓扑分析。节点（services）和线路（service relationships）的拓扑结构和度量指标数据，无法通过sdk轻而易举的拿到。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5dayj8mj31uy0u0184.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;为了解决端点度量指标收集的局限性，SkyWalking还要从跟踪数据中分析端点依赖关系，从而拿到链路上游、下游这些关键具体的信息。这些依赖关系和度量指标信息，有助于开发团队定位引起性能问题的边界，甚至代码块。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5dcuk7rj31v40u0gw4.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;预计算还是查询时计算&#34;&gt;预计算还是查询时计算？&lt;/h3&gt;
&lt;p&gt;相比查询时计算的灵活性，预计算可以提供更好、更稳定的性能，这在分析场景下尤为重要。回想一下我们的设计原则：SkyWalking是为了一个大规模的分布式系统而设计。查询时计算的使用范围非常有限，大多数度量计算都需要预先定义和预先计算。支持大数据集的关键是：在设计阶段，要减小数据集。预计算允许将原始数据合并到下游的聚合结果中，用于查询，甚至用于警报检查。&lt;/p&gt;
&lt;p&gt;使用SkyWalking的另一个重要因素是：指标的有效期，TTL（Time To Live）。由于采用了预先计算，查询提供了近似线性的高性能。这也帮助“查询系统”这类基础设施系统，提供更好的性能扩展。&lt;/p&gt;
&lt;p&gt;关于警报，使用查询时计算方案，也意味着警报查询需要基于查询引擎。但在这种情况下，随着数据集增加，查询性能会随之下降，其他指标查询也是一样的结果。&lt;/p&gt;
&lt;h3 id=&#34;目前使用案例&#34;&gt;目前使用案例&lt;/h3&gt;
&lt;p&gt;如今，SkyWalking在许多大型企业的超大规模分布式系统中使用，包括阿里巴巴、华为、腾讯、百度、中国通讯企业以及多家银行和保险公司。上线SkyWalking公司的流量，比银行和电信运营商这种传统公司还要大。&lt;/p&gt;
&lt;p&gt;在很多行业中，SkyWalking是被应用于超大型分布式系统各种场景下的一个可观测性平台：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;拉勾网&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking正在观测超过100个服务，500多个JVM实例&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking每天收集和分析40多亿个跟踪数据，用来分析性能，其中包括30万个端点和依赖关系的指标&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在整个群集中监控&amp;gt;50k流量/秒&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;永辉超市&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking每天分析至少100多亿（3B）的跟踪数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;其次，SkyWalking用较小的部署，每天分析2亿多个跟踪数据&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;百度&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking每天从1400多个pod中，从120多个服务收集1T以上的跟踪数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;随着更多服务的增加，规模会持续增大&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;贝壳找房(ke.com)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;很早就使用了SkyWalking，有两名成员已经成为PMC&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deployments每天收集160多亿个跟踪数据&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;阿里云效&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking每天收集和分析数十亿个span&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking使阿里云的45项服务和~300个实例保持稳定&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;阿里巴巴天猫&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SkyWalking个性化定制版，每天监控数十亿跟踪数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;与此同时，他们基于SkyWalking的Agent技术栈，利用其跟踪和上下文传播能力，正在构建一个全链路压测平台&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;结论&#34;&gt;结论&lt;/h3&gt;
&lt;p&gt;SkyWalking针对可观测性遵循以下原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;理解逻辑模型：不要把可观测性当作数学统计工具。&lt;/li&gt;
&lt;li&gt;首先确定依赖关系，然后确定它们的度量指标。&lt;/li&gt;
&lt;li&gt;原生和方便的支撑大规模增长。&lt;/li&gt;
&lt;li&gt;在不同的架构情况下，APM各方面表现依然保持稳定和一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;资源&#34;&gt;资源&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;阅读&lt;a href=&#34;https://github.com/apache/skywalking/blob/master/CHANGES.md&#34;&gt;SkyWalking 8.1发布亮点&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;在&lt;a href=&#34;https://twitter.com/asfskywalking?lang=en&#34;&gt;Twitter&lt;/a&gt;上获取更多SkyWalking更新。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.tetrate.io/contact-us/&#34;&gt;注册Tetrate&lt;/a&gt;以了解更多有关SkyWalking可观测性的信息。&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 度量服务网格健康度——Apdex得分</title>
      <link>/zh/2020-07-26-apdex-and-skywalking/</link>
      <pubDate>Sun, 26 Jul 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-07-26-apdex-and-skywalking/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者: Srinivasan Ramaswamy, tetrate&lt;/li&gt;
&lt;li&gt;翻译：唐昊杰，南京大学在读学生&lt;/li&gt;
&lt;li&gt;校对：吴晟&lt;/li&gt;
&lt;li&gt;Original link, &lt;a href=&#34;https://www.tetrate.io/blog/the-apdex-score-for-measuring-service-mesh-health/&#34;&gt;Tetrate.io blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;July. 26th, 2020&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;你感觉怎么样-比-你的症状是什么-更重要&#34;&gt;&amp;ldquo;你感觉怎么样&amp;rdquo; 比 &amp;ldquo;你的症状是什么&amp;rdquo; 更重要&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5813wt9j33200tcb2b.jpg&#34; alt=&#34;alt_text&#34; title=&#34;Intro to Apdex&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;背景&#34;&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;最近我拜访了我的医生。每次去看病，医生都会首先问我一连串轻快的问题，比如：你今天过得怎么样？上周过的怎么样？最近有什么出行吗？你打破了自己的骑车记录吗？你的锻炼计划实施如何？最后他会问：“你有什么麻烦吗？”如果这个时候我感觉自己不太好，我会说：“我这周感觉很沉闷，临近中午的时候感觉更累。”这时他就会拿出听诊器、脉搏血氧仪和血压仪。然后，如果他觉得自己需要更深入的了解情况，他就开始列出我需要做的具体检查。&lt;/p&gt;
&lt;p&gt;当我问他，最开始的讨论是否只是为了缓和氛围。他说：“这是必不可少的部分。它帮助我发现你感觉如何，而不是你的症状是什么。&amp;quot;。我们这样关于生活的开场聊天，帮助他组织了后续关于症状、调查和测试结果的问题。&lt;/p&gt;
&lt;p&gt;在回来的路上，我不停地问自己：“我们是不是也应该用这种方式管理我们的网格(service mesh)？”&lt;/p&gt;
&lt;p&gt;如果我把自己的健康检查和网格的健康检查进行类比，“医疗检查”就是日志分析，“调查”就是追踪，“症状”就是传统的RED指标（请求速率、请求错误和请求耗时）。那么根本的问题，就是我们在这里讨论的：健康因素（主要是网格的健康）。&lt;/p&gt;
&lt;h3 id=&#34;服务网格中的健康状况&#34;&gt;&lt;strong&gt;服务网格中的健康状况&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;我们可以通过RED指标来衡量任何被观察到的服务的性能。RED指标在了解每个服务的性能、可靠性和吞吐量方面提供了巨大的价值。这些指标在网格上的令人信服的可视化使得监控全部网格变得标准化和可扩展。此外，根据这些指标的阈值设置警报有助于在指标值异常的时候进行异常检测。&lt;/p&gt;
&lt;p&gt;为了建立任何服务的上下文环境并观察它们，理想的做法是将网格可视化为一个拓扑结构。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5821d3vj316z0u0hdt.jpg&#34; alt=&#34;alt_text&#34; title=&#34;Topology&#34;&gt;&lt;/p&gt;
&lt;p&gt;网格的拓扑结构可视化不仅允许使用者挑选任意服务并观察其指标，还可以提供有关服务依赖和特定服务在网格上的潜在影响这些重要信息。&lt;/p&gt;
&lt;p&gt;虽然每个服务的RED指标为使用者提供了深刻的洞察能力，但使用者更关心网格的整体响应性，而非每个单独出来的服务的响应性。&lt;/p&gt;
&lt;p&gt;为了描述任意服务的性能（即从提交请求到收到完成了的http响应这段时间内的表现），我们会测量用户对响应性的感知。这种将响应时间与设定的阈值进行比较的衡量标准叫做Apdex。Apdex是衡量一个服务在网格中的健康程度的指标。&lt;/p&gt;
&lt;h3 id=&#34;apdex&#34;&gt;&lt;strong&gt;Apdex&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Apdex是根据设定的阈值和响应时间结合考虑的衡量标准。它是满意响应时间和不满意响应时间相对于总响应时间的比率。&lt;/p&gt;
&lt;p&gt;Apdex是根据应用和服务的响应时间来衡量使用者满意程度的行业标准。它衡量的是用户对你的服务的满意程度，因为传统的指标（如平均响应时间）可能很快就会容易形成偏差。&lt;/p&gt;
&lt;p&gt;基于满意度的响应时间，表示特定服务的往返响应时间小于设定的阈值的次数。不满意响应时间虽然意思相反，但又进一步分为容忍型和失望型。容忍型包括了了任何响应时间不超过四倍阈值的表现，而任何超过四倍阈值或遇到了错误的表现都被认为是失望型。这里提到的阈值是我们对任意服务所期望的理想响应表现。我们可以设置一个全局范围的阈值，如，500ms。&lt;/p&gt;
&lt;p&gt;Apdex得分是满意型请求和容忍型请求与做出的总请求的比率。&lt;/p&gt;
&lt;p&gt;每个_满意的请求_算作一个请求，而每个_容忍的请求_算作半个_满意_的请求。&lt;/p&gt;
&lt;p&gt;一个Apdex得分从0到1的范围内取值。0是最差的分数，表示用户总是感到失望；而&#39;1&amp;rsquo;是最好的分数（100%的响应时间是令人满意的）。&lt;/p&gt;
&lt;p&gt;这个分数的百分比表示也可以用作服务的健康指标。&lt;/p&gt;
&lt;h2 id=&#34;数学表示&#34;&gt;&lt;strong&gt;数学表示&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Apdex得分的实际计算是通过以下公式实现的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;		                   满意请求数 +  ( 容忍请求数 / 2 )

Apdex 得分  =  ------------------------------------------------------

                                总请求数
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此公示得到的百分率，即可视为服务的健康度。&lt;/p&gt;
&lt;h3 id=&#34;样例计算&#34;&gt;&lt;strong&gt;样例计算&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在两分钟的采样时间内，主机处理200个请求。&lt;/p&gt;
&lt;p&gt;Apdex阈值T设置为0.5秒（500ms）。&lt;/p&gt;
&lt;p&gt;*.	170个请求在500ms内被处理完成，它们被分类为满意型。
*.	20个请求在500ms和2秒间被处理，它们被分类为容忍型。
*.	剩余的10个请求没有被正确处理或者处理时间超过了2秒，所以它们被分类为失望型。&lt;/p&gt;
&lt;p&gt;最终的Apdex得分是0.9，即（170 + （20 / 2））/ 200。&lt;/p&gt;
&lt;h3 id=&#34;深入使用&#34;&gt;&lt;strong&gt;深入使用&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在接下来的层次，我们可以尝试通过根据节点的健康状况来着色节点以改进我们的拓扑可视化。此外，我们还可以在用户点击服务时将健康状况作为我们展示的信息的一部分。&lt;/p&gt;
&lt;p&gt;Apdex规范推荐了以下Apdex质量评级，将Apdex得分分为优秀（0.94 - 1.00）、良好（0.85 - 0.93）、一般（0.70 - 0.84）、差（0.50 - 0.69）和不可接受（0.00 - 0.49）。&lt;/p&gt;
&lt;p&gt;为了可视化网格的健康状况，我们用交通灯的颜色将我们的节点标记为健康、有风险和不健康，其中不健康表示健康率低于80%。健康率在80%到95%之间的表示有风险，健康率在95%及以上的称为健康。&lt;/p&gt;
&lt;p&gt;让我们将这种着色融入到我们的拓扑可视化中，并将其可用性提升到一个新的水平。如果实施，我们将看到下图所示的情况。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl58088b6j316z0u0kjl.jpg&#34; alt=&#34;alt_text&#34; title=&#34;Health For Services&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;更进一步&#34;&gt;&lt;strong&gt;更进一步&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Apdex为客户对我们服务响应性的满意度提供了可见性。更有甚者，通过将实施范围扩展到调用该服务的调用关系，我们可以进一步了解网格本身的健康状况。&lt;/p&gt;
&lt;p&gt;两个有着相似Apdex分数的服务，为客户提供了相同的客户满意度。然而，流入服务的流量大小对于优先处理哪一服务有着巨大的帮助。流量较高的服务表明这种服务体验影响了网格上更大量的使用者。&lt;/p&gt;
&lt;p&gt;虽然健康程度与单个服务有关，但我们也可以分析两个服务之间的交互并计算交互过程的健康程度。这种对网格上每一个交互的健康程度的计算，可以帮助我们根据整个拓扑结构中所有交互的健康程度，建立一个关键路径。&lt;/p&gt;
&lt;p&gt;在一个大的网格中，将流量展示为另一个数字将使可视化和监控更具挑战性。我们可以根据服务的吞吐量，通过用不同的粗细程度渲染连接服务的边来改善整个可视化的效果。&lt;/p&gt;
&lt;p&gt;一个位于高吞吐量事务的不健康的服务可能会导致资源的过度消耗。另一方面，这种可视化也为调整服务时获取最大化投资效果提供了一个很好的提示。&lt;/p&gt;
&lt;p&gt;与调整一个偶尔使用的服务相比，调整作为高吞吐量事务的一部分的那些服务会带来指数级的收益。&lt;/p&gt;
&lt;p&gt;实施这种包括了交互的健康状况和吞吐量的可视化，我们会看到下图所示的情况:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5alrth6j316z0u0kjl.jpg&#34; alt=&#34;image-20201111125919085&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;这一天即将到来&#34;&gt;&lt;strong&gt;这一天即将到来&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;目前&lt;/strong&gt;，这些功能已经作为Tetrate服务网格平台的UI功能之一来提供给用户。该平台使用了高速可配置化、高性能的可观测性和监控性能管理平台：Apache SkyWalking (&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;https://skywalking.apache.org&lt;/a&gt;)，SkyWalking可以监控整个网格的流量，为服务及它们的交互合计RED指标，持续计算和监控服务的健康状况，并使用户能够在服务超过特定阈值时配置报警和通知。这些功能使得SkyWalking对网格拥有全面的健康状况可见性。&lt;/p&gt;
&lt;p&gt;有了这样强大的网格性能可视性，我们将可以在为网格准备的网络运营中心使用这种拓扑结构作为我们的HUD（Heads Up Display）。&lt;/p&gt;
&lt;p&gt;HUD随着时间的推移收集了解到的信息和模式，并将预测各种情况和主动提示我们潜在的重点领域以提高客户满意度。&lt;/p&gt;
&lt;p&gt;丰富的历史数据的可视化也可以使网络工程师能够看看过去中类似的一天的网格表现。&lt;/p&gt;
&lt;p&gt;可视化效果如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl5a5be9tj316z0u0qv5.jpg&#34; alt=&#34;image-20201111125853233&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;总结&#34;&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;综合到目前为止的所有讨论，网格的健康状况更多地是关于用户的感受，以及我们作为服务提供商可以采取积极行动来维持（如果不能增强）用户的体验。&lt;/p&gt;
&lt;p&gt;着个人化医学的发展，现在距离我的医生给我发这样短信的日子并不遥远：“要不今天享用冰淇淋并且沿着灰色小山步道到达沙斯塔山！”相似的，我们可以通过更好地了解客户的整体健康状况为他们做更多的事情。&lt;/p&gt;
&lt;p&gt;Tetrate的“服务网格健康程度”方法不仅提供了管理，监视和支持，而且从一开始就使基础架构保持健康以减少事故发生的可能性。在Istio，Envoy和SkyWalking的支持下，Tetrate的解决方案可为任何环境中的任何工作负载提供持续的端到端可观察性，运行时安全性和流量管理。&lt;/p&gt;
&lt;p&gt;我们的客户应该拥有健康的系统！请分享您对使用服务网格为我们的客户带来令人兴奋和强健的体验的想法。&lt;/p&gt;
&lt;h3 id=&#34;引用&#34;&gt;&lt;strong&gt;引用&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Apdex&#34;&gt;https://en.wikipedia.org/wiki/Apdex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.apdex.org/overview.html&#34;&gt;https://www.apdex.org/overview.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.apdex.org/index.php/specifications/&#34;&gt;https://www.apdex.org/index.php/specifications/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;https://skywalking.apache.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: Apache SkyWalking 8.0.1 发布</title>
      <link>/zh/2020-06-21-skywalking8-0-1-release/</link>
      <pubDate>Sun, 21 Jun 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-06-21-skywalking8-0-1-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking/releases/tag/v8.0.1&#34;&gt;Apache SkyWalking 8.0.1 已发布&lt;/a&gt;。SkyWalking 是观察性分析平台和应用性能管理系统，提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案，支持 Java, .Net Core, PHP, NodeJS, Golang, LUA 语言探针，支持 Envoy + Istio 构建的 Service Mesh。&lt;/p&gt;
&lt;p&gt;与 8.0.0 相比，此版本包含一个热修复程序。&lt;/p&gt;
&lt;p&gt;OAP-Backend&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修复 &lt;code&gt;no-init&lt;/code&gt; 模式在 Elasticsearch 存储中无法运行的错误&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/skywalking/releases/tag/v8.0.0&#34;&gt;8.0.0&lt;/a&gt; 值得关注的变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;添加并实现了 v3 协议，旧版本与 8.x 不兼容&lt;/li&gt;
&lt;li&gt;移除服务、实例、端点注册机制和 inventory 存储实体 (inventory storage entities)&lt;/li&gt;
&lt;li&gt;提供新的 GraphQL 查询协议，同时支持旧协议（计划在今年年底移除）&lt;/li&gt;
&lt;li&gt;支持 Prometheus 网络协议，可将 Prometheus 格式的指标传输到 SkyWalking 中&lt;/li&gt;
&lt;li&gt;提供 Python agent&lt;/li&gt;
&lt;li&gt;移除所有 inventory 缓存&lt;/li&gt;
&lt;li&gt;提供 Apache ShardingSphere (4.0.0, 4.1.1) agent 插件&lt;/li&gt;
&lt;li&gt;UI dashboard 100% 可配置，可采用后台定义的新指标&lt;/li&gt;
&lt;li&gt;修复 H2/MySQL 实现中的 SQL 注入漏洞&lt;/li&gt;
&lt;li&gt;Upgrade Nacos to avoid the FastJson CVE in high frequency.&lt;/li&gt;
&lt;li&gt;升级 Nacos 以避免 FastJson CVE&lt;/li&gt;
&lt;li&gt;升级 jasckson-databind 至 2.9.10&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下载地址：&lt;a href=&#34;http://skywalking.apache.org/downloads/&#34;&gt;http://skywalking.apache.org/downloads/&lt;/a&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 的最新动向？8.0 版本的 MeterSystem 和网格监控</title>
      <link>/zh/whats-new-in-skywalking-metersystem-and-mesh-monitoring-in-8-0/</link>
      <pubDate>Mon, 15 Jun 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/whats-new-in-skywalking-metersystem-and-mesh-monitoring-in-8-0/</guid>
      <description>
        
        
        &lt;p&gt;可观察性平台和开源应用程序性能监控（APM）项目 Apache SkyWalking，今天刚宣布 8.0 的发布版本。素以强劲指标、追踪与服务网格能力见称的 SkyWalking ，在最新版本中的功能性延展到用户渴求已久的功能 —— 将指标功能和包括 Prometheus 的其他指标收集系统进行了融合。&lt;/p&gt;
&lt;h3 id=&#34;什么是-apache-skywalking&#34;&gt;什么是 Apache SkyWalking？&lt;/h3&gt;
&lt;p&gt;SkyWalking 是可观察性平台和 APM 工具，可以选择是否搭载服务网格的使用，为微服务、云原生和容器化应用提供自动度量功能。顶尖的 Apache 项目由来自世界各地的社区人员支持，应用在阿里巴巴、华为、腾讯、百度和大量其他企业。SkyWalking 提供记录、监控和追踪功能，同时也得力于其架构而拥有数据收集终端、分析平台，还有用户界面。&lt;/p&gt;
&lt;h3 id=&#34;值得关注的优化包括&#34;&gt;值得关注的优化包括：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;用户界面 Dashboard 上提供百分百的自由度，用户可以任意进行配置，采用后台新定义的指标。&lt;/li&gt;
&lt;li&gt;支持 Prometheus 导出格式。Prometheus 格式的指标可以转换至 SkyWalking。&lt;/li&gt;
&lt;li&gt;SkyWalking 现已可以自主监控服务网格，为 Istio 和 Envoy 提供指标。&lt;/li&gt;
&lt;li&gt;服务、实例、终端地址的注册机制，和库存存储实体已经被移除了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;无须修改原始码的前提下为用户界面加入新的指标&#34;&gt;无须修改原始码的前提下，为用户界面加入新的指标&lt;/h3&gt;
&lt;p&gt;对于 SkyWalking 的用户，8.0 版本的亮点将会是数据模型的更新，而且传播格式也针对更多语言进行优化。再加上引进了新的 MeterSystem ，除了可以同步运行传统追踪模式，用户还可自定义需要收集的指标。追踪和服务网格专注在拓扑和服务流量的指标上，而 MeterSystem 则汇报用户感兴趣的业务指标，例如是数据库存取性能、圣诞节期间的下单率，或者用户注册或下单的百分比。这些指标数据会在 SkyWalking 的用户界面 Dashboard 上以图像显示。指标的面板数据和拓扑图可以通过 Envoy 的指标绘制，而追踪分析也可以支持 Istio 的遥测。Dashboard 还支持以 JSON 格式导入、导出，而 Dashboard 上的自定义指标也支持设定指标名称、实体种类（服务、实例、终端地址或全部）、标记值等。&lt;a href=&#34;https://ibaotu.com/tupian/yonghujiemian.html&#34;&gt;用户界面模板&lt;/a&gt;上已详细描述了用户界面的逻辑和原型配置，以及它的 Dashboard、tab 和组件。&lt;/p&gt;
&lt;h3 id=&#34;观察任何配备了-prometheus-的应用&#34;&gt;观察任何配备了 Prometheus 的应用&lt;/h3&gt;
&lt;p&gt;在这次最新的社区发布中，SkyWalking 可以观察任何配备了 Prometheus 或者提供了 Prometheus 终端地址的应用。这项更新为很多想采用 SkyWalking 指标和追踪的用户节省了不少时间，现在你不再需要重新设置指标工具，就可以获得 Prometheus 数据。因为 Prometheus 更简单、更为人熟悉，是不少用户的不二选择。有了 8.0 版本，Prometheus 网络协议就能够读取所有已设定在 API 上的数据，另外 Prometheus 格式的指标也可转换至 SkyWalking 上。如此一来，通过图像方式展示，所有的指标和拓扑都能一目了然。同时，也支持 Prometheus 的 &lt;a href=&#34;https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-fetcher.md&#34;&gt;fetcher&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;监控你的网格&#34;&gt;监控你的网格&lt;/h3&gt;
&lt;p&gt;SkyWalking 现在不再只是监控服务或平台，而是监控整个网格。有了 8.0 版本，你除了能获取关于你的网格的指标（包括 Istio 和 Envoy 在内），同时也能通过 SkyWalking 监控自身的性能。因为当监控服务在观察业务集群的同时，它也能实现自我观察，确保运维团队拥有稳定可靠的平台。&lt;/p&gt;
&lt;h3 id=&#34;性能优化&#34;&gt;性能优化&lt;/h3&gt;
&lt;p&gt;最后，8.0 发布移除了注册机制，也不再需要使用独一无二的整数来代表实体。这项改变将大幅优化性能。想了解完整的更新功能列表，可以阅读在 SkyWalking 社区发布的公告&lt;a href=&#34;https://baike.baidu.com/item/%E9%A1%B5%E9%9D%A2&#34;&gt;页面&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;额外资源&#34;&gt;额外资源&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;追踪 &lt;a href=&#34;https://twitter.com/ASFSkyWalking&#34;&gt;Twitter&lt;/a&gt; 获取更多 SkyWalking 最新资讯&lt;/li&gt;
&lt;li&gt;SkyWalking 未来的发布会加入原生指标 API 和融合 Micrometer (Sleuth) 指标集合。&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 支持云原生网络代理 MOSN 做分布式追踪</title>
      <link>/zh/2020-04-28-skywalking-and-mosn/</link>
      <pubDate>Tue, 28 Apr 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-04-28-skywalking-and-mosn/</guid>
      <description>
        
        
        &lt;p&gt;作者：&lt;a href=&#34;https://jimmysong.io&#34;&gt;宋净超&lt;/a&gt;、&lt;a href=&#34;https://github.com/arugal&#34;&gt;张伟&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;日前，云原生网络代理 MOSN v0.12.0 发布，观察性分析平台和应用性能管理系统 SkyWalking 完成了与 MOSN 的集成，作为 MOSN 中的支持的分布式追踪系统之一，旨在实现在微服务和 Service Mesh 中的更强大的可观察性。&lt;/p&gt;
&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;相比传统的巨石（Monolith）应用，微服务的一个主要变化是将应用中的不同模块拆分为了独立的进程。在微服务架构下，原来进程内的方法调用成为了跨进程的远程方法调用。相对于单一进程内的方法调用而言，跨进程调用的调试和故障分析是非常困难的，难以使用传统的代码调试程序或者日志打印来对分布式的调用过程进行查看和分析。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl55lnpujj30pj0d5t9h.jpg&#34; alt=&#34;分布式追踪示意图&#34;&gt;&lt;/p&gt;
&lt;p&gt;如上图右边所示，微服务架构中系统中各个微服务之间存在复杂的调用关系。&lt;/p&gt;
&lt;p&gt;一个来自客户端的请求在其业务处理过程中经过了多个微服务进程。我们如果想要对该请求的端到端调用过程进行完整的分析，则必须将该请求经过的所有进程的相关信息都收集起来并关联在一起，这就是“分布式追踪”。&lt;/p&gt;
&lt;p&gt;以上关于分布式追踪的介绍引用自 &lt;a href=&#34;https://www.servicemesher.com/istio-handbook/practice/distributed-tracing.html&#34;&gt;Istio Handbook&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;mosn-中-tracing-的架构&#34;&gt;MOSN 中 tracing 的架构&lt;/h2&gt;
&lt;p&gt;MOSN 的 tracing 框架由 Driver、Tracer 和 Span 三个部分组成。&lt;/p&gt;
&lt;p&gt;Driver 是 Tracer 的容器，管理注册的 Tracer 实例，Tracer 是 tracing 的入口，根据请求信息创建一个 Span，Span 存储当前跨度的链路信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl55l75ydj316u0gddgw.jpg&#34; alt=&#34;MOSN 中的 tracing 架构&#34;&gt;&lt;/p&gt;
&lt;p&gt;目前 MOSN tracing 有 &lt;a href=&#34;http://github.com/sofastack/sofa-tracer&#34;&gt;SOFATracer&lt;/a&gt; 和 SkyWalking 两种实现。SOFATracer 支持 http1 和 xprotocol 协议的链路追踪，将 trace 数据写入本地日志文件中。SkyWalking 支持 http1 协议的链路追踪，使用原生的 Go 语言探针 &lt;a href=&#34;https://github.com/SkyAPM/go2sky&#34;&gt;go2sky&lt;/a&gt; 将 trace 数据通过 gRPC 上报到 SkyWalking 后端服务。&lt;/p&gt;
&lt;h2 id=&#34;快速开始&#34;&gt;快速开始&lt;/h2&gt;
&lt;p&gt;下面将使用 Docker 和 &lt;code&gt;docker-compose&lt;/code&gt; 来快速开始运行一个集成了 SkyWalking 的分布式追踪示例，该示例代码请见 &lt;a href=&#34;https://github.com/mosn/mosn/tree/master/examples/codes/trace/skywalking/http&#34;&gt;MOSN GitHub&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;准备&#34;&gt;准备&lt;/h3&gt;
&lt;p&gt;安装 docker 和 docker-compose。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.docker.com/install/&#34;&gt;安装 docker&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.docker.com/compose/install/&#34;&gt;安装 docker-compose&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要一个编译好的 MOSN 程序，您可以&lt;a href=&#34;https://github.com/mosn/mosn&#34;&gt;下载 MOSN 源码&lt;/a&gt;自行编译，或者直接下载 &lt;a href=&#34;https://github.com/mosn/mosn/releases/tag/v0.12.0&#34;&gt;MOSN v0.12.0 发行版&lt;/a&gt;以获取 MOSN 的运行时二进制文件。&lt;/p&gt;
&lt;p&gt;下面将以源码编译的方式演示 MOSN 如何与 SkyWalking 集成。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;projectpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/cmd/mosn/main
go build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;获取示例代码目录。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;targetpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;projectpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/examples/codes/trace/skywalking/http/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将编译好的程序移动到示例代码目录。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;mv main &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;targetpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/
&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;targetpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;目录结构&#34;&gt;目录结构&lt;/h3&gt;
&lt;p&gt;下面是 SkyWalking 的目录结构。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;* skywalking
└─── http
│           main                           &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 编译完成的 MOSN 程序&lt;/span&gt;
|           server.go                      &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 模拟的 Http Server&lt;/span&gt;
|           clint.go                       &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 模拟的 Http Client&lt;/span&gt;
|           config.json                    &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# MOSN 配置&lt;/span&gt;
|           skywalking-docker-compose.yaml &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# skywalking docker-compose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;运行说明&#34;&gt;运行说明&lt;/h3&gt;
&lt;p&gt;启动 SkyWalking oap &amp;amp; ui。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;docker-compose -f skywalking-docker-compose.yaml up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启动一个 HTTP Server。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;go run server.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启动 MOSN。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;./main start -c config.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启动一个 HTTP Client。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;go run client.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打开 &lt;a href=&#34;http://127.0.0.1:8080/&#34;&gt;http://127.0.0.1:8080&lt;/a&gt; 查看 SkyWalking-UI，SkyWalking Dashboard 界面如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl55m257wj31hc0r2781.jpg&#34; alt=&#34;SkyWalking Dashboard&#34;&gt;&lt;/p&gt;
&lt;p&gt;在打开 Dashboard 后请点击右上角的 &lt;code&gt;Auto&lt;/code&gt; 按钮以使页面自动刷新。&lt;/p&gt;
&lt;h3 id=&#34;demo-视频&#34;&gt;Demo 视频&lt;/h3&gt;
&lt;p&gt;下面来看一下该 Demo 的操作视频。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bilibili.com/video/BV17i4y1t7mZ/&#34;&gt;&lt;img src=&#34;0081Kckwly1gkl55mj6f5j31bs0qo76f.jpg&#34; alt=&#34;Demo&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;清理&#34;&gt;清理&lt;/h3&gt;
&lt;p&gt;要想销毁 SkyWalking 后台运行的 docker 容器只需要下面的命令。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;projectpath&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/examples/codes/trace/skywalking/http/
docker-compose -f skywalking-docker-compose.yaml down
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;未来计划&#34;&gt;未来计划&lt;/h2&gt;
&lt;p&gt;在今年五月份，SkyWalking  8.0 版本会进行一次全面升级，采用新的探针协议和分析逻辑，探针将更具互感知能力，更好的在 Service Mesh 下使用探针进行监控。同时，SkyWalking 将开放之前仅存在于内核中的 metrics 指标分析体系。Prmoetheus、Spring Cloud Sleuth、Zabbix 等常用的 metrics 监控方式，都会被统一的接入进来，进行分析。此外， SkyWalking 与 MOSN 社区将继续合作：支持追踪 Dubbo 和 &lt;a href=&#34;https://github.com/sofastack/sofa-rpc&#34;&gt;SOFARPC&lt;/a&gt;，同时适配 sidecar 模式下的链路追踪。&lt;/p&gt;
&lt;h2 id=&#34;关于-mosn&#34;&gt;关于 MOSN&lt;/h2&gt;
&lt;p&gt;MOSN 是一款使用 Go 语言开发的网络代理软件，由蚂蚁金服开源并经过几十万容器的生产级验证。 MOSN 作为云原生的网络数据平面，旨在为服务提供多协议、模块化、智能化、安全的代理能力。 MOSN 是 Modular Open Smart Network 的简称。 MOSN 可以与任何支持 xDS API 的 Service Mesh 集成，亦可以作为独立的四、七层负载均衡，API Gateway、云原生 Ingress 等使用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub：&lt;a href=&#34;https://github.com/mosn/mosn&#34;&gt;https://github.com/mosn/mosn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官网：&lt;a href=&#34;https://mosn.io&#34;&gt;https://mosn.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;关于-skywalking&#34;&gt;关于 Skywalking&lt;/h2&gt;
&lt;p&gt;SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。支持 Java、.Net Core、PHP、NodeJS、Golang、LUA 语言探针，支持 Envoy/MOSN + Istio 构建的 Service Mesh。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub：&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;https://github.com/apache/skywalking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官网：&lt;a href=&#34;https://skywalking.apache.org&#34;&gt;https://skywalking.apache.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于本文中的示例请参考 &lt;a href=&#34;https://github.com/mosn/mosn/tree/master/examples/cn_readme/trace/skywalking/http&#34;&gt;MOSN GitHub&lt;/a&gt; 和 &lt;a href=&#34;https://mosn.io/zh/docs/configuration/trace/&#34;&gt;MOSN 官方文档&lt;/a&gt;。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 极简入门</title>
      <link>/zh/2020-04-19-skywalking-quick-start/</link>
      <pubDate>Sun, 19 Apr 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-04-19-skywalking-quick-start/</guid>
      <description>
        
        
        &lt;p&gt;目录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;1. 概述&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;2. 搭建 SkyWalking 单机环境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;3. 搭建 SkyWalking 集群环境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;4. 告警&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;5. 注意事项&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;6. Spring Boot 使用示例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#&#34;&gt;6. Spring Cloud 使用示例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;作者：&lt;a href=&#34;https://github.com/YunaiV&#34;&gt;芋道源码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.iocoder.cn/SkyWalking/install/?skywalkinng&#34;&gt;原文地址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;1-概述&#34;&gt;1. 概述&lt;/h1&gt;
&lt;h2 id=&#34;11-概念&#34;&gt;1.1 概念&lt;/h2&gt;
&lt;p&gt;SkyWalking 是什么？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;FROM &lt;a href=&#34;http://skywalking.apache.org/&#34;&gt;http://skywalking.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;分布式系统的应用程序性能监视工具，专为微服务、云原生架构和基于容器（Docker、K8s、Mesos）架构而设计。&lt;/p&gt;
&lt;p&gt;提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;12-功能列表&#34;&gt;1.2 功能列表&lt;/h2&gt;
&lt;p&gt;SkyWalking 有哪些功能？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;FROM &lt;a href=&#34;http://skywalking.apache.org/&#34;&gt;http://skywalking.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多种监控手段。可以通过语言探针和 service mesh 获得监控是数据。&lt;/li&gt;
&lt;li&gt;多个语言自动探针。包括 Java，.NET Core 和 Node.JS。&lt;/li&gt;
&lt;li&gt;轻量高效。无需大数据平台，和大量的服务器资源。&lt;/li&gt;
&lt;li&gt;模块化。UI、存储、集群管理都有多种机制可选。&lt;/li&gt;
&lt;li&gt;支持告警。&lt;/li&gt;
&lt;li&gt;优秀的可视化解决方案。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;13-整体架构&#34;&gt;1.3 整体架构&lt;/h2&gt;
&lt;p&gt;SkyWalking 整体架构如何？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;FROM &lt;a href=&#34;http://skywalking.apache.org/&#34;&gt;http://skywalking.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl533fk5xj31pc0s8h04.jpg&#34; alt=&#34;架构图&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;整个架构，分成上、下、左、右四部分：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;考虑到让描述更简单，我们舍弃掉 Metric 指标相关，而着重在 Tracing 链路相关功能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;上部分 &lt;strong&gt;Agent&lt;/strong&gt; ：负责从应用中，收集链路信息，发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是，SkyWalking Agent 收集 SkyWalking Tracing 数据，传递给服务器。&lt;/li&gt;
&lt;li&gt;下部分 &lt;strong&gt;SkyWalking OAP&lt;/strong&gt; ：负责接收 Agent 发送的 Tracing 数据信息，然后进行分析(Analysis Core) ，存储到外部存储器( Storage )，最终提供查询( Query )功能。&lt;/li&gt;
&lt;li&gt;右部分 &lt;strong&gt;Storage&lt;/strong&gt; ：Tracing 数据存储。目前支持 ES、MySQL、Sharding Sphere、TiDB、H2 多种存储器。而我们目前采用的是 ES ，主要考虑是 SkyWalking 开发团队自己的生产环境采用 ES 为主。&lt;/li&gt;
&lt;li&gt;左部分 &lt;strong&gt;SkyWalking UI&lt;/strong&gt; ：负责提供控台，查看链路等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;14-官方文档&#34;&gt;1.4 官方文档&lt;/h2&gt;
&lt;p&gt;在 &lt;a href=&#34;https://github.com/apache/skywalking/tree/master/docs&#34;&gt;https://github.com/apache/skywalking/tree/master/docs&lt;/a&gt; 地址下，提供了 SkyWalking 的&lt;strong&gt;英文&lt;/strong&gt;文档。&lt;/p&gt;
&lt;p&gt;考虑到大多数胖友的英语水平和艿艿不相伯仲，再加上胖友一开始对 SkyWalking 比较陌生，所以比较推荐先阅读 &lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking&#34;&gt;https://github.com/SkyAPM/document-cn-translation-of-skywalking&lt;/a&gt; 地址，提供了 SkyWalking 的&lt;strong&gt;中文&lt;/strong&gt;文档。&lt;/p&gt;
&lt;p&gt;考虑到胖友使用 SkyWalking 的目的，是实现&lt;strong&gt;分布式链路追踪&lt;/strong&gt;的功能，所以最好去了解下相关的知识。这里推荐阅读两篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/opentracing-contrib/opentracing-specification-zh&#34;&gt;《OpenTracing 官方标准 —— 中文版》&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google 论文 &lt;a href=&#34;http://www.iocoder.cn/Fight/Dapper-translation/?self&#34;&gt;《Dapper，大规模分布式系统的跟踪系统》&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;2-搭建-skywalking-单机环境&#34;&gt;2. 搭建 SkyWalking 单机环境&lt;/h1&gt;
&lt;p&gt;考虑到让胖友更快的入门，我们来搭建一个 SkyWalking &lt;strong&gt;单机&lt;/strong&gt;环境，步骤如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl533oq0xj30ww0pomzt.jpg&#34; alt=&#34;SkyWalking 单机环境&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一步，搭建一个 Elasticsearch 服务。&lt;/li&gt;
&lt;li&gt;第二步，下载 SkyWalking 软件包。&lt;/li&gt;
&lt;li&gt;第三步，搭建一个 SkyWalking OAP 服务。&lt;/li&gt;
&lt;li&gt;第四步，启动一个 Spring Boot 应用，并配置 SkyWalking Agent。&lt;/li&gt;
&lt;li&gt;第五步，搭建一个 SkyWalking UI 服务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;仅仅五步，按照艿艿标题党的性格，应该给本文取个《10 分钟快速搭建 SkyWalking 服务》标题才对，哈哈哈。&lt;/p&gt;
&lt;h2 id=&#34;21-elasticsearch-搭建&#34;&gt;2.1 Elasticsearch 搭建&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;FROM &lt;a href=&#34;https://www.elastic.co/cn/products/elasticsearch&#34;&gt;https://www.elastic.co/cn/products/elasticsearch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎，能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心，它集中存储您的数据，帮助您发现意料之中以及意料之外的情况。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;参考&lt;a href=&#34;http://www.iocoder.cn/Elasticsearch/install/?self&#34;&gt;《Elasticsearch 极简入门》&lt;/a&gt;的&lt;a href=&#34;#&#34;&gt;「1. 单机部署」&lt;/a&gt;小节，搭建一个 Elasticsearch 单机服务。&lt;/p&gt;
&lt;p&gt;不过要&lt;strong&gt;注意&lt;/strong&gt;，本文使用的是 Elasticsearch &lt;code&gt;7.5.1&lt;/code&gt; 版本。因为 SkyWalking &lt;a href=&#34;https://github.com/apache/skywalking/releases/tag/v6.6.0&#34;&gt;&lt;code&gt;6.6.0&lt;/code&gt;&lt;/a&gt; 版本，增加了对 Elasticsearch 7.X 版本的支持。当然，如果胖友使用 Elasticsearch 6.X 版本也是可以的。&lt;/p&gt;
&lt;h2 id=&#34;22-下载-skywalking-软件包&#34;&gt;2.2 下载 SkyWalking 软件包&lt;/h2&gt;
&lt;p&gt;对于 SkyWalking 的软件包，有两种方式获取：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手动编译&lt;/li&gt;
&lt;li&gt;官方包&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般情况下，我们建议使用&lt;strong&gt;官方包&lt;/strong&gt;。手动编译，更多是尝鲜或者等着急修复的 BUG 的版本。&lt;/p&gt;
&lt;h3 id=&#34;221-官方包&#34;&gt;2.2.1 官方包&lt;/h3&gt;
&lt;p&gt;在 &lt;a href=&#34;http://skywalking.apache.org/downloads/&#34;&gt;http://skywalking.apache.org/downloads/&lt;/a&gt; 下，我们下载&lt;strong&gt;操作系统&lt;/strong&gt;对应的发布版。&lt;/p&gt;
&lt;p&gt;这里，我们选择 &lt;a href=&#34;https://www.apache.org/dyn/closer.cgi/skywalking/6.6.0/apache-skywalking-apm-es7-6.6.0.tar.gz&#34;&gt;Binary Distribution for ElasticSearch 7 (Linux)&lt;/a&gt; 版本，因为艿艿是 Mac 环境，再加上想使用 Elasticsearch 7.X 版本作为存储。如果胖友想用 Elasticsearch 6.X 版本作为存储，记得下载 &lt;a href=&#34;https://www.apache.org/dyn/closer.cgi/skywalking/6.6.0/apache-skywalking-apm-6.6.0.tar.gz&#34;&gt;Binary Distribution (Linux)&lt;/a&gt; 版本。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① 下载&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 创建目录&lt;/span&gt;
$ mkdir -p /Users/yunai/skywalking
$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; /Users/yunai/skywalking

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 下载&lt;/span&gt;
$ wget http://mirror.bit.edu.cn/apache/skywalking/6.6.0/apache-skywalking-apm-es7-6.6.0.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;② 解压&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 解压&lt;/span&gt;
$ tar -zxvf apache-skywalking-apm-es7-6.6.0.tar.gz
$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt;  apache-skywalking-apm-bin-es7

$ ls -ls
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;8&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:09 agent &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 bin &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 执行脚本&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 config &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking OAP Server 配置文件&lt;/span&gt;
&lt;span style=&#34;color:#099&#34;&gt;32&lt;/span&gt; -rwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;28903&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 LICENSE
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 licenses
&lt;span style=&#34;color:#099&#34;&gt;32&lt;/span&gt; -rwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;31850&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 NOTICE
&lt;span style=&#34;color:#099&#34;&gt;16&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;16384&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:22 oap-libs &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking OAP Server&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; -rw-r--r-- &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;1978&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 README.txt
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 webapp &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking UI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;222-手动编译&#34;&gt;2.2.2 手动编译&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;友情提示：如果胖友没有编译 SkyWalking 源码的诉求，可以跳过本小节。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;参考 &lt;a href=&#34;https://github.com/apache/skywalking/blob/v6.3.0/docs/en/guides/How-to-build.md&#34;&gt;How to build project&lt;/a&gt; 文章。&lt;/p&gt;
&lt;p&gt;需要前置安装如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GIT&lt;/li&gt;
&lt;li&gt;JDK 8+&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;① 克隆代码&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;$ git clone https://github.com/apache/skywalking.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;因为网络问题，可能克隆会有点久。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② 初始化子模块&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; skywalking
$ git submodule init
$ git submodule update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;③ 编译&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;$ ./mvnw clean package -DskipTests
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;编译过程，如果机子比较差，花费时间会比较久。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;④ 查看编译结果&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; apm-dist &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 编译结果目录&lt;/span&gt;
$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; target
$ tar -zxvf apache-skywalking-apm-bin.tar.gz &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 解压 Linux 包&lt;/span&gt;
$ &lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; apache-skywalking-apm-bin
$ ls -ls
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;8&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:09 agent &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 bin &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 执行脚本&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 config &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking OAP Server 配置文件&lt;/span&gt;
&lt;span style=&#34;color:#099&#34;&gt;32&lt;/span&gt; -rwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;28903&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 LICENSE
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 licenses
&lt;span style=&#34;color:#099&#34;&gt;32&lt;/span&gt; -rwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;31850&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 NOTICE
&lt;span style=&#34;color:#099&#34;&gt;16&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root &lt;span style=&#34;color:#099&#34;&gt;16384&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:22 oap-libs &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking OAP Server&lt;/span&gt;
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; -rw-r--r-- &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;1978&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 14:32 README.txt
 &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; drwxr-xr-x &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; root root  &lt;span style=&#34;color:#099&#34;&gt;4096&lt;/span&gt; Sep  &lt;span style=&#34;color:#099&#34;&gt;9&lt;/span&gt; 15:44 webapp &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking UI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;23-skywalking-oap-搭建&#34;&gt;2.3 SkyWalking OAP 搭建&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;① 修改 OAP 配置文件&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;友情提示：如果配置文件，适合 SkyWalking 6.X 版本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-YAML&#34; data-lang=&#34;YAML&#34;&gt;$&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;vi&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;config/application.yml&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;storage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;elasticsearch7&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;nameSpace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_NAMESPACE:&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;elasticsearch&amp;#34;&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;clusterNodes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_CLUSTER_NODES:localhost:&lt;span style=&#34;color:#099&#34;&gt;9200&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_HTTP_PROTOCOL:&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    trustStorePath: ${SW_SW_STORAGE_ES_SSL_JKS_PATH:&amp;#34;../es_keystore.jks&amp;#34;}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    trustStorePass: ${SW_SW_STORAGE_ES_SSL_JKS_PASS:&amp;#34;&amp;#34;}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;user&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_ES_USER:&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;password&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_ES_PASSWORD:&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;indexShardsNumber&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;indexReplicasNumber&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Those data TTL settings will override the same settings in core module.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;recordDataTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_RECORD_DATA_TTL:&lt;span style=&#34;color:#099&#34;&gt;7&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Unit is day&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;otherMetricsDataTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_OTHER_METRIC_DATA_TTL:&lt;span style=&#34;color:#099&#34;&gt;45&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Unit is day&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;monthMetricsDataTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_MONTH_METRIC_DATA_TTL:&lt;span style=&#34;color:#099&#34;&gt;18&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Unit is month&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;bulkActions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_BULK_ACTIONS:&lt;span style=&#34;color:#099&#34;&gt;1000&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Execute the bulk every 1000 requests&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;flushInterval&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_FLUSH_INTERVAL:&lt;span style=&#34;color:#099&#34;&gt;10&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# flush the bulk every 10 seconds whatever the number of requests&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;concurrentRequests&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_CONCURRENT_REQUESTS:&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# the number of concurrent requests&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;resultWindowMaxSize&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_QUERY_MAX_WINDOW_SIZE:&lt;span style=&#34;color:#099&#34;&gt;10000&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadataQueryMaxSize&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_QUERY_MAX_SIZE:&lt;span style=&#34;color:#099&#34;&gt;5000&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;segmentQueryMaxSize&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:&lt;span style=&#34;color:#099&#34;&gt;200&lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#  h2:&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    user: ${SW_STORAGE_H2_USER:sa}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;#    metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;storage.elasticsearch7&lt;/code&gt; 配置项，设置使用 Elasticsearch 7.X 版本作为存储器。
&lt;ul&gt;
&lt;li&gt;这里，我们打开注释，并记得通过 &lt;code&gt;nameSpace&lt;/code&gt; 设置 Elasticsearch 集群名。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storage.elasticsearch&lt;/code&gt; 配置项，设置使用 Elasticsearch 6.X 版本作为存储器。
&lt;ul&gt;
&lt;li&gt;这里，我们无需做任何改动。&lt;/li&gt;
&lt;li&gt;如果胖友使用 Elasticsearch 6.X 版本作为存储器，记得设置这个配置项，而不是 &lt;code&gt;storage.elasticsearch7&lt;/code&gt; 配置项。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storage.h2&lt;/code&gt; 配置项，设置使用 H2 作为存储器。
&lt;ul&gt;
&lt;li&gt;这里，我们需要手动注释掉，因为 H2 是默认配置的存储器。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;友情提示：如果配置文件，适合 SkyWalking 7.X 版本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl534r2llj30pc0rs1kx.jpg&#34; alt=&#34;配置文件&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重点修改 &lt;code&gt;storage&lt;/code&gt; 配置项，通过 &lt;code&gt;storage.selector&lt;/code&gt; 配置项来设置具体使用的存储器。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storage.elasticsearch&lt;/code&gt; 配置项，设置使用 Elasticsearch 6.X 版本作为存储器。胖友可以主要修改 &lt;code&gt;nameSpace&lt;/code&gt;、&lt;code&gt;clusterNodes&lt;/code&gt; 两个配置项即可，设置使用的 Elasticsearch 的集群和命名空间。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storage.elasticsearch7&lt;/code&gt; 配置项，设置使用 Elasticsearch 7.X 版本作为存储器。&lt;/li&gt;
&lt;li&gt;还有 MySQL、H2、InfluxDB 等等存储器的配置可以选择，胖友自己根据需要去选择哈~&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② 启动 SkyWalking OAP 服务&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;$ bin/oapService.sh

SkyWalking OAP started successfully!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;是否&lt;strong&gt;真正&lt;/strong&gt;启动成功，胖友打开 &lt;code&gt;logs/skywalking-oap-server.log&lt;/code&gt; 日志文件，查看是否有错误日志。首次启动时，因为 SkyWalking OAP 会创建 Elasticsearch 的索引，所以会“疯狂”的打印日志。最终，我们看到如下日志，基本可以代表 SkyWalking OAP 服务启动成功：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;友情提示：因为首次启动会创建 Elasticsearch 索引，所以可能会比较慢。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;2020&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;01&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;02 18&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;22&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;53&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;635 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; org&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;eclipse&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;jetty&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;server&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;Server&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; 444 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;main&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt; INFO  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; Started &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@35249ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;24-skywalking-ui-搭建&#34;&gt;2.4 SkyWalking UI 搭建&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;① 启动 SkyWalking UI 服务&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;bin/webappService.sh

SkyWalking Web Application started successfully!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;是否&lt;strong&gt;真正&lt;/strong&gt;启动成功，胖友打开 &lt;code&gt;logs/logs/webapp.log&lt;/code&gt; 日志文件，查看是否有错误日志。最终，我们看到如下日志，基本可以代表 SkyWalking UI 服务启动成功：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;2020&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;01&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;02 18&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;27&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;02&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;824&lt;/span&gt;  INFO 48250 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;---&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;main&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt; o&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;s&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;apm&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;webapp&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;ApplicationStartUp&lt;/span&gt;      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; Started ApplicationStartUp in 7&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;774&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;seconds&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;JVM running &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;for&lt;/span&gt; 8&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;316&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果想要修改 SkyWalking UI 服务的参数，可以编辑 &lt;code&gt;webapp/webapp.yml&lt;/code&gt; 配置文件。例如说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;server.port&lt;/code&gt; ：SkyWalking UI 服务端口。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;collector.ribbon.listOfServers&lt;/code&gt; ：SkyWalking OAP 服务地址数组。因为 SkyWalking UI 界面的数据，是通过请求 SkyWalking OAP 服务来获得的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② 访问 UI 界面：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;浏览器打开 &lt;code&gt;http://127.0.0.1:8080&lt;/code&gt; 。界面如下图：&lt;img src=&#34;0081Kckwly1gkl534a7rnj31f60u0gtw.jpg&#34; alt=&#34;SkyWalking UI&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;25-skywalking-agent&#34;&gt;2.5 SkyWalking Agent&lt;/h2&gt;
&lt;p&gt;大多数情况下，我们在启动项目的 Shell 脚本上，通过 &lt;code&gt;-javaagent&lt;/code&gt; 参数进行配置 SkyWalking Agent 。我们在 &lt;a href=&#34;#&#34;&gt;「2.3.1 Shell」&lt;/a&gt; 小节来看。&lt;/p&gt;
&lt;p&gt;考虑到偶尔我们需要在 IDE 中，也希望使用 SkyWalking Agent ，所以我们在 &lt;a href=&#34;#&#34;&gt;「2.3.2 IDEA」&lt;/a&gt; 小节来看。&lt;/p&gt;
&lt;h3 id=&#34;231-shell&#34;&gt;2.3.1 Shell&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;① Agent 软件包&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们需要将 &lt;code&gt;apache-skywalking-apm-bin/agent&lt;/code&gt; 目录，拷贝到 Java 应用所在的服务器上。这样，Java 应用才可以配置使用该 SkyWalking Agent。我们来看看 Agent 目录下有哪些：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;$ ls -ls

total &lt;span style=&#34;color:#099&#34;&gt;35176&lt;/span&gt;
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@  &lt;span style=&#34;color:#099&#34;&gt;7&lt;/span&gt; yunai  staff       &lt;span style=&#34;color:#099&#34;&gt;224&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:20 activations
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@  &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt; yunai  staff       &lt;span style=&#34;color:#099&#34;&gt;128&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:21 bootstrap-plugins
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@  &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt; yunai  staff        &lt;span style=&#34;color:#099&#34;&gt;96&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:12 config &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent 配置&lt;/span&gt;
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@  &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt; yunai  staff        &lt;span style=&#34;color:#099&#34;&gt;96&lt;/span&gt; Jan  &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt; 19:29 logs &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent 日志&lt;/span&gt;
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@ &lt;span style=&#34;color:#099&#34;&gt;13&lt;/span&gt; yunai  staff       &lt;span style=&#34;color:#099&#34;&gt;416&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:22 optional-plugins &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 可选插件&lt;/span&gt;
    &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt; drwxr-xr-x@ &lt;span style=&#34;color:#099&#34;&gt;68&lt;/span&gt; yunai  staff      &lt;span style=&#34;color:#099&#34;&gt;2176&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:20 plugins &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 插件&lt;/span&gt;
&lt;span style=&#34;color:#099&#34;&gt;35176&lt;/span&gt; -rw-r--r--@  &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; yunai  staff  &lt;span style=&#34;color:#099&#34;&gt;18006420&lt;/span&gt; Dec &lt;span style=&#34;color:#099&#34;&gt;24&lt;/span&gt; 14:12 skywalking-agent.jar &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;关于 SkyWalking Agent 提供的插件列表，可以看看&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/service-agent/java-agent/Supported-list.md&#34;&gt;《SkyWalking 文档 —— 插件支持列表》&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为艿艿是在本机测试，所以无需拷贝，SkyWalking Agent 目录是 &lt;code&gt;/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;考虑到方便胖友，艿艿这里提供了一个最简的 Spring Boot 应用 &lt;a href=&#34;http://static.iocoder.cn/lab-39-demo-2.2.2.RELEASE.jar&#34;&gt;lab-39-demo-2.2.2.RELEASE.jar&lt;/a&gt;。对应 Github 仓库是 &lt;a href=&#34;https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-39/lab-39-demo&#34;&gt;lab-39-demo&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 配置 Java 启动脚本&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent 配置&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_NAME&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;demo-application &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 配置 Agent 名字。一般来说，我们直接使用 Spring Boot 项目的 `spring.application.name` 。&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_COLLECTOR_BACKEND_SERVICES&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;127.0.0.1:11800 &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 配置 Collector 地址。&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;SW_AGENT_SPAN_LIMIT&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;2000&lt;/span&gt; &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 配置链路的最大 Span 数量。一般情况下，不需要配置，默认为 300 。主要考虑，有些新上 SkyWalking Agent 的项目，代码可能比较糟糕。&lt;/span&gt;
&lt;span style=&#34;color:#0086b3&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;JAVA_AGENT&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;-javaagent:/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# SkyWalking Agent jar 地址。&lt;/span&gt;

&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Jar 启动&lt;/span&gt;
java -jar &lt;span style=&#34;color:#008080&#34;&gt;$JAVA_AGENT&lt;/span&gt; -jar lab-39-demo-2.2.2.RELEASE.jar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;通过环境变量，进行配置。&lt;/li&gt;
&lt;li&gt;更多的变量，可以在 &lt;a href=&#34;https://github.com/apache/skywalking/blob/master/apm-sniffer/config/agent.config&#34;&gt;&lt;code&gt;/work/programs/skywalking/apache-skywalking-apm-bin/agent/config/agent.config&lt;/code&gt;&lt;/a&gt; 查看。要注意，可能有些变量是被注释掉的，例如说 &lt;code&gt;SW_AGENT_SPAN_LIMIT&lt;/code&gt; 对应的 &lt;code&gt;agent.span_limit_per_segment&lt;/code&gt; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③ 执行脚本：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直接执行上述的 Shell 脚本，启动 Java 项目。在启动日志中，我们可以看到 SkyWalking Agent 被加载的日志。日志示例如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;DEBUG 2020&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;01&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;02 19&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;29&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;29&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;400 main AgentPackagePath &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; The beacon &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;location&lt;/span&gt; is jar&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;file&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:/&lt;/span&gt;Users&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;yunai&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;apache&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;apm&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;bin&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;es7&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;agent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;agent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;jar&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;!/&lt;/span&gt;org&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;apache&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;apm&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;agent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;core&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;boot&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;AgentPackagePath&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
INFO 2020&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;01&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;02 19&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;29&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;29&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;402 main SnifferConfigInitializer &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; Config file found in &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;Users&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;yunai&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;apache&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;skywalking&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;apm&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;bin&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;es7&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;agent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;config&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;agent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同时，也可以在 &lt;code&gt;/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/agent/logs/skywalking-api.log&lt;/code&gt; 查看对应的 SkyWalking Agent 日志。日志示例如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;DEBUG 2020&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;01&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;02 19&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;37&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;22&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;539 SkywalkingAgent&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;5&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;ServiceAndEndpointRegisterClient&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;0 ServiceAndEndpointRegisterClient &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; ServiceAndEndpointRegisterClient running&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; status&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;CONNECTED&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;这里，我们看到 &lt;code&gt;status:CONNECTED&lt;/code&gt; ，表示 SkyWalking Agent 连接 SkyWalking OAP 服务成功。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;④ 简单测试&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;完事，可以去 SkyWalking UI 查看是否链路收集成功。&lt;/p&gt;
&lt;p&gt;1、首先，使用浏览器，访问下 &lt;a href=&#34;http://127.0.0.1:8079/demo/echo&#34;&gt;http://127.0.0.1:8079/demo/echo&lt;/a&gt; 地址，请求下 Spring Boot 应用提供的 API。因为，我们要追踪下该链路。&lt;/p&gt;
&lt;p&gt;2、然后，继续使用浏览器，打开 &lt;a href=&#34;http://127.0.0.1:8080/&#34;&gt;http://127.0.0.1:8080/&lt;/a&gt; 地址，进入 SkyWalking UI 界面。如下图所示：&lt;img src=&#34;2017-01-01_02.png&#34; alt=&#34;SkyWalking UI 界面 —— 仪表盘&#34;&gt;&lt;/p&gt;
&lt;p&gt;这里，我们会看到 SkyWalking 中非常重要的三个概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;服务(Service)&lt;/strong&gt; ：表示对请求提供相同行为的一系列或一组工作负载。在使用 Agent 或 SDK 的时候，你可以定义服务的名字。如果不定义的话，SkyWalking 将会使用你在平台（例如说 Istio）上定义的名字。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里，我们可以看到 Spring Boot 应用的&lt;strong&gt;服务&lt;/strong&gt;为 &lt;code&gt;&amp;quot;demo-application&amp;quot;&lt;/code&gt;，就是我们在环境变量 &lt;code&gt;SW_AGENT_NAME&lt;/code&gt; 中所定义的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;服务实例(Service Instance)&lt;/strong&gt; ：上述的一组工作负载中的每一个工作负载称为一个实例。就像 Kubernetes 中的 pods 一样, 服务实例未必就是操作系统上的一个进程。但当你在使用 Agent 的时候, 一个服务实例实际就是操作系统上的一个真实进程。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里，我们可以看到 Spring Boot 应用的&lt;strong&gt;服务&lt;/strong&gt;为 &lt;code&gt;{agent_name}-pid:{pid}@{hostname}&lt;/code&gt;，由 Agent 自动生成。关于它，我们在&lt;a href=&#34;#&#34;&gt;「5.1 hostname」&lt;/a&gt;小节中，有进一步的讲解，胖友可以瞅瞅。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;端点(Endpoint)&lt;/strong&gt; ：对于特定服务所接收的请求路径, 如 HTTP 的 URI 路径和 gRPC 服务的类名 + 方法签名。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里，我们可以看到 Spring Boot 应用的一个&lt;strong&gt;端点&lt;/strong&gt;，为 API 接口 &lt;code&gt;/demo/echo&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3、之后，点击「拓扑图」菜单，进入查看拓扑图的界面。如下图所示：&lt;img src=&#34;2017-01-01_03.png&#34; alt=&#34;SkyWalking UI 界面 —— 拓扑图&#34;&gt;&lt;/p&gt;
&lt;p&gt;4、再之后，点击「追踪」菜单，进入查看链路数据的界面。如下图所示：&lt;img src=&#34;0081Kckwly1gkl535q88ej31ds0u0k0p.jpg&#34; alt=&#34;SkyWalking UI 界面 —— 追踪&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;232-idea&#34;&gt;2.3.2 IDEA&lt;/h3&gt;
&lt;p&gt;我们统一使用 IDEA 作为开发 IDE ，所以忽略 Eclipse 的配置方式。&lt;/p&gt;
&lt;p&gt;具体参考下图，比较简单：&lt;img src=&#34;0081Kckwly1gkl5354kg7j30rs0egwkv.jpg&#34; alt=&#34;IDEA 界面&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-搭建-skywalking-集群环境&#34;&gt;3. 搭建 SkyWalking 集群环境&lt;/h1&gt;
&lt;p&gt;在生产环境下，我们一般推荐搭建 SkyWalking 集群环境。😈 当然，如果公司比较抠门，也可以在生产环境下使用 SkyWalking 单机环境，毕竟 SkyWalking 挂了之后，不影响业务的正常运行。&lt;/p&gt;
&lt;p&gt;搭建一个 SkyWalking &lt;strong&gt;集群&lt;/strong&gt;环境，步骤如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一步，搭建一个 Elasticsearch 服务的&lt;strong&gt;集群&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;第二步，搭建一个注册中心的&lt;strong&gt;集群&lt;/strong&gt;。目前 SkyWalking 支持 Zookeeper、Kubernetes、Consul、Nacos 作为注册中心。&lt;/li&gt;
&lt;li&gt;第三步，搭建一个 SkyWalking OAP 服务的&lt;strong&gt;集群&lt;/strong&gt;，同时参考&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/backend/backend-cluster.md&#34;&gt;《SkyWalking 文档 —— 集群管理》&lt;/a&gt;，将 SkyWalking OAP 服务注册到注册中心上。&lt;/li&gt;
&lt;li&gt;第四步，启动一个 Spring Boot 应用，并配置 SkyWalking Agent。另外，在设置 SkyWaling Agent 的 &lt;code&gt;SW_AGENT_COLLECTOR_BACKEND_SERVICES&lt;/code&gt; 地址时，需要设置多个 SkyWalking OAP 服务的地址数组。&lt;/li&gt;
&lt;li&gt;第五步，搭建一个 SkyWalking UI 服务的&lt;strong&gt;集群&lt;/strong&gt;，同时使用 Nginx 进行负载均衡。另外，在设置 SkyWalking UI 的 &lt;code&gt;collector.ribbon.listOfServers&lt;/code&gt; 地址时，也需要设置多个 SkyWalking OAP 服务的地址数组。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;😈 具体的搭建过程，并不复杂，胖友自己去尝试下。&lt;/p&gt;
&lt;h1 id=&#34;4-告警&#34;&gt;4. 告警&lt;/h1&gt;
&lt;p&gt;在 SkyWaling 中，已经提供了告警功能，具体可见&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/backend/backend-alarm.md&#34;&gt;《SkyWalking 文档 —— 告警》&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;默认情况下，SkyWalking 已经&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/backend/backend-alarm.md#%E9%BB%98%E8%AE%A4%E5%91%8A%E8%AD%A6%E8%A7%84%E5%88%99&#34;&gt;内置告警规则&lt;/a&gt;。同时，我们可以参考&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/backend/backend-alarm.md#%E8%A7%84%E5%88%99&#34;&gt;告警规则&lt;/a&gt;，进行自定义。&lt;/p&gt;
&lt;p&gt;在满足 SkyWalking 告警规则的触发规则时，我们在 SkyWaling UI 的告警界面，可以看到告警内容。如下图所示：&lt;img src=&#34;2017-01-01_06.png&#34; alt=&#34;SkyWaling UI 界面 —— 告警&#34;&gt;&lt;/p&gt;
&lt;p&gt;同时，我们自定义 &lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking/blob/master/docs/zh/master/setup/backend/backend-alarm.md#webhook&#34;&gt;Webhook&lt;/a&gt; ，对接 SkyWalking 的告警请求。而具体的邮箱、钉钉等告警方式，需要自己进行开发。至于自定义 WebHook 如何实现，可以参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java 语言：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.iocoder.cn/Fight/Distributed-tracking-system-based-on-SkyWalking-abnormal-alert/?self&#34;&gt;《基于 SkyWalking 的分布式跟踪系统 - 异常告警》&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go 语言：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yanmaipian/dingding-notify-for-skywalking&#34;&gt;dingding-notify-for-skywalking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/weiqiang333/infra-skywalking-webhook&#34;&gt;infra-skywalking-webhook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;5-注意事项&#34;&gt;5. 注意事项&lt;/h1&gt;
&lt;h2 id=&#34;51-hostname-配置&#34;&gt;5.1 hostname 配置&lt;/h2&gt;
&lt;p&gt;在 SkyWalking 中，每个被监控的实例的名字，会包含 hostname 。格式为：&lt;code&gt;{agent_name}-pid:{pid}@{hostname}&lt;/code&gt; ，例如说：&lt;code&gt;&amp;quot;scrm-scheduler-pid:27629@iZbp1e2xlyvr7fh67qi59oZ&amp;quot;&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;因为有些服务器未正确设置 &lt;code&gt;hostname&lt;/code&gt; ，所以我们一定要去修改，不然都不知道是哪个服务器上的实例（😈 鬼知道 &lt;code&gt;&amp;quot;iZbp1e2xlyvr7fh67qi59oZ&amp;quot;&lt;/code&gt; 一串是哪个服务器啊）。&lt;/p&gt;
&lt;p&gt;修改方式如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、修改 &lt;code&gt;/etc/hosts&lt;/code&gt; 的 &lt;code&gt;hostname&lt;/code&gt;&lt;/strong&gt; ：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;127.0.0.1 localhost
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.80.62.151 pre-app-01 &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 就是这个，其中 10.80.62.151 是本机内网 IP ，pre-app-01 是 hostname 。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2、修改本机 &lt;code&gt;hostname&lt;/code&gt;&lt;/strong&gt; ：&lt;/p&gt;
&lt;p&gt;参考 &lt;a href=&#34;https://yq.aliyun.com/articles/427296&#34;&gt;《CentOS7 修改主机名（hostname）》&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;$ hostname pre-app-01 &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 其中 pre-app-01 就是你希望的 hostname 。&lt;/span&gt;

$ hostnamectl set-hostname pre-app-01 &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# 其中 pre-app-01 就是你希望的 hostname 。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;6-spring-boot-使用示例&#34;&gt;6. Spring Boot 使用示例&lt;/h1&gt;
&lt;p&gt;在 &lt;a href=&#34;http://www.iocoder.cn/Spring-Boot/SkyWalking/?self&#34;&gt;《芋道 Spring Boot 链路追踪 SkyWalking 入门》&lt;/a&gt; 中，我们来详细学习如何在 Spring Boot 中，整合并使用 SkyWalking 收集链路数据。😈 相比&lt;a href=&#34;#&#34;&gt;「2.5 SkyWaling Agent」&lt;/a&gt;来说，我们会提供更加丰富的示例哟。&lt;/p&gt;
&lt;h1 id=&#34;7-spring-cloud-使用示例&#34;&gt;7. Spring Cloud 使用示例&lt;/h1&gt;
&lt;p&gt;在 &lt;a href=&#34;http://www.iocoder.cn/Spring-Cloud/SkyWalking/?self&#34;&gt;《芋道 Spring Cloud 链路追踪 SkyWalking 入门》&lt;/a&gt; 中，我们来详细学习如何在 Spring Cloud 中，整合并使用 SkyWalking 收集链路数据。😈 相比&lt;a href=&#34;#&#34;&gt;「2.5 SkyWaling Agent」&lt;/a&gt;来说，我们会提供更加丰富的示例哟。&lt;/p&gt;
&lt;h1 id=&#34;666-彩蛋&#34;&gt;666. 彩蛋&lt;/h1&gt;
&lt;p&gt;本文仅仅是简单的 SkyWalking 入门文章，如果胖友想要更好的使用 SkyWalking，推荐通读下&lt;a href=&#34;https://github.com/SkyAPM/document-cn-translation-of-skywalking&#34;&gt;《SkyWalking 文档》&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;想要进一步深入的胖友，也可以阅读如下资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.iocoder.cn/categories/SkyWalking/?self&#34;&gt;《SkyWalking 源码解析》&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.iocoder.cn/Fight/APM-Apache-Skywalking-and-Pinpoint/?self&#34;&gt;《APM 巅峰对决：Apache Skywalking P.K. Pinpoint》&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://skywalking.apache.org/zh/blog/&#34;&gt;《SkyWalking 官方 —— 博客合集》&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;😈 最后弱弱的问一句，上完 SkyWaling 之后，有没发现自己系统各种地方慢慢慢！嘻嘻。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 在线代码级性能剖析，补全分布式追踪的最后一块“短板”</title>
      <link>/zh/2020-03-23-using-profiling-to-fix-the-blind-spot-of-distributed-tracing/</link>
      <pubDate>Mon, 23 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>/zh/2020-03-23-using-profiling-to-fix-the-blind-spot-of-distributed-tracing/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者：&lt;a href=&#34;https://github.com/wu-sheng&#34;&gt;吴晟&lt;/a&gt;，&lt;a href=&#34;https://github.com/mrproliu&#34;&gt;刘晗&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.infoq.cn/article/CWUOl1JA0EyXw0CxQ4Zm&#34;&gt;原文地址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在本文中，我们详细介绍了代码级的性能剖析方法，以及我们在 Apache SkyWalking 中的实践。希望能够帮助大家在线定位系统性能短板，缓解系统压力。&lt;/p&gt;
&lt;h2 id=&#34;分布式链路追踪的局限性&#34;&gt;分布式链路追踪的局限性&lt;/h2&gt;
&lt;p&gt;在传统的监控系统中，我们如果想要得知系统中的业务是否正常，会采用进程监控、日志收集分析等方式来对系统进行监控。当机器或者服务出现问题时，则会触发告警及时通知负责人。通过这种方式，我们可以得知具体哪些服务出现了问题。但是这时我们并不能得知具体的错误原因出在了哪里，开发人员或者运维人员需要到日志系统里面查看错误日志，甚至需要到真实的业务服务器上查看执行情况来解决问题。&lt;/p&gt;
&lt;p&gt;如此一来，仅仅是发现问题的阶段，可能就会耗费相当长的时间；另外，发现问题但是并不能追溯到问题产生具体原因的情况，也常有发生。这样反反复复极其耗费时间和精力，为此我们便有了基于分布式追踪的 APM 系统。&lt;/p&gt;
&lt;p&gt;通过将业务系统接入分布式追踪中，我们就像是给程序增加了一个放大镜功能，可以清晰看到真实业务请求的整体链路，包括请求时间、请求路径，甚至是操作数据库的语句都可以看得一清二楚。通过这种方式，我们结合告警便可以快速追踪到真实用户请求的完整链路信息，并且这些数据信息完全是持久化的，可以随时进行查询，复盘错误的原因。&lt;/p&gt;
&lt;p&gt;然而随着我们对服务监控理解的加深，我们发现事情并没有那么简单。在分布式链路追踪中我们有这样的两个流派：代码埋点和字节码增强。无论使用哪种方式，底层逻辑一定都逃不过面向切面这个基础逻辑。因为只有这样才可以做到大面积的使用。这也就决定了它只能做到框架级别和 RPC 粒度的监控。这时我们可能依旧会遇到程序执行缓慢或者响应时间不稳定等情况，但无法具体查询到原因。这时候，大家很自然的会考虑到增加埋点粒度，比如对所有的 Spring Bean 方法、甚至主要的业务层方法都加上埋点。但是这种思路会遇到不小的挑战：&lt;/p&gt;
&lt;p&gt;第一，增加埋点时系统开销大，埋点覆盖不够全面。通过这种方式我们确实可以做到具体业务场景具体分析。但随着业务不断迭代上线，弊端也很明显：大量的埋点无疑会加大系统资源的开销，造成 CPU、内存使用率增加，更有可能拖慢整个链路的执行效率。虽然每个埋点消耗的性能很小，在微秒级别，但是因为数量的增加，甚至因为业务代码重用造成重复埋点或者循环使用，此时的性能开销已经无法忽略。&lt;/p&gt;
&lt;p&gt;第二，动态埋点作为一项埋点技术，和手动埋点的性能消耗上十分类似，只是减少的代码修改量，但是因为通用技术的特别，上一个挑战中提到的循环埋点和重复使用的场景甚至更为严重。比如选择所有方法或者特定包下的所有方法埋点，很可能造成系统性能彻底崩溃。&lt;/p&gt;
&lt;p&gt;第三，即使我们通过合理设计和埋点，解决了上述问题，但是 JDK 函数是广泛使用的，我们很难限制对 JDK API 的使用场景。对 JDK 过多方法、特别是非 RPC 方法的监控会造成系统的巨大延迟风险。而且有一些基础类型和底层工具类，是很难通过字节码进行增强的。当我们的 SDK 使用不当或者出现 bug 时，我们无法具体得知真实的错误原因。&lt;/p&gt;
&lt;h2 id=&#34;代码级性能剖析方法&#34;&gt;代码级性能剖析方法&lt;/h2&gt;
&lt;h3 id=&#34;方法介绍&#34;&gt;方法介绍&lt;/h3&gt;
&lt;p&gt;基于以上问题，在系统性能监控方法上，我们提出了&lt;strong&gt;代码级性能剖析&lt;/strong&gt;这种在线诊断方法。这种方法基于一个高级语言编程模型共性，即使再复杂的系统，再复杂的业务逻辑，都是基于线程去进行执行的，而且多数逻辑是在单个线程状态下执行的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码级性能剖析&lt;/strong&gt;就是利用方法栈快照，并对方法执行情况进行分析和汇总。并结合有限的分布式追踪 span 上下文，对代码执行速度进行估算。&lt;/p&gt;
&lt;p&gt;性能剖析激活时，会对指定线程周期性的进行线程栈快照，并将所有的快照进行汇总分析，如果两个连续的快照含有同样的方法栈，则说明此栈中的方法大概率在这个时间间隔内都处于执行状态。从而，通过这种连续快照的时间间隔累加成为估算的方法执行时间。时间估算方法如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl527tsgwj30us0cwwet.jpg&#34; alt=&#34;Profile Time estimation&#34;&gt;&lt;/p&gt;
&lt;p&gt;在上图中，d0-d10 代表 10 次连续的内存栈快照，实际方法执行时间在 d3-d4 区间，结束时间在 d8-d9 之间。性能剖析无法告诉你方法的准确执行时间，但是他会估算出方法执行时间为 d4-d8 的 4 个快照采集间隔时间之和，这已经是非常的精确的时间估算了。&lt;/p&gt;
&lt;p&gt;而这个过程因为不涉及代码埋点，所以自然性能消耗是稳定和可控的，也无需担心是否被埋点，是否是 JDK 方法等问题。同时，由于上层已经在分布式追踪之下，性能剖析方法可以明确地确定分析开始和结束时间，减少不必要的性能开销。&lt;/p&gt;
&lt;p&gt;性能剖析可以很好的对线程的堆栈信息进行监控，主要有以下几点优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;精确的问题定位，直接到代码方法和代码行；&lt;/li&gt;
&lt;li&gt;无需反复的增删埋点，大大减少了人力开发成本；&lt;/li&gt;
&lt;li&gt;不用承担过多埋点对目标系统和监控系统的压力和性能风险；&lt;/li&gt;
&lt;li&gt;按需使用，平时对系统无消耗，使用时的消耗稳定可能。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;skywalking-实践实例&#34;&gt;SkyWalking 实践实例&lt;/h3&gt;
&lt;p&gt;我们首先在 Apache SkyWalking APM 中实现此技术方法，下面我们就以一个真实的例子来说明此方法的执行效果。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;final&lt;/span&gt; CountDownLatchcountDownLatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; CountDownLatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;2&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
threadPool&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;submit&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; Task1&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;countDownLatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;));&lt;/span&gt;
threadPool&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;submit&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; Task2&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;countDownLatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;));&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;try&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
   countDownLatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;await&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;500&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; TimeUnit&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;MILLISECONDS&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;InterruptedExceptione&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是我们故意加入的问题代码，我们使用 CountDownLanth 设置了两个任务完成后方法执行结束，Task1 和 Task2 是两个执行时间不稳定的任务，所以主任务也会执行速度不稳定。但对于运维和监控团队来说，很难定位到这个方法片段。&lt;/p&gt;
&lt;p&gt;针对于这种情况，我们看看性能剖析会怎样直接定位此问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl527i9fsj30l403j0tf.jpg&#34; alt=&#34;Profile Trace&#34;&gt;&lt;/p&gt;
&lt;p&gt;上图所示的就是我们在进行链路追踪时所看到的真实执行情况，其中我们可以看到在 service/processWithThreadPool 执行速度缓慢，这正是我们植入问题代码的方法。此时在这个调用中没有后续链路了，所以并没有更细致的原因，我们也不打算去 review 代码，从而增加新埋点。这时，我们可以对 HelloService 进行性能剖析，并执行只剖析响应速度大于 500 毫秒的请求。&lt;/p&gt;
&lt;p&gt;注意，指定特定响应时间的剖析是保证剖析有效性的重要特性，如果方法在平均响应时间上已经出现问题，往往通过分布式链路可以快速定位，因为此时链路总时间长，新埋点带来的性能影响相对可控。但是方法性能抖动是不容易用新增埋点来解决的，而且往往只发生在生产环境。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl528dv3cj30u010vdj1.jpg&#34; alt=&#34;Profile Thread Stack&#34;&gt;&lt;/p&gt;
&lt;p&gt;上图就是我们进行性能剖析后的真实结果图。从左到右分别表示：栈帧名称、该栈帧总计耗时（包含其下面所有自栈帧）、当前栈帧自身耗时和监控次数。我们可以在最后一行看到，线程卡在了 sun.misc.Unsafe.park 中了。如果你熟悉 Java 就可以知道此时进行了锁等待，我们继续按照树的结构向上推，便可以看到线程真正是卡在了 CountDownLatch.await 方法中。&lt;/p&gt;
&lt;h3 id=&#34;方法局限性&#34;&gt;方法局限性&lt;/h3&gt;
&lt;p&gt;当然任何的方法都不是万能的，性能剖析也有一些局限性。&lt;/p&gt;
&lt;p&gt;第一， 对于高频反复执行的方法，如循环调用，可能会误报为缓慢方法。但这并不是大问题，因为如果反复执行的耗时较长，必然是系统需要关注的性能瓶颈。&lt;/p&gt;
&lt;p&gt;第二， 由于性能栈快照有一定的性能消耗，所以采集周期不宜过密，如 SkyWalking 实践中，不支持小于 10ms 的采集间隔。所以如果问题方法执行时间过小（比如在 10 毫秒内波动），此方法并不适用。我们也再此强调，&lt;strong&gt;方法论和工具的强大，始终不能代替程序员&lt;/strong&gt;。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 使用 ElasticSearch 存储的优化</title>
      <link>/zh/2019-11-07-skywalking-elasticsearch-storage-optimization/</link>
      <pubDate>Thu, 07 Nov 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-11-07-skywalking-elasticsearch-storage-optimization/</guid>
      <description>
        
        
        &lt;p&gt;PS：本文仅仅是在我的测试环境实验过，如果有问题，请自行优化调整&lt;/p&gt;
&lt;p&gt;前记：记得skywlking还是6.0版本的时候我就在试用，当时是skywalking基本在两三天左右就会监控数据完全查不出来，elasticsearch日志报错，由于当时也算是初用es，主要用来日志收集，并且时间有限，没有继续深入研究，最近空闲，更新到最新的6.5.0(开发版本)还是会出现同样的问题，下定决心解决下，于是有了本文的浅知拙见&lt;/p&gt;
&lt;h3 id=&#34;本次调优环境&#34;&gt;本次调优环境&lt;/h3&gt;
&lt;p&gt;skywalking: 6.5.0
elasticsearch:6.3.2(下文用es代替)&lt;/p&gt;
&lt;h3 id=&#34;调优过程&#34;&gt;调优过程&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;当然是百度了，百度后其实翻来翻去就找到一个相关的文章https://my.oschina.net/keking/blog/3025303 ，参考之。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;调整skywalking的这两个参数试试
&lt;code&gt;bulkActions: 4000 # Execute the bulk every 2000 requests&lt;/code&gt;
&lt;code&gt; bulkSize: 60 # flush the bulk every 20mb&lt;/code&gt;
然后es还是继续挂，继续频繁的重启&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;继续看这个文章，发现了另外一篇https://www.easyice.cn/archives/207 ，继续参考之&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这篇文章发现每一个字我都认识，看起来也能懂，但是对于es小白的我来说，着实不知道怎么调整这些参数，姑且先加到es的配置文件里边试试看吧，于是就加了，然后重启es的时候说发现index参数配置，自从5.0之后就不支持这样配置了，还给调了个es的接口去设置，但是设置失败（真够不错的），朝着这个思路去百度，百度到快放弃，后来就寻思，再试试看吧，（百度的结果是知道了index有静态参数和动态参数，动态的参数是可以随时设置，静态的只能创建或者关闭状态的索引才可以设置）
然鹅并不知道怎么关闭索引，继续百度，（怎么全特么百度，好吧不百度了，直接来干货）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关闭索引（我的skywalking索引命名空间是dry_trace）
&lt;code&gt;curl -XPOST  &amp;quot;http://localhost:9200/dry_trace*/_close&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;设置参数
&lt;pre&gt;&lt;code&gt;curl -XPUT &#39;http://localhost:9200/dry_trace*/_settings?preserve_existing=true&#39; -H &#39;Content-type:application/json&#39; -d &#39;{  
&amp;quot;index.refresh_interval&amp;quot; : &amp;quot;10s&amp;quot;,  
&amp;quot;index.translog.durability&amp;quot; : &amp;quot;async&amp;quot;,  
&amp;quot;index.translog.flush_threshold_size&amp;quot; : &amp;quot;1024mb&amp;quot;,  
&amp;quot;index.translog.sync_interval&amp;quot; : &amp;quot;120s&amp;quot;  
}&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;打开索引
&lt;code&gt;curl -XPOST  &amp;quot;http://localhost:9200/dry_trace*/_open&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;还有一点，第四步的方式只适用于现有的索引设置，那么新的索引设置呢，总不能每天重复下第四步吧。当然不需要，来干货
首先登陆kinaba控制台找到开发工具
贴入以下代码&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;    PUT /_template/dry_trace_tmp 
   {
   &amp;quot;index_patterns&amp;quot;: &amp;quot;dry_trace*&amp;quot;,
   &amp;quot;order&amp;quot;: 1,
   &amp;quot;settings&amp;quot;: {
   	&amp;quot;index&amp;quot;: {
   		&amp;quot;refresh_interval&amp;quot;: &amp;quot;30s&amp;quot;,
   		&amp;quot;translog&amp;quot;: {
   			&amp;quot;flush_threshold_size&amp;quot;: &amp;quot;1GB&amp;quot;,
   			&amp;quot;sync_interval&amp;quot;: &amp;quot;60s&amp;quot;,
   			&amp;quot;durability&amp;quot;: &amp;quot;async&amp;quot;
   		}
   	}
   }
   }
&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;截止目前为止运行一周，还未发现挂掉，一切看起来正常&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3 id=&#34;完结---&#34;&gt;完结&amp;mdash;&lt;/h3&gt;
&lt;p&gt;于 2019年11月&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 使用 chart 部署 SkyWalking</title>
      <link>/zh/2019-10-08-how-to-use-sw-chart/</link>
      <pubDate>Tue, 08 Oct 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-10-08-how-to-use-sw-chart/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者：innerpeacez&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ipzgo.top/2019-10-08-%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-helm-chart-%E9%83%A8%E7%BD%B2-skywalking/&#34;&gt;原文地址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文主要讲述的是如何使用 Helm Charts  将 SkyWalking 部署到 Kubernetes 集群中，相关文档可以参考&lt;a href=&#34;https://github.com/apache/skywalking-kubernetes&#34;&gt;skywalking-kubernetes &lt;/a&gt;和 &lt;a href=&#34;https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-k8s.md&#34;&gt;backend-k8s 文档&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;目前推荐的四种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 helm 2 提供的 helm serve 启动本地 helm repo&lt;/li&gt;
&lt;li&gt;使用本地 chart 文件部署&lt;/li&gt;
&lt;li&gt;使用 harbor 提供的 repo 功能&lt;/li&gt;
&lt;li&gt;直接从官方 repo 进行部署&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：目前 skywalking 的 chart 还没有提交到官方仓库，请先参照前三种方式进行部署&lt;/p&gt;
&lt;h4 id=&#34;helm-2-提供的-helm-serve&#34;&gt;Helm 2 提供的 helm serve&lt;/h4&gt;
&lt;h5 id=&#34;打包对应版本的-skywalking-chart&#34;&gt;&lt;strong&gt;打包对应版本的 skywalking chart&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;1.配置 helm 环境，&lt;a href=&#34;https://ipzgo.top/2019-07-26-Windows-%E4%BD%BF%E7%94%A8-helm3-%E5%92%8C-kubectl/&#34;&gt;参考 Helm 环境配置&lt;/a&gt; ，如果你要部署 helm2 相关 chart 可以直接配置 helm2 的相关环境&lt;/p&gt;
&lt;p&gt;2.克隆/下载ZIP &lt;a href=&#34;https://github.com/apache/skywalking-kubernetes&#34;&gt;&lt;strong&gt;skywalking-kubernetes&lt;/strong&gt;&lt;/a&gt; 这个仓库，仓库关于chart的目录结构如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;helm-chart&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;helm2
&lt;ul&gt;
&lt;li&gt;6.0.0-GA&lt;/li&gt;
&lt;li&gt;6.1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;helm3
&lt;ul&gt;
&lt;li&gt;6.3.0&lt;/li&gt;
&lt;li&gt;6.4.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;克隆/下载ZIP 完成后进入指定目录打包对应版本的chart&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; skywalking-kubernetes/helm-chart/&amp;lt;helm-version&amp;gt;/&amp;lt;skywalking-version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意：helm-version 为对应的 helm 版本目录，skywalking-version 为对应的 skywalking 版本目录，下面以helm3 和 skywalking 6.3.0 为例&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#0086b3&#34;&gt;cd&lt;/span&gt; skywalking-kubernetes/helm-chart/helm3/6.3.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3.由于skywalking 依赖 elasticsearch 作为存储库，执行以下命令更新依赖，默认会从官方repo进行拉取&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm dep up skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Hang tight while we grab the latest from your chart repositories&amp;hellip;
&amp;hellip;Successfully got an update from the &amp;ldquo;stable&amp;rdquo; chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading elasticsearch from repo &lt;a href=&#34;https://kubernetes-charts.storage.googleapis.com/&#34;&gt;https://kubernetes-charts.storage.googleapis.com/&lt;/a&gt;
Deleting outdated charts&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果官方 repo 不存在，请先添加官方仓库&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm repo add stable https://kubernetes-charts.storage.googleapis.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;stable&amp;rdquo; has been added to your repositories&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;4.打包 skywalking , 执行以下命令&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm package skywalking/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Successfully packaged chart and saved it to: C:\code\innerpeacez_github\skywalking-kubernetes\helm-chart\helm3\6.3.0\skywalking-0.1.0.tgz&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;打包完成后会在当前目录的同级目录生成 .tgz 文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ls
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;skywalking/  skywalking-0.1.0.tgz&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id=&#34;启动-helm-serve&#34;&gt;启动 helm serve&lt;/h5&gt;
&lt;p&gt;由于上文配置的 helm 为 helm3 ,但是 helm 3中移除了 helm serve 的相关命令，所以需要另外一个环境配置helm2 的相关环境，&lt;a href=&#34;https://github.com/helm/helm/releases/tag/v2.14.3&#34;&gt;下载 helm 2.14.3 的二进制文件&lt;/a&gt;，配置基本上没有大的差别，不在赘述&lt;/p&gt;
&lt;p&gt;初始化 helm&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-shelm&#34; data-lang=&#34;shelm&#34;&gt;helm init
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将上文生成的 &lt;strong&gt;skywalking-0.1.0.tgz&lt;/strong&gt; 文件复制到 helm 相关目录 &lt;code&gt;/root/.helm/repository/local&lt;/code&gt;,启动 serve&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm serve --address &amp;lt;ip&amp;gt;:8879 --repo-path /root/.helm/repository/local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意： ip 为要能够被上文配置 helm 3 环境的机器访问到&lt;/p&gt;
&lt;p&gt;可以访问一下看看服务 serve 是否启动成功&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;curl ip:8879
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;部署-skywalking&#34;&gt;部署 skywalking&lt;/h5&gt;
&lt;p&gt;1.在helm3 环境中添加启动的本地 repo&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm repo add &lt;span style=&#34;color:#0086b3&#34;&gt;local&lt;/span&gt; http://&amp;lt;ip&amp;gt;:8879
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2.查看 skywalking chart 是否存在于本地仓库中&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm search skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;NAME             	CHART VERSION	APP VERSION	DESCRIPTION              &lt;br&gt;
local/skywalking 	0.1.0        	6.3.0      	Apache SkyWalking APM System&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3.部署&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm -n &lt;span style=&#34;color:#0086b3&#34;&gt;test&lt;/span&gt; install skywalking local/skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样 skywalking 就部署到了 k8s 集群中的 test 命名空间了，至此本地安装skywalking 就完成了。&lt;/p&gt;
&lt;h4 id=&#34;本地文件部署&#34;&gt;本地文件部署&lt;/h4&gt;
&lt;p&gt;如果你不想存储到 chart 到仓库中也可以直接使用本地文件部署 skywalking,按照上面的步骤将skywalking chart 打包完成之后，直接使用以下命令进行部署&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm -n &lt;span style=&#34;color:#0086b3&#34;&gt;test&lt;/span&gt; install skywalking skywalking-0.1.0.tgz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;harbor-作为-repo-存储-charts&#34;&gt;harbor 作为 repo 存储 charts&lt;/h4&gt;
&lt;p&gt;harbor 目前已经提供了，charts repo 的能力，这样就可以将 docker 镜像和 chart 存储在一个仓库中了，方便维护，具体harbor 的部署方法参考 &lt;a href=&#34;https://ipzgo.top/2019-07-26-Helm-3-%E4%BD%BF%E7%94%A8-harbor-%E4%BD%9C%E4%B8%BA%E4%BB%93%E5%BA%93%E5%AD%98%E5%82%A8-charts/&#34;&gt;Harbor 作为存储仓库存储 chart&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;官方-repo-部署&#34;&gt;官方 repo 部署&lt;/h4&gt;
&lt;p&gt;目前没有发布到官方 repo 中，后续发布完成后，只需要执行下面命令即可&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;helm install -n &lt;span style=&#34;color:#0086b3&#34;&gt;test&lt;/span&gt; stable/skywalking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;总结&#34;&gt;总结&lt;/h3&gt;
&lt;p&gt;四种方式都可以进行部署，如果你想要自定义 chart ,需要使用上述两种本地方法及 harbor 存储的方式，以便你修改好 chart 之后进行部署.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: Apache SkyWalking Committer申请流程</title>
      <link>/zh/2019-09-12-apache-skywalking-committer-apply-process/</link>
      <pubDate>Thu, 12 Sep 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-09-12-apache-skywalking-committer-apply-process/</guid>
      <description>
        
        
        &lt;p&gt;作者： SkyWalking committer，&lt;a href=&#34;https://github.com/x22x22&#34;&gt;Kdump&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文介绍申请Apache SkyWalking Committer流程, 流程包括以下步骤&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;与PMC成员表达想成为committer的意愿(主动/被动)&lt;/li&gt;
&lt;li&gt;PMC内部投票&lt;/li&gt;
&lt;li&gt;PMC正式邮件邀请&lt;/li&gt;
&lt;li&gt;填写Apache iCLA申请表&lt;/li&gt;
&lt;li&gt;设置ApacheID和邮箱&lt;/li&gt;
&lt;li&gt;设置GitHub加入Apache组织&lt;/li&gt;
&lt;li&gt;GitHub其它一些不重要设置&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;前期过程&#34;&gt;前期过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;与PMC成员表达想成为committer的意愿(主动/被动)&lt;/li&gt;
&lt;li&gt;PMC内部投票&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当你对项目的贡献活跃度足够高或足够多时, Skywalking项目的PMC(项目管理委员会)会找到你并询问你是否有意愿成为项目的Committer, 或者也可以主动联系项目的PMC表达自己的意向, 在此之后PMC们会进行内部讨论和投票并告知你是否可以进入下一个环节.这个过程可能需要一周.
如果PMC主动邀请你进行非正式的意愿咨询, 你可以选择接受或拒绝.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;PS&lt;/strong&gt;&lt;/em&gt;:PMC会向你索要你的个人邮箱, 建议提供Gmail, 因为后期绑定Apache邮箱需要用到, 其它邮箱我不确定是否能绑定.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;PS&lt;/strong&gt;&lt;/em&gt;:从Apache官方的流程来讲, 现有的PMC会在没有通知候选人的情况下先进行候选人投票, 但是Skywalking项目的PMC有可能更倾向于先得到候选人的意愿再进行投票.&lt;/p&gt;
&lt;h2 id=&#34;正式阶段&#34;&gt;正式阶段&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;PMC正式邮件邀请&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当你收到PMC正式的邀请邮件时, 恭喜你, 你已经通过了PMC的内部投票, 你需要用英文回答接受邀请或者拒绝邀请, 记住回复的时候一定要选择&lt;code&gt;全部回复&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;填写Apache iCLA申请表&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在你收到的PMC邮件中, 有几个ASF官方链接需要你去浏览, 重点的内容是查看&lt;a href=&#34;http://www.apache.org/licenses/contributor-agreements.html#clas&#34;&gt;CLAs&lt;/a&gt;, 并填写&lt;a href=&#34;http://www.apache.org/licenses/icla.pdf&#34;&gt;Individual Contributor License Agreement&lt;/a&gt;, 你可以将&lt;code&gt;icla.pdf&lt;/code&gt;文件下载到本地, 使用PDF工具填写里面所需的信息, 并打印出来签名(一定要手写签名, 否则会被要求重新签名), 再扫描(或手机拍照)成电子文档(需要回复PDF格式, 文件名建议重命名为&lt;code&gt;你的名字-icla.pdf&lt;/code&gt;), 使用gpg对电子文档进行签名(参考[HOW-TO: SUBMITTING LICENSE AGREEMENTS AND GRANTS&lt;/p&gt;
&lt;p&gt;](&lt;a href=&#34;http://www.apache.org/licenses/contributor-agreements.html#submitting)),&#34;&gt;http://www.apache.org/licenses/contributor-agreements.html#submitting)),&lt;/a&gt; Window可以使用GnuPG或者Gpg4win.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;完成gpg签名后, 请将你签名用的公钥上送到&lt;a href=&#34;http://hkps.pool.sks-keyservers.net&#34;&gt;pool.sks-keyservers.net&lt;/a&gt;服务器, 并在这个页面中验证你的公钥是否可以被搜索到, 搜索关键词可以是你秘钥中填写的名字或者邮箱地址.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gpg签名后, 会生成&lt;code&gt;.pdf.asc&lt;/code&gt;的文件, 需要将你的&lt;code&gt;你的名字-icla.pdf&lt;/code&gt;和&lt;code&gt;你的名字-icla.pdf.asc&lt;/code&gt;以附件的方式一起发送到&lt;a href=&#34;mailto:secretary@apache.org&#34;&gt;secretary@apache.org&lt;/a&gt;, 并抄送给&lt;a href=&#34;mailto:private@skywalking.apache.org&#34;&gt;private@skywalking.apache.org&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置ApacheID和邮箱&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大概5个工作日内, 你会收到一封来至于&lt;a href=&#34;mailto:root@apache.org&#34;&gt;root@apache.org&lt;/a&gt;的邮件, 主题为&lt;code&gt;Welcome to the Apache Software Foundation (ASF)!&lt;/code&gt;, 恭喜你, 你已经获得了ApacheID, 这时候你需要根据邮件内容的提示去设置你的ApacheID密码, 密码设置完成后, 需要在&lt;a href=&#34;https://id.apache.org/&#34;&gt;Apache Account Utility&lt;/a&gt;页面中重点设置&lt;code&gt;Forwarding email address&lt;/code&gt;和&lt;code&gt;Your GitHub Username&lt;/code&gt;两个信息.保存信息的时候需要你填写当前的ApacheID的密码.&lt;/li&gt;
&lt;li&gt;现在进入Gmail, 选择右上角的齿轮-&amp;gt;设置-&amp;gt;账号和导入-&amp;gt;添加其他电子邮件地址-&amp;gt;参考&lt;a href=&#34;https://reference.apache.org/committer/email&#34;&gt;Sending email from your apache.org email address&lt;/a&gt;给出的信息根据向导填写Apache邮箱.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置GitHub加入Apache组织&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入&lt;a href=&#34;https://gitbox.apache.org/setup/&#34;&gt;Welcome to the GitBox Account Linking Utility!&lt;/a&gt;, 按照顺序将&lt;code&gt;Apache Account&lt;/code&gt;和&lt;code&gt;GitHub Account&lt;/code&gt;点绿, 想点绿&lt;code&gt;MFA Status&lt;/code&gt;, 需要去GitHub开启2FA, 请参考&lt;a href=&#34;https://help.github.com/cn/articles/configuring-two-factor-authentication&#34;&gt;配置双重身份验证&lt;/a&gt;完成2FA的功能.&lt;/li&gt;
&lt;li&gt;等待1~2小时后登陆自己的GitHub的dashboard界面, 你应该会看到一条Apache组织邀请你加入的通知, 这个时候接受即可享有Skywalking相关GitHub项目权限了.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;其它提示&#34;&gt;其它提示&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;GitHub其它一些不重要设置
&lt;ul&gt;
&lt;li&gt;在GitHub首页展示Apache组织的logo: 进入&lt;a href=&#34;https://github.com/apache&#34;&gt;Apache GitHub组织&lt;/a&gt;-&amp;gt;People-&amp;gt;搜索自己的GitHubID-&amp;gt;将&lt;code&gt;Private&lt;/code&gt;改成&lt;code&gt;Public&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 如何使用 SkyWalking Agent ？</title>
      <link>/zh/2019-08-30-how-to-use-skywalking-agent/</link>
      <pubDate>Fri, 30 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-08-30-how-to-use-skywalking-agent/</guid>
      <description>
        
        
        &lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;作者：innerpeacez&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ipzgo.top/2019-08-30-%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-Skywalking-Agent/&#34;&gt;原文地址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你还不知道 Skywalking agent 是什么，&lt;a href=&#34;https://github.com/apache/skywalking/blob/master/docs/en/concepts-and-designs/README.md&#34;&gt;请点击这里查看 Probe&lt;/a&gt; 或者&lt;a href=&#34;https://github.com/apache/skywalking/blob/master/docs/en/setup/service-agent/java-agent/README.md&#34;&gt;这里查看快速了解agent&lt;/a&gt;,由于我这边大部分都是 JAVA 服务，所以下文以 Java 中使用 agent 为例，提供了以下三种方式供你选择&lt;/p&gt;
&lt;h4 id=&#34;三种方式&#34;&gt;三种方式：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;使用官方提供的基础镜像&lt;/li&gt;
&lt;li&gt;将 agent 包构建到已经存在的基础镜像中&lt;/li&gt;
&lt;li&gt;sidecar 模式挂载 agent&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;1使用官方提供的基础镜像&#34;&gt;1.使用官方提供的基础镜像&lt;/h5&gt;
&lt;p&gt;查看官方 docker hub 提供的&lt;a href=&#34;https://hub.docker.com/r/apache/skywalking-base&#34;&gt;基础镜像&lt;/a&gt;，只需要在你构建服务镜像是 From 这个镜像即可，直接集成到 Jenkins 中可以更加方便&lt;/p&gt;
&lt;h5 id=&#34;2将-agent-包构建到已经存在的基础镜像中&#34;&gt;2.将 agent 包构建到已经存在的基础镜像中&lt;/h5&gt;
&lt;p&gt;提供这种方式的原因是：官方的镜像属于精简镜像，并且是 openjdk ，可能很多命令没有，需要自己二次安装，以下是我构建的过程&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;下载 oracle jdk&lt;/p&gt;
&lt;p&gt;这个现在 oracle 有点恶心了，wget 各种不行，然后我放弃了，直接从&lt;a href=&#34;https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&#34;&gt;官网&lt;/a&gt;下载了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载 skywalking &lt;a href=&#34;https://www.apache.org/dyn/closer.cgi/skywalking/6.3.0/apache-skywalking-apm-6.3.0.tar.gz&#34;&gt;官方发行包&lt;/a&gt;，并解压（以6.3.0为例）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;wget https://www.apache.org/dyn/closer.cgi/skywalking/6.3.0/apache-skywalking-apm-6.3.0.tar.gz &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; tar -zxvf apache-skywalking-apm-6.3.0.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过以下 dockerfile 构建基础镜像&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt; alpine:3.8 &lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ENV&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;LANG&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;C.UTF-8&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;RUN&lt;/span&gt; &lt;span style=&#34;color:#0086b3&#34;&gt;set&lt;/span&gt; -eux &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  apk update &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk upgrade &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;        wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;        apk --no-cache add unzip vim curl git bash ca-certificates glibc-2.30-r0.apk file &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;  rm -rf /var/lib/apk/* &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&lt;/span&gt;        mkdir -p /usr/skywalking/agent/&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# A streamlined jre&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ADD&lt;/span&gt; jdk1.8.0_221/ /usr/java/jdk1.8.0_221/&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ADD&lt;/span&gt; apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# set env&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ENV&lt;/span&gt; JAVA_HOME /usr/java/jdk1.8.0_221&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ENV&lt;/span&gt; PATH &lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;PATH&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;:&lt;span style=&#34;color:#d14&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;JAVA_HOME&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;}&lt;/span&gt;/bin&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# run container with base path:/&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;WORKDIR&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt; /&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;CMD&lt;/span&gt; bash&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里由于 alpine 是基于mini lib 的，但是 java 需要 glibc ,所以加入了 glibc 相关的东西，最后构建出的镜像大小在 490M 左右，因为加了挺多命令还是有点大，仅供参考，同样构建出的镜像也可以直接配置到 jenkins 中。&lt;/p&gt;
&lt;h5 id=&#34;3sidecar-模式挂载-agent&#34;&gt;3.sidecar 模式挂载 agent&lt;/h5&gt;
&lt;p&gt;如果你们的服务是部署在 Kubernetes 中，你还可以使用这种方式来使用 Skywalking Agent ,这种方式的好处在与不需要修改原来的基础镜像，也不用重新构建新的服务镜像，而是以sidecar 模式，通过共享volume的方式将agent 所需的相关文件挂载到已经存在的服务镜像中&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构建 skywalking agent sidecar 镜像的方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;下载skywalking &lt;a href=&#34;https://www.apache.org/dyn/closer.cgi/skywalking/6.3.0/apache-skywalking-apm-6.3.0.tar.gz&#34;&gt;官方发行包&lt;/a&gt;，并解压&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;wget https://www.apache.org/dyn/closer.cgi/skywalking/6.3.0/apache-skywalking-apm-6.3.0.tar.gz &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; tar -zxvf apache-skywalking-apm-6.3.0.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过以下 dockerfile 进行构建&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt; busybox:latest &lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ENV&lt;/span&gt; &lt;span style=&#34;color:#008080&#34;&gt;LANG&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;C.UTF-8&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;RUN&lt;/span&gt; &lt;span style=&#34;color:#0086b3&#34;&gt;set&lt;/span&gt; -eux &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; mkdir -p /usr/skywalking/agent/&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ADD&lt;/span&gt; apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;WORKDIR&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt; /&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：这里我没有在dockerfile中下载skywalking 发行包是因为保证构建出的 sidecar 镜像保持最小，bosybox 只有700 k左右，加上 agent 最后大小小于20M&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如何使用 sidecar 呢？&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-sw&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-sw&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;replicas&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-sw&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;template&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-sw&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;initContainers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;innerpeacez/sw-agent-sidecar:latest&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sw-agent-sidecar&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;imagePullPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;IfNotPresent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;sh&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;args&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;-c&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#d14&#34;&gt;&amp;#39;mkdir -p /skywalking/agent &amp;amp;&amp;amp; cp -r /usr/skywalking/agent/* /skywalking/agent&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/skywalking/agent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sw-agent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;nginx:&lt;span style=&#34;color:#099&#34;&gt;1.7.9&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;nginx&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/usr/skywalking/agent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sw-agent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sw-agent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;emptyDir&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上是挂载 sidecar 的 deployment.yaml 文件，以nginx 作为服务为例，主要是通过共享 volume 的方式挂载 agent，首先 initContainers 通过 sw-agent 卷挂载了 sw-agent-sidecar 中的 /skywalking/agent ，并且将上面构建好的镜像中的 agent 目录 cp 到了 /skywalking/agent 目录，完成之后 nginx 启动时也挂载了 sw-agent 卷，并将其挂载到了容器的 /usr/skywalking/agent 目录，这样就完成了共享过程。&lt;/p&gt;
&lt;h4 id=&#34;总结&#34;&gt;总结&lt;/h4&gt;
&lt;p&gt;这样除去 ServiceMesh 以外，我能想到的方式就介绍完了，希望可以帮助到你。最后给 &lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Skywalking 一个 Star 吧&lt;/a&gt;，国人的骄傲。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking调研与初步实践</title>
      <link>/zh/2019-03-29-introduction-of-skywalking-and-simple-practice/</link>
      <pubDate>Sat, 23 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-03-29-introduction-of-skywalking-and-simple-practice/</guid>
      <description>
        
        
        &lt;h2 id=&#34;apm和调用链跟踪&#34;&gt;APM和调用链跟踪&lt;/h2&gt;
&lt;p&gt;随着企业经营规模的扩大，以及对内快速诊断效率和对外SLA（服务品质协议，service-level agreement)的追求，对于业务系统的掌控度的要求越来越高，主要体现在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于第三方依赖的监控，实时/准实时了解第三方的健康状况/服务品质，降低第三方依赖对于自身系统的扰动（服务降级、故障转移）&lt;/li&gt;
&lt;li&gt;对于容器的监控，实时/准实时的了解应用部署环境（CPU、内存、进程、线程、网络、带宽）情况，以便快速扩容/缩容、流量控制、业务迁移&lt;/li&gt;
&lt;li&gt;业务方对于自己的调用情况，方便作容量规划，同时对于突发的请求也能进行异常告警和应急准备&lt;/li&gt;
&lt;li&gt;自己业务的健康、性能监控，实时/准实时的了解自身的业务运行情况，排查业务瓶颈，快速诊断和定位异常，增加对自己业务的掌控力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时，对于企业来说，能够更精确的了解资源的使用情况，对于成本核算和控制也有非常大的裨益。&lt;/p&gt;
&lt;p&gt;在这种情况下，一般都会引入APM（Application Performance Management &amp;amp; Monitoring）系统，通过各种探针采集数据，收集关键指标，同时搭配数据呈现和监控告警，能够解决上述的大部分问题。&lt;/p&gt;
&lt;p&gt;然而随着RPC框架、微服务、云计算、大数据的发展，同时业务的规模和深度相比过往也都增加了很多，一次业务可能横跨多个模块/服务/容器，依赖的中间件也越来越多，其中任何一个节点出现异常，都可能导致业务出现波动或者异常，这就导致服务质量监控和异常诊断/定位变得异常复杂，于是催生了新的业务监控模式：调用链跟踪&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能够分布式的抓取多个节点的业务记录，并且通过统一的业务id（traceId，messageId，requestId等）将一次业务在各个节点的记录串联起来，方便排查业务的瓶颈或者异常点&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;产品对比&#34;&gt;产品对比&lt;/h4&gt;
&lt;p&gt;APM和调用链跟踪均不是新诞生事务，很多公司已经有了大量的实践，不过开源的并且能够开箱即用的产品并不多，这里主要选取了Pinpoint，Skywalking，CAT来进行对比（当然也有其他的例如Zipkin，Jaeger等产品，不过总体来说不如前面选取的3个完成度高），了解一下APM和调用链跟踪在开源方面的发展状态。&lt;/p&gt;
&lt;h6 id=&#34;pinpoint&#34;&gt;Pinpoint&lt;/h6&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/naver/pinpoint&#34;&gt;Pinpoint&lt;/a&gt;是一个比较早并且成熟度也非常高的APM+调用链监控的项目，在全世界范围内均有用户使用，支持Java和PHP的探针，数据容器为HBase，其界面参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q40u9jj316z0q7gpl.jpg&#34; alt=&#34;pinpoint_server-map&#34;&gt;&lt;/p&gt;
&lt;h6 id=&#34;skywalking&#34;&gt;Skywalking&lt;/h6&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/apache/incubator-skywalking&#34;&gt;Skywalking&lt;/a&gt;是一个新晋的项目，最近一两年发展非常迅猛，本身支持OpenTracing规范，优秀的设计提供了良好的扩展性，支持Java、PHP、.Net、NodeJs探针，数据容器为ElasticSearch，其界面参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qcx4bzj31h10qjtcv.jpg&#34; alt=&#34;skywalking-dashboard&#34;&gt;&lt;/p&gt;
&lt;h6 id=&#34;cat&#34;&gt;CAT&lt;/h6&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/dianping/cat&#34;&gt;CAT&lt;/a&gt;是由美团开源的一个APM项目，也历经了多年的迭代升级，拥有大量的企业级用户，对于监控和报警整合比较紧密，支持Java、C/C++、.Net、Python、Go、NodeJs，不过CAT目前主要通过侵入性的方式接入，数据容器包括HDFS（存储原始数据）和mysql（二次统计），其界面参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q862ehj31go0os0vv.jpg&#34; alt=&#34;CAT&#34;&gt;&lt;/p&gt;
&lt;h6 id=&#34;横向对比&#34;&gt;横向对比&lt;/h6&gt;
&lt;p&gt;上面只是做了一个简介，那这三个项目各自有什么特色或者优势/劣势呢（三者的主要产品均针对Java，这里也主要针对Java的特性）？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pinpoint
&lt;ul&gt;
&lt;li&gt;优势
&lt;ul&gt;
&lt;li&gt;大企业/长时间验证，稳定性和完成度高&lt;/li&gt;
&lt;li&gt;探针收集的数据粒度比较细&lt;/li&gt;
&lt;li&gt;HBase的数据密度较大，支持PB级别下的数据查询&lt;/li&gt;
&lt;li&gt;代码设计考虑的扩展性较弱，二次开发难度较大（探针为插件式，开发比较简单）&lt;/li&gt;
&lt;li&gt;拥有完整的APM和调用链跟踪功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;劣势
&lt;ul&gt;
&lt;li&gt;代码针对性强，扩展较难&lt;/li&gt;
&lt;li&gt;容器为HBase，查询功能较弱（主要为时间维度）&lt;/li&gt;
&lt;li&gt;探针的额外消耗较多（探针采集粒度细，大概10%~20%）&lt;/li&gt;
&lt;li&gt;项目趋于成熟，而扩展难度较大，目前社区活跃度偏低，基本只进行探针的增加或者升级&lt;/li&gt;
&lt;li&gt;缺少自定义指标的设计&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Skywalking
&lt;ul&gt;
&lt;li&gt;优势
&lt;ul&gt;
&lt;li&gt;数据容器为ES，查询支持的维度较多并且扩展潜力大&lt;/li&gt;
&lt;li&gt;项目设计采用微内核+插件，易读性和扩展性都比较强&lt;/li&gt;
&lt;li&gt;主要的研发人员为华人并且均比较活跃，能够进行更加直接的沟通&lt;/li&gt;
&lt;li&gt;拥有完整的APM和调用链跟踪功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;劣势
&lt;ul&gt;
&lt;li&gt;项目发展非常快，稳定性有待验证&lt;/li&gt;
&lt;li&gt;ES数据密度较小，在PB级别可能会有性能压力&lt;/li&gt;
&lt;li&gt;缺少自定义指标的设计&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CAT
&lt;ul&gt;
&lt;li&gt;优势
&lt;ul&gt;
&lt;li&gt;大企业/长时间验证，稳定性和完成度高&lt;/li&gt;
&lt;li&gt;采用手动数据埋点而不是探针，数据采集的灵活性更强&lt;/li&gt;
&lt;li&gt;支持自定义指标&lt;/li&gt;
&lt;li&gt;代码设计考虑的扩展性较弱，并且数据结构复杂，二次开发难度较大&lt;/li&gt;
&lt;li&gt;拥有完善的监控告警机制&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;劣势
&lt;ul&gt;
&lt;li&gt;代码针对性强，扩展较难&lt;/li&gt;
&lt;li&gt;需要手动接入埋点，代码侵入性强&lt;/li&gt;
&lt;li&gt;APM功能完善，但是不支持调用链跟踪&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;基本组件&#34;&gt;基本组件&lt;/h4&gt;
&lt;p&gt;如果分别去看Pinpoint/Skywalking/CAT的整体设计，我们会发现三者更像是一个规范的三种实现，虽然各自有不同的机制和特性，但是从模块划分和功能基本是一致的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qa2gf2j30no0gvwfd.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;当然也有一些微小的区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pinpoint基本没有aggregator，同时query和alarm集成在了web中，只有agent，collector和web&lt;/li&gt;
&lt;li&gt;Skywalking则是把collector、aggregator、alarm集成为OAP（Observability Analysis Platform），并且可以通过集群部署，不同的实例可以分别承担collector或者aggregator+alarm的角色&lt;/li&gt;
&lt;li&gt;CAT则和Skywalking类似，把collector、aggregator、alarm集成为cat-consumer，而由于CAT有比较复杂的配置管理，所以query和配置一起集成为cat-home&lt;/li&gt;
&lt;li&gt;当然最大的区别是Pinpoint和Skywalking均是通过javaagent做字节码的扩展，通过切面编程采集数据，类似于探针，而CAT的agent则更像是一个工具集，用于手动埋点&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;skywalking-1&#34;&gt;Skywalking&lt;/h2&gt;
&lt;p&gt;前戏这么多，终于开始进入主题，介绍今天的主角：Skywalking，不过通过之前的铺垫，我们基本都知道了Skywalking期望解决的问题以及总体的结构，下面我们则从细节来看Skywalking是怎么一步一步实现的。&lt;/p&gt;
&lt;h4 id=&#34;模块构成&#34;&gt;模块构成&lt;/h4&gt;
&lt;p&gt;首先，Skywalking进行了精准的领域模型划分：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qcfso8j31ol0u0te6.jpg&#34; alt=&#34;integration&#34;&gt;&lt;/p&gt;
&lt;p&gt;整个系统分为三部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent：采集tracing（调用链数据）和metric（指标）信息并上报&lt;/li&gt;
&lt;li&gt;OAP：收集tracing和metric信息通过analysis core模块将数据放入持久化容器中（ES，H2（内存数据库），mysql等等），并进行二次统计和监控告警&lt;/li&gt;
&lt;li&gt;webapp：前后端分离，前端负责呈现，并将查询请求封装为graphQL提交给后端，后端通过ribbon做负载均衡转发给OAP集群，再将查询结果渲染展示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而整个Skywalking（包括agent和OAP，而webapp后端业务非常简单主要就是认证和请求转发）均通过微内核+插件式的模式进行编码，代码结构和扩展性均非常强，具体设计可以参考： &lt;a href=&#34;https://linz.ink/skywalking/microcore/2018/11/26/how-to-build-micro-core-project-by-skywalking-style.html&#34;&gt;从Skywalking看如何设计一个微核+插件式扩展的高扩展框架&lt;/a&gt; ，Spring Cloud Gateway的GatewayFilterFactory的扩展也是通过这种plugin define的方式来实现的。&lt;/p&gt;
&lt;p&gt;Skywalking也提供了其他的一些特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置重载：支持通过jvm参数覆写默认配置，支持动态配置管理&lt;/li&gt;
&lt;li&gt;集群管理：这个主要体现在OAP，通过集群部署分担数据上报的流量压力和二次计算的计算压力，同时集群也可以通过配置切换角色，分别面向数据采集（collector）和计算（aggregator，alarm），需要注意的是agent目前不支持多collector负载均衡，而是随机从集群中选择一个实例进行数据上报&lt;/li&gt;
&lt;li&gt;支持k8s和mesh&lt;/li&gt;
&lt;li&gt;支持数据容器的扩展，例如官方主推是ES，通过扩展接口，也可以实现插件去支持其他的数据容器&lt;/li&gt;
&lt;li&gt;支持数据上报receiver的扩展，例如目前主要是支持gRPC接受agent的上报，但是也可以实现插件支持其他类型的数据上报（官方默认实现了对Zipkin，telemetry和envoy的支持）&lt;/li&gt;
&lt;li&gt;支持客户端采样和服务端采样，不过服务端采样最有意义&lt;/li&gt;
&lt;li&gt;官方制定了一个数据查询脚本规范：OAL（Observability Analysis Language），语法类似Linq，以简化数据查询扩展的工作量&lt;/li&gt;
&lt;li&gt;支持监控预警，通过OAL获取数据指标和阈值进行对比来触发告警，支持webhook扩展告警方式，支持统计周期的自定义，以及告警静默防止重复告警&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;数据容器&#34;&gt;数据容器&lt;/h4&gt;
&lt;p&gt;由于Skywalking并没有自己定制的数据容器或者使用多种数据容器增加复杂度，而是主要使用ElasticSearch（当然开源的基本上都是这样来保持简洁，例如Pinpoint也只使用了HBase），所以数据容器的特性以及自己数据结构基本上就限制了业务的上限，以ES为例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ES查询功能异常强大，在数据筛选方面碾压其他所有容器，在数据筛选潜力巨大（Skywalking默认的查询维度就比使用HBase的Pinpoint强很多）&lt;/li&gt;
&lt;li&gt;支持sharding分片和replicas数据备份，在高可用/高性能/大数据支持都非常好&lt;/li&gt;
&lt;li&gt;支持批量插入，高并发下的插入性能大大增强&lt;/li&gt;
&lt;li&gt;数据密度低，源于ES会提前构建大量的索引来优化搜索查询，这是查询功能强大和性能好的代价，但是链路跟踪往往有非常多的上下文需要记录，所以Skywalking把这些上下文二进制化然后通过Base64编码放入data_binary字段并且将字段标记为&lt;strong&gt;not_analyzed&lt;/strong&gt;来避免进行预处理建立查询索引&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体来说，Skywalking尽量使用ES在大数据和查询方面的优势，同时尽量减少ES数据密度低的劣势带来的影响，从目前来看，ES在调用链跟踪方面是不二的数据容器，而在数据指标方面，ES也能中规中矩的完成业务，虽然和时序数据库相比要弱一些，但在PB级以下的数据支持也不会有太大问题。&lt;/p&gt;
&lt;h4 id=&#34;数据结构&#34;&gt;数据结构&lt;/h4&gt;
&lt;p&gt;如果说数据容器决定了上限，那么数据结构则决定了实际到达的高度。Skywalking的数据结构主要为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据维度（ES索引为skywalking_*_inventory)
&lt;ul&gt;
&lt;li&gt;service：服务&lt;/li&gt;
&lt;li&gt;instance：实例&lt;/li&gt;
&lt;li&gt;endpoint：接口&lt;/li&gt;
&lt;li&gt;network_adress：外部依赖&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数据内容
&lt;ul&gt;
&lt;li&gt;原始数据
&lt;ul&gt;
&lt;li&gt;调用链跟踪数据（调用链的trace信息，ES索引为skywalking_segment，Skywalking主要的数据消耗都在这里）&lt;/li&gt;
&lt;li&gt;指标（主要是jvm或者envoy的运行时指标，例如ES索引skywalking_instance_jvm_cpu）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;二次统计指标
&lt;ul&gt;
&lt;li&gt;指标（按维度/时间二次统计出来的例如pxx、sla等指标，例如ES索引skywalking_database_access_p75_month）&lt;/li&gt;
&lt;li&gt;数据库慢查询记录（数据库索引：skywalking_top_n_database_statement）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;关联关系（维度/指标之间的关联关系，ES索引为skywalking_*_relation_*)&lt;/li&gt;
&lt;li&gt;特别记录
&lt;ul&gt;
&lt;li&gt;告警信息（ES索引为skywalking_alarm_record）&lt;/li&gt;
&lt;li&gt;并发控制（ES索引为skywalking_register_lock）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中数量占比最大的就是调用链跟踪数据和各种指标，而这些数据均可以通过OAP设置过期时间，以降低历史数据的对磁盘占用和查询效率的影响。&lt;/p&gt;
&lt;h6 id=&#34;调用链跟踪数据&#34;&gt;调用链跟踪数据&lt;/h6&gt;
&lt;p&gt;作为Skywalking的核心数据，调用链跟踪数据（skywalking_segment）基本上奠定了整个系统的基础，而如果要详细的了解调用链跟踪的话，就不得不提到&lt;a href=&#34;https://opentracing.io/&#34;&gt;openTracing&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;openTracing基本上是目前开源调用链跟踪系统的一个事实标准，它制定了调用链跟踪的基本流程和基本的数据结构，同时也提供了各个语言的实现。如果用一张图来表现openTracing，则是如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q9qhwaj30ms0fdjrl.jpg&#34; alt=&#34;openTracing基本结构&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SpanContext：一个类似于MDC（Slfj)或者ThreadLocal的组件，负责整个调用链数据采集过程中的上下文保持和传递&lt;/li&gt;
&lt;li&gt;Trace：一次调用的完整记录
&lt;ul&gt;
&lt;li&gt;Span：一次调用中的某个节点/步骤，类似于一层堆栈信息，Trace是由多个Span组成，Span和Span之间也有父子或者并列的关系来标志这个节点/步骤在整个调用中的位置
&lt;ul&gt;
&lt;li&gt;Tag：节点/步骤中的关键信息&lt;/li&gt;
&lt;li&gt;Log：节点/步骤中的详细记录，例如异常时的异常堆栈&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Baggage：和SpanContext一样并不属于数据结构而是一种机制，主要用于跨Span或者跨实例的上下文传递，Baggage的数据更多是用于运行时，而不会进行持久化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以一个Trace为例：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q8omk9j30kg0bgabj.jpg&#34; alt=&#34;span间的关系&#34;&gt;&lt;/p&gt;
&lt;p&gt;首先是外部请求调用A，然后A依次同步调用了B和C，而B被调用时会去同步调用D，C被调用的时候会依次同步调用E和F，F被调用的时候会通过异步调用G，G则会异步调用H，最终完成一次调用。&lt;/p&gt;
&lt;p&gt;上图是通过Span之间的依赖关系来表现一个Trace，而在时间线上，则可以有如下的表达：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q960foj30q009674i.jpg&#34; alt=&#34;span的调用顺序&#34;&gt;&lt;/p&gt;
&lt;p&gt;当然，如果是同步调用的话，父Span的时间占用是包括子Span的时间消耗的。&lt;/p&gt;
&lt;p&gt;而落地到Skywalking中，我们以一条skywalking_segment的记录为例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
	&amp;quot;trace_id&amp;quot;: &amp;quot;52.70.15530767312125341&amp;quot;,
	&amp;quot;endpoint_name&amp;quot;: &amp;quot;Mysql/JDBI/Connection/commit&amp;quot;,
	&amp;quot;latency&amp;quot;: 0,
	&amp;quot;end_time&amp;quot;: 1553076731212,
	&amp;quot;endpoint_id&amp;quot;: 96142,
	&amp;quot;service_instance_id&amp;quot;: 52,
	&amp;quot;version&amp;quot;: 2,
	&amp;quot;start_time&amp;quot;: 1553076731212,
	&amp;quot;data_binary&amp;quot;: &amp;quot;CgwKCjRGnPvp5eikyxsSXhD///////////8BGMz62NSZLSDM+tjUmS0wju8FQChQAVgBYCF6DgoHZGIudHlwZRIDc3FsehcKC2RiLmluc3RhbmNlEghyaXNrZGF0YXoOCgxkYi5zdGF0ZW1lbnQYAiA0&amp;quot;,
	&amp;quot;service_id&amp;quot;: 2,
	&amp;quot;time_bucket&amp;quot;: 20190320181211,
	&amp;quot;is_error&amp;quot;: 0,
	&amp;quot;segment_id&amp;quot;: &amp;quot;52.70.15530767312125340&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;trace_id：本次调用的唯一id，通过snowflake模式生成&lt;/li&gt;
&lt;li&gt;endpoint_name：被调用的接口&lt;/li&gt;
&lt;li&gt;latency：耗时&lt;/li&gt;
&lt;li&gt;end_time：结束时间戳&lt;/li&gt;
&lt;li&gt;endpoint_id：被调用的接口的唯一id&lt;/li&gt;
&lt;li&gt;service_instance_id：被调用的实例的唯一id&lt;/li&gt;
&lt;li&gt;version：本数据结构的版本号&lt;/li&gt;
&lt;li&gt;start_time：开始时间戳&lt;/li&gt;
&lt;li&gt;data_binary：里面保存了本次调用的所有Span的数据，序列化并用Base64编码，不会进行分析和用于查询&lt;/li&gt;
&lt;li&gt;service_id：服务的唯一id&lt;/li&gt;
&lt;li&gt;time_bucket：调用所处的时段&lt;/li&gt;
&lt;li&gt;is_error：是否失败&lt;/li&gt;
&lt;li&gt;segment_id：数据本身的唯一id，类似于主键，通过snowflake模式生成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里可以看到，目前Skywalking虽然相较于Pinpoint来说查询的维度要多一些，但是也很有限，而且除了endPoint，并没有和业务有关联的字段，只能通过时间/服务/实例/接口/成功标志/耗时来进行非业务相关的查询，如果后续要增强业务相关的搜索查询的话，应该还需要增加一些用于保存动态内容（如messageId，orderId等业务关键字）的字段用于快速定位。&lt;/p&gt;
&lt;h6 id=&#34;指标&#34;&gt;指标&lt;/h6&gt;
&lt;p&gt;指标数据相对于Tracing则要简单得多了，一般来说就是指标标志、时间戳、指标值，而Skywalking中的指标有两种：一种是采集的原始指标值，例如jvm的各种运行时指标（例如cpu消耗、内存结构、GC信息等）；一种是各种二次统计指标（例如tp性能指标、SLA等，当然也有为了便于查询的更高时间维度的指标，例如基于分钟、小时、天、周、月）&lt;/p&gt;
&lt;p&gt;例如以下是索引skywalking_endpoint_cpm_hour中的一条记录，用于标志一个小时内某个接口的cpm指标：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
	&amp;quot;total&amp;quot;: 8900,
	&amp;quot;service_id&amp;quot;: 5,
	&amp;quot;time_bucket&amp;quot;: 2019031816,
	&amp;quot;service_instance_id&amp;quot;: 5,
	&amp;quot;entity_id&amp;quot;: &amp;quot;7&amp;quot;,
	&amp;quot;value&amp;quot;: 148
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;各个字段的释义如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;total：一分钟内的调用总量&lt;/li&gt;
&lt;li&gt;service_id：所属服务的唯一id&lt;/li&gt;
&lt;li&gt;time_bucket：统计的时段&lt;/li&gt;
&lt;li&gt;service_instance_id：所属实例的唯一id&lt;/li&gt;
&lt;li&gt;entity_id：接口（endpoint）的唯一id&lt;/li&gt;
&lt;li&gt;value：cpm的指标值（cpm=call per minute，即total/60）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;工程实现&#34;&gt;工程实现&lt;/h4&gt;
&lt;p&gt;Skywalking的工程实现堪比Dubbo，框架设计和代码质量都达到非常高的水准，以dubbo为例，即使2012年发布的老版本放到当今，其设计和编码看起来也依然赏心悦目，设计简洁但是覆盖了所有的核心需求，同时又具备非常强的扩展性，二次开发非常简单，然而却又不会像Spring那样过度封装（当然Spring作为一个更加高度通用的框架，更高的封装也是有必要的）导致代码阅读异常困难。&lt;/p&gt;
&lt;h6 id=&#34;agent&#34;&gt;agent&lt;/h6&gt;
&lt;p&gt;agent（apm-sniffer）是Skywalking的Java探针实现，主要负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;采集应用实例的jvm指标&lt;/li&gt;
&lt;li&gt;通过切向编程进行数据埋点，采集调用链数据&lt;/li&gt;
&lt;li&gt;通过RPC将采集的数据上报&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，agent还实现了客户端采样，不过在APM监控系统里进行客户端数据采样都是没有灵魂的，所以这里就不再赘述了。&lt;/p&gt;
&lt;p&gt;首先，agent通过 &lt;em&gt;org.apache.skywalking.apm.agent.core.boot.BootService&lt;/em&gt; 实现了整体的插件化，agent启动会加载所有的BootService实现，并通过 &lt;em&gt;ServiceManager&lt;/em&gt; 来管理这些插件的生命周期，采集jvm指标、gRPC连接管理、调用链数据维护、数据上报OAP这些服务均是通过这种方式扩展。&lt;/p&gt;
&lt;p&gt;然后，agent还通过bytebuddy以javaagent的模式，通过字节码增强的机制来构造AOP环境，再提供PluginDefine的规范方便探针的开发，最终实现非侵入性的数据埋点，采集调用链数据。&lt;/p&gt;
&lt;p&gt;最终落地到代码上则异常清晰：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//通过bytebuddy的AgentBuilder构造javaagent增强classLoader
new AgentBuilder.Default(byteBuddy)
    .ignore( //忽略这些包的内容，不进行增强
        nameStartsWith(&amp;quot;net.bytebuddy.&amp;quot;)
        .or(nameStartsWith(&amp;quot;org.slf4j.&amp;quot;))
        .or(nameStartsWith(&amp;quot;org.apache.logging.&amp;quot;))
        .or(nameStartsWith(&amp;quot;org.groovy.&amp;quot;))
        .or(nameContains(&amp;quot;javassist&amp;quot;))
        .or(nameContains(&amp;quot;.asm.&amp;quot;))
        .or(nameStartsWith(&amp;quot;sun.reflect&amp;quot;))
        .or(allSkyWalkingAgentExcludeToolkit())
        .or(ElementMatchers.&amp;lt;TypeDescription&amp;gt;isSynthetic()))
    //通过pluginFinder加载所有的探针扩展，并获取所有可以增强的class
    .type(pluginFinder.buildMatch())
    //按照pluginFinder的实现，去改变字节码增强类
    .transform(new Transformer(pluginFinder))
    //通过listener订阅增强的操作记录，方便调试
    .with(new Listener())
    .installOn(instrumentation);

try {
    //加载所有的service实现并启动
    ServiceManager.INSTANCE.boot();
} catch (Exception e) {
    logger.error(e, &amp;quot;Skywalking agent boot failure.&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;agent也提供了非常简单的扩展实现机制，以增强一个普通类的方法为例，首先你需要定义一个切向点：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface InstanceMethodsInterceptPoint {

    //定义切向方法的适配器，符合适配器的class将被增强
    ElementMatcher&amp;lt;MethodDescription&amp;gt; getMethodsMatcher();

    //增强的具体实现类，classReference
    String getMethodsInterceptor();

    //是否重写参数
    boolean isOverrideArgs();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后你还需要一个增强的实现类：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface InstanceMethodsAroundInterceptor {

    //方法真正执行前执行
    void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class&amp;lt;?&amp;gt;[] argumentsTypes,
        MethodInterceptResult result) throws Throwable;

    //方法真正执行后执行
    Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class&amp;lt;?&amp;gt;[] argumentsTypes,
        Object ret) throws Throwable;

    //当异常发生时执行
    void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class&amp;lt;?&amp;gt;[] argumentsTypes,
        Throwable t);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一般在执行前和执行后进行数据埋点，就可以采集到想要的数据，当然实际编程要稍微复杂一点，不过官方也实现了对应的abstract类和数据埋点工具类，所以探针的二次开发在Skywalking这个级别确实是非常简单，只需要处理好资源占用和并发问题即可。真正的难点是要对需要增强的对象非常了解，熟悉其运作机制，才能找准切向点，既要所有的流程都需要经过这个点，又可以抓取到期望抓取的上下文信息。同时，多版本的适配和测试也是非常大的工作量，官方虽然提供witness的机制（通过验证某个class是否存在来验证版本），但是作为影响全局的探针，开发和测试都是需要慎之又慎的。&lt;/p&gt;
&lt;h6 id=&#34;oap&#34;&gt;OAP&lt;/h6&gt;
&lt;p&gt;同agent类似，OAP作为Skywalking最核心的模块，也实现了自己的扩展机制，不过在这里叫做Module，具体可以参考library-module，在module的机制下，Skywalking实现了自己必须核心组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;core：整个OAP核心业务（remoting、cluster、storage、analysis、query、alarm）的规范和接口&lt;/li&gt;
&lt;li&gt;cluster：集群管理的具体实现&lt;/li&gt;
&lt;li&gt;storage：数据容器的具体实现&lt;/li&gt;
&lt;li&gt;query：为前端提供的查询接口的具体实现&lt;/li&gt;
&lt;li&gt;receiver：接收探针上报数据的接收器的具体实现&lt;/li&gt;
&lt;li&gt;alarm：监控告警的具体实现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以及一个可选组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;telemetry：用于监控OAP自身的健康状况&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而前面提到的OAP的高扩展性则体现在核心业务的规范均定义在了core中，如果有需要自己扩展的，只需要自己单独做自己的实现，而不需要做侵入式的改动，最典型的示例则是官方支持的storage，不仅支持单机demo的内存数据库H2和经典的ES，连目前开源的Tidb都可以接入。&lt;/p&gt;
&lt;h2 id=&#34;初步实践&#34;&gt;初步实践&lt;/h2&gt;
&lt;p&gt;对于Skywalking的实践我们经历了三个阶段&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;线下测试&lt;/li&gt;
&lt;li&gt;第一次生产环境小规模测试&lt;/li&gt;
&lt;li&gt;第二次生产环境小规模测试+全量接入&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;线下测试&#34;&gt;线下测试&lt;/h4&gt;
&lt;h6 id=&#34;环境&#34;&gt;环境&lt;/h6&gt;
&lt;p&gt;由于是线下测试，所以我们直接使用物理机（E5-2680v2 x2, 128G)虚拟了一个集群（实际性能相比云服务器应该偏好一些）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ES：单机实例，v6.5，4C8G，jvm内存分配为4G&lt;/li&gt;
&lt;li&gt;OAP：单机实例，v6.1.0-SNAPSHOT，4C8G，jvm内存分配为4G&lt;/li&gt;
&lt;li&gt;应用：基于SpringCloud的4个测试实例,调用关系为A-&amp;gt;B-&amp;gt;C-&amp;gt;D，QPS为200&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&#34;测试结果&#34;&gt;测试结果&lt;/h6&gt;
&lt;p&gt;拓扑图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q5cqinj30o90dx3za.jpg&#34; alt=&#34;测试拓扑图&#34;&gt;&lt;/p&gt;
&lt;p&gt;OAP机器监控：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qanxy5j30fn0gb750.jpg&#34; alt=&#34;OAP监控&#34;&gt;&lt;/p&gt;
&lt;p&gt;ES机器监控：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qbzgx2j30fn0js3zn.jpg&#34; alt=&#34;es机器监控&#34;&gt;&lt;/p&gt;
&lt;p&gt;服务监控面板：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q0e7zwj30t20ta0vh.jpg&#34; alt=&#34;服务面板&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中一个调用链记录：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q60h0uj30oo0dt0u5.jpg&#34; alt=&#34;测试调用链&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以看出，Skywalking非常依赖CPU（不论是OAP还是ES），同时对于网络IO也有一定的要求，至于ES的文件IO在可接受范围内，毕竟确实有大量内容需要持久化。测试结果也基本达到预期要求，调用链和各个指标的监控都工作良好。&lt;/p&gt;
&lt;h4 id=&#34;第一次生产环境测试&#34;&gt;第一次生产环境测试&lt;/h4&gt;
&lt;p&gt;在线下测试之后，我们再进行了一次基于实际业务针对探针的测试，测试没有发现探针的异常问题，也没有影响业务的正常运作，同时对于jvm实例影响也不是很大，CPU大概提高了5%左右，并不很明显。在这个基础上我们选择了线上的一台服务器，进行了我们第一次生产环境的测试。&lt;/p&gt;
&lt;h6 id=&#34;环境-1&#34;&gt;环境&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;ES：基于现有的一个ES集群，node x 3，v6.0&lt;/li&gt;
&lt;li&gt;OAP：2C4G x 2，v6.1.0-SNAPSHOT，jvm内存分配为2G&lt;/li&gt;
&lt;li&gt;应用：两个jvm实例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试时间：03.11-03.16&lt;/p&gt;
&lt;h6 id=&#34;测试结果-1&#34;&gt;测试结果&lt;/h6&gt;
&lt;p&gt;业务机器负载情况：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q7aczcj30s20ht77p.jpg&#34; alt=&#34;dp1-cpu&#34;&gt;&lt;/p&gt;
&lt;p&gt;从最敏感的CPU指标上来看，增加agent并没有导致可见的CPU使用率的变化，而其他的内存、网络IO、连接数也基本没有变化。&lt;/p&gt;
&lt;p&gt;OAP负载情况：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4qbjk28j30rz0httax.jpg&#34; alt=&#34;第一次测试CPU&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q6jo3sj30rs0lfq5n.jpg&#34; alt=&#34;第一次测试网络&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以看到机器的CPU和网络均有较大的波动，但是也都没有真正打爆服务器，但是我们的实例却经常出现两种日志：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One trace segment has been abandoned, cause by buffer is full.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Collector traceSegment service doesn&amp;rsquo;t response in xxx seconds.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过阅读源码发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent和OAP只会使用一个长连接阻塞式的交换数据，如果某次数据交换没有得到响应，则会阻塞后续的上报流程（一般长连接的RPC请求会在数据传输期间互相阻塞，但是不会在等待期间互相阻塞，当然这也是源于agent并没有并发上报的机制），所以一旦OAP在接收数据的过程中发生阻塞，就会导致agent本地的缓冲区满，最终只能将监控数据直接丢弃防止内存泄漏&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而导致OAP没有及时响应的一方面是OAP本身性能不够（OAP需要承担大量的二次统计工作，通过Jstack统计，长期有超过几十个线程处于RUNNABLE状态，据吴晟描述目前OAP都是高性能模式，后续将会提供配置来支持低性能模式），另一方面可能是ES批量插入效率不够，因此我们修改了OAP的批量插入参数来增加插入频率，降低单次插入数量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000 -&amp;gt; 20} # Execute the bulk every 2000 requests&lt;/li&gt;
&lt;li&gt;bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20 -&amp;gt; 2} # flush the bulk every 20mb&lt;/li&gt;
&lt;li&gt;flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10 -&amp;gt; 2} # flush the bulk every 10 seconds whatever the number of requests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;虽然 &lt;em&gt;service doesn&amp;rsquo;t response&lt;/em&gt; 出现的频率明显降低，但是依然还是会偶尔出现，而每一次出现都会伴随大量的  &lt;em&gt;trace segment has been abandoned&lt;/em&gt; ，推测OAP和ES可能都存在性能瓶颈（应该进行更进一步的诊断确定问题，不过当时直接和吴晟沟通，确认确实OAP非常消耗CPU资源，考虑到当时部署只是2C，并且还部署有其他业务，就没有进一步的测试）。&lt;/p&gt;
&lt;p&gt;同时，在频繁的数据丢弃过程中，也偶发了一个bug：当agent上报数据超时并且大量丢弃数据之后，即使后续恢复正常也能通过日志看到数据正常上报，在查询界面查询的时候，会查不到这个实例上报的数据，不过在重启OAP和agent之后，之前上报的数据又能查询到，这个也和吴晟沟通过，没有其他的案例，后续想重现却也一直没有成功。&lt;/p&gt;
&lt;p&gt;而同时还发现两个更加严重的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我们使用的是线上已经部署好的ES集群，其版本只有6.0，而新的Skywalking使用了6.3的查询特性，导致很多查询执行报错，只能使用最简单的查询&lt;/li&gt;
&lt;li&gt;我们的kafka集群版本也非常古老，不支持v1或者更高版本的header，而kafka的探针强依赖header来传输上下文信息，导致kafka客户端直接报错影响业务，所以也立即移除了kafka的探针&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在这一次测试中，我们基本确认了agent对于应用的影响，同时也发现了一些我们和Skywalking的一些问题，留待后续测试确认。&lt;/p&gt;
&lt;h4 id=&#34;第二次生产环境测试&#34;&gt;第二次生产环境测试&lt;/h4&gt;
&lt;p&gt;为了排除性能和ES版本的影响，测试Skywalking本身的可用性，参考吴晟的建议（这也是在最初技术选型的时候没有选择Pinpoint和CAT的部分原因：一方面Skywalking的功能符合我们的要求，更重要的是有更加直接和效率的和项目维护者直接沟通的渠道），所以这一次我们新申请了ES集群和OAP机器。&lt;/p&gt;
&lt;h6 id=&#34;环境-2&#34;&gt;环境&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;ES：腾讯云托管ES集群，4C16G x 3 SSD，v6.4&lt;/li&gt;
&lt;li&gt;OAP：16C32G，standalone，jvm分配24G&lt;/li&gt;
&lt;li&gt;应用：2~8个jvm实例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试时间：03.18-至今&lt;/p&gt;
&lt;h6 id=&#34;测试结果-2&#34;&gt;测试结果&lt;/h6&gt;
&lt;p&gt;OAP负载情况：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q7qh37j30nh0hmmzv.jpg&#34; alt=&#34;二次测试&#34;&gt;&lt;/p&gt;
&lt;p&gt;ES集群负载：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4q6sscbj30uo0l80wj.jpg&#34; alt=&#34;二测es监控&#34;&gt;&lt;/p&gt;
&lt;p&gt;测试过程中，我们先接入了一台机器上的两个实例，完全没有遇到一测中的延迟或者数据丢弃的问题，三天后我们又接入了另外两台机器的4个实例，这之后两天我们又接入了另外两台机器的2个实例。依然没有遇到一测中的延迟或者数据丢弃的问题。&lt;/p&gt;
&lt;p&gt;而ES负载的监控也基本验证了一测延迟的问题，Skywalking由于较高的并发插入，对于ES的性能压力很大（批量插入时需要针对每条数据分析并且构建查询索引），大概率是ES批量插入性能不够导致延迟，考虑到我们仅仅接入了8个实例，日均segment插入量大概5000万条（即日均5000万次独立调用），如果想支持更大规模的监控，对于ES容量规划势必要留够足够的冗余。同时OAP和ES集群的网络开销也不容忽视，在支撑大规模的监控时，需要集群并且receiver和aggregattor分离部署来分担网络IO的压力。&lt;/p&gt;
&lt;p&gt;而在磁盘容量占用上，我们设置的原始数据7天过期，目前刚刚开始滚动过期，目前segment索引已经累计了314757240条记录总计158G数据，当然我们目前异常记录较少，如果异常记录较多的话，其磁盘开销将会急剧增加（span中会记录异常堆栈信息）。而由于选择的SSD，磁盘的写入和查询性能都很高，即使只有3个节点，也完全没有任何压力。&lt;/p&gt;
&lt;p&gt;而在新版本的ES集群下，Skywalking的所有查询功能都变得可用，和我们之前自己的单独编写的异常指标监控都能完美对照。当然我们也遇到一个问题：Skywalking仅采集了调用记录，但是对于调用过程中的过程数据，除了异常堆栈其他均没有采集，导致真的出现异常也缺少充足的上下文信息还原现场，于是我们扩展了Skywalking的两个探针（我们项目目前重度依赖的组件）：OkHttp（增加对requestBody和responseBody的采集）和SpringMVC（增加了对requestBody的采集），目前工作正常，如果进一步的增加其他的探针，采集到足够的数据，那么我们基本可以脱离ELK了。&lt;/p&gt;
&lt;p&gt;而OAP方面，CPU和内存的消耗远远低于预期的估计，CPU占用率一直较低，而分配的24G内存也仅使用了10+G，完全可以支持更大规模的接入量，不过在网络IO方面可能存在一定的风险，推测应该8C16G的容器就足以支持十万CPM级别的数据接入。&lt;/p&gt;
&lt;p&gt;当然我们在查询也遇到了一些瓶颈，最大的问题就是无法精确的命中某一条调用记录，就如前面的分析，因为segment的数据结构问题，无法进行面向业务的查询（例如messageId、requestId、orderId等），所以如果想精确匹配某一次调用请求，需要通过各个维度的条件约束慢慢缩小范围最后定位。&lt;/p&gt;
&lt;h2 id=&#34;skywalking展望&#34;&gt;Skywalking展望&lt;/h2&gt;
&lt;p&gt;通过上述对Skywalking的剖析和实践，Skywalking确实是一个优秀的APM+调用链跟踪监控系统，能够覆盖大部分使用场景，让研发和运维能够更加实时/准实时的了解线上服务的运行情况。当然Skywailking也不是尽善尽美，例如下面就是个人觉得目前可见的不满足我们期望的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据准实时通过gRPC上报，本地缓存的瓶颈（当然官方主要是为了简化模型，减少依赖，否则Skywalking还依赖ELK就玩得有点大了）
&lt;ul&gt;
&lt;li&gt;缓存队列的长度，过长占据内存，过短容易buffer满丢弃数据&lt;/li&gt;
&lt;li&gt;优雅停机同时又不丢失缓存&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数据上报需要在起点上报，链路回传的时候需要携带SPAN及子SPAN的信息，当链路较长或者SPAN保存的信息较多时，会额外消耗一定的带宽&lt;/li&gt;
&lt;li&gt;skywalking更多是一个APM系统而不是分布式调用链跟踪系统
&lt;ul&gt;
&lt;li&gt;在整个链路的探针上均缺少输入输出的抓取&lt;/li&gt;
&lt;li&gt;在调用链的筛查上并没用进行增强，并且体现在数据结构的设计，例如TAG信息均保存在SPAN信息中，而SPAN信息均被BASE64编码作为数据保存，无法检索，最终trace的筛查只能通过时间/traceId/service/endPoint/state进行非业务相关的搜索&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;skywalking缺少对三方接口依赖的指标，这个对于系统稳定往往非常重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而作为一个初级的使用者，个人觉得我们可以使用有限的人力在以下方向进行扩展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加receiver：整合ELK，通过日志采集采集数据，降低异构系统的采集开发成本&lt;/li&gt;
&lt;li&gt;优化数据结构，提供基于业务关键数据的查询接口&lt;/li&gt;
&lt;li&gt;优化探针，采集更多的业务数据，争取代替传统的ELK日志简单查询，绝大部分异常诊断和定位均可以通过Skywalking即可完成&lt;/li&gt;
&lt;li&gt;增加业务指标监控的模式，能够自定义业务指标（目前官方已经在实现 &lt;a href=&#34;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/backend/metric-exporter.md&#34;&gt;Metric Exporter&lt;/a&gt; ）&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking线上问题排查定位</title>
      <link>/zh/2019-03-01-skywalking-troubleshoot/</link>
      <pubDate>Fri, 01 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-03-01-skywalking-troubleshoot/</guid>
      <description>
        
        
        &lt;h1 id=&#34;前言&#34;&gt;前言&lt;/h1&gt;
&lt;p&gt;首先描述下问题的背景，博主有个习惯，每天上下班的时候看下skywalking的trace页面的error情况。但是某天突然发现生产环境skywalking页面没有任何数据了，页面也没有显示任何的异常，有点慌，我们线上虽然没有全面铺开对接skywalking，但是也有十多个应用。看了应用agent端日志后，其实也不用太担心，对应用毫无影响。大概情况就是这样，但是问题还是要解决，下面就开始排查skywalking不可用的问题。&lt;/p&gt;
&lt;h1 id=&#34;使用到的工具arthas&#34;&gt;使用到的工具arthas&lt;/h1&gt;
&lt;p&gt;Arthas是阿里巴巴开源的一款在线诊断java应用程序的工具，是greys工具的升级版本，深受开发者喜爱。当你遇到以下类似问题而束手无策时，Arthas可以帮助你解决：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这个类从哪个 jar 包加载的？为什么会报各种类相关的 Exception？&lt;/li&gt;
&lt;li&gt;我改的代码为什么没有执行到？难道是我没 commit？分支搞错了？&lt;/li&gt;
&lt;li&gt;遇到问题无法在线上 debug，难道只能通过加日志再重新发布吗？&lt;/li&gt;
&lt;li&gt;线上遇到某个用户的数据处理有问题，但线上同样无法 debug，线下无法重现！&lt;/li&gt;
&lt;li&gt;是否有一个全局视角来查看系统的运行状况？&lt;/li&gt;
&lt;li&gt;有什么办法可以监控到JVM的实时运行状态？&lt;/li&gt;
&lt;li&gt;Arthas采用命令行交互模式，同时提供丰富的 Tab 自动补全功能，进一步方便进行问题的定位和诊断。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;项目地址：https://github.com/alibaba/arthas&lt;/p&gt;
&lt;h1 id=&#34;先定位问题一&#34;&gt;先定位问题一&lt;/h1&gt;
&lt;p&gt;查看skywalking-oap-server.log的日志，发现会有一条异常疯狂的在输出，异常详情如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2019-03-01 09:12:11,578 - org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker -3264081149 [DataCarrier.IndicatorPersistentWorker.endpoint_inventory.Consumser.0.Thread] ERROR [] - Validation Failed: 1: id is too long, must be no longer than 512 bytes but was: 684;
org.elasticsearch.action.ActionRequestValidationException: Validation Failed: 1: id is too long, must be no longer than 512 bytes but was: 684;
        at org.elasticsearch.action.ValidateActions.addValidationError(ValidateActions.java:26) ~[elasticsearch-6.3.2.jar:6.3.2]
        at org.elasticsearch.action.index.IndexRequest.validate(IndexRequest.java:183) ~[elasticsearch-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:515) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:508) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.index(RestHighLevelClient.java:348) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient.forceInsert(ElasticSearchClient.java:141) ~[library-client-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.RegisterEsDAO.forceInsert(RegisterEsDAO.java:66) ~[storage-elasticsearch-plugin-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.lambda$onWork$0(RegisterPersistentWorker.java:83) ~[server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at java.util.HashMap$Values.forEach(HashMap.java:981) [?:1.8.0_201]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.onWork(RegisterPersistentWorker.java:74) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.access$100(RegisterPersistentWorker.java:35) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker$PersistentConsumer.consume(RegisterPersistentWorker.java:120) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.apm.commons.datacarrier.consumer.ConsumerThread.consume(ConsumerThread.java:101) [apm-datacarrier-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.apm.commons.datacarrier.consumer.ConsumerThread.run(ConsumerThread.java:68) [apm-datacarrier-6.0.0-alpha.jar:6.0.0-alpha]
2019-03-01 09:12:11,627 - org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker -3264081198 [DataCarrier.IndicatorPersistentWorker.endpoint_inventory.Consumser.0.Thread] ERROR [] - Validation Failed: 1: id is too long, must be no longer than 512 bytes but was: 684;
org.elasticsearch.action.ActionRequestValidationException: Validation Failed: 1: id is too long, must be no longer than 512 bytes but was: 684;
        at org.elasticsearch.action.ValidateActions.addValidationError(ValidateActions.java:26) ~[elasticsearch-6.3.2.jar:6.3.2]
        at org.elasticsearch.action.index.IndexRequest.validate(IndexRequest.java:183) ~[elasticsearch-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:515) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:508) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.elasticsearch.client.RestHighLevelClient.index(RestHighLevelClient.java:348) ~[elasticsearch-rest-high-level-client-6.3.2.jar:6.3.2]
        at org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient.forceInsert(ElasticSearchClient.java:141) ~[library-client-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.RegisterEsDAO.forceInsert(RegisterEsDAO.java:66) ~[storage-elasticsearch-plugin-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.lambda$onWork$0(RegisterPersistentWorker.java:83) ~[server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at java.util.HashMap$Values.forEach(HashMap.java:981) [?:1.8.0_201]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.onWork(RegisterPersistentWorker.java:74) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker.access$100(RegisterPersistentWorker.java:35) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.oap.server.core.register.worker.RegisterPersistentWorker$PersistentConsumer.consume(RegisterPersistentWorker.java:120) [server-core-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.apm.commons.datacarrier.consumer.ConsumerThread.consume(ConsumerThread.java:101) [apm-datacarrier-6.0.0-alpha.jar:6.0.0-alpha]
        at org.apache.skywalking.apm.commons.datacarrier.consumer.ConsumerThread.run(ConsumerThread.java:68) [apm-datacarrier-6.0.0-alpha.jar:6.0.0-alpha]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以看到，上面的异常输出的时间节点，以这种频率在疯狂的刷新。通过异常message，得知到是因为skywalking在写elasticsearch时，索引的id太长了。下面是elasticsearch的源码：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;id &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; id&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getBytes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;StandardCharsets&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;UTF_8&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; 512&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            validationException &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; addValidationError&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;id is too long, must be no longer than 512 bytes but was: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
                            id&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getBytes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;StandardCharsets&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;UTF_8&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;length&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; validationException&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;具体可见：&lt;a href=&#34;https://github.com/elastic/elasticsearch/blob/5.2/core/src/main/java/org/elasticsearch/action/index/IndexRequest.java#L240&#34;&gt;elasticsearch/action/index/IndexRequest.java#L240&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;问题一&#34;&gt;问题一：&lt;/h2&gt;
&lt;p&gt;通过日志，初步定位是哪个系统的url太长，skywalking在注册url数据时触发elasticsearch针对索引id校验的异常，而skywalking注册失败后会不断的重试，所以才有了上面日志不断刷的现象。&lt;/p&gt;
&lt;h2 id=&#34;问题解决&#34;&gt;问题解决：&lt;/h2&gt;
&lt;p&gt;elasticsearch client在写es前通过硬编码的方式写死了索引id的长度不能超过512字节大小。也就是我们不能通过从ES侧找解决方案了。回到异常的message，只能看到提示id太长，并没有写明id具体是什么，这个异常提示其实是不合格的，博主觉得应该把id的具体内容抛出来，问题就简单了。因为异常没有明确提示，系统又比较多，不能十多个系统依次关闭重启来验证到底是哪个系统的哪个url有问题。这个时候Arthas就派上用场了，在不重启应用不开启debug模式下，查看实例中的属性对象。下面通过Arthas找到具体的url。&lt;/p&gt;
&lt;p&gt;从异常中得知，org.elasticsearch.action.index.IndexRequest这个类的validate方法触发的，这个方法是没有入参的，校验的id属性其实是对象本身的属性，那么我们使用Arthas的watch指令来看下这个实例id属性。先介绍下watch的用法：&lt;/p&gt;
&lt;h3 id=&#34;功能说明&#34;&gt;功能说明&lt;/h3&gt;
&lt;p&gt;让你能方便的观察到指定方法的调用情况。能观察到的范围为：返回值、抛出异常、入参，通过编写 OGNL 表达式进行对应变量的查看。&lt;/p&gt;
&lt;h3 id=&#34;参数说明&#34;&gt;参数说明&lt;/h3&gt;
&lt;p&gt;watch 的参数比较多，主要是因为它能在 4 个不同的场景观察对象&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数名称&lt;/th&gt;
&lt;th&gt;参数说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;class-pattern&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;类名表达式匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;method-pattern&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;方法名表达式匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;express&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;观察表达式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;condition-express&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;条件表达式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[b]&lt;/td&gt;
&lt;td&gt;在&lt;strong&gt;方法调用之前&lt;/strong&gt;观察&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[e]&lt;/td&gt;
&lt;td&gt;在&lt;strong&gt;方法异常之后&lt;/strong&gt;观察&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[s]&lt;/td&gt;
&lt;td&gt;在&lt;strong&gt;方法返回之后&lt;/strong&gt;观察&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[f]&lt;/td&gt;
&lt;td&gt;在&lt;strong&gt;方法结束之后&lt;/strong&gt;(正常返回和异常返回)观察&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[E]&lt;/td&gt;
&lt;td&gt;开启正则表达式匹配，默认为通配符匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[x:]&lt;/td&gt;
&lt;td&gt;指定输出结果的属性遍历深度，默认为 1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;从上面的用法说明结合异常信息，我们得到了如下的指令脚本：&lt;/p&gt;
&lt;p&gt;watch org.elasticsearch.action.index.IndexRequest validate &amp;ldquo;target&amp;rdquo;&lt;/p&gt;
&lt;p&gt;执行后，就看到了我们希望了解到的内容，如：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4mgci6pj316e0iv77t.jpg&#34; alt=&#34;Arthas&#34;&gt;&lt;/p&gt;
&lt;p&gt;索引id的具体内容看到后，就好办了。我们暂时把定位到的这个应用启动脚本中的的skywalking agent移除后（计划后面重新设计下接口）重启了下系统验证下。果然疯狂输出的日志停住了，但是问题并没完全解决，skywalking页面上的数据还是没有恢复。&lt;/p&gt;
&lt;h1 id=&#34;定位问题二&#34;&gt;定位问题二&lt;/h1&gt;
&lt;p&gt;skywalking数据存储使用了elasticsearch，页面没有数据，很有可能是elasticsearch出问题了。查看elasticsearch日志后，发现elasticsearch正在疯狂的GC，日志如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;: 139939K-&amp;gt;3479K(153344K), 0.0285655 secs] 473293K-&amp;gt;336991K(5225856K), 0.0286918 secs] [Times: user=0.05 sys=0.00, real=0.03 secs] 
2019-02-28T20:05:38.276+0800: 3216940.387: Total time for which application threads were stopped: 0.0301495 seconds, Stopping threads took: 0.0001549 seconds
2019-02-28T20:05:38.535+0800: 3216940.646: [GC (Allocation Failure) 2019-02-28T20:05:38.535+0800: 3216940.646: [ParNew
Desired survivor size 8716288 bytes, new threshold 6 (max 6)
- age   1:    1220136 bytes,    1220136 total
- age   2:     158496 bytes,    1378632 total
- age   3:      88200 bytes,    1466832 total
- age   4:      46240 bytes,    1513072 total
- age   5:     126584 bytes,    1639656 total
- age   6:     159224 bytes,    1798880 total
: 139799K-&amp;gt;3295K(153344K), 0.0261667 secs] 473311K-&amp;gt;336837K(5225856K), 0.0263158 secs] [Times: user=0.06 sys=0.00, real=0.03 secs] 
2019-02-28T20:05:38.562+0800: 3216940.673: Total time for which application threads were stopped: 0.0276971 seconds, Stopping threads took: 0.0001030 seconds
2019-02-28T20:05:38.901+0800: 3216941.012: [GC (Allocation Failure) 2019-02-28T20:05:38.901+0800: 3216941.012: [ParNew
Desired survivor size 8716288 bytes, new threshold 6 (max 6)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;问题二&#34;&gt;问题二：&lt;/h2&gt;
&lt;p&gt;查询后得知，elasticsearch的内存配置偏大了，GC时间太长，导致elasticsearch脱离服务了。elasticsearch所在主机的内存是8G的实际内存7.6G,刚开始配置了5G的堆内存大小，可能Full GC的时候耗时太久了。查询elasticsearch官方文档后，得到如下的jvm优化建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将最小堆大小（&lt;code&gt;Xms&lt;/code&gt;）和最大堆大小（&lt;code&gt;Xmx&lt;/code&gt;）设置为彼此相等。&lt;/li&gt;
&lt;li&gt;Elasticsearch可用的堆越多，它可用于缓存的内存就越多。但请注意，过多的堆可能会使您陷入长时间的垃圾收集暂停。&lt;/li&gt;
&lt;li&gt;设置&lt;code&gt;Xmx&lt;/code&gt;为不超过物理RAM的50％，以确保有足够的物理RAM用于内核文件系统缓存。&lt;/li&gt;
&lt;li&gt;不要设置&lt;code&gt;Xmx&lt;/code&gt;为JVM用于压缩对象指针（压缩oops）的截止值之上; 确切的截止值变化但接近32 GB。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详情见：&lt;a href=&#34;https://www.elastic.co/guide/en/elasticsearch/reference/6.5/heap-size.html&#34;&gt;https://www.elastic.co/guide/en/elasticsearch/reference/6.5/heap-size.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;问题解决-1&#34;&gt;问题解决：&lt;/h2&gt;
&lt;p&gt;根据&lt;code&gt;Xmx&lt;/code&gt;不超过物理RAM的50％上面的jvm优化建议。后面将Xms和Xmx都设置成了3G。然后先停掉skywalking（由于skywalking中会缓存部分数据，如果直接先停ES，会报索引找不到的类似异常，这个大部分skywalking用户应该有遇到过），清空skywalking缓存目录下的内容，如：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4mfxyoij30nr09kmya.jpg&#34; alt=&#34;skywalking-trace-buffer&#34;&gt;&lt;/p&gt;
&lt;p&gt;在重启elasticsearch，接着启动skywalking后页面终于恢复了&lt;/p&gt;
&lt;h1 id=&#34;结语&#34;&gt;结语&lt;/h1&gt;
&lt;p&gt;整个问题排查到解决大概花了半天时间，幸好一点也不影响线上应用的使用，这个要得益于skywalking的设计，不然就是大灾难了。然后要感谢下Arthas的技术团队，写了这么好用的一款产品并且开源了，如果没有Arthas，这个问题真的不好定位，甚至一度想到了换掉elasticsearch，采用mysql来解决索引id过长的问题。Arthas真的是线上找问题的利器，博主在Arthas刚面世的时候就关注了，并且一直在公司推广使用，在这里在硬推一波。&lt;/p&gt;
&lt;h3 id=&#34;作者简介&#34;&gt;作者简介：&lt;/h3&gt;
&lt;p&gt;陈凯玲，2016年5月加入凯京科技。曾任职高级研发和项目经理，现任凯京科技研发中心架构&amp;amp;运维部负责人。pmp项目管理认证，阿里云MVP。热爱开源，先后开源过多个热门项目。热爱分享技术点滴，独立博客KL博客（&lt;a href=&#34;http://www.kailing.pub/&#34;&gt;http://www.kailing.pub&lt;/a&gt;）博主。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: APM巅峰对决：SkyWalking P.K. Pinpoint</title>
      <link>/zh/2019-02-24-skywalking-pk-pinpoint/</link>
      <pubDate>Sun, 24 Feb 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-02-24-skywalking-pk-pinpoint/</guid>
      <description>
        
        
        &lt;blockquote&gt;
&lt;p&gt;作者：王振飞, 写于：2019-02-24
&lt;strong&gt;说明&lt;/strong&gt;：此文是个人所写，版本归属作者，代表个人观点，仅供参考，不代表skywalking官方观点。
&lt;strong&gt;说明&lt;/strong&gt;：本次对比基于skywalking-6.0.0-GA和Pinpoint-1.8.2（截止2019-02-19最新版本）。另外，我们这次技术选型直接否定了Zipkin，其最大原因是它对代码有侵入性，CAT也是一样。这是我们所完全无法接受的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这应该是目前最优秀的两款开源APM产品了，而且两款产品都通过字节码注入的方式，实现了对代码&lt;strong&gt;完全无任何侵入&lt;/strong&gt;，他们的对比信息如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kjo1okj30in0q3gnb.jpg&#34; alt=&#34;Pinpoint P.K. skywalking&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OAP说明&lt;/strong&gt;: skywalking6.x才有OAP这个概念，skywalking5.x叫collector。&lt;/p&gt;
&lt;p&gt;接下来，对每个PK项进行深入分析和对比。更多精彩和首发内容请关注公众号：【&lt;strong&gt;阿飞的博客&lt;/strong&gt;】。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;社区比较&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这一点上面skywalking肯定完胜。一方面，skywalking已经进入apache孵化，社区相当活跃。而且项目发起人是中国人，我们能够进入官方群（Apache SkyWalking交流群：&lt;code&gt;392443393&lt;/code&gt;）和项目发起人吴晟零距离沟通，很多问题能第一时间得到大家的帮助（玩过开源的都知道，这个价值有多大）。
而Pinpoint是韩国人开发的，免不了有沟通障碍。至于github上最近一年的commit频率，skywalking和Pinpoint旗鼓相当，都是接近20的水平:
&lt;img src=&#34;0081Kckwly1gkl4kone2qj30rs0eudgj.jpg&#34; alt=&#34;Insight commit&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所以，社区方面，skywalking更胜一筹。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;支持语言比较&#34;&gt;&lt;strong&gt;支持语言比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint只支持Java和PHP，而skywalking支持5种语言：Java, C#, PHP, Node.js, Go。如果公司的服务涉及到多个开发语言，那么skywalking会是你更好的选择。并且，如果你要实现自己的探针（比如python语言），skywalking的二次开发成本也比Pinpoint更低。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：Github上有开发者为Pinpoint贡献了对Node.js的支持，请戳链接：https://github.com/peaksnail/pinpoint-node-agent。但是已经停止维护，几年没更新了！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;所以，支持语言方面，skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;协议比较&#34;&gt;&lt;strong&gt;协议比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;SkyWalking支持gRPC和http，不过建议使用gRPC，skywalking6.x版本已经不提供http方式（但是还会保留接收5.x的数据），以后会考虑删除。
而Pinpoint使用的是thrift协议。
协议本身没有谁好谁坏。&lt;/p&gt;
&lt;h3 id=&#34;存储比较重要&#34;&gt;&lt;strong&gt;存储比较(重要)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;笔者认为，存储是skywalking和Pinpoint最大的差异所在，因为底层存储决定了上层功能。&lt;/p&gt;
&lt;p&gt;Pinpoint只支持HBase，且扩展代价较大。这就意味着，如果选择Pinpoint，还要有能力hold住一套HBase集群（daocloud从Pinpoint切换到skywalking就是因为HBase的维护代价有点大）。在这方面，skywalking支持的存储就多很多，这样的话，技术选型时可以根据团队技术特点选择合适的存储，而且还可以自行扩展（不过生产环境上应该大部分是以es存储为主）。&lt;/p&gt;
&lt;p&gt;Pinpoint只支持HBase的另一个缺陷就是，HBase本身查询能力有限（HBase只能支持三种方式查询：RowKey精确查找，SCAN范围查找，全表扫描）限制了Pinpoint的查询能力，所以其支持的查询一定是在时间的基础上（Pinpoint通过鼠标圈定一个时间范围后查看这个范围内的Trace信息）。而skywalking可以多个维度任意组合查询，例如：时间范围，服务名，Trace状态，请求路径，TraceId等。&lt;/p&gt;
&lt;p&gt;另外，Pinpoint和skywalking都支持TTL，即历史数据保留策略。skywalking是在OAP模块的application.yml中配置从而指定保留时间。而Pinpoint是通过HBase的ttl功能实现，通过Pinpoint提供的hbase脚本&lt;code&gt;https://github.com/naver/pinpoint/blob/master/hbase/scripts/hbase-create.hbase&lt;/code&gt;可以看到：ApplicationTraceIndex配置了&lt;code&gt;TTL =&amp;gt; 5184000&lt;/code&gt;，SqlMetaData_Ver2配合了&lt;code&gt;TTL =&amp;gt; 15552000&lt;/code&gt;，单位是秒。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：es并不是完全碾压HBase，es和HBase没有绝对的好和坏。es强在检索能力，存储能力偏弱(千亿以下，es还是完全有能力hold的住的)。HBase强在存储能力，检索能力偏弱。如果搜集的日志量非常庞大，那么es存储就比较吃力。当然，没有蹩脚的中间件，只有蹩脚的程序员，无论是es还是HBase，调优才是最关键的。同样的，如果对检索能力有一定的要求，那么HBase肯定满足不了你。所以，又到了根据你的业务和需求决定的时刻了，trade-off真是无所不在。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kqmtxej30nt0mb74w.jpg&#34; alt=&#34;skywalking trace query&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ui比较&#34;&gt;&lt;strong&gt;UI比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint的UI确实比skywalking稍微好些，尤其是服务的拓扑图展示。不过daocloud根据Pinpoint的风格为skywalking定制了一款UI。请戳链接：https://github.com/TinyAllen/rocketbot，项目介绍是：&lt;code&gt;rocketbot: A UI for Skywalking&lt;/code&gt;。截图如下所示；
&lt;img src=&#34;0081Kckwly1gkl4kmm7q3j30yg0jmgmm.jpg&#34; alt=&#34;rocketbot: A UI for Skywalking&#34;&gt;
&lt;strong&gt;所以，只比较原生UI的话，Pinpoint更胜一筹。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;扩展性比较&#34;&gt;&lt;strong&gt;扩展性比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint好像设计之初就没有过多考虑扩展性，无论是底层的存储，还是自定义探针实现等。而skywalking核心设计目标之一就是&lt;strong&gt;Pluggable&lt;/strong&gt;，即可插拔。&lt;/p&gt;
&lt;p&gt;以存储为例，pinpoint完全没有考虑扩展性，而skywalking如果要自定义实现一套存储，只需要定义一个类实现接口&lt;code&gt;org.apache.skywalking.oap.server.library.module.ModuleProvider&lt;/code&gt;，然后实现一些DAO即可。至于Pinpoint则完全没有考虑过扩展底层存储。&lt;/p&gt;
&lt;p&gt;再以实现一个自己的探针为例（比如我要实现python语言的探针），Pinpoint选择thrift作为数据传输协议标准，而且为了节省数据传输大小，在传递常量的时候也尽量使用数据参考字典，传递一个数字而不是直接传递字符串等等。这些优化也增加了系统的复杂度：包括使用 Thrift 接口的难度、UDP 数据传输的问题、以及数据常量字典的注册问题等等。Pinpoint发展这么年才支持Java和PHP，可见一斑。而skywalking的数据接口就标准很多，并且支持OpenTracing协议，除了官方支持Java以外，C#、PHP和Node.js的支持都是由社区开发并维护。&lt;/p&gt;
&lt;p&gt;还有后面会提到的告警，skywalking的可扩展性也要远好于Pinpoint。&lt;/p&gt;
&lt;p&gt;最后，Pinpoint和skywalking都支持插件开发，Pinpoint插件开发参考：http://naver.github.io/pinpoint/1.8.2/plugindevguide.html。skywalking插件开发参考：https://github.com/apache/incubator-skywalking/blob/master/docs/en/guides/Java-Plugin-Development-Guide.md。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所以，扩展性方面skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;告警比较&#34;&gt;&lt;strong&gt;告警比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint和skywalking都支持自定义告警规则。&lt;/p&gt;
&lt;p&gt;但是恼人的是，Pinpoint如果要配置告警规则，还需要安装MySQL(配置告警时的用户，用户组信息以及告警规则都持久化保存在MySQL中)，这就导致Pinpoint的维护成本又高了一些，既要维护HBase又要维护MySQL。&lt;/p&gt;
&lt;p&gt;Pinpoint支持的告警规则有：SLOW COUNT|RATE, ERROR COUNT|RATE, TOTAL COUNT, SLOW COUNT|RATE TO CALLEE, ERROR COUNT|RATE TO CALLEE, ERROR RATE TO CALLEE, HEAP USAGE RATE, JVM CPU USAGE RATE, DATASOURCE CONNECTION USAGE RATE。&lt;/p&gt;
&lt;p&gt;Pinpoint每3分钟周期性检查过去5分钟的数据，如果有符合规则的告警，就会发送sms/email给用户组下的所有用户。需要说明的是，实现发送sms/email的逻辑需要自己实现，Pinpoint只提供了接口&lt;code&gt;com.navercorp.pinpoint.web.alarm.AlarmMessageSender&lt;/code&gt;。并且Pinpoint发现告警持续时，会递增发送sms/email的时间间隔 3min -&amp;gt; 6min -&amp;gt; 12min -&amp;gt; 24min，防止sms/email狂刷。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pinpoint告警参考&lt;/strong&gt;：http://naver.github.io/pinpoint/1.8.2/alarm.html&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;skywalking配置告警不需要引入任何其他存储。skywalking在config/alarm-settings.xml中可以配置告警规则，告警规则支持自定义。&lt;/p&gt;
&lt;p&gt;skywalking支持的告警规则（配置项中的名称是indicator-name）有：service_resp_time, service_sla, service_cpm, service_p99, service_p95, service_p90, service_p75, service_p50, service_instance_sla, service_instance_resp_time, service_instance_cpm, endpoint_cpm, endpoint_avg, endpoint_sla, endpoint_p99, endpoint_p95, endpoint_p90, endpoint_p75, endpoint_p50。&lt;/p&gt;
&lt;p&gt;Skywalking通过HttpClient的方式远程调用在配置项webhooks中定义的告警通知服务地址。skywalking也支持silence-period配置，假设在TN这个时间点触发了告警，那么TN -&amp;gt; TN+period 这段时间内不会再重复发送该告警。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;skywalking告警参考&lt;/strong&gt;：https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/backend/backend-alarm.md。目前只支持official_analysis.oal脚本中Service, Service Instance, Endpoint scope的metric，其他scope的metric需要等待后续扩展。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pinpoint和skywalking都支持常用的告警规则配置，但是skywalking采用webhooks的方式就灵活很多：短信通知，邮件通知，微信通知都是可以支持的。而Pinpoint只能sms/email通知，并且还需要引入MySQL存储，增加了整个系统复杂度。所以，&lt;strong&gt;告警方面，skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;jvm监控&#34;&gt;&lt;strong&gt;JVM监控&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;skywalking支持监控：Heap, Non-Heap, GC(YGC和FGC)。
Pinpoint能够监控的指标主要有：Heap, Non-Heap, FGC, DirectBufferMemory, MappedBufferMemory，但是没有YGC。另外，Pinpoint还支持多个指标同一时间点查看的功能。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kp7botj30yg0i5jwg.jpg&#34; alt=&#34;Pinpoint JVM inspector&#34;&gt;
&lt;strong&gt;所以，对JVM的监控方面，Pinpoint更胜一筹。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;服务监控&#34;&gt;&lt;strong&gt;服务监控&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;包括操作系统，和部署的服务实例的监控。
Pinpoint支持的维度有：CPU使用率，Open File Descriptor，数据源，活动线程数，RT，TPS。
skywalking支持的维度有：CPU使用率，SLA，RT，CPM（Call Per Minutes）。
所以，这方面两者旗鼓相当，没有明显的差距。&lt;/p&gt;
&lt;h3 id=&#34;跟踪粒度比较&#34;&gt;&lt;strong&gt;跟踪粒度比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint在这方面做的非常好，跟踪粒度非常细。如下图所示，是Pinpoint对某个接口的trace信息：
&lt;img src=&#34;0081Kckwly1gkl4kppkcjj30yg0je7ck.jpg&#34; alt=&#34;Pinpoint trace detail&#34;&gt;&lt;/p&gt;
&lt;p&gt;而同一个接口skywalking的trace信息如下图所示：
&lt;img src=&#34;0081Kckwly1gkl4knyttmj30yg091dhi.jpg&#34; alt=&#34;skywalking trace detail&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kq1n8vj30yg0bggna.jpg&#34; alt=&#34;skywalking trace sql&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;备注&lt;/strong&gt;: 此截图是skywalking加载了插件&lt;code&gt;apm-spring-annotation-plugin-6.0.0-GA.jar&lt;/code&gt;（这个插件允许跟踪加了@Bean, @Service, @Component and @Repository注解的spring context中的bean的方法）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过对比发现，&lt;strong&gt;在跟踪粒度方面，Pinpoint更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;过滤追踪&#34;&gt;&lt;strong&gt;过滤追踪&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pinpoint和skywalking都可以实现，而且配置的表达式都是基于ant风格。
Pinpoint在Web UI上配置 &lt;code&gt;filter wizard&lt;/code&gt; 即可自定义过滤追踪。
skywalking通过加载apm-trace-ignore-plugin插件就能自定义过滤跟踪，skywalking这种方式更灵活，比如一台高配服务器上有若干个服务，在共用的agent配置文件apm-trace-ignore-plugin.config中可以配置通用的过滤规则，然后通过-D的方式为每个服务配置个性化过滤。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所以，在过滤追踪方面，skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;性能损耗&#34;&gt;&lt;strong&gt;性能损耗&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;由于Pinpoint采集信息太过详细，所以，它对性能的损耗最大。而skywalking默认策略比较保守，对性能损耗很小。
有网友做过压力测试，对比如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kk0bgjj30yg0ae45o.jpg&#34; alt=&#34;压力测试&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;图片来源于：https://juejin.im/post/5a7a9e0af265da4e914b46f1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;所以，在性能损耗方面，skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;发布包比较&#34;&gt;&lt;strong&gt;发布包比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;skywalking与时俱进，全系标配jar包，部署只需要执行start.sh脚本即可。而Pinpoint的collector和web还是war包，部署时依赖web容器（比如Tomcat）。拜托，都9012年了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所以，在发布包方面，skywalking更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;支持组件比较&#34;&gt;&lt;strong&gt;支持组件比较&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4kkfvddj30ox0sx74l.jpg&#34; alt=&#34;支持组件对比&#34;&gt;&lt;/p&gt;
&lt;p&gt;skywalking和Pinpoint支持的中间件对比说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WEB容器说明&lt;/strong&gt;：Pinpoint支持几乎所有的WEB容器，包括开源和商业的。而wkywalking只支持开源的WEB容器，对2款大名鼎鼎的商业WEB容器Weblogic和Wevsphere都不支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RPC框架说明&lt;/strong&gt;：对RPC框架的支持，skywalking简直秒杀Pinpoint。连小众的motan和sofarpc都支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MQ说明&lt;/strong&gt;：skywalking比Pinpoint多支持一个国产的MQ中间件RocketMQ，毕竟RocketMQ在国内名气大，而在国外就一般了。加之skywalking也是国产的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RDBMS/NoSQL说明&lt;/strong&gt;：Pinpoint对RDBMS和NoSQL的支持都要略好于skywalking，RDBMS方面，skywalking不支持MSSQL和MariaDB。而NoSQL方面，skywalking不支持Cassandra和HBase。至于Pinpoint不支持的H2，完全不是问题，毕竟生产环境是肯定不会使用H2作为底层存储的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redis客户端说明&lt;/strong&gt;：虽然skywalking和Pinpoint都支持Redis，但是skywalking支持三种流行的Redis客户端：Jedis，Redisson，Lettuce。而Pinpoint只支持Jedis和Lettuce，再一次，韩国人开发的Pinpoint无视了目前中国人开发的GitHub上star最多的Redis Client &amp;ndash; Redisson。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志框架说明&lt;/strong&gt;：Pinpoint居然不支持log4j2？但是已经有人开发了相关功能，详情请戳链接：&lt;a href=&#34;https://github.com/naver/pinpoint/issues/3055&#34;&gt;log4j plugin support log4j2 or not? https://github.com/naver/pinpoint/issues/3055&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过对skywalking和Pinpoint支持中间件的对比我们发现，skywalking对国产软件的支持真的是全方位秒杀Pinpoint，比如小众化的RPC框架：motan（微博出品），sofarpc，阿里的RocketMQ，Redis客户端Redisson，以及分布式任务调度框架elastic-job等。当然也从另一方面反应国产开源软件在世界上的影响力还很小。&lt;/p&gt;
&lt;p&gt;这方面没有谁好谁坏，毕竟每个公司使用的技术栈不一样。如果你对RocketMQ有强需求，那么skywalking是你的最佳选择。如果你对es有强需求，那么skywalking也是你的最佳选择。如果HBase是你的强需求，那么Pinpoint就是你的最佳选择。如果MSSQL是你的强需求，那么Pinpoint也是你的最佳选择。总之，这里完全取决你的项目了。&lt;/p&gt;
&lt;h3 id=&#34;总结&#34;&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;经过前面对skywalking和Pinpoint全方位对比后我们发现，对于两款非常优秀的APM软件，有一种既生瑜何生亮的感觉。Pinpoint的优势在于：追踪数据粒度非常细、功能强大的用户界面，以及使用HBase作为存储带来的海量存储能力。而skywalking的优势在于：非常活跃的中文社区，支持多种语言的探针，对国产开源软件非常全面的支持，以及使用es作为底层存储带来的强大的检索能力，并且skywalking的扩展性以及定制化要更优于Pinpoint：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果你有海量的日志存储需求，推荐Pinpoint。&lt;/li&gt;
&lt;li&gt;如果你更看重二次开发的便捷性，推荐skywalking。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后，参考上面的对比，结合你的需求，哪些不能妥协，哪些可以舍弃，从而更好的选择一款最适合你的APM软件。&lt;/p&gt;
&lt;h3 id=&#34;参考链接&#34;&gt;&lt;strong&gt;参考链接&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;参考[1]. &lt;a href=&#34;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/service-agent/java-agent/Supported-list.md&#34;&gt;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/service-agent/java-agent/Supported-list.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;参考[2]. &lt;a href=&#34;http://naver.github.io/pinpoint/1.8.2/main.html#supported-modules&#34;&gt;http://naver.github.io/pinpoint/1.8.2/main.html#supported-modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;参考[3]. &lt;a href=&#34;https://juejin.im/post/5a7a9e0af265da4e914b46f1&#34;&gt;https://juejin.im/post/5a7a9e0af265da4e914b46f1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;如果觉得本文不错，请关注作者公众号：【&lt;strong&gt;阿飞的博客&lt;/strong&gt;】，多谢！&lt;/p&gt;
&lt;/blockquote&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking的远程调试</title>
      <link>/zh/2019-01-24-skywalking-remote-debug/</link>
      <pubDate>Thu, 24 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-01-24-skywalking-remote-debug/</guid>
      <description>
        
        
        &lt;p&gt;ps:本文仅写给菜鸟，以及不知道如何远程调试的程序员，并且仅仅适用skywalking的远程调试&lt;/p&gt;
&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;
&lt;p&gt;远程调试的目的是为了解决代码或者说程序包部署在服务器上运行，只能通过log来查看问题，以及不能跟在本地IDE运行debug那样查找问题，观看程序运行流程&amp;hellip;
想想当你的程序运行在服务器上，你在本地的IDE随时debug，是不是很爽的感觉。&lt;/p&gt;
&lt;p&gt;好了不废话，切入正题。&lt;/p&gt;
&lt;h2 id=&#34;环境篇&#34;&gt;环境篇&lt;/h2&gt;
&lt;p&gt;IDE：推荐 &lt;a href=&#34;https://www.jetbrains.com/idea/&#34;&gt;IntelliJ IDEA&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;开发语言: 本文仅限于java，其他语言请自行询问google爸爸或者baidu娘娘&lt;/p&gt;
&lt;p&gt;源代码：自行从github下载，并且确保你运行的skywalking包也源代码的一致，（也就是说你自己从源代码编译打包运行，虽然不一样也可以调试，但是你想想你在本地开发，更改完代码，没有重新运行，debug出现的诡异情况）&lt;/p&gt;
&lt;h2 id=&#34;场景篇&#34;&gt;场景篇&lt;/h2&gt;
&lt;p&gt;假定有如下三台机器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;IP&lt;/th&gt;
&lt;th align=&#34;center&#34;&gt;用途&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10.193.78.1&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;oap-server&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;skywalking 的oap服务（或者说collector所在的服务器）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.193.78.2&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;agent&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;skywalking agent运行所在的服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.193.78.0&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;IDE&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;你自己装IDE也就是IntelliJ IDEA的机器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;以上环境，场景请自行安装好，并确认正常运行。本文不在赘述&lt;/p&gt;
&lt;p&gt;废话终于说完了&lt;/p&gt;
&lt;h2 id=&#34;操作篇&#34;&gt;操作篇&lt;/h2&gt;
&lt;p&gt;首要条件，下载源码后，先用maven 打包编译。然后使用Idea打开源码的父目录，整体结构大致如下图
&lt;img src=&#34;0081Kckwly1gkl4h16jepj30u00ui0wk.jpg&#34; alt=&#34;IMAGE&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;1-agent调试&#34;&gt;1 :agent调试&lt;/h3&gt;
&lt;h4 id=&#34;1idea-配置部分&#34;&gt;1)Idea 配置部分&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4gsba9dj32m803k40w.jpg&#34; alt=&#34;IMAGE&#34;&gt;
点击Edit Configurations
在弹出窗口中依次找到（红色线框的部分）并点击
&lt;img src=&#34;0081Kckwly1gkl4gxw1u0j319s0c8mzm.jpg&#34; alt=&#34;IMAGE&#34;&gt;
&lt;img src=&#34;0081Kckwly1gkl4gsox3jj30ek10gadm.jpg&#34; alt=&#34;IMAGE&#34;&gt;
打开的界面如下
&lt;img src=&#34;0081Kckwly1gkl4gt601gj31cp0u0gsh.jpg&#34; alt=&#34;IMAGE&#34;&gt;&lt;/p&gt;
&lt;p&gt;修改Name值，自己随意，好记即可
然后Host输入10.193.78.2 Port默认或者其他的，重要的是这个端口在10.193.78.2上没有被占用&lt;/p&gt;
&lt;p&gt;然后找到Use module classpath 选择 apm-agent
最终的结果如下：
&lt;img src=&#34;0081Kckwly1gkl4h0pw50j30yu0u0jxk.jpg&#34; alt=&#34;IMAGE&#34;&gt;&lt;/p&gt;
&lt;p&gt;注意选择目标agent运行的jdk版本，很重要&lt;/p&gt;
&lt;p&gt;然后点击Apply，并找到如下内容，并且复制待用
&lt;img src=&#34;0081Kckwly1gkl4gytahmj30y50u0wka.jpg&#34; alt=&#34;IMAGE&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;2agent配置部分&#34;&gt;2）agent配置部分&lt;/h4&gt;
&lt;p&gt;找到agent配置的脚本，并打开，找到配置agent的地方，
&lt;img src=&#34;0081Kckwly1gkl4h05q0uj30ji016q3a.jpg&#34; alt=&#34;IMAGE&#34;&gt;
就这个地方，在这个后边加上刚才复制的内容
最终的结果如下
&lt;img src=&#34;0081Kckwly1gkl4gz8kowj31e000uaav.jpg&#34; alt=&#34;IMAGE&#34;&gt;
提供一个我配置的weblogic的配置（仅供参考）
&lt;img src=&#34;0081Kckwly1gkl4gyfw8lj31r6020abk.jpg&#34; alt=&#34;IMAGE&#34;&gt;
然后重启应用（agent）&lt;/p&gt;
&lt;h4 id=&#34;3调试&#34;&gt;3）调试&lt;/h4&gt;
&lt;p&gt;回到Idea中找到这个地方，并点击debug按钮，你没看错，就是红色圈住的地方
&lt;img src=&#34;0081Kckwly1gkl4gun36lj30ew01mmxa.jpg&#34; alt=&#34;IMAGE&#34;&gt;
然后控制台如果出现以下字样：
&lt;img src=&#34;0081Kckwly1gkl4gzq0t3j30y40123z2.jpg&#34; alt=&#34;IMAGE&#34;&gt;
那么恭喜你，可以愉快的加断点调试了。
ps:需要注意的是agent的、
service instance的注册可能不能那么愉快的调试。因为这个注册比较快，而且是在agent启动的时候就发生的，
而远程调试也需要agent打开后才可以调试，所以，如果你手快当我没说这句话。&lt;/p&gt;
&lt;h3 id=&#34;2-oap-server的调试也就是collector的调试&#34;&gt;2 :oap-server的调试（也就是collector的调试）&lt;/h3&gt;
&lt;p&gt;具体过程不在赘述，和上一步的agent调试大同小异，不同的是
Use module classpath需要选择oap-server&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4gxeoh7j319g03amxr.jpg&#34; alt=&#34;IMAGE&#34;&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking Java 插件贡献实践</title>
      <link>/zh/2019-01-21-agent-plugin-practice/</link>
      <pubDate>Mon, 21 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-01-21-agent-plugin-practice/</guid>
      <description>
        
        
        &lt;h2 id=&#34;引言&#34;&gt;引言&lt;/h2&gt;
&lt;p&gt;《SkyWalking Java 插件贡献实践》：本文将基于SkyWalking 6.0.0-GA-SNAPSHOT版本，以编写Redis客户端&lt;a href=&#34;#Lettuce&#34;&gt;&lt;code&gt;Lettuce&lt;/code&gt;&lt;/a&gt;的SkyWalking Java Agent 插件为例，与大家分享我贡献PR的过程，希望对大家了解SkyWalking Java Agent插件有所帮助。&lt;/p&gt;
&lt;h2 id=&#34;基础概念&#34;&gt;基础概念&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;#OpenTracing&#34;&gt;&lt;code&gt;OpenTracing&lt;/code&gt;&lt;/a&gt;和SkyWalking链路模块几个很重要的语义概念。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Span:可理解为一次方法调用，一个程序块的调用，或一次RPC/数据库访问。只要是一个具有完整时间周期的程序访问，都可以被认为是一个span。SkyWalking &lt;a href=&#34;#AbstractSpan&#34;&gt;&lt;code&gt;Span&lt;/code&gt;&lt;/a&gt;对象中的重要属性&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;属性&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;名称&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;component&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;组件&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;插件的组件名称，如：Lettuce，详见:ComponentsDefine.Class。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;tag&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;标签&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;k-v结构，关键标签，key详见：Tags.Class。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;peer&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;对端资源&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;用于拓扑图，若DB组件，需记录集群信息。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;operationName&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;操作名称&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;若span=0，operationName将会搜索的下拉列表。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;layer&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;显示&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;在链路页显示，详见SpanLayer.Class。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trace:调用链，通过归属于其的Span来隐性的定义。一条Trace可被认为是一个由多个Span组成的有向无环图（DAG图），在SkyWalking链路模块你可以看到，Trace又由多个归属于其的trace segment组成。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trace segment:Segment是SkyWalking中的一个概念，它应该包括单个OS进程中每个请求的所有范围，通常是基于语言的单线程。由多个归属于本线程操作的Span组成。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;核心api&#34;&gt;核心API&lt;/h2&gt;
&lt;h3 id=&#34;跨进程contextcarrier核心api&#34;&gt;跨进程ContextCarrier核心API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;为了实现分布式跟踪，需要绑定跨进程的跟踪，并且应该传播上下文 整个过程。 这就是ContextCarrier的职责。&lt;/li&gt;
&lt;li&gt;以下是实现有关跨进程传播的步骤：
&lt;ul&gt;
&lt;li&gt;在客户端，创建一个新的空的ContextCarrier，将ContextCarrier所有信息放到HTTP heads、Dubbo attachments 或者Kafka messages。&lt;/li&gt;
&lt;li&gt;通过服务调用，将ContextCarrier传递到服务端。&lt;/li&gt;
&lt;li&gt;在服务端，在对应组件的heads、attachments或messages获取ContextCarrier所有消息。将服务端和客户端的链路信息绑定。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;跨线程contextsnapshot核心api&#34;&gt;跨线程ContextSnapshot核心API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;除了跨进程，跨线程也是需要支持的，例如异步线程（内存中的消息队列）和批处理在Java中很常见，跨进程和跨线程十分相似，因为都是需要传播 上下文。 唯一的区别是，不需要跨线程序列化。&lt;/li&gt;
&lt;li&gt;以下是实现有关跨线程传播的步骤：
&lt;ul&gt;
&lt;li&gt;使用ContextManager＃capture获取ContextSnapshot对象。&lt;/li&gt;
&lt;li&gt;让子线程以任何方式，通过方法参数或由现有参数携带来访问ContextSnapshot。&lt;/li&gt;
&lt;li&gt;在子线程中使用ContextManager#continued。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详尽的核心API相关知识，可点击阅读 《&lt;a href=&#34;https://github.com/apache/incubator-skywalking/blob/master/docs/others/cn/guides/Java-Plugin-Development-Guide.md&#34;&gt;插件开发指南-中文版本&lt;/a&gt;》&lt;/p&gt;
&lt;h2 id=&#34;插件实践&#34;&gt;插件实践&lt;/h2&gt;
&lt;h3 id=&#34;lettuce操作redis代码&#34;&gt;Lettuce操作redis代码&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@PostMapping&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/ping&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ping&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;HttpServletRequest request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;throws&lt;/span&gt; ExecutionException&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; InterruptedException &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    RedisClient redisClient &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; RedisClient&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;redis://&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;:6379&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    StatefulRedisConnection&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; connection0 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; redisClient&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;connect&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
    RedisAsyncCommands&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; asyncCommands0 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; connection0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;async&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
    AsyncCommand&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; future &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;AsyncCommand&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;)&lt;/span&gt;asyncCommands0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;set&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;key_a&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;value_a&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    future&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;onComplete&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;s &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; OkHttpClient&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;call&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;http://skywalking.apache.org&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;));&lt;/span&gt;
    future&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;get&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
    connection0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
    redisClient&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;shutdown&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pong&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;插件源码架构&#34;&gt;插件源码架构&lt;/h3&gt;
&lt;p&gt;Lettuce对Redis封装与Redisson &lt;a href=&#34;#Redisson&#34;&gt;&lt;code&gt;Redisson&lt;/code&gt;&lt;/a&gt; 类似，目的均是实现简单易用，且无学习曲线的Java的Redis客户端。所以要是先对Redis操作的拦截，需要学习对应客户端的源码。&lt;/p&gt;
&lt;h3 id=&#34;设计插件&#34;&gt;设计插件&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4eg1vz5j30vp0gbgn0.jpg&#34; alt=&#34;Lettuce时序图&#34;&gt;
理解插件实现过程，找到最佳InterceptPoint位置是实现插件融入SkyWalking的核心所在。&lt;/p&gt;
&lt;h3 id=&#34;代码实现&#34;&gt;代码实现&lt;/h3&gt;
&lt;p&gt;PR的url：&lt;a href=&#34;https://github.com/apache/incubator-skywalking/pull/2152&#34;&gt;Support lettuce plugin&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;实践中遇到的问题&#34;&gt;实践中遇到的问题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;多线程编程使用debug断点会将链路变成同步，建议使用run模式增加log，或者远程debug来解决。&lt;/li&gt;
&lt;li&gt;多线程编程，需要使用跨线程ContextSnapshot核心API，否则链路会断裂。&lt;/li&gt;
&lt;li&gt;CompleteableCommand.onComplete方法有时会同步执行，这个和内部机制有关，有时候不分离线程。&lt;/li&gt;
&lt;li&gt;插件编译版本若为1.7+，需要将插件放到可选插件中。因为sniffer支持的版本是1.6。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;插件兼容&#34;&gt;插件兼容&lt;/h2&gt;
&lt;p&gt;为了插件得到插件最终的兼容兼容版本，我们需要使用docker对所有插件版本的测试，具体步骤如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编写测试用例：关于如何编写测试用例，请按照&lt;a href=&#34;https://github.com/SkywalkingTest/skywalking-agent-testcases/blob/master/docs/how-to-write-a-plugin-testcase.md&#34;&gt;如何编写文档&lt;/a&gt;来实现。&lt;/li&gt;
&lt;li&gt;提供自动测试用例。 如：&lt;a href=&#34;https://github.com/SkywalkingTest/skywalking-agent-testcases/pull/45&#34;&gt;Redisson插件testcase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;确保本地几个流行的插件版本，在本地运行起来是和自己的预期是一致的。&lt;/li&gt;
&lt;li&gt;在提供自动测试用例并在CI中递交测试后，插件提交者会批准您的插件。&lt;/li&gt;
&lt;li&gt;最终得到完整的插件测试报告。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pull-request&#34;&gt;Pull Request&lt;/h2&gt;
&lt;h3 id=&#34;提交pr&#34;&gt;提交PR&lt;/h3&gt;
&lt;p&gt;提交PR的时候，需要简述自己对插件的设计，这样有助于与社区的贡献者讨论完成codereview。&lt;/p&gt;
&lt;h3 id=&#34;申请自动化测试&#34;&gt;申请自动化测试&lt;/h3&gt;
&lt;p&gt;测试用例编写完成后，可以申请自动化测试，在自己的PR中会生成插件兼容版本的报告。&lt;/p&gt;
&lt;h3 id=&#34;插件文档&#34;&gt;插件文档&lt;/h3&gt;
&lt;p&gt;插件文档需要更新：&lt;a href=&#34;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/service-agent/java-agent/Supported-list.md&#34;&gt;Supported-list.md&lt;/a&gt;相关插件信息的支持。&lt;/p&gt;
&lt;p&gt;插件如果为可选插件需要在&lt;a href=&#34;https://github.com/apache/incubator-skywalking/tree/master/docs/en/setup/service-agent/java-agent/agent-optional-plugins&#34;&gt;agent-optional-plugins&lt;/a&gt;可选插件文档中增加对应的描述。&lt;/p&gt;
&lt;h2 id=&#34;注释&#34;&gt;注释&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;Lettuce&#34;&gt;&lt;/a&gt;Lettuce是一个完全无阻塞的Redis客户端，使用netty构建，提供反应，异步和同步数据访问。了解细节可点击阅读 &lt;a href=&#34;https://lettuce.io/&#34;&gt;lettuce.io&lt;/a&gt;;&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;OpenTracing&#34;&gt;&lt;/a&gt;OpenTracing是一个跨编程语言的标准，了解细节可点击阅读 《&lt;a href=&#34;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/specification.md&#34;&gt;OpenTracing语义标准&lt;/a&gt;》;&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;AbstractSpan&#34;&gt;&lt;/a&gt;span:org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan接口定义了所有Span实现需要完成的方法;&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;Redisson&#34;&gt;&lt;/a&gt;Redisson是一个非常易用Java的Redis客户端， 它没有学习曲线，无需知道任何Redis命令即可开始使用它。了解细节可点击阅读 &lt;a href=&#34;https://redisson.org/&#34;&gt;redisson.org&lt;/a&gt;;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking 微服务监控分析</title>
      <link>/zh/2019-01-03-monitor-microservice/</link>
      <pubDate>Thu, 03 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-01-03-monitor-microservice/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者：赵瑞栋&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mp.weixin.qq.com/s/0XXUpnxR8xiExE4iwu90xg&#34;&gt;原文地址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;引言&#34;&gt;引言&lt;/h2&gt;
&lt;p&gt;微服务框架落地后，分布式部署架构带来的问题就会迅速凸显出来。服务之间的相互调用过程中，如果业务出现错误或者异常，如何快速定位问题？如何跟踪业务调用链路？如何分析解决业务瓶颈？&amp;hellip;本文我们来看看如何解决以上问题。&lt;/p&gt;
&lt;h2 id=&#34;一skywalking初探&#34;&gt;一、SkyWalking初探&lt;/h2&gt;
&lt;h3 id=&#34;skywalking-简介&#34;&gt;Skywalking 简介&lt;/h3&gt;
&lt;p&gt;Skywalking是一款国内开源的应用性能监控工具，支持对分布式系统的监控、跟踪和诊断。&lt;/p&gt;
&lt;p&gt;它提供了如下的主要功能特性：
&lt;img src=&#34;0081Kckwly1gkl48z91szj30t90hvmyo.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;skywalking-技术架构&#34;&gt;Skywalking 技术架构&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl497pc5dj30tw0esabr.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;SW总体可以分为四部分：&lt;/p&gt;
&lt;p&gt;1.Skywalking Agent：使用Javaagent做字节码植入，无侵入式的收集，并通过HTTP或者gRPC方式发送数据到Skywalking Collector。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Skywalking Collector ：链路数据收集器，对agent传过来的数据进行整合分析处理并落入相关的数据存储中。&lt;/li&gt;
&lt;li&gt;Storage：Skywalking的存储，时间更迭，sw已经开发迭代到了6.x版本，在6.x版本中支持以ElasticSearch、Mysql、TiDB、H2、作为存储介质进行数据存储。&lt;/li&gt;
&lt;li&gt;UI ：Web可视化平台，用来展示落地的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;skywalking-agent配置&#34;&gt;Skywalking Agent配置&lt;/h3&gt;
&lt;p&gt;通过了解配置，可以对一个组件功能有一个大致的了解。让我们一起看一下skywalking的相关配置。&lt;/p&gt;
&lt;p&gt;解压开skywalking的压缩包，在agent/config文件夹中可以看到agent的配置文件。&lt;/p&gt;
&lt;p&gt;从skywalking支持环境变量配置加载，在启动的时候优先读取环境变量中的相关配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl49air42j30tw0k0tbw.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent.namespace: 跨进程链路中的header，不同的namespace会导致跨进程的链路中断&lt;/li&gt;
&lt;li&gt;agent.service_name:一个服务（项目）的唯一标识，这个字段决定了在sw的UI上的关于service的展示名称&lt;/li&gt;
&lt;li&gt;agent.sample_n_per_3_secs: 客户端采样率，默认是-1代表全采样&lt;/li&gt;
&lt;li&gt;agent.authentication: 与collector进行通信的安全认证，需要同collector中配置相同&lt;/li&gt;
&lt;li&gt;agent.ignore_suffix: 忽略特定请求后缀的trace&lt;/li&gt;
&lt;li&gt;collecttor.backend_service: agent需要同collector进行数据传输的IP和端口&lt;/li&gt;
&lt;li&gt;logging.level: agent记录日志级别&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;skywalking agent使用javaagent无侵入式的配合collector实现对分布式系统的追踪和相关数据的上下文传递。&lt;/p&gt;
&lt;h3 id=&#34;skywalking-collector关键配置&#34;&gt;Skywalking Collector关键配置&lt;/h3&gt;
&lt;p&gt;Collector支持集群部署，zookeeper、kubernetes（如果你的应用是部署在容器中的）、consul（GO语言开发的服务发现工具）是sw可选的集群管理工具，结合大家具体的部署方式进行选择。详细配置大家可以去Skywalking官网下载介质包进行了解。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Collector端口设置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl496t7kuj30tu0azabr.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;downsampling: 采样汇总统计维度，会分别按照分钟、【小时、天、月】（可选）来统计各项指标数据。&lt;/li&gt;
&lt;li&gt;通过设置TTL相关配置项可以对数据进行自动清理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Skywalking 在6.X中简化了配置。collector提供了gRPC和HTTP两种通信方式。&lt;/p&gt;
&lt;p&gt;UI使用rest http通信，agent在大多数场景下使用grpc方式通信，在语言不支持的情况下会使用http通信。&lt;/p&gt;
&lt;p&gt;关于绑定IP和端口需要注意的一点是，通过绑定IP，agent和collector必须配置对应ip才可以正常通信。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Collector存储配置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在application.yml中配置的storage模块配置中选择要使用的数据库类型，并填写相关的配置信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl48yfewej30u00dm42a.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Collector Receiver&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Receiver是Skywalking在6.x提出的新的概念，负责从被监控的系统中接受指标数据。用户完全可以参照OpenTracing规范来上传自定义的监控数据。Skywalking官方提供了service-mesh、istio、zipkin的相关能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4978f3fj30ty0dz76h.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;现在Skywalking支持服务端采样，配置项为sampleRate，比例采样，如果配置为5000则采样率就是50%。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关于采样设置的一点注意事项&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;关于服务采样配置的一点建议，如果Collector以集群方式部署，比如：Acollector和Bcollector，建议Acollector.sampleRate = Bcollector.sampleRate。如果采样率设置不相同可能会出现数据丢失问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl495ce6zj30lm0jqwfm.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;假设Agent端将所有数据发送到后端Collector处，A采样率设置为30%，B采样率为50%。&lt;/p&gt;
&lt;p&gt;假设有30%的数据，发送到A上，这些数据被全部正确接受并存储，极端情况（与期望的采样数据量相同）下，如果剩下20%待采样的数据发送到了B，这个时候一切都是正常的，如果这20%中有一部分数据被送到了A那么，这些数据将是被忽略的，由此就会造成数据丢失。&lt;/p&gt;
&lt;h2 id=&#34;二业务调用链路监控&#34;&gt;二、业务调用链路监控&lt;/h2&gt;
&lt;h3 id=&#34;service-topology监控&#34;&gt;Service Topology监控&lt;/h3&gt;
&lt;p&gt;调用链路监控可以从两个角度去看待。我们先从整体上来认识一下我们所监控的系统。&lt;/p&gt;
&lt;p&gt;通过给服务添加探针并产生实际的调用之后，我们可以通过Skywalking的前端UI查看服务之间的调用关系。&lt;/p&gt;
&lt;p&gt;我们简单模拟一次服务之间的调用。新建两个服务，service-provider以及service-consumer，服务之间简单的通过Feign Client 来模拟远程调用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl498m9caj30th0e1wfn.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;从图中可以看到:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有两个服务节点：provider &amp;amp; consumer&lt;/li&gt;
&lt;li&gt;有一个数据库节点：localhost【mysql】&lt;/li&gt;
&lt;li&gt;一个注册中心节点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;consumer消费了provider提供出来的接口。&lt;/p&gt;
&lt;p&gt;一个系统的拓扑图让我们清晰的认识到系统之间的应用的依赖关系以及当前状态下的业务流转流程。细心的可能发现图示节点consumer上有一部分是红色的，红色是什么意思呢？&lt;/p&gt;
&lt;p&gt;红色代表当前流经consumer节点的请求有一断时间内是响应异常的。当节点全部变红的时候证明服务现阶段内就彻底不可用了。运维人员可以通过Topology迅速发现某一个服务潜在的问题，并进行下一步的排查并做到预防。&lt;/p&gt;
&lt;h3 id=&#34;skywalking-trace监控&#34;&gt;Skywalking Trace监控&lt;/h3&gt;
&lt;p&gt;Skywalking通过业务调用监控进行依赖分析，提供给我们了服务之间的服务调用拓扑关系、以及针对每个endpoint的trace记录。&lt;/p&gt;
&lt;p&gt;我们在之前看到consumer节点服务中发生了错误，让我们一起来定位下错误是发生在了什么地方又是什么原因呢？&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl499mksxj30tq0drjsq.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;在每一条trace的信息中都可以看到当前请求的时间、GloableId、以及请求被调用的时间。我们分别看一看正确的调用和异常的调用。&lt;/p&gt;
&lt;h3 id=&#34;trace调用链路监控&#34;&gt;Trace调用链路监控&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl494ki2uj30tu09ewfb.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;图示展示的是一次正常的响应，这条响应总耗时19ms，它有4个span：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;span1 /getStore = 19ms  响应的总流转时间&lt;/li&gt;
&lt;li&gt;span2 /demo2/stores = 14ms  feign client 开始调用远程服务后的响应的总时间&lt;/li&gt;
&lt;li&gt;span3 /stores = 14ms 接口服务响应总时间&lt;/li&gt;
&lt;li&gt;span4 Mysql = 1ms  服务提供端查询数据库的时间&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里span2和span3的时间表现相同，其实是不同的，因为这里时间取了整。&lt;/p&gt;
&lt;p&gt;在每个Span中可以查看当前Span的相关属性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;组件类型: SpringMVC、Feign&lt;/li&gt;
&lt;li&gt;Span状态: false&lt;/li&gt;
&lt;li&gt;HttpMethod: GET&lt;/li&gt;
&lt;li&gt;Url: http://192.168.16.125:10002/demo2/stores&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl494v1kaj30tw0ksdhf.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;这是一次正常的请求调用Trace日志，可能我们并不关心正常的时候，毕竟一切正常不就是我们期待的么！&lt;/p&gt;
&lt;p&gt;我们再来看下，异常状态下我们的Trace以及Span又是什么样的呢。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl495t7hrj30tx0asgmh.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;发生错误的调用链中Span中的is error标识变为true，并且在名为Logs的TAB中可以看到错误发生的具体原因。根据异常情况我们就可以轻松定位到影响业务的具体原因，从而快速定位问题，解决问题。&lt;/p&gt;
&lt;p&gt;通过Log我们看到连接被拒，那么可能是我们的网络出现了问题（可能性小，因为实际情况如果网络出现问题我们连这个trace都看不到了），也有可能是服务端配置问题无法正确建立连接。通过异常日志，我们迅速就找到了问题的关键。&lt;/p&gt;
&lt;p&gt;实际情况是，我把服务方停掉了，做了一次简单的模拟。可见，通过拓扑图示我们可以清晰的看到众多服务中哪个服务是出现了问题的，通过trace日志我们可以很快就定位到问题所在，在最短的时间内解决问题。&lt;/p&gt;
&lt;h2 id=&#34;三服务性能指标监控&#34;&gt;三、服务性能指标监控&lt;/h2&gt;
&lt;p&gt;Skywalking还可以查看具体Service的性能指标，根据相关的性能指标可以分析系统的瓶颈所在并提出优化方案。&lt;/p&gt;
&lt;h3 id=&#34;skywalking-性能监控&#34;&gt;Skywalking 性能监控&lt;/h3&gt;
&lt;p&gt;在服务调用拓扑图上点击相应的节点我们可以看到该服务的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SLA: 服务可用性（主要是通过请求成功与失败次数来计算）&lt;/li&gt;
&lt;li&gt;CPM: 每分钟调用次数&lt;/li&gt;
&lt;li&gt;Avg Response Time: 平均响应时间&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl49a0prgj30tz0cet98.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;从应用整体外部来看我们可以监测到应用在一定时间段内的&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;服务可用性指标SLA&lt;/li&gt;
&lt;li&gt;每分钟平均响应数&lt;/li&gt;
&lt;li&gt;平均响应时间&lt;/li&gt;
&lt;li&gt;服务进程PID&lt;/li&gt;
&lt;li&gt;服务所在物理机的IP、HostName、Operation System&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;service-jvm信息监控&#34;&gt;Service JVM信息监控&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl48ytfc0j30ty087t95.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;还可以监控到Service运行时的CPU、堆内存、非堆内存使用率、以及GC情况。这些信息来源于JVM。注意这里的数据可不是机器本身的数据。&lt;/p&gt;
&lt;h1 id=&#34;四服务告警&#34;&gt;四、服务告警&lt;/h1&gt;
&lt;p&gt;前文我们提到了通过查看拓扑图以及调用链路可以定位问题，可是运维人员又不可能一直盯着这些数据，那么我们就需要告警能力，在异常达到一定阈值的时候主动的提示我们去查看系统状态。&lt;/p&gt;
&lt;p&gt;在Sywalking 6.x版本中新增了对服务状态的告警能力。它通过webhook的方式让我们可以自定义我们告警信息的通知方式。诸如:邮件通知、微信通知、短信通知等。&lt;/p&gt;
&lt;h2 id=&#34;skywalking-服务告警&#34;&gt;Skywalking 服务告警&lt;/h2&gt;
&lt;p&gt;先来看一下告警的规则配置。在alarm-settings.xml中可以配置告警规则，告警规则支持自定义。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl4997b8rj30tn08dq3p.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;一份告警配置由以下几部分组成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;service_resp_time_rule：告警规则名称 ***_rule （规则名称可以自定义但是必须以’_rule’结尾&lt;/li&gt;
&lt;li&gt;indicator-name：指标数据名称： 定义参见http://t.cn/EGhfbmd&lt;/li&gt;
&lt;li&gt;op: 操作符： &amp;gt; , &amp;lt; , = 【当然你可以自己扩展开发其他的操作符】&lt;/li&gt;
&lt;li&gt;threshold：目标值：指标数据的目标数据 如sample中的1000就是服务响应时间，配合上操作符就是大于1000ms的服务响应&lt;/li&gt;
&lt;li&gt;period: 告警检查周期：多久检查一次当前的指标数据是否符合告警规则&lt;/li&gt;
&lt;li&gt;counts: 达到告警阈值的次数&lt;/li&gt;
&lt;li&gt;silence-period：忽略相同告警信息的周期&lt;/li&gt;
&lt;li&gt;message：告警信息&lt;/li&gt;
&lt;li&gt;webhooks：服务告警通知服务地址&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Skywalking通过HttpClient的方式远程调用在配置项webhooks中定义的告警通知服务地址。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl49871dsj30tx087myl.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;了解了SW所传送的数据格式我们就可以对告警信息进行接收处理，实现我们需要的告警通知服务啦！&lt;/p&gt;
&lt;p&gt;我们将一个服务停掉，并将另外一个服务的某个对外暴露的接口让他休眠一定的时间。然后调用一定的次数观察服务的状态信息以及告警情况。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl496dosuj30ty04ogmu.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;总结&#34;&gt;总结&lt;/h1&gt;
&lt;p&gt;本文简单的通过skwaylking的配置来对skywlaking的功能进行一次初步的了解，对skwaylking新提出的概念以及新功能进行简单的诠释，方便大家了解和使用。通过使用APM工具，可以让我们方便的查看微服务架构中系统瓶颈以及性能问题等。&lt;/p&gt;
&lt;h3 id=&#34;精选提问&#34;&gt;精选提问&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;问1：想问问选型的时候用pinpoint还是SK好？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：选型问题&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;要结合具体的业务场景， 比如你的代码运行环境 是java、php、net还是什么。&lt;/li&gt;
&lt;li&gt;pinpoint在安装部署上要比skywalking略微复杂&lt;/li&gt;
&lt;li&gt;pinpoint和sw支持的组件列表是不同的。
&lt;a href=&#34;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/service-agent/java-agent/Supported-list.md&#34;&gt;https://github.com/apache/incubator-skywalking/blob/master/docs/en/setup/service-agent/java-agent/Supported-list.md&lt;/a&gt;你可以参照这里的支持列表对比下pinpoint的支持对象做一个简单对比。&lt;/li&gt;
&lt;li&gt;sw经过测试在并发量较高的情况下比pinpoint的吞吐量更好一些。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;问2：有没有指标统计，比如某个url 的top10 请求、响应最慢的10个请求？某个服务在整个链条中的耗时占比？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：1.sw自带有响应最慢的请求top10统计针对所有的endpoint的统计。
2.针对每个url的top10统计，sw本身没有做统计，数据都是现成的通过简单的检索就可以搜到你想要的结果。
3.没有具体的耗时占比，但是有具体总链路时间统计以及某个服务的耗时统计，至于占比自己算吧，可以看ppt中的调用链路监控的span时间解释。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问3：能不能具体说一下在你们系统中的应用？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：EOS8LA版本中，我们整合sw对应用提供拓扑、调用链路、性能指标的监控、并在sw数据的基础上增加系统的维度。
当服务数很庞大的时候，整体的拓扑其实就是一张密密麻麻的蜘蛛网。我们可以通过系统来选择具体某个系统下的应用。
8LA中SW是5.0.0alpha版本，受限于sw功能，我们并没有提供告警能力，这在之后会是我们的考虑目标。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问4：业务访问日志大概每天100G，kubernetes 环境中部署，使用稳定吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：监控数据没有长时间的存储必要，除非你有特定的需求。它有一定的时效性，你可以设置ttl自动清除过时信息。100g，es集群还是能轻松支撑的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问5：和pinpoint相比有什么优势吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;部署方式、使用方式简单&lt;/li&gt;
&lt;li&gt;功能特性支持的更多&lt;/li&gt;
&lt;li&gt;高并发性能会更好一些&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;问6：skywalking的侵入式追踪功能方便进行单服务链的服务追踪。但是跨多台服务器多项目的整体服务链追踪是否有整体设计考虑？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：sw本身特性就是对分布式系统的追踪，他是无侵入式的。无关你的应用部署在多少台服务器上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问7：应用在加上代理之后性能会下降。请问您有什么解决方法吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：性能下降是在所难免的，但是据我了解，以及官方的测试，他的性能影响是很低的。这是sw的测试数据供你参考。
&lt;a href=&#34;https://skywalkingtest.github.io/Agent-Benchmarks/README_zh.html&#34;&gt;https://skywalkingtest.github.io/Agent-Benchmarks/README_zh.html&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问8：有异构系统需求的话可以用sw吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：只要skywalking的探针支持的应该都是可以的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问9：sw对于商用的web中间件，如bes、tongweb、websphere、weblogic的支持如何？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答：商业组件支持的比较少，因为涉及到相关license的问题，sw项目组需要获得他们的支持来进行数据上报，据我了解，支持不是很好。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 关于 ElastiSsearch 因 basic 认证导致 SkyWalking 无法正常调用接口问题</title>
      <link>/zh/2019-01-02-skywalking-elasticsearch-basic/</link>
      <pubDate>Wed, 02 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-01-02-skywalking-elasticsearch-basic/</guid>
      <description>
        
        
        &lt;p&gt;SkyWalking 依赖 elasticsearch 集群，如果 elasticsearch 安装有 x-pack 插件的话，那么就会存在一个 Basic 认证，导致 skywalking 无法调用 elasticsearch, 解决方法是使用 nginx 做代理，让 nginx 来做这个 Basic 认证，那么这个问题就自然解决了。&lt;/p&gt;
&lt;p&gt;方法如下:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装 nginx&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;yum install -y nginx&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;配置 nginx&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;server {
        listen       9200 default_server;
        server_name  _;
        
        location / {
                 proxy_set_header Host $host;
                 proxy_set_header X-Real-IP $remote_addr;
                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                 proxy_pass http://localhost:9200;
                 #Basic字符串就是使用你的用户名(admin),密码(12345)编码后的值
                 #注意:在进行Basic加密的时候要使用如下格式如:admin:123456 注意中间有个冒号
                 proxy_set_header Authorization &amp;#34;Basic YWRtaW4gMTIzNDU2&amp;#34;;
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;验证&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;curl localhost:9200&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;{
  &amp;#34;name&amp;#34; : &amp;#34;Yd0rCp9&amp;#34;,
  &amp;#34;cluster_name&amp;#34; : &amp;#34;es-cn-4590xv9md0009doky&amp;#34;,
  &amp;#34;cluster_uuid&amp;#34; : &amp;#34;jAPLrqY5R6KWWgHnGCWOAA&amp;#34;,
  &amp;#34;version&amp;#34; : {
    &amp;#34;number&amp;#34; : &amp;#34;6.3.2&amp;#34;,
    &amp;#34;build_flavor&amp;#34; : &amp;#34;default&amp;#34;,
    &amp;#34;build_type&amp;#34; : &amp;#34;tar&amp;#34;,
    &amp;#34;build_hash&amp;#34; : &amp;#34;053779d&amp;#34;,
    &amp;#34;build_date&amp;#34; : &amp;#34;2018-07-20T05:20:23.451332Z&amp;#34;,
    &amp;#34;build_snapshot&amp;#34; : false,
    &amp;#34;lucene_version&amp;#34; : &amp;#34;7.3.1&amp;#34;,
    &amp;#34;minimum_wire_compatibility_version&amp;#34; : &amp;#34;5.6.0&amp;#34;,
    &amp;#34;minimum_index_compatibility_version&amp;#34; : &amp;#34;5.0.0&amp;#34;
  },
  &amp;#34;tagline&amp;#34; : &amp;#34;You Know, for Search&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;看到如上结果那么恭喜你成功了。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 更容易理解将要到来的分布式链路追踪 6.0GA (翻译)</title>
      <link>/zh/2019-01-02-understand-trace-trans2cn/</link>
      <pubDate>Wed, 02 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>/zh/2019-01-02-understand-trace-trans2cn/</guid>
      <description>
        
        
        &lt;ul&gt;
&lt;li&gt;作者: Wu Sheng, tetrate, SkyWalking original creator&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/wu-sheng&#34;&gt;GitHub&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/wusheng1108&#34;&gt;Twitter&lt;/a&gt;, &lt;a href=&#34;https://www.linkedin.com/in/wusheng1108&#34;&gt;Linkedin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;翻译: jjlu521016&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;背景&#34;&gt;背景&lt;/h1&gt;
&lt;p&gt;在当前的微服务架构中分布式链路追踪是很有必要的一部分，但是对于一些用户来说如何去理解和使用分布式链路追踪的相关数据是不清楚的。
这个博客概述了典型的分布式跟踪用例，以及Skywalking的V6版本中新的可视化功能。我们希望新的用户通过这些示例来更好的理解。&lt;/p&gt;
&lt;h2 id=&#34;指标和拓扑图&#34;&gt;指标和拓扑图&lt;/h2&gt;
&lt;p&gt;跟踪数据支持两个众所周知的分析特性：&lt;code&gt;指标&lt;/code&gt;和&lt;code&gt;拓扑图&lt;/code&gt;&lt;br&gt;
&lt;code&gt;指标&lt;/code&gt;: 每个service, service instance, endpoint的指标都是从跟踪中的入口span派生的。指标代表响应时间的性能。所以可以有一个平均响应时间，99%的响应时间，成功率等。它们按service, service instance, endpoint进行分解。&lt;br&gt;
&lt;code&gt;拓扑图&lt;/code&gt;: 拓扑表示服务之间的链接，是分布式跟踪最有吸引力的特性。拓扑结构允许所有用户理解分布式服务关系和依赖关系，即使它们是不同的或复杂的。这一点很重要，因为它为所有相关方提供了一个单一的视图，无论他们是开发人员、设计者还是操作者。&lt;/p&gt;
&lt;p&gt;这里有一个拓扑图的例子包含了4个项目，包括kafka和两个外部依赖。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl44oveesj31gr0u00u1.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-在skywalking的可选择UI0RocketBot的拓扑图-&lt;/p&gt;
&lt;h1 id=&#34;trace&#34;&gt;Trace&lt;/h1&gt;
&lt;p&gt;在分布式链路追踪系统中，我们花费大量资源（CPU、内存、磁盘和网络）来生成、传输和持久跟踪数据。让我们试着回答为什么要这样做？我们可以用跟踪数据回答哪些典型的诊断和系统性能问题？&lt;/p&gt;
&lt;p&gt;Skywalking v6包含两种追踪视图:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;TreeMode: 第一次提供,帮助您更容易识别问题。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;ListMode: 常规的时间线视图，通常也出现在其他跟踪系统中，如Zipkin。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;发生错误&#34;&gt;发生错误&lt;/h1&gt;
&lt;p&gt;在trace视图，最简单的部分是定位错误，可能是由代码异常或网络故障引起的。通过span详情提供的细节，ListMode和TreeMode都能够找到错误
&lt;img src=&#34;0081Kckwly1gkl44lh09oj32ha0se42w.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-ListMode 错误span-&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl44kwl6nj31q20u0dl0.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-TreeMode 错误span-&lt;/p&gt;
&lt;h1 id=&#34;慢span&#34;&gt;慢span&lt;/h1&gt;
&lt;p&gt;一个高优先级的特性是识别跟踪中最慢的span。这将使用应用程序代理捕获的执行持续时间。在旧的ListMode跟踪视图中，由于嵌套，父span几乎总是包括子span的持续时间。换句话说，一个缓慢的span通常会导致它的父节点也变慢，在Skywalking 6中，我们提供了 &lt;code&gt;最慢的前5个span&lt;/code&gt; 过滤器来帮助你您直接定位span。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;0081Kckwly1gkl44odek5j31sd0u0q8f.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-最慢的前5个span-&lt;/p&gt;
&lt;h1 id=&#34;太多子span&#34;&gt;太多子span&lt;/h1&gt;
&lt;p&gt;在某些情况下，个别持续时间很快，但跟踪速度仍然很慢，如：
&lt;img src=&#34;0081Kckwly1gkl44mxmddj310i0lktbp.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-没有慢span的追踪-&lt;/p&gt;
&lt;p&gt;如果要了解根问题是否与太多操作相关，请使用子范围号的&lt;code&gt;Top 5 of children span number&lt;/code&gt;,筛选器显示每个span的子级数量，突出显示前5个。
&lt;img src=&#34;0081Kckwly1gkl44nbryhj31fa0tcafl.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-13个数据库访问相关的span-&lt;/p&gt;
&lt;p&gt;在这个截图中，有一个包含13个子项的span，这些子项都是数据库访问。另外，当您看到跟踪的概述时，这个2000ms跟踪的数据库花费了1380ms。
&lt;img src=&#34;0081Kckwly1gkl44lzkbwj31040famyy.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-1380ms花费在数据库访问-&lt;/p&gt;
&lt;p&gt;在本例中，根本原因是数据库访问太多。这在其他场景中也很常见，比如太多的RPC或缓存访问。&lt;/p&gt;
&lt;h1 id=&#34;链路深度&#34;&gt;链路深度&lt;/h1&gt;
&lt;p&gt;跟踪深度也与延迟有关。像&lt;a href=&#34;#%E5%A4%AA%E5%A4%9A%E5%AD%90span&#34;&gt;太多子span&lt;/a&gt;的场景一样，每个span延迟看起来不错，但整个链路追踪的过程很慢。
&lt;img src=&#34;0081Kckwly1gkl44nv4gfj32600u0q7a.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;-链路深度-&lt;/p&gt;
&lt;p&gt;上图所示,最慢的span小鱼500ms,对于2000毫秒的跟踪来说，速度并不太慢。当您看到第一行时，有四种不同的颜色表示这个分布式跟踪中涉及的四个services。每一个都需要100~400ms，这四个都需要近2000ms，从这里我们知道这个缓慢的跟踪是由一个序列中的3个RPC造成的。&lt;/p&gt;
&lt;h2 id=&#34;结束语&#34;&gt;结束语&lt;/h2&gt;
&lt;p&gt;分布式链路追踪和APM 工具帮助我们确定造成问题的根源，允许开发和操作团队进行相应的优化。我们希望您喜欢这一点，并且喜欢Apache Skywalking和我们的新链路追踪可视化界面。如果你喜欢的话，在&lt;a href=&#34;https://github.com/apache/incubator-skywalking&#34;&gt;github上面给我们加start来鼓励我们&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Skywakling 6计划在2019年的1月底完成release。您可以通过以下渠道联系项目团队成员&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关注 &lt;a href=&#34;https://twitter.com/ASFSkyWalking&#34;&gt;skywalking推特&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;订阅邮件:dev@skywalking.apache.org。发送邮件到 &lt;a href=&#34;mailto:dev-subscribe@kywalking.apache.org&#34;&gt;dev-subscribe@kywalking.apache.org&lt;/a&gt; 来订阅.&lt;/li&gt;
&lt;li&gt;加入&lt;a href=&#34;https://gitter.im/OpenSkywalking/Lobby&#34;&gt;Gitter&lt;/a&gt;聊天室&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: SkyWalking apm-sniffer 原理学习与插件编写</title>
      <link>/zh/2018-12-21-skywalking-apm-sniffer-beginning/</link>
      <pubDate>Fri, 21 Dec 2018 00:00:00 +0000</pubDate>
      
      <guid>/zh/2018-12-21-skywalking-apm-sniffer-beginning/</guid>
      <description>
        
        
        &lt;h2 id=&#34;导读&#34;&gt;导读&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SkyWalking 中 Java 探针是使用 JavaAgent 的两大字节码操作工具之一的 Byte Buddy（另外是 Javassist）实现的。项目还包含.Net core 和 Nodejs 自动探针，以及 Service Mesh Istio 的监控。总体上，SkyWalking 是一个多语言，多场景的适配，特别为微服务、云原生和基于容器架构设计的可观测性分析平台（Observability Analysis Platform）。&lt;/li&gt;
&lt;li&gt;本文基于 SkyWalking 5.0.0-RC2 和 Byte Buddy 1.7.9 版本，会从以下几个章节，让大家掌握 SkyWalking Java 探针的使用，进而让 SkyWalking 在自己公司中的二次开发变得触手可及。
&lt;ul&gt;
&lt;li&gt;Byte Buddy 实现 JavaAgent 项目&lt;/li&gt;
&lt;li&gt;迭代 JavaAgent 项目的方法论&lt;/li&gt;
&lt;li&gt;SkyWalking agent 项目如何 Debug&lt;/li&gt;
&lt;li&gt;SkyWalking 插件开发实践&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;文章底部有 SkyWalking 和 Byte Buddy 相应的学习资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;byte-buddy-实现&#34;&gt;Byte Buddy 实现&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;首先如果你对 JavaAgent 还不是很了解可以先百度一下，或在公众号内看下《JavaAgent 原理与实践》简单入门下。&lt;/li&gt;
&lt;li&gt;SpringMVC 分发请求的关键方法相信已经不用我在赘述了，那我们来编写 Byte Buddy JavaAgent 代码吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;AgentMain&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;premain&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;String agentOps&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Instrumentation instrumentation&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; AgentBuilder&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;Default&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;ElementMatchers&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;named&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;org.springframework.web.servlet.DispatcherServlet&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;transform&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;((&lt;/span&gt;builder&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; type&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; classLoader&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; module&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;
                        builder&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;method&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;ElementMatchers&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;named&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;doDispatch&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt;
                                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;intercept&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;MethodDelegation&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;to&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;DoDispatchInterceptor&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)))&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;installOn&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;instrumentation&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;编写 DispatcherServlet doDispatch 拦截器代码（是不是跟 AOP 如出一辙）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;DoDispatchInterceptor&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@RuntimeType&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;static&lt;/span&gt; Object &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;intercept&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Argument&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; HttpServletRequest request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@SuperCall&lt;/span&gt; Callable&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; callable&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;final&lt;/span&gt; StringBuilder in &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; StringBuilder&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getParameterMap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getParameterMap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; 0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getParameterMap&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;keySet&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;forEach&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;key &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt; in&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;append&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;key=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; key &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;_value=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getParameter&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;key&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;));&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
        &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;long&lt;/span&gt; agentStart &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; System&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;currentTimeMillis&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;try&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; callable&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;call&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;Exception e&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            System&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;out&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;println&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Exception :&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; e&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getMessage&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;());&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;null&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;finally&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            System&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;out&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;println&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;path:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getRequestURI&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34; 入参:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; in &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34; 耗时:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;System&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;currentTimeMillis&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; agentStart&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;));&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;resources/META-INF/MANIFEST.MF&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;Manifest-Version: 1.0
Premain-Class: com.z.test.agent.AgentMain
Can-Redefine-Classes: true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;pom.xml 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;dependencies
    +net.bytebuddy.byte-buddy 
    +javax.servlet.javax.servlet-api *scope=provided
plugins
    +maven-jar-plugin *manifestFile=src/main/resources/META-INF/MANIFEST.MF
    +maven-shade-plugin *include:net.bytebuddy:byte-buddy:jar:
    +maven-compiler-plugin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;小结：没几十行代码就完成了，通过 Byte Buddy 实现应用组件 SpringMVC 记录请求路径、入参、执行时间 JavaAgent 项目，是不是觉得自己很优秀。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;持续迭代-javaagent&#34;&gt;持续迭代 JavaAgent&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本章节主要介绍 JavaAgent 如何 Debug，以及持续集成的方法论。&lt;/li&gt;
&lt;li&gt;首先我的 JavaAgent 项目目录结构如图所示:&lt;/li&gt;
&lt;li&gt;应用项目是用几行代码实现的 SpringBootWeb 项目:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;&lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@SpringBootApplication&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;scanBasePackages &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;TestBootWeb&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;String&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; args&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        SpringApplication&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;TestBootWeb&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; args&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@RestController&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;ApiController&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@PostMapping&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;/ping&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ping&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;HttpServletRequest request&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pong&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;下面是关键 JavaAgent 项目如何持续迭代与集成:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;VM options增加:-JavaAgent:{$HOME}/Code/github/z_my_test/test-agent/target/test-agent-1.0-SNAPSHOT.jar=args
Before launch 在Build之前增加：
    Working directory:{$HOME}/Code/github/incubator-skywalking
    Command line:-T 1C -pl test-agent -am clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;小结：看到这里的将 JavaAgent 持续迭代集成方法，是不是瞬间觉得自己手心已经发痒起来，很想编写一个自己的 agent 项目了呢，等等还有一个好消息:test-demo 这 10 几行的代码实现的 Web 服务，居然有 5k 左右的类可以使用 agent 增强。&lt;/li&gt;
&lt;li&gt;注意 mvn 编译加速的命令是 maven3 + 版本以上才支持的哈。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;skywalking-debug&#34;&gt;SkyWalking Debug&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;峰回路转，到了文章的主题《SkyWalking 之高级用法》的正文啦。首先，JavaAgent 项目想 Debug，还需要将 agent 代码与接入 agent 项目至少在同一个工作空间内，网上方法有很多，这里我推荐大家一个最简单的方法。File-&amp;gt;New-&amp;gt;Module from Exisiting Sources… 引入 skywalking-agent 源码即可&lt;/li&gt;
&lt;li&gt;详细的 idea 编辑器配置：&lt;/li&gt;
&lt;li&gt;优化 SkyWalking agent 编译时间，我的集成时间优化到 30 秒左右：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;VM options增加:-JavaAgent:-JavaAgent:{$HOME}/Code/github/incubator-skywalking/skywalking-agent/skywalking-agent.jar：不要用dist里面的skywalking-agent.jar，具体原因大家可以看看源码：apm-sniffer/apm-agent/pom.xml中的maven插件的使用。
Before launch 在Build之前增加：
    Working directory:{$HOME}/Code/github/incubator-skywalking
    Command line:-T 1C -pl apm-sniffer/apm-sdk-plugin -amd clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true： 这里我针对插件包，因为紧接着下文要开发插件
另外根pom注释maven-checkstyle-plugin也可加速编译
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;kob-之-skywalking-插件编写&#34;&gt;kob 之 SkyWalking 插件编写&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;kob（贝壳分布式作业调度框架）是贝壳找房项目微服务集群中的基础组件，通过编写贝壳分布式作业调度框架的 SkyWalking 插件，可以实时收集作业调度任务的执行链路信息，从而及时得到基础组件的稳定性，了解细节可点击阅读《&lt;a href=&#34;https://mp.weixin.qq.com/s/3hXyFCgclsuoznNQ2ulC4g&#34;&gt;贝壳分布式调度框架简介&lt;/a&gt;》。想详细了解 SkyWalking 插件编写可在文章底部参考链接中，跳转至对应的官方资源，好话不多说，代码一把唆起来。&lt;/li&gt;
&lt;li&gt;apm-sdk-plugin pom.xml 增加自己的插件 model&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;apm-sdk-plugin&lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;modules&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;kob-plugin&lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;/module&amp;gt;&lt;/span&gt;
        ...
    &lt;span style=&#34;color:#000080&#34;&gt;&amp;lt;modules&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;resources.skywalking-plugin.def 增加自己的描述&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;kob=org.apache.skywalking.apm.plugin.kob.KobInstrumentation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;在 SkyWalking 的项目中，通过继承 ClassInstanceMethodsEnhancePluginDefine 可以定义需要拦截的类和增强的方法，编写作业调度方法的 instrumentation&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;KobInstrumentation&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;extends&lt;/span&gt; ClassInstanceMethodsEnhancePluginDefine &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;final&lt;/span&gt; String ENHANCE_CLASS &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;com.ke.kob.client.spring.core.TaskDispatcher&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;final&lt;/span&gt; String INTERCEPT_CLASS &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;org.apache.skywalking.apm.plugin.kob.KobInterceptor&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protected&lt;/span&gt; ClassMatch &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;enhanceClass&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; NameMatch&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;byName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;ENHANCE_CLASS&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protected&lt;/span&gt; ConstructorInterceptPoint&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getConstructorsInterceptPoints&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;null&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;protected&lt;/span&gt; InstanceMethodsInterceptPoint&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getInstanceMethodsInterceptPoints&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; InstanceMethodsInterceptPoint&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; InstanceMethodsInterceptPoint&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; ElementMatcher&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;MethodDescription&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getMethodsMatcher&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; named&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dispatcher1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
                    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;getMethodsInterceptor&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; INTERCEPT_CLASS&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
                    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;boolean&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;isOverrideArgs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;通过实现 InstanceMethodsAroundInterceptor 后，定义 beforeMethod、afterMethod 和 handleMethodException 的实现方法，可以环绕增强指定目标方法，下面自定义 interceptor 实现 span 的跟踪（这里需要注意 SkyWalking 中 span 的生命周期，在 afterMethod 方法中结束 span）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Java&#34; data-lang=&#34;Java&#34;&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;KobInterceptor&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;implements&lt;/span&gt; InstanceMethodsAroundInterceptor &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;beforeMethod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;EnhancedInstance objInst&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Method method&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; allArguments&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;  Class&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; argumentsTypes&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; MethodInterceptResult result&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;throws&lt;/span&gt; Throwable &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;final&lt;/span&gt; ContextCarrier contextCarrier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;new&lt;/span&gt; ContextCarrier&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        com&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;ke&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;kob&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;spring&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;model&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;TaskContext&lt;/span&gt; context &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;TaskContext&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; allArguments&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;];&lt;/span&gt;
        CarrierItem next &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; contextCarrier&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;items&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;next&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;hasNext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            next &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; next&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;next&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
            next&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;setHeadValue&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;JSON&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;toJSONString&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;context&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getUserParam&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()));&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
        AbstractSpan span &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; ContextManager&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;createEntrySpan&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;client:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;allArguments&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;1&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]+&lt;/span&gt;&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;,task:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;context&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;getTaskKey&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt; contextCarrier&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
        span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;setComponent&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;ComponentsDefine&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;TRANSPORT_CLIENT&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
        SpanLayer&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;asRPCFramework&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;span&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; Object &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;afterMethod&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;EnhancedInstance objInst&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Method method&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; allArguments&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Class&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; argumentsTypes&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Object ret&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;throws&lt;/span&gt; Throwable &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        ContextManager&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;stopSpan&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;return&lt;/span&gt; ret&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#3c5d5d;font-weight:bold&#34;&gt;@Override&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#458;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;handleMethodException&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;EnhancedInstance objInst&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Method method&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; allArguments&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Class&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; argumentsTypes&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; Throwable t&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;实现效果，将操作名改成任务执行节点 + 任务执行方法，实现 kob 的 SkyWalking 的插件编写，加上报警体系，可以进一步增加公司基础组件的稳定性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考链接&#34;&gt;参考链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apache/skywalking&#34;&gt;Apache SkyWalking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/raphw/byte-buddy&#34;&gt;Byte Buddy（runtime code generation for the Java virtual machine）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
  </channel>
</rss>
