<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Apache SkyWalking – R3</title>
    <link>/tags/r3/</link>
    <description>Recent content in R3 on Apache SkyWalking</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 17 Oct 2024 00:00:00 +0000</lastBuildDate>
    
	  <atom:link href="/tags/r3/feed.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Zh: 引入 R3 识别 RESTFul URI</title>
      <link>/zh/2024-010-15-introduce-r3-to-recognition-restful-url/</link>
      <pubDate>Thu, 17 Oct 2024 00:00:00 +0000</pubDate>
      <guid>/zh/2024-010-15-introduce-r3-to-recognition-restful-url/</guid>
      <description>
        
        
        &lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;在现代应用中，服务通常通过 RESTFul HTTP URI 提供。使用 RESTFul HTTP URI 作为唯一的资源标识符，不仅具备良好的可读性，还能让客户端和服务器更容易理解请求。然而，在可观测性领域，这种方式也带来了一些挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;大量的端点（HTTP URI）&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;：在某些框架中，通常会声明规则来处理 RESTFul 请求。例如，在 Java 的 Spring Web 中可以使用 &lt;code&gt;@GET&lt;/code&gt; 等注解，然后可以通过 Java Agent 将其与当前请求关联起来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAPI&lt;/strong&gt;：应用可以关联预定义文件，使可观测性系统知晓可能使用的 URI。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这两种解决方案都与应用设置紧密耦合，这对于未知应用或者无法监控代理的应用来说是一个局限。因此，我们需要考虑是否有一种更通用的解决方案来识别 URI，并合并来自类似 URI 生成的指标，以便更好地展示数据。&lt;/p&gt;
&lt;h2 id=&#34;r3&#34;&gt;R3&lt;/h2&gt;
&lt;p&gt;R3（RESTFul 模式识别）是一个高性能的 RESTFul URI 识别工具，其灵感来自 &lt;a href=&#34;https://github.com/logpai/Drain3&#34;&gt;Drain3&lt;/a&gt;。它可以作为独立应用部署在可观测性服务器上，并与 SkyWalking OAP 进行通信。&lt;/p&gt;
&lt;p&gt;R3 可以通过 gRPC 协议接收 URI 列表，并将类似的 URI 聚合为特定格式。聚合后的（格式化）URI 列表也可以通过 gRPC 协议进行查询。&lt;/p&gt;
&lt;h3 id=&#34;数据交互流程&#34;&gt;数据交互流程&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;data_interaction_flow.png&#34; alt=&#34;OAP 与 R3 之间的数据交互流程&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;OAP 接收并缓存未格式化的 URI 列表&lt;/strong&gt;：OAP 通过不同协议接收可观测性数据，并识别出所有未格式化的 URI。然后将这些 URI 按照所属服务暂时存储在列表中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OAP 将待格式化的 URI 发送给 R3&lt;/strong&gt;：OAP 定期将需要格式化的 URI 批量发送到 R3 服务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;R3 接收并解析 URI 列表&lt;/strong&gt;：R3 异步分析接收到的 URI 相似性，并将结果存储（持久化）在本地磁盘中，以便在重启后进行恢复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OAP 查询 R3 中的格式化 URI 列表&lt;/strong&gt;：OAP 定期查询 R3 中检测到的格式化 URI，并将结果保存在内存中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OAP 格式化 URI&lt;/strong&gt;：当 OAP 接收到新的可观测性数据时，会将 URI 与从 R3 获取的格式化 URI 进行匹配。如果匹配成功，后续的指标计算将使用格式化后的 URI。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;场景&#34;&gt;场景&lt;/h3&gt;
&lt;p&gt;在 R3 中，主要解决以下场景。对于识别为重复的 URI，R3 将用 &lt;code&gt;{var}&lt;/code&gt; 替换变量部分以标准化 URI。&lt;/p&gt;
&lt;h4 id=&#34;id-匹配&#34;&gt;ID 匹配&lt;/h4&gt;
&lt;p&gt;在 RESTFul API 中，常见做法是将各种 ID 包含在 URI 路径中，这导致了大量唯一的 URI 端点。例如，以下路径将被 R3 聚合为标准化格式 &lt;code&gt;/api/users/{var}&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/api/users/cbf11b02ea464447b507e8852c32190a&lt;/li&gt;
&lt;li&gt;/api/users/5e363a4a18b7464b8cbff1a7ee4c91ca&lt;/li&gt;
&lt;li&gt;/api/users/44cf77fc351f4c6c9c4f1448f2f12800&lt;/li&gt;
&lt;li&gt;/api/users/38d3be5f9bd44f7f98906ea049694511&lt;/li&gt;
&lt;li&gt;/api/users/5ad14302e7924f4aa1d60e58d65b3dd2&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;词语检测&#34;&gt;词语检测&lt;/h4&gt;
&lt;p&gt;在 RESTFul URI 中，实体的操作通常通过 HTTP 方法指定，但有时还需要在路径中添加特定名词。为此，R3 实现了词语解析：当 R3 检测到路径中的特定词语时，将不会格式化该部分。例如，以下 URI 将不会被视为相似，因此不会被合并：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/api/sale&lt;/li&gt;
&lt;li&gt;/api/product_sale&lt;/li&gt;
&lt;li&gt;/api/ProductSale&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;样本不足&#34;&gt;样本不足&lt;/h4&gt;
&lt;p&gt;为防止由于样本不足而导致错误判断，R3 允许在&lt;a href=&#34;https://github.com/SkyAPM/R3/blob/main/servers/simple/uri_drain.ini&#34;&gt;配置文件&lt;/a&gt;中配置&lt;a href=&#34;https://github.com/SkyAPM/R3/blob/main/servers/simple/uri_drain.ini#L38&#34;&gt;最小 URI 合并计数&lt;/a&gt;参数。&lt;/p&gt;
&lt;p&gt;例如，当阈值为 &lt;code&gt;3&lt;/code&gt; 时，以下 URI 将保持原样，不会被参数化。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/api/fetch1&lt;/li&gt;
&lt;li&gt;/api/fetch2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是以下 URI 将被参数化为 &lt;code&gt;/api/{var}&lt;/code&gt;，因为样本数大于阈值。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/api/fetch1&lt;/li&gt;
&lt;li&gt;/api/fetch2&lt;/li&gt;
&lt;li&gt;/api/fetch3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;版本-api&#34;&gt;版本 API&lt;/h4&gt;
&lt;p&gt;在实际场景中，常会遇到包含多个版本的 URI。R3 通过确保指定路径中包含 &lt;code&gt;v\\d+&lt;/code&gt; 参数（表示版本信息）来解决这个问题，该部分将不会被参数化。例如，以下 URI 将分别解析为 &lt;code&gt;/test/v1/{var}&lt;/code&gt; 和 &lt;code&gt;/test/v999/{var}&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/test/v1/cbf11b02ea464447b507e8852c32190a&lt;/li&gt;
&lt;li&gt;/test/v1/5e363a4a18b7464b8cbff1a7ee4c91ca&lt;/li&gt;
&lt;li&gt;/test/v1/38d3be5f9bd44f7f98906ea049694511&lt;/li&gt;
&lt;li&gt;/test/v999/1&lt;/li&gt;
&lt;li&gt;/test/v999/2&lt;/li&gt;
&lt;li&gt;/test/v999/3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;演示&#34;&gt;演示&lt;/h2&gt;
&lt;p&gt;接下来我们快速演示如何使用 R3 格式化观察到的端点，帮助你更具体地理解它的功能。&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、R3 服务和 UI。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#953800&#34;&gt;FEATURE_FLAGS&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;java-agent-injector,single-node,elasticsearch,r3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make deploy.kubernetes
&lt;/span&gt;&lt;/span&gt;&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 tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl port-forward svc/ui 8080:8080 --namespace default
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;触发-restful-请求&#34;&gt;触发 RESTFul 请求&lt;/h3&gt;
&lt;p&gt;在 R3 中，默认启动了定时任务以定期生成 RESTFul 流量。不过，你也可以使用以下命令手动触发此过程：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl &lt;span style=&#34;color:#6639ba&#34;&gt;exec&lt;/span&gt; -n sample-services &lt;span style=&#34;color:#cf222e&#34;&gt;$(&lt;/span&gt;kubectl get pod -n sample-services --selector&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#953800&#34;&gt;app&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;gateway -o &lt;span style=&#34;color:#953800&#34;&gt;jsonpath&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;)&lt;/span&gt; -- /bin/bash -c &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;for i in $(seq 1 200); do curl http://rating/songs/$i/reviews/$((i+1)); sleep 1; done&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述命令中，R3 将自动定位网关节点，并以 RESTFul 格式向该节点内的 rating 服务发送请求。此操作允许 R3 生成并测试模拟实际 RESTFul 请求的流量模式。&lt;/p&gt;
&lt;h3 id=&#34;查看格式化-uri&#34;&gt;查看格式化 URI&lt;/h3&gt;
&lt;p&gt;一旦触发 RESTFul 请求，你可以在 UI 中查看聚合后的端点。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：由于格式化端点是异步生成的，因此一些较早的请求可能尚未被格式化。你可能需要等待一段时间，UI 才会仅显示格式化后的地址。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;formated_images.png&#34; alt=&#34;格式化端点&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;结论&#34;&gt;结论&lt;/h2&gt;
&lt;p&gt;在本文中，我们详细讨论了 SkyWalking 如何利用 R3 服务来格式化 RESTFul URI，并在接收后聚合相关的指标。目前，它适用于大多数 RESTFul 场景，如果需要支持更多情况，我们可以根据需求进一步扩展。&lt;/p&gt;

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