zoukankan      html  css  js  c++  java
  • 稳定性 问题定位[基于此监控系统] 系统优化[内部调用异常数据流量,基于此系统上的压测瓶颈发现]

    自己的另外一篇:稳定性 耗时 gc 过长问题排查 和工具 http://www.cnblogs.com/fei33423/p/7800395.html

    老的思考:稳定性 监控 业务后期 - 架构师 https://www.cnblogs.com/fei33423/p/7169590.html

    总结:

         新的指标概念: 1. cpu 节区间 2. 耗时*请求量 3. 耗时 diff*请求量/平均耗时*总>1/5 provider 请求量 4.对方 provider (rpc 或者是)耗时统计 5.provider 线程池满拒绝异常 5. consumer- provider 耗时- ping 耗时(这样雪崩时,本系统不会报错) 6. 类似 traceId,有个全局的traceMethod. 这样就能知道是谁调用过来的.

           层级概念:

         去除报警指标: 1. provider 耗时,errno异常 2. consumer errno [下游系统provider_errno=consumer_errno] 3.consumer 耗时异常 4.割裂 traceId 的统计是无效的. 丢弃小米监控系统. 还要根据分位, 正态分布叠加还确立定位合适的traceId.

       

         动静,统计和 case 结合.

         指标: 耗时,请求量,错误量

         静: 绝对值.

         动: 环比,同比

         报警因果推断. 1. 只要有 trace 分段了. 耗时因果推断就简单了. 2.请求量 只要有了 traceMethod 就知道diff来源了. 3.  有个 traceError 就知道 appName_errCode

    背景介绍:

          一次雪崩时: 查问题毫无头绪,到处都是抛错. 查来查去可能都是某个系统的问题. 那个系统呢,抽样查很多 flag ,很多都是调用外部的问题.

          原因: 下游系统从1ms 变成2ms, 就引发雪崩了. 说明该接口调用占比占整个入口占比的60%了.  调用该接口又用了一个无限队列线程池,快饱和了, 2倍后饱和,排队, 最终导致 dubbo provider 的线程池满. 导致其他接口无法调用该核心系统.

         后期防范: 系统占比较高的耗时节区间,需要特别注意. 排名: 耗时段的耗时 diff*次数/总 provider 耗时. [耗时节区间段概念见下文]

     问题梳理+案例说明:

        核心问题(梳理完知识体系后想到的): 带有 flag 的监控数据缺失.现有监控数据擦除了大量信息.

     新方案知识体系:

    节区间:

          zipkin 监控中的节区间.

          复合节区间: 是指包含多个原子节区间的节点. 例如dubbo provider . 注意复合节区间的监控统计是宏观上考察用的,对问题分析排查无太大的意义.还有就是 consumer 的耗时. 这个耗时首先要关注provider 提供方的耗时,对方也是高的,那就是对方的责任.如果对方低,我方高,那么就应该好好研究研究了.

        对于 consumer 还有外部 io 节点: 1. 耗时增加异常 2. 耗时不增加但是非 success 调用.(fast-failure)

     节区间上承载的的信息种类(zipkin只有耗时信息):

    1.  耗时

    2. 接口调用量.

    3. error code .

    其他为用于分析原因的异常:

         1. 数量. cpu 占比 . 磁盘 io 数量. 网络 io 数量. 当时 swap 次数.

    异常比较方式:

      1. 同比

                耗时多用同比,

          2. 环比

                数量多用环比.

    3. 绝对值

      调用量远超过业务量,耗时也是远超正常值. cpu : 10ms consumer: 5000ms

    统计层级:

    1. 接口层级

          模块交互时的相关问题

    两个 rpc 调用之间包含中间件代码,网络io.

      常规日志手段无法检测的

      1.1 隐匿在接口层,但是你获取不到时间的.例如: dubbo单连接复用 dubbo 连接池分发耗时. 可以通过代码注入改造. 现有的 java 性能耗时分析工具已经很多.

      接口监控可能需要改造的点,获得更多的节区间数据:

      1.  中间件间切面flag 日志
      2.  系统级切面 flag
      3.  中间件和系统级日志查看. 如果未收到监控系统中,就需要专家主动查看. 监控 list check表单.
      4.  gc日志监控

    2. 比接口层级还低的层级. 只能通过非业务系统来调用监控了.

        比如通过ping,得到网络耗时情况. route .

        低层级的影响的是全局. 如果有这些数据,就可以反证全局影响不是这些因素照成的.有些"节区间"包含了 网络传输 和 中间件等无法监控统计的点.

           2.1 基于 byte 的 传输. 通过纯净无影响的ping来确定网络耗时. jvm 内,jvm 外. 2种. jvm 外的统计都有运维自己搞定.

           2.2 基于 byte 的 cpu 执行. 通过一段每隔10毫秒执行一次的纯净. jvm 内,jvm 外. 2种.

           2.2 基于 byte 的文件 io. 通过一段定时写入磁盘的 logger + file 操作.来统计纯洁的 io耗时表现. jvm 内,jvm 外. 4种.

           2.3 基于 byte的netty 的粘包,拆包.

    监控展现:

       报警展现(有最小流量限制,统计样本有限不报警):

                 两种展现类型 1.耗时异常展现 2.数量异常展现:

    展现方式

    拓扑图展现法:

    整体拓扑图节区间( 可以用TWaver实现 )展现. 有节区间报警就显示在某个应用上,点击进去进入下一层级拓扑图. 如果是 consumser 的调用发起节区间. 那么就展现对应的机器连 接拓扑图.

              任何zipkin节区间都能属于最终整体拓扑图的点或者线.

    列表展现法: 从大到小. 可以层层点入( 如果拓扑图有难度的话 ):

           接口级的展现: 如果节区间报警,把对应的 provider 的整体节区间展现出来. [对应拓扑图方式的是你得知道这个报警是属于哪个拓扑节点的]

               从面到点展现报警图. 点击某个最细粒度监控节后,

      1. 纵向对比,和自己比, 展现与之相关的各种统计数据,同比,环比量.

      2. 横向对比 和别人比, 同level 的其他节区间情况. 即同一个节点的其他 cpu 区间. [可能有些流量变化不大,但已经到了边界点, 要看具体代码来理解思考. 是否有阻塞,排队等.]

     note: 拓扑报警切记对复合节区间报警. 这是目前现有报警系统的大坑.

    如何打印 zipkin 日志:

      1. 如果接口种不同的参数导致的耗时差别很大. 那么就需要根据不同的 type 来打印不同的日志,区分 consumer 接口.

      2.

     

    Q&A

    1. 如果遇到某个接口本身不同的分支导致耗时差别很大怎么办?

       1.1 可以通过接口参数区分出来

       1.2 无法通过接口参数区分. 不同的 userId 有不同的参数. 这种就没办法了. 不过问题也不是很大,只要数据量够大,平均值就比较稳定. 一旦异常,也会影响相关问题.

    2.如何确定两个节区间是相同的节区间?

        例如 a b c c d 和 a c d . 这种需要技术处理内在子序列的概念.  其中 cd 就是重叠的. 或者大序列严格相等,子节区间从认为是相同的子节区间.这个不太好. 特别是在 service 层也打上 zipkin 标记的时候.

    监控衍生产品:

      1. 通过现有数据库

      2. 通过状态变更时的日志

            

     (日志,采集,展示)监控,参照系异常抽取,关联清洗,优化,报警,报警关联清洗,定位五部曲. [目前监控系统,在日志,关联清洗上是缺失的]

     从表到里的分析过程.

    何为异常:

         前提: 大流量下,稳定性才显得重要.否则不用关心. 这种业务平台也要有机会遇到.

         作用: 现有数据收集,展示,再有智能数据处理,最终告警,形成告警时间轴,并分析同时间内[分钟级]的告警点在整体监控点下的关系,排除非因告警点.

            1. 业务异常.  - 简单.

            2. 稳定性因素导致的异常.特别是雪崩时,很难排查.

    2.1  耗时对比增加. 同比增加, 环比增加, 同期平均值增加,小流量平台对比.  [ ]

    2.2  耗时超时变成 error

         按严重程度:

    1. 大量error异常 [这个是老的监控平台优点,通过error查看flag,太迟了]

    2. 无error异常 [ 接口耗时增加,io总量增加提前暴露性能问题,新监控平台小米优点. 通过报警时间轴去定位问题,最好报警阈值时时可调 ] 有时候只有几台机器异常. 

                  这种极有可能 1. 某些 io 调用耗时增加(未监控) 2. 线程池满等待 3. dubbo tcp 复用等待 4.swap 耗时等待 5.gc 耗时 6. 线程加锁等待

          参照系: 大流量自身同期, 大流量自身环期. 正常的小流量平台下自身同期,自身环期. 两个比例. 1.平均放大比 放大比异常的.                   

        2.1 同比环比对比

    同平台: 同比,环比;

                 大小平台: 先取个平均放大值,然后放大值异常的报警]

               如果本身就抖动,那就先把抖动问题解决掉,  0.有些内部没有问题,来源于外部不同输入,数据库响应抖动,偶发性的请求冷数据. 1. 根据业务场景的业务配置 例如gc 2. 例如更换引擎 , 随机读太多,改用ssd 硬件架构. 3. 有些是外部系统导致的, 那就没办法了. 比如外部支付网络 只能取值40-60%这部分统计值作为平均考量. 或者换用供应商,多渠道控制. 也可以辅助外部人员本质上也要查,要看对应提供方的代码和日志,点问题,面问题, 可能需要服务提供方提供对应的数据,对应的 flag 的接收和返回的时间点.  并且要保证机器时钟的准确性.

    所以好的设计是不依赖外部方,让外部放依赖我们. 限制调用量. 通知总是需要的,限制timeOut 时间.

                即使同一个接口,也要比对参数是否相同. 不同的人属性不同,走的逻辑和外部 io 路径不同. 可以对有限值的参数和耗时进行聚类,聚类完之后进行监控,然后进行监控.这就没法监控了. 这个 type 值最好是结构化的,有业务来确定,通过注解等方式,而不是从文本来解析出来.这种解析太多了.

    3. 压测异常. 压测突破边界点, 耗时边界点,导致增加的请求流量,全部变成了 error 异常, 故流量增加,但是正常返回反而下降.

         那么zipkin整个时间轴上的统计纬度有多少.

            说耗时: A -->  B 接口名.  from纬度比较 其他参数相同, to纬度比较, time纬度比较(同比,环比) 大流量和小流量比较.

         不同的接口名比较没意义,不同的 内存执行区间比较也没意义(而且重构了,有可能变化很大. 只能同一时间点比较,前后比较)

         同期比异常:  流量异常, 耗时异常,请求数量异常

                  原因: gc导致偶发[和swap一起时耗时更长, 大内存耗时也长], 营销活动导致偶发.

                          边界: 1. 内部线程池边界[订单因为下游耗时增加,导致线程池耗尽,新的请求排队 fastError ],  2.有效耗时边界[ timeOut , 直接fastError], 3. io边界[dubbo 连接共用,导致定时任务时,突然导致连接满额, 导致无法可用] 4. mysql线程池耗满 [ 有慢查,就挂了. ]

         环比异常: 定时任务,gc,定点营销,催款短信

    方法论: 

         监控+及早报警:

      • 通过zipkin耗时优化问题. 及早发现及早优化.
      • 通过调用数量优化问题
      • 通过压测发现问题.
        • 压测能突破边际,本来只是耗时增加的,后来演变成 exception 抛出
        • bean 数量也能极大放大,便于定位

        最细粒度报警. fromIp 接口 toIp. 内存执行报警. 对gc监控有用. 外部都不变,但是内部变化了. 有时候监控报警不全,需要自己在去排查.

        1. 大面积报警

              报警顺序排放.

        2. 少部分报警

    场景 :

          1.  观察线上耗时统计, 发现间歇性耗时抖动? [之前写的例子,犯了 复合节区间的大忌. ]

          2.  更甚至直接导致oom

          雪崩分析时要看异常报警时间轴, 和平时抖动性分析 需要看 异常报警时间轴,异常同比/环比抖动超过20%的图.

        压测,稳定性建设分析看整个链路耗时情况. 特别是异常抖动点的耗时情况,流量情况,io 情况.

    分析:

       * 报警信息

             报警计算方式:

                    同比(雪崩等),环比(抖动,毛刺,斜率超过多少就算毛刺. 何为毛刺?,稳定性排查  )

       报警计算阈值动态配置:

                    这些信息可以时时调整报警额度值,动态计算一遍,然后展现) 按同粒度+上下游的时间轴展现

          * 报警信息分类:

        * 耗时抖动报警

                * 流量抖动报警

                 * io 超量报警

                 * 异常码 error 报警

         * 点

        接口维度: 流量大小,耗时,次数. 且要有流量入口 type,这个最好有前缀是app_入口_app 名_接口名[].

             zipkin 时间轴,能够很快的识别出 网络耗时, 内部执行耗时,外部 io 耗时 这些都是关键的 耗时 key.  [所以一定要把 mysql, dubbo, 文件操作都监控起来. 不然有些耗时 key 可能是混合了 内存执行+外部io执行]

             内部的内存耗时如何统计?

            通过 zipkin 的sr (server 接受) 和 cs(客户端发送)的时间差来定义.  cs-cr (两个流量中间)这个需要有框架来完成. 特别是内部出现多线程的情况.

       一个大系统由 N 个小业务系统组成, 虽然大系统找原因,拆解到各个小业务系统上. 雪崩时定位出各个系统的初始异常原因. 然后切换到下游系统或者面原因定位. ( 所以不如整体定位, 不对粗粒度的分析.)

           优点:  以往只有系统级的监控(), 有了接口级的以后就好定位很多. 但是内存操作怎么定位?

         * 面

              外部网络, 内部gc ,磁盘问题,网络

         * 另外一种是达到耗时边界, 耗时可能只增加了20ms,但是已经超过1s 中. 导致 error 报警.这种需要平时稳定性治理,耗时从高到低排查问题.耗时到底在哪里?

         * 时间点刚好是定时任务执行点

         排查代码,看是否有优化空间

         * 规律性不明显

                 查看是否 gc 导致? gc 耗时过长原因是 swap http://lovesoo.org/linux-sar-command-detailed.html sar -W  https://blog.csdn.net/rlhua/article/details/24669037

    相关工具和命令:

        可视化 gc 和耗时时间轴.

    效果 :

    1. jmap -histo 46454 | head -n 20

    要判断系统瓶颈问题,有时需几个 sar 命令选项结合起来

    怀疑CPU存在瓶颈,可用 sar -u 和 sar -q 等来查看

    怀疑内存存在瓶颈,可用 sar -B、sar -r 和 sar -W 等来查看

    怀疑I/O存在瓶颈,可用 sar -b、sar -u 和 sar -d 等来查看

  • 相关阅读:
    2016012061 小学四则运算练习软件项目报告
    阅读《构建之法》的几点思考
    软件工程之我见
    作业五
    结对作业
    第4.17章读书笔记
    week_2 四则运算
    第1.2.16章读书笔记
    我与软件工程
    团队项目Alpha冲刺阶段之学习总结
  • 原文地址:https://www.cnblogs.com/fei33423/p/7805186.html
Copyright © 2011-2022 走看看