<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>服务治理 on </title>
    <link>https://note.lican.site/tags/%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86/</link>
    <description>Recent content in 服务治理 on </description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>© lican.asia All rights reserved</copyright>
    <lastBuildDate>Tue, 06 Oct 2020 12:44:10 +0800</lastBuildDate>
    <atom:link href="https://note.lican.site/tags/%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>带你快速了解：限流中的漏桶和令牌桶算法</title>
      <link>https://note.lican.site/posts/posts/microservice/leaky-token-buckets/</link>
      <pubDate>Tue, 06 Oct 2020 12:44:10 +0800</pubDate>
      <guid>https://note.lican.site/posts/posts/microservice/leaky-token-buckets/</guid>
      <description>&lt;p&gt;在前文 《限流熔断是什么，怎么做，不做行不行？》中针对 “限流” 动作，有提到流量控制其内部对应着两种常用的限流算法，分别是漏桶算法和令牌桶算法。因此会有的读者会好奇，这都是些啥？&lt;/p&gt;&#xA;&lt;p&gt;为了更进一步的了解 WHY，本文来快速探索一下，看看限流下的一些 “算法” 们到底有何作用，是为何成为流量控制的基石的？&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/815f7524b5367149cc9c6725ee28cd12.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;&#xA;&lt;p&gt;理论上每一个对外/内提供功能的资源点，都需要进行一定的流量控制，否则在业务的持续迭代中，是有可能出现突发性流量的场景（就像年初所带来的一些行业突发转变，导致业务流量突然暴增）：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/c29272e53f9e125dbbfba133b3eea7c4.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;若没有进行限流，就会出现一些奇奇怪怪的问题点，实则就是系统无法承受这波流量，逐渐崩溃，走向系统假死。&lt;/p&gt;&#xA;&lt;h2 id=&#34;现实场景&#34;&gt;现实场景&lt;/h2&gt;&#xA;&lt;p&gt;最常见的现实场景就是日常随处可见的排插、插座，其内置的保险丝，也被称为电流保险丝，其主要是起过载保护作用，保险丝会在电流异常升高到一定的高度和热度的时候，自身熔断切断电流，从而起到保护电路安全运行的作用。&lt;/p&gt;&#xA;&lt;p&gt;因此真实世界中有许多与软件工程中的限流熔断的场景有异曲同工之处，也是为了控制量，超量就切断。你也可以想想现实生活中是否有遇到其他类似的例子呢？&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/23af65486fc991e1bd976c37626ccf18.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;漏桶算法leaky-bucket&#34;&gt;漏桶算法（Leaky Bucket）&lt;/h2&gt;&#xA;&lt;p&gt;漏桶算法（Leaky Bucket）是网络中流量整形（Traffic Shaping）或速率限制（Rate Limiting）时常用的一种算法，它的主要目的是控制数据注入到网络的速率，平滑网络上的突发流量。&lt;/p&gt;&#xA;&lt;p&gt;漏桶算法通过其算法调控了流量访问，使得突发流量可以被整形，去毛刺，变成一个相对缓和，以便为网络提供一个稳定的流量。&lt;/p&gt;&#xA;&lt;p&gt;漏桶算法的存储桶主要由三个参数定义，分别是：桶的容量、水从桶中流出的速率、桶的初始充满度。&lt;/p&gt;&#xA;&lt;p&gt;其核心理念就如字面意思：一个会漏水的桶。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/386bdd6a907a2130f5bfa74696817221.jpg&#34; alt=&#34;图片来自 geeksforgeeks&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;bursty-flow&#34;&gt;Bursty Flow&lt;/h3&gt;&#xA;&lt;p&gt;在上图中，水龙头代表着突发流量（Bursty Flow）。当网络中存在突发流量，且无任何调控时，就会出现像 Bursty Data 处类似的场景。主机以 12 Mbps 的速率发送数据，时间持续 2s，总计 24 Mbits 数据。随后主机暂停发送 5s，然后再以 2 Mbps 的速率发送数据 3s，最终总共发送了 6 Mbits 的数据。&lt;/p&gt;&#xA;&lt;p&gt;因此主机在 10s 内总共发送了 30 Mbits 的数据。但这里存在一个问题，就是数据的发送并不是平滑的，存在一个较大的波峰。若所有流量都是如此的传输方式，将会 “旱的旱死涝的涝死”，对系统并不是特别的友好。&lt;/p&gt;&#xA;&lt;h3 id=&#34;fixed-flow&#34;&gt;Fixed Flow&lt;/h3&gt;&#xA;&lt;p&gt;为了解决 Bursty Flow 场景的问题。漏桶（Leaky Bucket）出现了，漏桶具有固定的流出速率、固定的容量大小。&lt;/p&gt;&#xA;&lt;p&gt;在上图中，漏桶在相同的 10s 内以 3 Mbps 的速率持续发送数据来平滑流量。若水（流量）来的过猛，但水流（漏水）不够快时，其最终结果就是导致水直接溢出，呈现出来就是拒绝请求/排队等待的表现。另外当 Buckets 空时，是会出现一次性倒入达到 Bucket 容量限制的水的可能性，此时也可能会出现波峰。&lt;/p&gt;</description>
    </item>
    <item>
      <title>限流熔断是什么，怎么做，不做行不行？</title>
      <link>https://note.lican.site/posts/posts/microservice/flowcontrol-circuitbreaker/</link>
      <pubDate>Mon, 05 Oct 2020 13:24:16 +0800</pubDate>
      <guid>https://note.lican.site/posts/posts/microservice/flowcontrol-circuitbreaker/</guid>
      <description>&lt;p&gt;“在分布式应用中，最常见的问题是什么呢？”&lt;/p&gt;&#xA;&lt;p&gt;“一个分布式应用部署上去后，还要关注什么？”&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/8c42e87dd4f7f1c59431c6185f608699.png&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;“这服务的远程调用依赖似乎有点多&amp;hellip;”&lt;/p&gt;&#xA;&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;&#xA;&lt;p&gt;在 &lt;a href=&#34;https://eddycjy.com/posts/microservice/linkage/&#34;&gt;《微服务的战争：级联故障和雪崩》&lt;/a&gt;中有提到，在一个分布式应用中，最常见，最有危险性之一的点就是级联故障所造成的雪崩，而其对应的解决方案为&lt;strong&gt;根据特定的规则/规律进行流量控制和熔断降级&lt;/strong&gt;，避免请求发生堆积，保护自身应用，也防止服务提供方进一步过载。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/79a7f8870edffd331432272cf5db2c46.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;简单来讲就是，要控制访问量的流量，要防各类调用的强/弱依赖，才能保护好应用程序的底线。&lt;/p&gt;&#xA;&lt;h2 id=&#34;诉求期望&#34;&gt;诉求，期望&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;诉求：作为一个业务，肯定是希望自家的应用程序，能够全年无休，最低限度也要有个 4 个 9，一出突发性大流量，在资源贫乏的窗口期，就马上能够自动恢复。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;期望：万丈高楼平地起，我们需要对应用程序进行流量控制、熔断降级。确保在特定的规则下，系统能够进行容错，只处理自己力所能及的请求。若有更一步诉求，再自动扩缩容，提高系统资源上限。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;解决方案&#34;&gt;解决方案&lt;/h2&gt;&#xA;&lt;p&gt;要如何解决这个问题呢，可以关注到问题的核心点是 “系统没有任何的保护的情况下”，因此核心就是让系统，让你的应用程序有流量控制的保护。一般含以下几个方面：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;来自端控制：在业务/流量网关处内置流量控制、熔断降级的外部插件，起到端控制的效果。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;来自集群/节点控制：在统一框架中内建流量控制、熔断降级的处理逻辑，起到集群/节点控制的效果。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;来自 Mesh 控制：通过 ServiceMesh 来实现流量控制、熔断降级。侵入性小，能带来多种控制模式，但有利有弊。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以上的多种方式均可与内部的治理平台打通，且流量控制、熔断降级是不止面试应用程序的，就看资源埋点上如何设计、注入。常见有如下几种角度：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;资源的调用关系：例如远程调用，像是面向 HTTP、SQL、Redis、RPC 等调用均，另外针对文件句柄控制也可以。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;运行指标：例如 QPS、线程池、系统负载等。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;流量控制&#34;&gt;流量控制&lt;/h2&gt;&#xA;&lt;p&gt;在资源不变的情况下，系统所能提供的处理能力是有限的。而系统所面对的请求所到来的时间和量级往往是随机且不可控的。因此就会存在可能出现突发性流量，而在系统没有任何的保护的情况下，系统就会在数分钟内无法提供正常服务，常见过程为先是出现调用延迟，接着持续出现饱和度上升，最终假死。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/6a58406bb7c90355c82c5cb50f417f9a.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;流量控制一般常见的有两种方式，分别是：基于 QPS、基于并发隔离。&lt;/p&gt;&#xA;&lt;h3 id=&#34;基于-qps&#34;&gt;基于 QPS&lt;/h3&gt;&#xA;&lt;p&gt;最常用的流量控制场景，就是基于 QPS 来做流控，在一定的时间窗口内按照特定的规则达到所设定的阈值则进行调控：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/58f0d6fe0043963f6e40c1d73c8e019e.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;案例&#34;&gt;案例&lt;/h4&gt;&#xA;&lt;p&gt;在本文中借助 &lt;a href=&#34;https://github.com/alibaba/sentinel-golang&#34;&gt;sentinel-golang&lt;/a&gt; 来实现案例所需的诉求，代码如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import (&#xA;&#x9;...&#xA;&#x9;sentinel &amp;#34;github.com/alibaba/sentinel-golang/api&amp;#34;&#xA;&#x9;&amp;#34;github.com/alibaba/sentinel-golang/core/base&amp;#34;&#xA;&#x9;&amp;#34;github.com/alibaba/sentinel-golang/core/flow&amp;#34;&#xA;&#x9;&amp;#34;github.com/alibaba/sentinel-golang/util&amp;#34;&#xA;)&#xA;&#xA;func main() {&#xA;&#x9;_ = sentinel.InitDefault()&#xA;&#x9;_, _ = flow.LoadRules([]*flow.Rule{&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Resource:               &amp;#34;控制吃煎鱼的速度&amp;#34;,&#xA;&#x9;&#x9;&#x9;Threshold:              60,&#xA;&#x9;&#x9;&#x9;ControlBehavior:        flow.Reject,&#xA;&#x9;&#x9;},&#xA;&#x9;})&#xA;&#xA;&#x9;...&#xA;&#x9;e, b := sentinel.Entry(&amp;#34;控制吃煎鱼的速度&amp;#34;, sentinel.WithTrafficType(base.Inbound))&#xA;&#x9;if b != nil {&#xA;&#x9;    // Blocked&#xA;&#x9;} else {&#xA;&#x9;    // Passed&#xA;&#x9;    e.Exit()&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;总的来讲，上述规则结果就是 1s 内允许通过 60 个请求，超出的请求的处理策略为直接拒绝（Reject）。&lt;/p&gt;</description>
    </item>
    <item>
      <title>想要4个9？本文告诉你监控告警如何做</title>
      <link>https://note.lican.site/posts/posts/microservice/monitor-alarm/</link>
      <pubDate>Sun, 13 Sep 2020 18:42:17 +0800</pubDate>
      <guid>https://note.lican.site/posts/posts/microservice/monitor-alarm/</guid>
      <description>&lt;p&gt;“你说说，没有仪表盘的车，你敢开吗？”&lt;/p&gt;&#xA;&lt;p&gt;“没有仪表盘的车开在路上，你怎么知道现在是什么情况？”&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/6e2774d84ddcdb2d73918e06575a07b7.jpeg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;“客户说你这车又崩了，咋知道什么时候好的？​啥时候出的问题？”&lt;/p&gt;&#xA;&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;&#xA;&lt;p&gt;将思考转换到现实的软件系统中，可想而知没有监控系统的情况下，也就是没有 ”仪表盘“ 的情况下实在是太可怕了。&lt;/p&gt;&#xA;&lt;p&gt;你的故障永远都是你的客户告诉你的，而&amp;hellip;在什么时候发生的，你也无法确定，只能通过客户的反馈倒推时间节点，最后从错误日志中得到相对完整的日志信息。&lt;/p&gt;&#xA;&lt;h2 id=&#34;问题&#34;&gt;问题&lt;/h2&gt;&#xA;&lt;p&gt;更要命的是你无法掌握主动权，错误日志有可能会有人漏记录，平均修复时间（MTTR）更不用想了，需要从 0.1 开始定位，先看 APP 是哪个模块报错，再猜测是哪个服务导致，再打开链路追踪系统，或是日志平台等。&lt;/p&gt;&#xA;&lt;p&gt;稍微复杂些的，排查来来往往基本都是半小时、一小时以上，那 4 个 9 肯定是达不到的了，以此几次 P0 几小时怕不是业务绩效也凉凉，因为故障修复的速度实在是太慢了。&lt;/p&gt;&#xA;&lt;p&gt;那归根到底，想破局怎么办，核心第一步就是要把监控告警的整个生态圈给建设好。&lt;/p&gt;&#xA;&lt;h2 id=&#34;监控定义&#34;&gt;监控定义&lt;/h2&gt;&#xA;&lt;p&gt;常说监控监控，监控的定义就是监测和控制，检测某些事物的变化，以便于进行控制。在常见的软件系统中，大多分为三大观察类别：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/b567a71921b7e54d703d9e47f491d6c0.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;业务逻辑：项目所对应的服务其承担的业务逻辑，通常需要对其进行度量。例如：每秒的下单数等。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;应用程序：应用程序。例如：统一的基础框架。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;硬件资源：服务器资源情况等。例如：Kubernetes 中的 Cadvisor 组件便会提供大量的资源指标。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;从软件系统来讲，监控的定义就是收集、处理、汇总，显示关于某个系统的实时量化数据，例如：请求的数量和类型，错误的数量和类型，以及各类调用/处理的耗时，应用服务的存活时间等。&lt;/p&gt;&#xA;&lt;h2 id=&#34;监控目标&#34;&gt;监控目标&lt;/h2&gt;&#xA;&lt;p&gt;知道了监控的定义，了解了监控的作用和具体的实施指标后。我们需要明确的知道，做监控的目标是什么：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/bab6275c4b7c73deec2d9f9919f967c7.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;从现实层面出发，做监控的初衷，就是希望能够及时的发现线上环境的各种各样奇奇怪怪的问题，为业务的正常运转保驾护航。因此整体分为上图四项：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;预测故障：故障还没出现，但存在异常。监控系统根据流量模型、数据分析、度量趋势来推算应用程序的异常趋势，推算可能出现故障的问题点。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;发现故障：故障已经出现，客户还没反馈到一线人员。监控系统根据真实的度量趋势来计算既有的告警规则，发现已经出现故障的问题点。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;定位故障：故障已经出现，需要监控系统协助快速定位问题，也就是根因定位（root cause）。此时是需要协调公司内生态圈的多个组件的，例如：链路追踪系统、日志平台、监控系统、治理平台（限流熔断等），根据监控系统所告警出来的问题作为起始锚点，对其进行有特定方向的分析，再形成 ”线索“ 报告，就可以大力的协助开发人员快速的定位问题，发现故障点。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;故障恢复：故障已经出现，但自动恢复了，又或是通过自动化自愈了。这种情况大多出现在告警规则的阈值配置的不够妥当，又或是第三方依赖恰好恢复了的场景。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;而更值得探讨的的是监控告警的后半段闭环，故障自愈，通过上述三点 “预测故障、发现故障、定位故障”，已经定位到故障了，就可以配合内部组件，实现自动化的 ”自愈“，减少人工介入，提高 MTTR。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://image.eddycjy.com/437e9d859ee86916f5d2d0bc409ab9f5.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;因此做监控系统的目标很明确，就是发现问题，解决问题，最好自愈，达到愉快休假，业务安心的目的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;4-个黄金指标&#34;&gt;4 个黄金指标&lt;/h2&gt;&#xA;&lt;p&gt;有定义，有目标，那指导呢。实际上 “业务逻辑、应用程序、硬件资源” 已经成为了一个监控系统所要监控构建的首要目标，绝大部分的监控场景都可以归类进来。且针对这三大项，《Google SRE 运维解密》 也总结出了 4 个黄金指标，在业界广为流传和借鉴：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;延迟：服务处理某个请求所需要的时间。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;区分成功和失败请求很重要，例如：某个由于数据库连接丢失或者其他后端问题造成的 HTTP 500 错误可能延迟很低。因此在计算整体延迟时，如果将 500 回复的延迟也计算在内，可能会产生误导性的结果。&lt;/li&gt;&#xA;&lt;li&gt;“慢” 错误要比 “快” 错误更糟糕。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;流量：使用系统中的某个高层次的指标针对系统负载需求所进行的度量。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
