从零开始搭建前端监控系统三实现控制iframe前进后退

前言本系列文章旨在讲解如何从零开始搭建前端监控系统。 项目已经开源 项目地址: https://github.com/bombayjs/b... (web sdk)https://github.com/bombayjs/b... (服务端,用于提供api)(未完)https://github.com/bombayjs/b... (后台管理系统,可视化数据等)(未完)您的支持是我们不断前进的动力。 喜欢请start!!! 喜欢请start!!! 喜欢请start!!! 本文是该系列第三篇,重点讲解如何控制iframe的前进后退。 系列文章: 从零开始搭建前端监控系统(一)——web探针sdk从零开始搭建前端监控系统(二)——实现圈选(无埋点)k示例https://abc-club.github.io/de... 演示 源码https://github.com/abc-club/demo 如果想看跟复杂的例子,可以看bombayjs的源码 后台截图如下: 难点document.getElementById('iframe id').contentWindow.history.back();以上面这种方式控制会存在跨域问题!!! 原理解决iframe的跨域问题,我们需要通过postMessage实现iframe的通信通过window.history.back()和window.history.forward()控制前进后退实现index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <iframe id='iframe'></iframe> <br/> url: <span id='url'></span> <br/> <button id='back' onclick='back()'>back</button> <button id='forward' onclick='forward()'>forward</button></div> <script> var url = './iframe.html' var div = document.getElementById('url'), iframe = document.getElementById('iframe') iframe.src = url div.innerHTML = url window.addEventListener('message', function(event) { if (!event.data.url) return div.innerHTML = event.data.url; }, false) function back() { iframe.contentWindow.postMessage('back', '*'); } function forward() { iframe.contentWindow.postMessage('forward', '*'); } </script></body></html>iframe.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <a href='#a'>to #a</a> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p id='a'>a</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p></div> <script> window.addEventListener('message', function(event) { if (event.data === 'back') { window.history.back() } else { window.history.forward() } }, false) window.addEventListener('hashchange', function(event) { window.parent.postMessage({ url: location.href }, '*') return }, false) </script></body></html>更多资源https://github.com/abc-club/f... ...

October 8, 2019 · 1 min · jiezi

从零开始搭建前端监控系统二实现圈选无埋点

前言本系列文章旨在讲解如何从零开始搭建前端监控系统。 项目已经开源 项目地址: https://github.com/bombayjs/b... (web sdk)https://github.com/bombayjs/b... (服务端,用于提供api)(未完)https://github.com/bombayjs/b... (后台管理系统,可视化数据等)(未完)您的支持是我们不断前进的动力。 喜欢请start!!! 喜欢请start!!! 喜欢请start!!! 本文是该系列第二篇,重点讲解如何实现圈选功能。 如果你还不了解怎么捕获click事件,请先看第一篇 系列文章: 从零开始搭建前端监控系统(一)——web探针sdk示例https://bombayjs.github.io/bo... 演示 源码https://github.com/bombayjs/b... 原理通过postMessage实现iframe的通信通过监听mouseover事件来圈选通过监听click事件获取点击目标的路径通过stopPropagation阻止原来的点击事件实现parent<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <iframe id='iframe' src='./a.html'></iframe></div> <script> window.addEventListener('message', function(event) { console.log(event.data.path) }, false) </script></body></html>iframe// a.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <a href='#a'>click me</a></div> <script> window.addEventListener('message', function(event) { console.log(event.data.path) }, false) window.addEventListener('click', function(event) { event.stopPropagation() window.parent.postMessage({ path: '此处需要自己解析出元素路径' }, '*') return }, false) window.addEventListener('mouseover', function(event) { event.target.style = 'border: #ff0000 solid 1px' }, false) </script></body></html>更多资源https://github.com/abc-club/f... ...

September 30, 2019 · 1 min · jiezi

10-人2-个月-虾mi音乐的监控体系升级之路

背景监控一直是服务端掌握应用运行状态的重要手段,经过近几年的发展,阿里虾米服务端目前已经有 100 多个 Java 应用,承担核心业务的应用也有将近 50 个,对于应用的监控配置也是因人而异。有的人配置的监控比较细,有的应用在经历了多人开发阶段以后,监控就逐渐疏于管理,有些应用的监控项最后修改时间只停留到 2 年以前,早已不适应业务的发展。 与大部分团队一样,虾米也有一个报警处理群,将内部的监控报警平台(如 Sunfire 等)的信息通过机器人投递到群中,由于监控项配置不合理、监控粒度较大,每天报警群都被几十条甚至上百条报警通知狂轰乱炸,长此以往大家对报警已经麻木,大部分报警也不会去处理。 基于这样的现状,虾米 SRE 团队(SRE全称Site Reliability Engineering,最早由Google提出。致力于打造高可用、高拓展的站点稳定性工程)将工作重点放在了对监控的治理上面,经过 2 个月的研发,构建了虾米全新的监控体系。 报警原因分析过去的监控配置可谓五花八门,由应用负责同学配置的一些监控大多局限在应用整体 RT、QPS 的监控和部分业务日志的监控,报警发生时,大部分情况只知道这个应用有了问题,但很难快速定位是哪里出了问题,出了什么问题。一个新接手的同学可能需要经过查看配置项、登录机器、扫描日志甚至去查离线日志等步骤,经过十几分钟才能定位到问题,有的时候甚至需要排查个大半天时间。 经过一段时间的研究和摸索,我们发现一个应用如果在稳定运行了一段时间以后突然发生报警,那么原因通常都是以下几类: 程序 Bug:如代码问题导致空指针、频繁 FullGC 等。上游依赖出问题:上游某个接口出了问题导致本应用出现接口超时、调用失败等。单机故障:某个容器受宿主机应用导致 Load、CPU 突然升高,最终导致超时、线程池满等情况发生。中间件故障:常见的如 Cache、DB抖 动导致一段时间内 RT 增长、超时增多。不过这里需要注意的是,单机 Load 高同样会引发单机读写 Cache、DB 出现问题。监控优化分析了报警原因,下一步就是优化监控。监控的报警可以告诉你出了问题,而好的监控是可以告诉你哪里出了问题。我们以前的监控通常只完成了第一阶段,而不能很好的告诉我们哪里出了问题,要通过一大堆辅助手段去定位。在分析了报警原因以后,我们就要想办法通过监控的手段来精准定位问题。 目前虾米的监控分为故障监控、基础监控和通用监控三类,如下图所示: 故障监控所谓故障监控,就是这些监控发生报警意味着有故障产生了。我们认为一切外在因素如果对应用产生影响,那么必然反应在接口的 RT 和成功率上,要么引起接口 RT 升高,要么导致接口失败数增加,成功率下跌,如果没有这种影响,那么这个外在影响可以被忽略掉。因此我们把接口监控作为故障监控的一大块来重点配置,如果每个应用都配置了核心接口的故障监控,在排查问题时,就很容易定位是否由于上游应用的某个接口导致了我的应用出了问题。 因此我们使用成功率、RT 和错误码三个指标来进行一个接口的故障监控。特别指出的是,对于客户端接口的 RT 监控上,我们没有使用平均 RT,而是使用 Top 75% RT。因为想用它来反应用户侧的感受,比如 RT的 75% 分位线报警阈值设置为 1000ms,那么当这一监控项发生报警时,意味着有 25% 的用户请求接口已经超过 1000ms。通常这一报警阈值设置成用户不能忍受的一个 RT,比如 500ms 或 1000ms。 在故障监控里,我们还设置了应用维度的异常、错误和消息异常三种类型的监控,他们对服务器上的Exception和Error进行监控。这一类监控主要用于快速发现程序bug。例如当一次发布进行时,如果这三种类型的错误增加,那么应该可以考虑进行回滚了。 通用监控大多数情况下,应用出现的问题都是由于单机故障引起的时候,如果某台机器的接口黄金指标突然变化、错误或异常数量突然增多,而其他机器没有什么变化,那就说明是单机引起的。因此我们对应用的故障监控都配置了对应的单机监控,在此处我们还额外引入了 HSF(Dubbo) 线程池满和 HSF(Dubbo) 超时两个类型的单机监控,是因为当单机 Load 高、CPU 有问题时,最为常见的表现就是HSF线程池突然打满,HSF(Dubbo) 超时数量增多,这两个监控同样可以来辅助定位单机问题。通过这一类监控,我们可以方便地接口报警是否由某台机器引起。 ...

August 27, 2019 · 1 min · jiezi

阿里巴巴在应用性能测试场景设计和实现上的实践

本文是《Performance Test Together》(简称PTT)系列专题分享的第5期,该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能压测的理论体系,并提供有例可依的实战。 该系列专题分享由阿里巴巴 PTS 团队出品,欢迎在文末处加入性能压测交流群,参与该系列的线上分享。 第1期:《压测环境的设计和搭建》 第2期:《性能压测工具选型对比》 第3期:《阿里巴巴在开源压测工具 JMeter 上的实践和优化》 第4期:《并发模式与 RPS 模式之争,性能压测领域的星球大战》 本文将介绍应用性能测试场景的设计和实现,旨在借助阿里巴巴在这方面的沉淀帮助您更准确的找到性能瓶颈,文章将围绕以下: 性能测试的常见分类应用性能测试场景的设计应用性能测试场景的设计实践应用性能测试场景的实现性能测试的常见分类负载测试:一种验证性测试,它的目的是验证预设负载条件下的性能表现是否达到性能目标(可用性、并发数/RPS、响应时间等),在达到性能目标之后不会继续增加负载。 稳定性测试:负载测试的一个子集,侧重于发现、验证只有经过长时间的运行才会暴露的问题。比如内存泄漏、FGC 等。 压力测试:一种破坏性测试,尝试探测应用或者基础设施的极限能力。因此压力测试过程中会一直增加负载直到部分性能指标不再符合性能预期。压力测试能发现仅在高负载条件下出现的同步问题、竞争条件、内存泄漏等。通过压力测试我们还可以确定应用服务在什么条件下会变得不可用,不可用的现象,以及可以通过哪些监控指标来监控即将发生的不可用,压测结果通常可以为限流等管控系统提供数据支撑。 容量测试:往往与容量规划一起进行,是在保证用户体验不受影响(稳定性)的前提下,使有限的资源的利用率最大化(成本)。也可以用它来预估未来用户量增长到某个量级的情况下,需要多少资源(例如处理器、内存、磁盘、网络带宽)来支持。 应用性能测试场景的设计在了解了相关背景之后,我们开始进入正题。性能场景的设计主要包括:业务场景建模、测试数据准备、监控指标确认三个关键步骤。下面我们用实战的方式说明每个步骤的常见做法。 业务场景建模确定压测场景范围:人类是不可预测的,在性能测试中模拟每个用户可能的操作场景基本上是不可能实现的。一般情况下我们必须要关注的性能场景包括但不限于: 高频使用的场景关键的业务场景最耗性能的场景曾经出现过问题的场景……在测试具有大量新功能的业务时,往往需要与业务方一起确认预期内有哪些功能点可能会被高频使用,需要与研发人员确认哪些功能虽然使用频率不高,但是存在性能隐患、容易引起雪崩效应;在测试已经上线的功能时,还可以通过业务监控、系统日志来分析现有用户的行为模式,得到更加逼近真实用户行为的业务场景。 业务场景的操作路径:业务场景的操作路径可以借助一些可视化的工具来描述,这部分工作相对比较简单,不再详细深入。我们详细说明一下比较常见的延时策略。 思考时间:思考时间模拟的是用户在等待响应、阅读页面内容、表单填写等延迟操作的场景。每个人的阅读速度、输入速度都存在非常大的差异,决定了每个人的思考时间也是不一样的,在性能测试配置中有常见的四种延时模型覆盖了绝大部分的延时场景: 固定时间:顾名思义,设置一个固定的思考时间。均匀分布:均匀分布在范围的上限和下限之间的随机数。正态分布:根据中心极限定理,如果一个事物受到多种因素的影响,不管每个因素本身是什么分布,它们加总后,结果的平均值就是正态分布。负指数分布:该模型将延迟时间的频率强烈地偏向该范围的一端。双驼峰正态分布:双峰驼正态分布可以模拟第一次访问时把页面说明整个仔细的阅读一遍,但下次访问时直接扫过页面,点击页面深处的操作链接。我们通常可以通过以下方式对思考时间进行建模: 如果是已上线系统,可以从线上日志统计分析出来平均值以及标准方差没有线上日志,可以从内部人员的使用模式中收集响应的数据可以计算自己和同事访问的时候,在不同页面停留的时间如果没有更好的来源,也可以从第三方统计数据获取延时数据集合点集合点模拟的是大量的用户在同一时刻一起做同样的操作(加购、付款等),集合的方式通常包括按时间集合和按量集合。一般只有具备秒杀特性的业务才会使用到。虽然直接在压测工具中设置巨大的起步量级看似也能模拟秒杀的行为,但是压测工具一般都存在一个不太稳定的预热的过程,因此不推荐超高的起步量级模拟秒杀。 确定场景的施压参数施压模式:常见的施压模式有以下两种, 并发模式与 RPS 模式没有优劣,各自有各自适用的场景。 1、并发模式(虚拟用户模式)并发是指虚拟并发用户数,从业务角度,也可以理解为同时在线的用户数。如果需要从客户端的角度出发,摸底业务系统各节点能同时承载的在线用户数,可以使用该模式设置目标并发。 2、RPS 模式(吞吐量模式)RPS(Requests Per Second)是指每秒请求数。RPS 模式即“吞吐量模式”,通过设置每秒发出的请求数,从服务端的角度出发,直接衡量系统的吞吐能力,免去并发到 RPS 的繁琐转化,一步到位。 目标量级:目标量级往往来自于对项目计划、目标,业务方要求,或者是技术文档的量化。 场景的负载占比:已上线应用,尽量使用线上的日志、埋点数据结合业务运营的预期目标确保分配比例尽可能的符合实际情况;新上线的应用一般依靠事前预期分配虚拟用户,在测试的执行过程中可以逐步的调整。 测试数据准备高质量的测试数据应当能真实的反映用户的使用场景。我们一般会选择以线上真实数据作为数据源,经过采样、过滤、脱敏,作为性能测试的测试数据。低质量的测试数据也许能够测试出一些问题,但是更大的可能性是无效的测试结果。压测数据至少包括基础数据和运行时数据两种。基础数据,主要是应用系统存储的元数据,比如用户信息、产品信息、商品信息等;基础数据的数据量、数据分布应当与线上运行的数据量相当,否则容易引起无效测试。运行时数据,主要是虚拟用户操作过程中需要使用的表单数据,比如虚拟用户的用户名、密码、搜索关键词等;运行数据的逼真度也是至关重要的。 确认监控指标在性能测试执行过程中,往往需要实时观察各项指标是否正常,包括客户端指标、应用服务器、数据库、中间件、网络入口等各方面的指标。更重要的是,监控的过程是发现系统瓶颈的过程,监控数据是性能基线管理、容量规划甚至是高可用架构的重要基础。我们通常需要关注的监控指标包括: 业务接口指标,响应时间、RPS、成功率等;网络指标,数据吞吐量、数据错误率等;服务器指标,连接数、CPU、内存、I/O、磁盘等;……最理想的状态是,这些监控指标能够与性能测试工具集成,在一个操作界面上展示各个维度的监控数据,并能够基于策略来智能化、自动化识别指标异常。这对快速、准确的定位压测过程中可能出现的各种问题是至关重要的。 应用性能测试场景设计的实践JPetStore 是一个开源的简单的Java语言开发的在线宠物商店,可以从 GitHub 获取到源码。为了方便演示,我们用阿里云 EDAS 部署了一套 JPetStore 宠物购物网站。 业务场景建模在这次的实战演示中,我们通过实际操作体验的方式来获取所有的业务场景、操作路径、思考时间。我们先用文字的方式来描述场景和操作路径。 用户登录,访问首页->进登录页->登录操作购买流程1,访问首页->选择产品大类->进入产品列表->进入型号列表->查看型号详情->加购物车->思考(3s-5s)->提交订单->确认订单购买流程2,访问首页->搜索产品->进入产品列表->进入型号列表->查看型号详情>加购物车->思考(3s-5s)->提交订单->确认订单购买流程3,访问首页->搜索商品->进入产品列表->进入型号列表->加购物车->思考(3s-5s)->提交订单->确认订单我们的目的是做压力测试。我们选择 RPS 模式,梯度递增,漏斗模型; 与并发模式相比,RPS 模式可以实现更加精准的流量控制;常见的限流设施都是基于TPS设置阈值的;因此我们首选 RPS 模式。我们使用手动递增的方式,逐步的逼近系统极限。在真实的业务中,用户会由于各种原因(网络、库存、不喜欢、付款失败等)而放弃购买,在此我们构造一个漏斗模型,我们假定100个人查看详情之后有30个人加入了购物车,15个人提交订单,最终10个人确认订单,购买成功;在真实的场景中我们可以从线上用户行为中采集到这些信息。假定用户登录容量足够,不是这次压力测试的重点业务。我们基于线上日志和产品运营分析得出以下结论: 使用购买流程1的用户占比10%使用购买流程2的用户占比60%使用购买流程3的用户占比为30%最终,我们得到的业务模型如下图所示: 测试数据准备因为该应用专为测试而生,不用考虑数据污染,我们免去采样、过滤、脱敏步骤,直接使用线上的基础数据作为压测的基础数据。基础数据的结构如下图所示,当然真实系统的基础数据,比这个复杂的多: 常见的压测工具都支持 CSV 格式(可以简单理解为逗号分隔值,但是实际上更加复杂)的数据源。我们构造的用户登录的运行时数据格式如下图所示: ...

August 20, 2019 · 1 min · jiezi

云原生化的迁云实战

云原生的时代已经到来,云原生技术正在重塑整个软件生命周期,阿里巴巴是国内最早布局云原生技术的公司之一。 容器服务团队在过去的几年时间内帮助很多用户成功把业务云原生化并迁移上云,其中有现在已经是我们TOP10的大客户,也有需要在国内开展业务的海外用户,有些是从其他云厂商迁移过来的用户,有些是从IDC里迁移上云的用户,而且越来越多的用户开始咨询如何对自己的应用做云原生化改造、如何把业务平滑地迁移到云上。每个用户的业务场景都是不同的,有些差异化的业务场景对容器平台也有一些定制化的需求,我们在帮助这些用户落实迁云方案的同时也在不断思考如何把这些案例中共性的东西做一些沉淀,总结出一些优秀的解决方案、最佳实践以及开发一些工具来帮助用户快速完成迁云的这件事情。这些解决方案、最佳实践以及迁云工具就是今天这篇文章想要分享的内容。 在帮助用户落实迁云方案之前,我们首先必须要回答至少3个问题:(1)ACK(阿里云容器服务Kubernetes)如何能保证用户业务的可靠性、稳定性、安全性和灵活性;(2)如何设计迁云方案把业务平滑地迁移到ACK;(3)应用如何做进一步改造来适配ACK提供的更强大的扩展能力。 1. ACK如何保证用户业务的可靠性、稳定性、安全性和灵活扩展性 首先,ACK是以阿里云可靠稳定的IaaS平台为底座的,有最大的弹性化与低廉成本和全球化接入的优势;其次,ACK本身处于阿里云的安全体系架构之下并从基础设施到容器运行时环境对容器集群有全维度的安全加固;过去几年我们很好地支撑了成百上千家大小企业的业务运行,有海量用户经验总结并经过双11验证;除此之外。ACK是在标准的Kubernetes基础上,对与用户息息相关的能力做了大幅提升,用户完全不需要担心会被某一家厂商绑定。 在我们过去帮助用户业务上云的案例中,绝大部分是自建Kubernetes集群迁移到ACK集群,与自建Kubernetes集群相比较,ACK在成本、弹性、IaaS高度融合、性能、安全加固以及实践经验等方面都有非常巨大的优势。 另外,ACK与阿里云的所有region保持一致,除了国内多个区域开服外,在东南亚、中东、欧洲、美东美西都有开服,完全可以满足用户开展全球业务的需求。 2. 整体迁云方案设计用户业务整体迁云的方案设计会涉及到集群规划、数据搬迁、监控切换、日志切换以及最终的生产流量切换或并网操作。 迁云到ACK需要做涉及到哪些组件、搬迁哪些数据、切换哪些服务等,都是需要用户又清晰的概念的。首先需要做集群规划,用户需要根据自己业务场景的不同来选择不同的机器类型,比如CPU机器还是GPU机器,比如虚拟服务器ECS还是神龙裸金属服务器等等,网络规划这部分会涉及到容器集群基础设施选择vpc内网网络还是经典网络,集群内pod之间进行通信模式是flannel模式还是terway模式等,在容量规划这部分,用户可以根据自己的成本以及预算规划一个可满足初期业务正常运行的容量即可,随后可以配置动态扩缩容随时弹缩集群规模;在安全防护提升这部分,有基础架构安全比如设置合理的安全组规则,有镜像安全比如使用私有镜像并定义镜像安全扫描,K8S应用安全管理比如设置不同服务间互相访问的网络安全策略等;监控切换这部分相对于用户自建Kubernetes会更加全维度和立体,从基础设施到容器运行时监控一应俱全,并可根据阈值设定触发报警通知;用户一般也会把自建的日志收集方案切换成阿里云上企业级的日志产品SLS;数据迁移是非常重要的一部分,这些数据包括数据库数据、存储数据、容器镜像等,我们会对接阿里云上企业级的粗出产品以及迁移工具,目的是为了保证数据迁云的可靠性、安全性;应用改造主要涉及的内容包括镜像地址的更新、服务暴露方式的优化以及存储盘挂载方式的更新适配;最后提供一个满足用户快速迭代上线产品的CICD方案。以上各个组件调试完毕后,我们就可以进行一部分生产流量的切换。以上从集群规划到生产流量切换便是用户业务迁移上云所需要涉及到的方方面面。 我们提供了一个企业容器化生命周期模型,这个模型是根据时间阶段和用户侧各个业务角色来划分的,比如业务架构师角色需要关心的是业务上云能给公司带来什么价值,在TCO和场景上会带来哪些优化,云平台在安全性以及计算、存储、网络能力上是否能满足当前业务需求;IT架构师负责规划当前业务需要的集群容量和规模以及网络选型等问题,剩下的就是系统管理员与应用管理员把迁云方案的各个细节落实下来。这个模型的主要核心关注点是让用户的业务上云后能更稳定、成本更低、效率更高。 全栈迁云架构思路分两种,一种是整体迁移,一种是平滑迁移。整体迁移是指用户应用全部迁移上云后,各个组件调试完毕、测试验收通过后,可以整体切换生产流量到线上集群,待线上集群上的业务稳定运行一段时间后再下线原有环境。平滑迁移是指用户可以使用线上ACK集群纳管线下节点,或者线上集群与线下集群混合组网对外提供服务,逐步改造业务组件上云后将原有环境下线。这两种方式相比,整体迁移更简单,平滑迁移响度复杂但对业务影响小,所以也需要根据用户的实际场景做选择。 容器化整体迁云这部分还有两个小场景,一个是用户从自建Kubernetes集群迁移到ACK,此场景下用户的应用已经做了很大一部分的云原生化改造,迁移工作相对来说会简单些,还有一部分用户的应用是传统应用,直接运行在虚拟机或者裸金属服务器上,没有做过任何云原生化的改造,对于这部分场景,我们也提供了相关工具或方案帮助用户进行云原生化的迁云改造,比如使用derrick项目可以自动检测源码项目类型并生成Dockerfile和用于应用部署编排的yaml文件,比如我们正在联合ECS SMC(迁云中心)开发的虚拟机转换容器镜像并运行在ACk集群中的能力。 为了帮助用户提高迁云的效率,我们也在持续积累和开源一些迁云工具。比ack-image-builder为用户提供创建ACK集群节点自定义镜像的模板并通过校验模块检查自定义镜像是否满足ACK集群要求;sync-repo能够帮助用户快速完成容器镜像批量迁移至ACR(容器镜像仓库服务); velero能够帮助用户快速把其他云厂商后者自建Kubernetes集群下的完整应用迁移至ACK集群。 Velero迁移Kubernetes应用到ACK视频DEMO 在数据搬迁部分,可靠迁移是关键,根据用户数据类型的不同,我们会使用与之匹配的企业级迁移工具,比如数据在线迁移服务DOMS,比如OSS的迁移工具,还有离线海量数据迁移方案闪电立方等。 数据、应用迁云完成后,需要进一步适配监控、日志等组件,待各个组件调试完毕通过验收后,可以使用智能DNS进行生产流量的切割。 3. 应用改造和优化 对于应用改造和优化这部分,K8s到K8s的场景下,需要优化的是去适配自动扩容等自建K8s不具备的那些能力,在传统应用迁移到ACK的场景下,这部分的工作量会更大些,所以我们针对这个场景也输出了一些方案,比如类似于异地多活的方案,我们把用户传统应用环境,通常是虚拟机或者裸机环境集成到线上ACK部署的Istio网格中,逐步改造应用直至业务全部切换到线上ACK集群。 在应用逐步改造的这个过程中,会涉及到应用如何容器化、网络环境如何迁移以及数据迁移的问题,应用容器化这个问题,我们可以使用前面我提到过的一个服务叫做SMC迁云中心来完成虚拟机转换为容器镜像的过程,网络这部分可以通过iptables,External,CoreDNS PrivateZone等方式对IP地址DNS域名做处理,保持原先的逻辑IP和域名不变,并通过Istio实现网络虚拟路由和可观测性的管理。 4. 案例 接下来是部分迁云案例,有对高性能网络有特殊需求的用户,有做深度学习相关业务对大规模GPU机器有需求的用户,有要求裸金属机型服务器的用户等等。 5. 总结不同用户的不同业务场景在云原生化迁云方案的设计和落实上都有各自的差异性,不尽相同,需要结合ACK团队沉淀下来的最佳实践来快速做出评估和计划,并借助已有的一系列迁云工具快速完成业务从线下迁移上云的过程。 本文作者:流生 阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 26, 2019 · 1 min · jiezi

借助URLOS快速安装Netdata主机监控

环境需求最低硬件配置:1核CPU,1G内存(1+1)提示:如果你的应用较多,而主机节点的硬件配置较低,建议在部署节点时开通虚拟虚拟内存;生产环境建议使用2G或以上内存;推荐安装系统:Ubuntu-16.04、Ubuntu-18.04、CentOS7.X、Debian9X的64位的纯净的操作系统;URLOS安装curl -LO www.urlos.com/iu && sh iuNetdata主机监控安装流程登录URLOS系统后台,在应用市场中搜索“Netdata”,找到之后,直接点击安装按钮填写服务名称、选择运行节点、选择智能部署填写域名:www.aaa.com(这里填写自己的域名)然后点击“提交”按钮,等待部署完成;

July 15, 2019 · 1 min · jiezi

Kubernetes事件离线工具kubeeventer正式开源

前言监控是保障系统稳定性的重要组成部分,在Kubernetes开源生态中,资源类的监控工具与组件百花齐放。除了社区自己孵化的metrics-server,还有从CNCF毕业的Prometheus等等,开发者可选的方案有很多。但是,只有资源类的监控是远远不够的,因为资源监控存在如下两个主要的缺欠: 监控的实时性与准确性不足大部分资源监控都是基于推或者拉的模式进行数据离线,因此通常数据是每隔一段时间采集一次,如果在时间间隔内出现一些毛刺或者异常,而在下一个采集点到达时恢复,大部分的采集系统会吞掉这个异常。而针对毛刺的场景,阶段的采集会自动削峰,从而造成准确性的降低。 监控的场景覆盖范围不足部分监控场景是无法通过资源表述的,比如Pod的启动停止,是无法简单的用资源的利用率来计量的,因为当资源为0的时候,我们是不能区分这个状态产生的真实原因。 基于上述两个问题,Kubernetes是怎么解决的呢? 事件监控-监控的新维度Kubernetes作为云原生的平台实现,从架构设计上将接口与实现做到了完整的解耦和插拔,以状态机为整体的设计原则,通过设定期望状态、执行状态转换、检查并补偿状态的方式将资源的生命周期进行接管。 状态之间的转换会产生相应的转换事件,在Kubernetes中,事件分为两种,一种是Warning事件,表示产生这个事件的状态转换是在非预期的状态之间产生的;另外一种是Normal事件,表示期望到达的状态,和目前达到的状态是一致的。我们用一个Pod的生命周期进行举例,当创建一个Pod的时候,首先Pod会进入Pending的状态,等待镜像的拉取,当镜像录取完毕并通过健康检查的时候,Pod的状态就变为Running。此时会生成Normal的事件。而如果在运行中,由于OOM或者其他原因造成Pod宕掉,进入Failed的状态,而这种状态是非预期的,那么此时会在Kubernetes中产生Warning的事件。那么针对这种场景而言,如果我们能够通过监控事件的产生就可以非常及时的查看到一些容易被资源监控忽略的问题。 一个标准的Kubernetes事件有如下几个重要的属性,通过这些属性可以更好地诊断和告警问题。 Namespace:产生事件的对象所在的命名空间。Kind:绑定事件的对象的类型,例如:Node、Pod、Namespace、Componenet等等。Timestamp:事件产生的时间等等。Reason:产生这个事件的原因。Message: 事件的具体描述。其他信息通过事件的机制,我们可以丰富Kuernetes在监控方面的维度和准确性,弥补其他监控方案的缺欠。 kube-eventer v1.0.0的发布与开源针对Kubernetes的事件监控场景,Kuernetes社区在Heapter中提供了简单的事件离线能力,后来随着Heapster的废弃,相关的能力也一起被归档了。为了弥补事件监控场景的缺失,阿里云容器服务发布并开源了kubernetes事件离线工具kube-eventer。支持离线kubernetes事件到钉钉机器人、SLS日志服务、Kafka开源消息队列、InfluxDB时序数据库等等。 在本次正式发布的v1.0.0的版本中,作了如下功能的增强。 钉钉插件支持Namespace、Kind的过滤支持与NPD插件的集成与部署优化SLS插件的数据离线性能修复InfluxDB插件启动参数失效的问题修复Dockerfile的安全漏洞以及其他共11项功能修复典型场景分析: 使用钉钉进行事件告警使用SLS进行事件告警结合NPD进行异常检测与事件告警,此外使用容器服务的开发者可以直接用应用目录中的Helm Chart进行部署。项目开源地址:https://github.com/AliyunContainerService/kube-eventer 本文作者:莫源阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 15, 2019 · 1 min · jiezi

阿里云InfluxDB®-Raft-HybridStorage实现方案

背景阿里云InfluxDB®是阿里云基于开源版InfluxDB打造的一款时序数据库产品,提供更稳定的持续运行状态、更丰富强大的时序数据计算能力。在现有的单节点版本之外,阿里云InfluxDB®团队还将推出多节点的高可用版本。 我们知道现有的开源版InfluxDB只提供单节点的能力,早期开源的集群版本功能不完善、且社区不再提供更新与支持。经过对官网商业版InfluxDB现有文档的研究,我们猜测在商业版InfluxDB集群方案中,meta信息集群是基于一致性协议Raft做同步的,而数据是异步复制的。这种分离的方式虽然有优点,但也引起了一系列的一致性问题,在一些公开的文档中,官方也承认这种数据复制方案并不令人满意。 因此,团队在参考多项技术选型后,决定采用最为广泛使用并有较长历史积累的ETCD/Raft作为核心组件实现阿里云InfluxDB®的Raft内核,对用户所有的写入或一致性读请求直接进行Raft同步(不做meta信息同步与数据写入在一致性过程中的拆分),保证多节点高可用版本拥有满足强一致性要求的能力。 有幸笔者参与到多节点的高可用版本的开发中,期间遇到非常多的挑战与困难。其中一项挑战是ETCD的Raft框架移植过程中,在移除了ETCD自身较为复杂、对时序数据库没有太多作用的Raft日志模块后,所带来的一系列问题。本文就业界Raft日志的几种不同实现方案做讨论,并提出一种自研的Raft HybridStorage方案。 业内方案ETCD由于我们采用了ETCD/Raft的方案,绕不开讨论一下ETCD本家的Raft日志实现方式。 官网对Raft的基本处理流程总结参考下图所示,协议细节本文不做扩展: 对于ETCD的Raft日志,主要包含两个主要部分:文件部分(WAL)、内存存储部分(MemoryStorage)。 文件部分(WAL),是ETCD Raft过程所用的日志文件。Raft过程中收到的日志条目,都会记录在WAL日志文件中。该文件只会追加,不会重写和覆盖。 内存存储部分(MemoryStorage),主要用于存储Raft过程用到的日志条目一段较新的日志,可能包含一部分已共识的日志和一些尚未共识的日志条目。由于是内存维护,可以灵活的重写替换。MemoryStorage有两种方式清理释放内存:第一种是compact操作,对appliedId之前的日志进行清理,释放内存;第二种是周期snapshot操作,该操作会创建snapshot那一时刻的ETCD全局数据状态并持久化,同时清理内存中的日志。 在最新的ETCD 3.3代码仓库中,ETCD已经将Raft日志文件部分(WAL)和Raft日志内存存储部分(MemoryStorage)都抽象提升到了与Raft节点(Node)、Raft节点id以及Raft集群其他节点信息(*membership.RaftCluster)平级的Server层级,这与老版本的ETCD代码架构有较大区别,在老版本中Raft WAL与MemoryStorage都仅仅只是Raft节点(Node)的成员变量。 一般情况下,一条Raft日志的文件部分与内存存储部分配合产生作用,写入时先写进WAL,保证持久化;随之马上追加到MemoryStorage中,保证热数据的高效读取。 无论是文件部分还是内存存储部分,其存储的主要数据结构一致,都是raftpb.Entry。一条log Entry主要包含以下几个信息: 参数描述Termleader的任期号Index当前日志索引Type日志类型Data日志内容此外,ETCD Raft日志的文件部分(WAL)还会存储针对ETCD设计的一些额外信息,比如日志类型、checksum等等。 CockroachDBCockroachDB是一款开源的分布式数据库,具有NoSQL对海量数据的存储管理能力,又保持了传统数据库支持的ACID和SQL等,还支持跨地域、去中 心、高并发、多副本强一致和高可用等特性。 CockroachDB的一致性机制也是基于Raft协议:单个Range的多个副本通过Raft协议进行数据同步。Raft协议将所有的请求以Raft Log的形式串行化并由Leader同步给Follower,当绝大多数副本写Raft Log成功后,该Raft Log会标记为Committed状态,并Apply到状态机。 我们来分析一下CockroachDB Raft机制的关键代码,可以很明显的观察到也是从鼻祖ETCD的Raft框架移植而来。但是CockroachDB删除了ETCD Raft日志的文件存储部分,将Raft日志全部写入RocksDB,同时自研一套热数据缓存(raftentry.Cache),利用raftentry.Cache与RocksDB自身的读写能力(包括RocksDB的读缓存)来保证对日志的读写性能。 此外,Raft流程中的创建snapshot操作也是直接保存到RocksDB。这样实现的原因,个人推测是可能由于CockroachDB底层数据存储使用的就是RocksDB,直接使用RocksDB的能力读写WAL或者存取snapshot相对简单,不需要再额外开发适用于CockroachDB特性的Raft日志模块了。 自研HybridStorage移除snapshot在阿里云InfluxDB多节点高可用方案实现过程中,我们采用了ETCD/Raft作为核心组件,根据移植过程中的探索与InfluxDB实际需要,移除了原生的snapshot过程。同时放弃原生的日志文件部分WAL,而改用自研方案。 为什么移除snapshot呢?原来在Raft的流程中,为了防止Raft日志的无限增加,会每隔一段时间做snapshot,早于snapshot index的Raft日志请求,将直接用snapshot回应。然而我们的单Raft环架构如果要做snapshot,就是对整个InfluxDB做,将非常消耗资源和影响性能,而且过程中要锁死整个InfluxDB,这都是不能让人接受的。所以我们暂时不启用snapshot功能,而是存储固定数量的、较多的Raft日志文件备用。 自研的Raft日志文件模块会周期清理最早的日志防止磁盘开销过大,当某个节点下线的时间并不过长时,其他正常节点上存储的日志文件如果充足,则足够满足它追取落后的数据。但如果真的发生单节点宕机太长,正常节点的日志文件已出现被清理而不足故障节点追取数据时,我们将利用InfluxDB的backup和restore工具,将落后节点还原至被Raft日志涵盖的较新的状态,然后再做追取。 在我们的场景下,ETCD自身的WAL模块并不适用于InfluxDB。ETCD的WAL是纯追加模式的,当故障恢复时,正常节点要相应落后节点的日志请求时,就有必要分析并提取出相同index且不同term中那条最新的日志,同时InfluxDB的一条entry可能包含超过20M的时序数据,这对于非kv模式的时序数据库而言是非常大的磁盘开销。 HybridStorage设计我们自研的Raft日志模块命名为HybridStorage,即意为内存与文件混合存取,内存保留最新热数据,文件保证全部日志落盘,内存、文件追加操作高度一致。 HybridStorage的设计思路是这样的: (1)保留MemoryStorage:为了保持热数据的读取效率,内存中的MemoryStorage会保留作为热数据cache提升性能,但是周期清理其中最早的数据,防止内存消耗过大。 (2)重新设计WAL:WAL不再是像ETCD那样的纯追加模式、也不需要引入类似RocksDB这样重的读写引擎。新增的日志在MemoryStorage与WAL都会保存,WAL文件中最新内容始终与MemoryStorage保持完全一致。 一般情况下,HybridStorage新增不同index的日志条目时,需要在写内存日志时同时操作文件执行类似的增减。正常写入流程如下图所示: 当出现了同index不同term的日志条目的情况,此时执行truncate操作,截断对应文件位置之后一直到文件尾部的全部日志,然后重新用append方式写入最新term编号的日志,操作逻辑上十分清晰,不存在Update文件中间的某个位置的操作。 例如在一组Raft日志执行append操作时,出现了如下图所示的同index(37、38、39)不同term的日志条目的情况。在MemoryStorage的处理方式是:找到对应index位置的内存位置(内存位置37),并抛弃从位置A以后的全部旧日志占用的内存数据(因为在Raft机制中,这种情况下内存位置37以后的那些旧日志都是无效的,无需保留),然后拼接上本次append操作的全部新日志。在自研WAL也需要执行类似的操作,找到WAL文件中对应index的位置(文件位置37),删除从文件位置37之后的所有文件内容,并写入最新的日志。如下图分析: 方案对比ETCD的方案,Raft日志有2个部分,文件与内存,文件部分因为只有追加模式,因此并不是每一条日志都是有效的,当出现同index不同term的日志条目时,只有最新的term之后的日志是生效的。配合snapshot机制,非常适合ETCD这样的kv存储系统。但对于InfluxDB高可用版本而言,snapshot将非常消耗资源和影响性能,而且过程中要锁死整个InfluxDB。同时,一次Raft流程的一条entry可能包含超过20M的时序数据。所以这种方案不适合。 CockroachDB的方案,看似偷懒使用了RocksDB的能力,但因其底层存储引擎也是RocksDB,所以无何厚非。但对于我们这样需要Raft一致性协议的时序数据库而言,引入RocksDB未免过重了。 自研的Raft HybridStorage是比较符合阿里云InfluxDB®的场景的,本身模块设计轻便简介,内存保留了热数据缓存,文件使用接近ETCD append only的方式,遇到同index不同term的日志条目时执行truncate操作,删除冗余与无效数据,降低了磁盘压力。 总结本文对比了业内常见的两种Raft日志的实现方案,也展示了阿里云InfluxDB®团队自研的HybridStorage方案。在后续开发过程中,团队内还会对自研Raft HybridStorage进行多项优化,例如异步写、日志文件索引、读取逻辑优化等等。也欢迎读者提出自己的解决方案。相信阿里云InfluxDB®团队在技术积累与沉淀方面会越做越好,成为时序数据库技术领导者。 本文作者:德施阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 11, 2019 · 1 min · jiezi

分布式服务架构下的混沌工程实践

本文来自阿里巴巴高可用架构团队高级开发工程师肖长军(花名穹谷)在 GIAC(全球互联网架构大会)上的分享,包含三部分内容:(阿里巴巴中间件公众号对话框发送“混沌工程”,获取分享PPT) 混沌工程的定义、价值、原则和流程;混沌工程如何在企业中落地,以及 ChaosBlade 和混沌实验平台 AHAS Chaos 架构设计;结合两个具体案例介绍了分布式服务下的混沌工程实践;大家好,我是来自阿里的肖长军,今天给大家分享混沌工程在分布式服务架构下的具体实践。 先做个自我介绍,我来自于阿里高可用架构团队,花名穹谷,做过分布式系统设计和 APM 研发相关工作,现在专注于高可用架构和混沌工程领域,是阿里云产品 AHAS 底层技术负责人和开源项目 ChaosBlade 负责人,并且承担集团内故障演练、突袭演练、攻防演练相关的研发工作。今天分享的内容包含以下三个方面。 先从混沌工程的定义、价值、原则和实施步骤介绍混沌工程,然后分享混沌工程如何在企业中落地,最后介绍分布式服务下混沌工程实践案例。我们先来看一下什么是混沌工程。 混沌工程理论一文中提到,其是在分布式系统上进行实验的学科,核心目的是提高生产环境中系统的容错性和可恢复性。尼采的这句话: "打不倒我的必使我强大",也很好的诠释了混沌工程反脆弱的思想。除了这里提到的目的,实施混沌工程还有哪些价值呢? 这里我从四个角色来说明,对于架构师来说,可以验证系统架构的容错能力,比如验证现在提倡的面向失败设计的系统;对于开发和运维,可以提高故障的应急效率,实现故障告警、定位、恢复的有效和高效性。对于测试来说,可以弥补传统测试方法留下的空白,之前的测试方法基本上是从用户的角度去做,而混沌工程是从系统的角度进行测试,降低故障复发率。对于产品和设计,通过混沌事件查看产品的表现,提升客户使用体验。所以说混沌工程面向的不仅仅是开发、测试,拥有最好的客户体验是每个人的目标。我们知道,系统发生故障的那一刻不是由你来选择的,而是那一刻选择你,你所能做,只能是为之做好准备。了解了混沌工程的价值,我们再来看一下实施混沌工程的一些原则。 前面 Vilas 老师也提到了,我这里重点来介绍一下这五项原则。第一条:”建立一个围绕稳定状态行为的假说“,其包含两个含义,一个是定义能直接反应业务服务的监控指标,需要注意的是这里的监控指标并不是系统资源指标,比如CPU、内存等,这里的监控指标是能直接衡量系统服务质量的业务监控。举个例子,一个调用延迟故障,请求的 RT 会变长,对上层交易量造成下跌的影响,那么这里交易量就可以作为一个监控指标。这条原则的另一个含义是故障触发时,对系统行为作出假设以及监控指标的预期变化。第二个指模拟生产环境中真实的或有理论依据的故障,第三个建议在生产环境中运行实验,但也不是说必须在生产环境中执行,只是实验环境越真实,混沌工程越有价值。持续的执行才能持续的降低故障复发率和提前发现故障,所以需要持续的自动化运行试验,最后一个,混沌工程很重要的一点是控制爆炸半径,也就是试验影响面,防止预期外的资损发生,后面会介绍控制爆炸半径的方式。依据这些指导原则可以更有效实施混沌工程,那么混沌工程的实施步骤是什么? 主要细分为这 8 步,指定试验计划,定义稳态指标,做出系统容错假设,执行实验,检查稳态指标,记录、恢复 实验,修复发现的问题,然后做持续验证。以上是对混沌工程理论相关的介绍,那么如何在企业中落地混沌工程呢? 我这里分为三个阶段,首先要坚定价值,因为你会受到来自多方面的挑战,其次引入混沌工程技术,最后在企业中推广混沌工程文化。在实施混沌工程之前,必须能说清楚混沌工程的价值,而且当受到挑战时,意志要坚定。 比如来自老板的挑战,”如何衡量混沌工程的价值?“,可以向老板表达出,”从故障的应急效率、故障复发率、线上故障发现数来衡量“等等。所以这些问题自己要想清楚。有了坚定的意志,就要开始落地,首先要先了解自己的系统。 这里系统成熟度分 5 个等级,也可以说是业务系统所处的阶段,列出了每个阶段适合什么故障场景。刚才也有听众问,”我的服务就是单点的,还有没有实施混沌工程的必要?“,有必要,可以实施简单的实验场景,比如 CPU 满载等,来验证监控告警,如果发现没有监控告警,就要去推动完善它,然后再推动服务多实例部署,通过混沌工程一级一级的去推动系统的演进,最终实现具有韧性的系统。根据系统成熟度了解自己系统所适合的场景,接下来就要选择一款合适的混沌实验工具。 这里列举了五个维度:场景丰富度、工具类型、易用性等。可以从 awesome-chaos-engineering github 项目查找或者从 CNCF Landscpage 中查看混沌实验工具。阿里今年开源的 ChaosBlade 也已经加入到 CNCF Landscape 中,后面会对此项目做重点介绍,先来看阿里混沌工程技术的演进。 2012 年阿里内部就上线了 EOS 项目,用于梳理分布式服务强弱依赖问题,同年进行了同城容灾的断网演练。 15 年 实现异地多活,16 年内部推出故障演练平台 MonkeyKing,开始在线上环境实施混沌实验,然后 18 年输出了 ACP 专有云产品 和 AHAS 公有云产品,其中 AHAS 旨在将阿里的高可用架构经验以产品的形式对外输出,服务于外部。19 年推出 ChaosBlade 项目,将底层的故障注入能力对外开源,同年也推出混沌实验平台专有云版本 AHAS Chaos,接下来重点介绍一下 ChaosBlade 项目。 ...

July 5, 2019 · 1 min · jiezi

干货-云解析DNS之网站监控

云解析是在域名解析的基础上,由京东云团队,结合京东云的优质网络、主机资源研发的高可用、高可靠、功能丰富的权威DNS服务器。云解析拥有简单易用的控制台,方便用户对域名进行操作。采用多集群、多节点部署,拥有百G防护套餐,专业DNS团队提供全面的服务保障能力。本次操作需要用到京东云云解析【企业高级版】¥3888/年,因为只有这个版本才有网站监控功能 一、搭建测试站点具体配置如下: 计费模式:按配置地域与可用区:华北-北京(可用区随意)镜像:CentOS 7.4 64位规格:1核4GB存储:保持默认安全组:开放全部端口(仅用于测试,生产环境根据需求开放)带宽:1Mbps名称:自定义自定义数据:如下云主机dns_test1: 1 #!/bin/bash2 yum install httpd -y3 systemctl enable httpd4 systemctl start httpd5 echo "Web01" > /var/www/html/index.html云主机dns_test2: 1 #!/bin/bash2 yum install httpd -y3 systemctl enable httpd4 systemctl start httpd5 echo "Web02" > /var/www/html/index.html云主机创建完成如下: 浏览器中分别输入以上两个云主机的公网IP可验证测试站点是否创建成功 二、在云解析中添加域名1. 添加域名 打开京东云控制台:https://console.jdcloud.com/,在左侧导航中依次点击域名服务-云解析,如图添加需要被解析的域名(需要填写一级域名) 添加完成后,需要到原域名服务商所在的控制台修改NS 各个服务商界面不同 NS修改完成 NS修改是否生效,由于控制台是定时查询同步,所以会有所延迟,具体可查询whois:https://net.jdcloud.com/domai...2. 添加域名解析记录 如图添加两条A记录,分别指向上一步创建的云主机dns_test1的公网IP和云主机dns_test2的公网IP(这里设置的两条记录主机记录要相同,记录值不同,具体看后面操作) 解析记录添加完如下: 验证添加的记录 三、设置网站监控1. 设置报警联系人信息 注意:网站监控报警只有安全设置中绑定的手机号和邮箱才能收到信息,联系人管理中设置的联系人信息无法收到报警。 2. 添加网站监控 ...

July 4, 2019 · 1 min · jiezi

云原生应用-Kubernetes-监控与弹性实践

前言   云原生应用的设计理念已经被越来越多的开发者接受与认可,而Kubernetes做为云原生的标准接口实现,已经成为了整个stack的中心,云服务的能力可以通过Cloud Provider、CRD Controller、Operator等等的方式从Kubernetes的标准接口向业务层透出。开发者可以基于Kubernetes来构建自己的云原生应用与平台,Kubernetes成为了构建平台的平台。今天我们会向大家介绍一个云原生应用该如何在Kubernetes中无缝集成监控和弹性能力。 本文整理自由阿里云容器平台技术专家 刘中巍(莫源)在 KubeCon 分享的《Cloud Native Application monitoring and autoscaling in kubernetes》演讲。获取 KubeCon 全部阿里演讲PPT,关注阿里巴巴云原生公众号,微信菜单栏点击 PPT下的“获取PPT” 阿里云容器服务Kubernetes的监控总览 云服务集成  阿里云容器服务Kubernetes目前已经和四款监控云服务进行了打通,分别是SLS(日志服务)、ARMS(应用性能监控)、AHAS(架构感知监控服务)、Cloud Monitor(云监控)。 SLS主要负责日志的采集、分析。在阿里云容器服务Kubernetes中,SLS可以采集三种不同类型的日志 APIServer等核心组件的日志Service Mesh/Ingress等接入层的日志应用的标准日志  除了采集日志的标准链路外,SLS还提供了上层的日志分析能力,默认提供了基于APIServer的审计分析能力、接入层的可观测性展现、应用层的日志分析。在阿里云容器服务Kubernetes中,日志组件已经默认安装,开发者只需要通过在集群创建时勾选即可。 ARMS主要负责采集、分析、展现应用的性能指标。目前主要支持Java与PHP两种语言的集成,可以采集虚拟机(JVM)层的指标,例如GC的次数、应用的慢SQL、调用栈等等。对于后期性能调优可以起到非常重要的作用。 AHAS是架构感知监控,通常在Kubernetes集群中负载的类型大部分为微服务,微服务的调用拓扑也会比较复杂,因此当集群的网络链路出现问题时,如何快速定位问题、发现问题、诊断问题则成为了最大的难题。AHAS通过网络的流量和走向,将集群的拓扑进行展现,提供更高层次的问题诊断方式。 开源方案集成开源方案的兼容和集成也是阿里云容器服务Kubernetes监控能力的一部分。主要包含如下两个部分: Kubernetes内置监控组件的增强与集成  在kubernetes社区中,heapster/metrics-server是内置的监控方案,而且例如Dashboard、HPA等核心组件会依赖于这些内置监控能力提供的metrics。由于Kubernetes生态中组件的发布周期和Kubernetes的release不一定保证完整的同步,这就造成了部分监控能力的消费者在Kubernetes中存在监控问题。因此阿里云就这个问题做了metrics-server的增强,实现版本的兼容。此外针对节点的诊断能力,阿里云容器服务增强了NPD的覆盖场景,支持了FD文件句柄的监测、NTP时间同步的校验、出入网能力的校验等等,并开源了eventer,支持离线Kubernetes的事件数据到SLS、kafka以及钉钉,实现ChatOps。 Prometheus生态的增强与集成   Promethes作为Kubernetes生态中三方监控的标准,阿里云容器服务也提供了集成的Chart供开发者一键集成。此外,我们还在如下三个层次作了增强: 存储、性能增强:支持了产品级的存储能力支持(TSDB、InfluxDB),提供更持久、更高效的监控存储与查询。采集指标的增强:修复了部分由于Prometheus自身设计缺欠造成的监控不准的问题,提供了GPU单卡、多卡、共享分片的exporter。提供上层可观测性的增强:支持场景化的CRD监控指标集成,例如argo、spark、tensorflow等云原生的监控能力,支持多租可观测性。阿里云容器服务Kubernetes的弹性总览   阿里云容器服务Kubernetes主要包含如下两大类弹性组件:调度层弹性组件与资源层弹性组件。 调度层弹性组件  调度层弹性组件是指所有的弹性动作都是和Pod相关的,并不关心具体的资源情况。 HPAHPA是Pod水平伸缩的组件,除了社区支持的Resource Metrics和Custom Metrics,阿里云容器服务Kubernetes还提供了external-metrics-adapter,支持云服务的指标作为弹性伸缩的判断条件。目前已经支持例如:Ingress的QPS、RT,ARMS中应用的GC次数、慢SQL次数等等多个产品不同维度的监控指标。 VPA VPA是Pod的纵向伸缩的组件,主要面向有状态服务的扩容和升级场景。    cronHPA cronHPA是定时伸缩组件,主要面向的是周期性负载,通过资源画像可以预测有规律的负载周期,并通过周期性伸缩,实现资源成本的节约。 ResizerResizer是集群核心组件的伸缩控制器,可以根据集群的CPU核数、节点的个数,实现线性和梯度两种不同的伸缩,目前主要面对的场景是核心组件的伸缩,例如:CoreDNS。 资源层弹性组件资源层弹性组件是指弹性的操作都是针对于Pod和具体资源关系的。 Cluster-Autoscaler Cluster-Autoscaler是目前比较成熟的节点伸缩组件,主要面向的场景是当Pod资源不足时,进行节点的伸缩,并将无法调度的Pod调度到新弹出的节点上。 virtual-kubelet-autoscaler virtual-kubelet-autoscaler是阿里云容器服务Kubernetes开源的组件,和Cluster-Autoscaler的原理类似,当Pod由于资源问题无法调度时,此时弹出的不是节点,而是将Pod绑定到虚拟节点上,并通过ECI的方式将Pod进行启动。 Demo Show Case  最后给大家进行一个简单的Demo演示:应用主体是apiservice,apiservice会通sub-apiservice调用database,接入层通过ingress进行管理。我们通过PTS模拟上层产生的流量,并通过SLS采集接入层的日志,ARMS采集应用的性能指标,并通过alibaba-cloud-metrics-adapster暴露external metrics触发HPA重新计算工作负载的副本,当伸缩的Pod占满集群资源时,触发virtual-kubelet-autoscaler生成ECI承载超过集群容量规划的负载。 总结  在阿里云容器服务Kubernetes上使用监控和弹性的能力是非常简单的,开发者只需一键安装相应的组件Chart即可完成接入,通过多维度的监控、弹性能力,可以让云原生应用在最低的成本下获得更高的稳定性和鲁棒性。 本文作者:jessie筱姜阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 4, 2019 · 1 min · jiezi

性能压测工具选型对比

本文是《Performance Test Together》(简称PTT)系列专题分享的第二期,该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能压测的理论体系,并提供有例可依的实战。 该系列专题分享由阿里巴巴 PTS 团队出品。 第一期:《压测环境的设计和搭建》,点击这里。 本文致力于给出性能压测的概念与背景介绍,同时针对市场上的一些性能压测工具,给出相应的对比,从而帮助大家更好地针对自身需求实现性能压测。 为什么要做性能压测在介绍性能压测概念与背景之前,首先解释下为什么要做性能压测。从09年的淘宝双十一大促导致多家合作银行后台系统接连宕机,到春运期间12306购票难,再到前不久聚美优品促销活动刚开始就遭秒杀。根据Amazon统计,每慢100毫秒,交易额下降1%。这些事件和统计数据为大家敲响了警钟,也客观说明了性能压测对于企业应用的重要性。 从具体的作用上讲,性能压测可以用于新系统上线支持、技术升级验证、业务峰值稳定性保障、站点容量规划以及性能瓶颈探测。 1. 新系统上线支持在新系统上线前,通过执行性能压测能够对系统的负载能力有较为清晰的认知,从而结合预估的潜在用户数量保障系统上线后的用户体验。 2. 技术升级验证在系统重构过程中,通过性能压测验证对比,可以有效验证新技术的高效性,指导系统重构。 3. 业务峰值稳定性保障在业务峰值到来前,通过充分的性能压测,确保大促活动等峰值业务稳定性,保障峰值业务不受损。 4. 站点容量规划通过性能压测实现对站点精细化的容量规划,指导分布式系统机器资源分配。 5. 性能瓶颈探测通过性能压测探测系统中的性能瓶颈点,进行针对性优化,从而提升系统性能。 综上所述,性能压测伴随着系统开发、重构、上线到优化的生命周期,因此有效的性能压测对系统的稳定性具有重要的指导意义,是系统生命周期中不可或缺的一部分。 性能压测概念性能压测是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。从测试目的上性能压测又可以划分为负载测试、压力测试、并发测试、配置测试以及可靠性测试。 负载测试是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接受的性能点,来获得系统能提供的最大服务级别的测试。并发测试通过模拟用户并发访问,测试多用户并发访问同一个软件、同一个模块或者数据记录时是否存在死锁等性能问题。配置测试是通过对被测系统的软/硬件环境的调整,了解各种不同方法对软件系统的性能影响的程度,从而找到系统各项资源的最优分配原则。可靠性测试是在给系统加载一定业务压力的情况下,使系统运行一段时间,以此检测系统是否稳定。总的来说,性能压测是在对系统性能有一定程度了解的前提下,在确定的环境下针对压测需求进行的一种测试。 如何选取性能压测工具在选取合适的性能压测工具之前,我们需要先先了解执行一次完整的性能压测所需要的步骤: 1. 确定性能压测目标:性能压测目标可能源于项目计划、业务方需求等 2. 确定性能压测环境:为了尽可能发挥性能压测作用,性能压测环境应当尽可能同线上环境一致 3. 确定性能压测通过标准:针对性能压测目标以及选取的性能压测环境,制定性能压测通过标准,对于不同于线上环境的性能压测环境,通过标准也应当适度放宽 4. 设计性能压测:编排压测链路,构造性能压测数据,尽可能模拟真实的请求链路以及请求负载 5. 执行性能压测:借助性能压测工具,按照设计执行性能压测 6. 分析性能压测结果报告:分析解读性能压测结果报告,判定性能压测是否达到预期目标,若不满足,要基于性能压测结果报告分析原因 由上述步骤可知,一次成功的性能压测涉及到多个环节,从场景设计到施压再到分析,缺一不可。工欲善其事,必先利其器,而一款合适的性能工具意味着我们能够在尽可能短的时间内完成一次合理的性能压测,达到事半功倍的效果。 工具选型对比在论述了性能压测必要性之后,如何选取性能压测工具成为一个重要的议题?本文选取了市场上主流性能压测工具:(ab)Apache Bench、LoadRunner、JMeter、阿里云PTS,并从多个方面出发分析了各个工具的优缺点,汇总后的优缺点如下表所示: 压测工具Apache Bench(ab)LoadRunnerJMeterPTS学习成本低高高低安装部署成本低高高低是否免费是否是否是否支持多协议否是是是压测结果是否能够图形化展示否是是是是否支持TPS模式否否否是是否有链路、场景编排管理支持否是是是是否支持场景录制否是是是生态环境强弱弱弱弱强监控指标是否完备否否否是是否原生支持流量地域定制否否否是Apache Bench(ab) ab是一款用来针对HTTP协议做性能压测的命令行工具,支持在本地环境发起测试请求,验证服务器的处理性能。它主要具有以下特点: 首先,作为一款开源工具,ab具有较好的扩展性,测试开发人员可以基于自身需求对其进行二次开发,同时它对HTTP协议支持度较好,比如支持设定HTTP请求头、支持Cookie以及HTTP的多种方法。此外,使用ab时还可以通过指定性能压测产生的总请求数、并发数与压测时长控制性能压测,结合其能够输出性能压测过程中的TPS(每秒事务数)、RT(响应时延)等信息的特点,ab具有简单易上手的特点。但ab也存在一些缺点,如无图形化界面支持,支持协议较为单一,只支持HTTP协议,缺少对HTTPS协议、WebSocket等协议的支持,对于较为复杂的性能压测场景,ab缺少链路编排、场景管理等支持,只能够对单一地址发起性能压测,此外,它的性能压测统计指标纬度较少,缺少性能压测过程中的数据统计,只能够在压测结束后获取相关的统计数据,无法实时获取系统负载等指标,难以应用于生产环境下的性能压测。 总的来说,ab作为一款命令行测试工具,适用于本地对支持HTTP协议的单一地址进行性能压测,但缺少相应的链路编排、场景管理、数据可视化等大规模性能压测基础功能,无法应用于生产环境。 LoadRunner LoadRunner,是一款发布于1993年11月的预测系统行为和性能的负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner作为一款历史悠久的商业性能压测工具,能够对整个企业架构进行测试。企业使用LoadRunner能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期。 LoadRunner可适用于各种体系架构的自动负载测试,能预测系统行为并评估系统性能。 LoadRunner从组件上可划分为四部分: 负载生成器:模拟用户对服务器发起请求虚拟用户生成器:捕捉用户业务流,用于录制和生成脚本控制器:用于提供场景设计与场景监控,能够实时监控脚本的运行情况分析器:汇集来自各种负载生成器的日志并格式化报告,以便可视化运行结果数据和监控数据从组件划分上可以看出 LoadRunner 对于性能压测拥有较为系统的支持,结合多个组件的功能特性,用户可以较为方便地设计复杂背景下的性能压测场景,例如结合场景设计设置虚拟用户数量、设置执行时间等,结合虚拟用户生成器实现复杂链路、场景的高效设计与编排。此外,LoadRunner支持设置思考时间、集合点,还可以结合分析器实现压测报告统计数据、指标的可视化,助力测试人员理解性能压测结果。但 LoadRunner 作为一款商业软件,价格较高,需要本地安装,安装过程较复杂,在实际设计执行压测时需要编写相应的脚本,对使用人员来说学习成本比较高,此外缺少监控告警等支持,性能压测过程中难以实时发现问题。 总的来说,LoadRunner 作为一款性能压测商业软件,功能较为齐全,使用者能够借助 LoadRunner 达到简单的性能压测场景编排、施压目标;但它也存在学习成本居高不下、扩展性差等缺点,此外支持的协议有限,不适合复杂的性能压测环境。 JMeter Apache JMeter是Apache组织开发的基于Java的压力测试工具。它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器等等。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。同时JMeter支持对性能压测结果做图形分析。 JMeter 作为一款开源软件,扩展性强,具有强大的开源社区支持,社区内开发者活跃程度高,也正是在开源社区的积极发展下,JMeter 具有性能压测的诸多特性,如支持场景编排、断言设置,支持对多种资源施压,有图形化界面支持,支持脚本录制,使用人员能够较为简单的设计并发起性能压测,此外 JMeter 提供资源监控、性能压测报告生成等功能。但在需要高负载施压的场景下,JMeter 需要部署分布式环境,部署成本比较高,在使用时,需要编写相应的脚本,而每个脚本文件只能保存一个测试用例,学习门槛居高不下的同时也不利于脚本的维护,此外它缺少监控告警等支持,在性能压测过程中使用人员难以借助 JMeter 实时发现问题。 ...

July 2, 2019 · 1 min · jiezi

揭秘每秒千万级的实时数据处理是怎么实现的

1、设计背景闲鱼目前实际生产部署环境越来越复杂,横向依赖各种服务盘宗错节,纵向依赖的运行环境也越来越复杂。当服务出现问题的时候,能否及时在海量的数据中定位到问题根因,成为考验闲鱼服务能力的一个严峻挑战。 线上出现问题时常常需要十多分钟,甚至更长时间才能找到问题原因,因此一个能够快速进行自动诊断的系统需求就应用而生,而快速诊断的基础是一个高性能的实时数据处理系统。 这个实时数据处理系统需要具备如下的能力: 1、数据实时采集、实时分析、复杂计算、分析结果持久化。2、可以处理多种多样的数据。包含应用日志、主机性能监控指标、调用链路图。3、高可靠性。系统不出问题且数据不能丢。4、高性能,底延时。数据处理的延时不超过3秒,支持每秒千万级的数据处理。 本文不涉及问题自动诊断的具体分析模型,只讨论整体实时数据处理链路的设计。 2、输入输出定义为了便于理解系统的运转,我们定义该系统整体输入和输出如下:  输入: 服务请求日志(包含traceid、时间戳、客户端ip、服务端ip、耗时、返回码、服务名、方法名)        环境监控数据(指标名称、ip、时间戳、指标值)。比如cpu、 jvm gc次数、jvm gc耗时、数据库指标。 输出: 一段时间内的某个服务出现错误的根因,每个服务的错误分析结果用一张有向无环图表达。(根节点即是被分析的错误节点,叶子节点即是错误根因节点。叶子节点可能是一个外部依赖的服务错误也可能是jvm异常等等)。 3、架构设计 在实际的系统运行过程中,随着时间的推移,日志数据以及监控数据是源源不断的在产生的。每条产生的数据都有一个自己的时间戳。而实时传输这些带有时间戳的数据就像水在不同的管道中流动一样。 如果把源源不断的实时数据比作流水,那数据处理过程和自来水生产的过程也是类似的: 自然地,我们也将实时数据的处理过程分解成采集、传输、预处理、计算、存储几个阶段。 整体的系统架构设计如下: 采集采用阿里自研的sls日志服务产品(包含logtail+loghub组件),logtail是采集客户端,之所以选择logtail是因为其优秀的性能、高可靠性以及其灵活插件扩展机制,闲鱼可以定制自己的采集插件实现各种各样数据的实时采集。 传输loghub可以理解为一个数据发布订阅组件,和kafka的功能类似,作为一个数据传输通道其更稳定、更安全,详细对比文章参考:https://yq.aliyun.com/articles/35979?spm=5176.10695662.1996646101.searchclickresult.6f2c7fbe6g3xgP 预处理实时数据预处理部分采用blink流计算处理组件(开源版本叫做flink,blink是阿里在flink基础上的内部增强版本)。目前常用的实时流计算开源产品有Jstorm、SparkStream、Flink。Jstorm由于没有中间计算状态的,其计算过程中需要的中间结果必然依赖于外部存储,这样会导致频繁的io影响其性能;SparkStream本质上是用微小的批处理来模拟实时计算,实际上还是有一定延时;Flink由于其出色的状态管理机制保证其计算的性能以及实时性,同时提供了完备SQL表达,使得流计算更容易。  计算与持久化数据经过预处理后最终生成调用链路聚合日志和主机监控数据,其中主机监控数据会独立存储在tsdb时序数据库中,供后续统计分析。tsdb由于其针对时间指标数据的特别存储结构设计,非常适合做时序数据的存储与查询。调用链路日志聚合数据,提供给cep/graph service做诊断模型分析。cep/graph service是闲鱼自研的一个应用,实现模型分析、复杂的数据处理以及外部服务进行交互,同时借助rdb实现图数据的实时聚合。 最后cep/graph service分析的结果作为一个图数据,实时转储在lindorm中提供在线查询。lindorm可以看作是增强版的hbase,在系统中充当持久化存储的角色。 4、设计细节与性能优化采集日志和指标数据采集使用logtail,整个数据采集过程如图: 其提供了非常灵活的插件机制,共有四种类型的插件: inputs: 输入插件,获取数据。processors: 处理插件,对得到的数据进行处理。aggregators: 聚合插件,对数据进行聚合。flushers: 输出插件,将数据输出到指定 sink。由于指标数据(比如cpu、内存、jvm指标)的获取需要调用本地机器上的服务接口获取,因此应尽量减少请求次数,在logtail中,一个input占用一个goroutine。闲鱼通过定制input插件和processors插件,将多个指标数据(比如cpu、内存、jvm指标)在一个input插件中通过一次服务请求获取(指标获取接口由基础监控团队提供),并将其格式化成一个json数组对象,在processors插件中再拆分成多条数据,以减少系统的io次数同时提升性能。 传输数据传输使用LogHub,logtail写入数据后直接由blink消费其中的数据,只需设置合理的分区数量即可。分区数要大于等于bink读取任务的并发数,避免blink中的任务空转。 预处理预处理主要采用bink实现,主要的设计和优化点: 1:编写高效的计算流程blink是一个有状态的流计算框架,非常适合做实时聚合、join等操作。在我们的应用中只需要关注出现错误的的请求上相关服务链路的调用情况,因此整个日志处理流分成两个流:a、服务的请求入口日志作为一个单独的流来处理,筛选出请求出错的数据。b、其他中间链路的调用日志作为另一个独立的流来处理,通过和上面的流join on traceid实现出错服务依赖的请求数据塞选。  如上图所示通过双流join后,输出的就是所有发生请求错误相关链路的完整数据。 2:设置合理的state生存周期blink在做join的时候本质上是通过state缓存中间数据状态,然后做数据的匹配。而如果state的生命周期太长会导致数据膨胀影响性能,如果state的生命周期太短就会无法正常关联出部分延迟到来的数据,所以需要合理的配置state生存周期,对于该应用允许最大数据延迟为1分钟。 使用niagara作为statebackend,以及设定state数据生命周期,单位毫秒state.backend.type=niagarastate.backend.niagara.ttl.ms=600003:开启 MicroBatch/MiniBatchMicroBatch 和 MiniBatch 都是微批处理,只是微批的触发机制上略有不同。原理上都是缓存一定的数据后再触发处理,以减少对 state 的访问从而显著提升吞吐,以及减少输出数据量。 开启joinblink.miniBatch.join.enabled=true使用 microbatch 时需要保留以下两个 minibatch 配置blink.miniBatch.allowLatencyMs=5000防止OOM,每个批次最多缓存多少条数据blink.miniBatch.size=200004:动态负载使用 Dynamic-Rebalance 替代 Rebalanceblink任务在运行是最忌讳的就是存在计算热点,为保证数据均匀使用Dynamic Rebalance,它可以根据当前各subpartition中堆积的buffer的数量,选择负载较轻的subpartition进行写入,从而实现动态的负载均衡。相比于静态的rebalance策略,在下游各任务计算能力不均衡时,可以使各任务相对负载更加均衡,从而提高整个作业的性能。 开启动态负载task.dynamic.rebalance.enabled=true5:自定义输出插件数据关联后需要将统一请求链路上的数据作为一个数据包通知下游图分析节点,传统的方式的是通过消息服务来投递数据。但是通过消息服务有两个缺点:1、其吞吐量和rdb这种内存数据库相比比还是较大差距(大概差一个数量级)。2、在接受端还需要根据traceid做数据关联。 ...

June 21, 2019 · 1 min · jiezi

基于Knative开发应用

目录安装 Istio安装 Knative玩转 helloworld-goWordPress 实战创建 Kubernetes 集群确保 Kubernetes 集群创建的时候已经选择了启用日志服务确保 Kubernetes 集群和 OSS 在一个 regionKubernetes 集群创建的时候需要开启 kube-apiserver 公网访问提前帮用户配置好 kubeconfig 命令行安装 Istio安装 Istio 时注意以下几点: 默认要安装 gateway日志服务和 Xtrace 要提前开通,Istio 需要使用 ZipKin v1 向 Xtrace 汇报监控数据在容器服务集群管理页面可以直接在目标集群上部署 Istio 安装 Knative选择好目标集群使用一键部署功能直接安装即可, 安装文档 玩转 helloworld-go配置日志采集策略部署 Helloworld监控告警调用链压测数据展示日志管理日志服务控制台: https://sls.console.aliyun.com本示例以容器标准输出采集为例进行展示,详细设置步骤可以参考日志服务文档根据 Kubernetes 集群 ID 找到对应的日志服务 Project创建一个新的 Logstore设置数据导入方式 选择 Docker标准输出 配置容器标准输出日志采集策略{ "inputs": [ { "detail": { "IncludeEnv": { "K_SERVICE": "helloworld-go" }, "IncludeLabel": {}, "ExcludeLabel": {} }, "type": "service_docker_stdout" } ], "processors": [ { "detail": { "KeepSource": false, "NoMatchError": true, "Keys": [ "time", "level", "msg" ], "NoKeyError": true, "Regex": "(\\d+-\\d+-\\d+ \\d+:\\d+:\\d+)\\s+(\\w+)\\s+(*)", "SourceKey": "content" }, "type": "processor_regex" } ]}分别为相应的键值 time、level 和 msg 设置数据类型 ...

June 17, 2019 · 2 min · jiezi

支付宝技术风险负责人陈亮把事情做到极致技术的差异性才会体现出来

“很多事情,说出来很多人都在做,但是只有真正做到极致,技术的差异性才会体现出来”,蚂蚁金服技术风险部研究员陈亮(花名:俊义)在接受 InfoQ 采访时如是说道。在此前的支付宝技术嘉年华,InfoQ 对支付宝数次技术架构升级的见证者及主导架构师陈亮进行了独家采访,首次系统了解稳定支撑“双十一”等多次实战背后的支付宝技术风险体系。 支付宝技术风险体系2007 年,陈亮加入支付宝,负责支付宝搜索及通信中间件架构。在之后的十年时间里,陈亮先后负责过支付宝交易拆分整体架构,这成为支付宝数据库拆分架构标准;支付宝三代架构单元化及容灾整体架构,实现异地多活,这成为支付宝单元化架构标准。如果简单总结在支付宝工作的前十年,陈亮表示: 前十年,我一直在做可扩展性相关的工作。在这期间,问题和需求驱动占据上风。陈亮回忆道:“最初的支付宝是单体架构,一个小型机加两个 Java 写的 APP,那年 DBA 就找过来说如果不进行数据库拆分,很难扛住业务发展”。 经过系列改造,这一工作终于完成。当时,陈亮以为这个架构起码可以支撑支付宝未来五到十年的发展。然而,双十一很快就来了,超大规模瞬时流量的冲击对架构提出了全新挑战,整个团队又开始马不停蹄地进行异地多活相关项目研发。 彼时,支付宝有两个主要应对技术风险的团队,一个叫技术质量团队,另一个则是运维团队。技术质量主要是各种功能测试,并解决程序 Bug、故障等问题;运维团队主要是生产偏基础设施以及应用、DB 运维管理保障,同时也会自发性地做一些技术风险相关的事情,但并未形成体系化的技术风险组织阵型及打法。 2013 年,支付宝技术团队提出质量 2.0 战略,其目的是希望在技术风险领域有一些延展,体系化沉淀 Bug 检测等方面的能力。自此,支付宝的技术风险体系建设逐渐步入正轨。 组织架构演进 2014 年,质量技术部成立希望从全域视角解决技术风险问题。但是,质量技术部并没有运维团队,主要就是通用质量检测和高可用保障相关的技术解决方案,并驱动各业务部门的技术团队落地。当时,质量技术部人员并不多,是一个小而精悍的中台部门。 经过一年多的发展,质量技术部发现仅仅依靠质量技术并不能解决生产上的各种故障风险。虽然,质量技术部会关注生产研发过程,但主要精力在于对各业务技术团队输出技术风险,比如高可用及通用质量检测的解决方案,高可用及资金保障方面尚未出现成型的平台体系。虽然当时的全链路压测和持续集成平台已有所成型,但关于高可用等并没有成型的平台。 当时,技术团队判断,不能只从质量角度看风险,而需要从更高的维度和更全面的视角看待风险。2015 年,质量技术部升级为技术风险部,专注研发及架构技术风险问题,做相应的解决方案和落地平台。 2016 年,陈亮一手打造了支付宝的 SRE(Site Risk Engineer,参考谷歌的 Site Reliability Engineer)体系。技术风险部增加 PE 和 DBA 团队,PE 团队直接对生产环节中的运营、操作等做技术风险防控,整个大团队的职能属于 SRE。据了解,这也是国内第一个 SRE 团队。 陈亮发现,传统的运维思路和文化已经无法彻底解决支付宝的稳定性问题,因此需要成立 SRE 团队。事实上,传统的运维方式侧重于靠人肉解决风险,不管是调参还是更改配置,都无法从本质上解决支付宝的稳定性问题,相反会让运维人员的工作成就感很低。说到底,运维领域的问题终究还是软件问题,需要建立软件平台更好地管理风险。 在组建 SRE 团队的过程中,陈亮认为最难的反而不是技术层面的推进,而是让团队工程师,包括整个公司认同 SRE 的价值,这需要让所有人理解 SRE 可以解决哪些新的问题以及传统的思维方式为何不可取。 据了解,支付宝的 SRE 团队主要由研发、运维和测试人员组成,八成运维人员都需要写稳定性相关的代码。团队组建完成即全面开展故障自动定位、自适应容灾、防抖、精细化高可用等工作。其中,防抖要保证任何网络或基础设施抖动,用户都无感知;精细化高可用,又叫单笔高可用,其颗粒度可以精准到用户的每一笔交易,远远优于行业内的机房级高可用。 2016 年,SRE 团队建设了很多平台和能力。同时,技术团队发现了两个极为重要的现象,一是生产故障不是必然的,通常都是偶然性的;二是生产故障是低频的。这带来的问题就是故障样本很少,没有办法证明在真实故障到来时平台是否具备能力应对。也就是说,SRE 团队建设的防御系统的可靠性,无法充分验证。 2017 年,SRE 团队成立了专门的、独立职能的技术蓝军,其主要的工作就是发掘防御系统的弱点并发起真实的攻击。技术蓝军并不对各业务方负责,只对这套防御系统的稳定性和可靠性负责。 在技术蓝军看来,发生故障是必然的,只是时间早晚而已,技术蓝军会想尽办法触发这些故障,以保障在故障真实发生时,团队有足够的应付能力。目前,全栈级的技术攻防演练每周都在进行,而故障防御系统及不断优化的高可用架构则是由 SRE 团队的红军与各业务深度合作,沉淀、构建出来的。 ...

June 14, 2019 · 1 min · jiezi

Istio-on-ACK集成生态1-集成TSDB助力可观测性存储

阿里云容器服务Kubernetes(简称ACK)支持一键部署Istio,可以参考文档在ACK上部署使用Isito。Istio on ACK提供了丰富的监控能力,为网格中的服务收集遥测数据,其中Mixer是负责提供策略控制和遥测收集的Istio组件。使用Prometheus进行监控是Istio提供的监控能力之一。Prometheus是一个开源的监控和报警系统,Prometheus依赖少,功能齐全,广泛用于Kubernetes集群的监控系统中。Istio自0.8版本开始默认将Prometheus包含在内,Mixer支持对接到Prometheus监控设施的Adapter。用户可以通过查询service或pod看到Prometheus的运行状态和地址。也可以通过简洁明了的Prometheus的UI界面查看监测数据。 Prometheus的存储挑战及解决方案Prometheus的本地存储设计可以减少其自身运维和管理的复杂度,能够满足大部分用户监控规模的需求,但是本地存储也意味着Prometheus无法持久化数据,无法存储大量历史数据,同时也无法灵活扩展。Prometheus本身没有尝试解决以上问题,而是通过定义一组remote storage adapter标准接口,让用户可以基于这组标准接口自主决定将Promthues中的监控样本数据存储至第三方的远端存储服务中,来解决本地存储带来的问题。 TSDB for Prometheus是一种高性能,低成本,稳定可靠的在线时序数据库服务,通过内置实现的Prometheus的remote storage adapter,天然原生支持作为Promtheus的第三方在线远端存储服务。 相较于其他第三方远端存储而言,TSDB for Prometheus具有集成程度高,同时支持读写等优势。 集成程度高目前Prometheus对接第三方存储系统的主流做法是实现一个独立于第三方存储系统的remote storage adapter, 这个adapter需要单独部署和运维,另外单独部署的remote storage adapter还存在单点故障和读写性能问题。TSDB for Prometheus在服务端内置实现的Prometheus remote storage adapter,只需在Prometheus的配置文件prometheus.yaml中修改下远程读写配置,即可原生支持Prometheus直接读写TSDB,集成程度高,无需额外单独部署adapter,极大地降低了adapter的单点故障风险和运维成本。 同时支持读写当前一些第三方远端存储仅支持Prometheus将监控样本数据写入,而不支持读取。比如对于OpenTSDB、Graphite和Elasticsearch等第三方存储,Prometheus社区提供的adapter只支持写入模式,不支持读取模式。而TSDB for Prometheus同时支持读写。如要了解更多第三方存储系统对于Prometheus读写的支持程度,请参考Remote Endpoints and Storage。TSDB for Prometheus时序时空数据库(Time Series & Spatial Temporal Database,简称 TSDB)是一种高性能、低成本、稳定可靠的在线时序时空数据库服务,提供高效读写、高压缩比存储、时序数据插值及聚合计算等服务。TSDB 具备秒级写入百万级时序数据的性能,提供高压缩比低成本存储、预降采样、插值、多维聚合计算、可视化查询结果等功能。 TSDB for Prometheus是阿里云时序时空数据库TSDB为Prometheus提供的一种高性能、低成本、稳定可靠的在线远端存储服务,具备以下能力: 提供高效读写、高压缩比存储的能力,可无缝被Prometheus集成,在协议上原生支持Prometheus远端存储对接至TSDB。解决了以往需要为Prometheus额外开发remote storage adapter的问题,极大的降低了Prometheus远端存储对接TSDB的成本。TSDB for Prometheus最大程度的兼容Prometheus的PromQL查询语法,从而降低了用户的开发,迁移和维护成本。解决Prometheus local stroge 无法存储大量历史数据的场景,且无法扩展的问题。通过内置实现的Prometheus的remote storage adapter,天然原生支持作为Promtheus的第三方在线远端存储服务。相较于其他第三方远端存储而言,TSDB for Prometheus具有集成程度高,同时支持读写等优势。TSDB for Prometheus的使用要求具体可以参见使用要求 阿里云提供的不同规格的TSDB实例,设置了不同的最大写入TPS,避免过大TPS导致TSDB示例不可用,保护TSDB实例正常运行。当写入TPS超过TSDB实例允许的最大TPS时,将触发TSDB实例限流保护规则,会造成写入失败异常。因此需要根据TSDB实例规格来调整Prometheus的remote_write配置,从而实现平稳可靠的将Prometheus采集到的指标写入TSDB中。 关于Remote Write配置,除了参考Prometheus官方提供的Remote Write配置说明之外,还可以参考Prometheus对接阿里云TSDB时的写入配置最佳实践。 创建TSDB实例创建一个TSDB实例非常简单,登录TSDB 控制台,参照创建实例文档即可创建。获取开通的TSDB实例的地址,可以参考TSDB官方文档快速入门 确认Prometheus所在机器能够正常访问TSDB实例。直接使用http访问TSDB实例的地址,如果能够得到包含”Welcome to use the TSDB”的字符串,表示Prometheus所在机器能够正常访问TSDB实例。 ...

June 11, 2019 · 1 min · jiezi

移动研发-DevOps-落地实践

作者:姚兰天(十镜),蚂蚁金服技术专家。概要:传统的研发模式已经无法适应企业在数字化转型中快速迭代以及研发协同的要求,建设符合业务场景特性和有效支撑高并发、持续迭代集成需求的研发效能实践迫在眉睫。本文将围绕支付宝如何随着移动市场的高速发展,逐步沉淀优化出适用业务发展需求的研发效能实践。 现场视频):http://t.cn/Ai9HuCNT 大家好,我是来自支付宝终端工程技术团队的十境。本文将带领大家了解支付宝移动端如何随着移动市场的告诉发展,逐步沉淀优化出适用业务发展需求的研发效能实践。 0. 背景如何解决百万级代码的极速构建?如何让上百开发者在同一个 App 上高效研发协同?如何保障代码频繁变更下的交付质量?显然,传统的研发模式已经无法适应企业在数字化转型中快速迭代以及研发协同的要求,建设符合业务场景特性和有效支撑高并发、持续迭代集成需求的研发效能实践迫在眉睫。 1. 研发协作平台现状关于支付宝在移动端研发平台构建的历程,首先我们先展开看看目前平台的现状,并讲述如何参考 DevOps “三步工作法” 来正向建模我们的交付价值流,以及这些活动中比较核心的分支模型,构建,持续集成等。 研发协作平台大概从 2014 年开始建设,如今支持的 iOS 和 Android 客户端代码量都已经超过 300w 行,拆分的 Bundle 数量也都在 300 个以上。我们每周的构建次数在 1.4W,安装包平均每天会灰度 2~3 次,开发测试同学达到近千人的规模。 我们支撑了蚂蚁集团支付宝、网商银行、财富、口碑等产品的交付,支持的技术栈从最开始的 Android 和 iOS,演进到厂商 SDK、小程序、IoT 及桌面应用等。在这些能力输出的下层是我们沉淀的一套研发协作流程,从需求到开发、测试、交付、及发布后的反馈闭环。 支付宝业务的飞速发展,从工具到超级 App,代码量猛增到 300W+。技术架构上,采用了模块化动态加载的技术,这就给我们提了一个问题,如何将 300+ 个 Bundle,在不同的团队里开发,集成,变成一个高质量的 App 推送到用户手机上。 2. DevOps 三步工作法 DevOps 三步工作法,第一步,我们正向价值流建模,把研发划分为 5 个阶段(需求阶段、开发阶段、测试阶段、集成阶段以及发布阶段),定义每个阶段的准入准出标准。比如需求分析的结果需要拆分到 User Story 级别,通过大家需求评审,达成一致。接着,每个阶段我们提炼出最重要的活动,比如开发阶段,开发同学每天最多的就是写代码,代码 Review,以及代码 MR/Push 后触发的自动化流水线,如编译、扫描、自动化测试等。这些阶段和每个阶段的活动以及人员之间的协作,就构成了我们交付大图的脉络,即我们常说的价值流。 通过正向价值流的建模,结合团队的开发实践,便可以得到研发协作平台产品的一个信息架构图。 如上图所示,随时间演进,我们沉淀出了一套产品信息图:从最开始仅仅是安装包构建的一个在线工具,到产物管理,版本管理,架构拆分后的模块信息、模块构建管理,根据构建的产物及场景的不同,抽象出了构建配置、渠道配置、持续集成的配置,当然还有其它元数据如证书信息的配置。 我们参考了敏捷、Scrum 实践,抽象出迭代的概念来组织每个模块涉及的资源如代码仓库、需求、缺陷、任务、持续集成流水线还有最重要的团队和人员。发布定义了我们交付的产物,同时也是各团队工作集成到一起的大容器。 这是我们研发协作平台的门户首页,开发者能直观地看到自己关注项目的日常发布、迭代信息,以及每天需要解决的待办等,每个类目和我们上一页提炼的信息架构相对应。 拆解「依赖配置」 前面提到我们通过架构拆分,团队模块化协作的方式来应对激增的业务需求。那么之所以有这张截图,是想让大家对我们的依赖配置有个直观的感受,每个模块的产物可以理解为一个 Zip 包,在某一个安装包发布中管理这样由 300 多个 Bundle 构成的一个依赖列表。我们的需求集成某种意义上就是这个依赖列表中中模块版本的升级。模块拆分也让我们的小批量快速交付成为得以践行、拥有 2 周发布一个大版本的能力。 ...

June 10, 2019 · 1 min · jiezi

自动化日志收集及分析在支付宝-App-内的演进

背景结合《蚂蚁金服面对亿级并发场景的组件体系设计》,我们能够通盘了解支付宝移动端基础组件体系的构建之路和背后的思考,本文基于服务端组建体系的大背景下,着重探讨“自动化日志手机与分析”在支付宝 App 内的演进之路。 支付宝移动端技术服务框架 这是整个支付宝移动端无线基础团队的技术架构图,同时蚂蚁金服体系内的其他业务 口碑、网商银行、香港支付宝、天弘基金等) 通过移动开发平台 mPaaS进行代码开发、打包、灰度发布、上线、问题修复、运营、分析。因此,mPaaS 源自于支付宝移动端的核心技术架构,并在 App 全生命周期的每个环节提供特定的能力支持。接下来,我们将着重分享“日志诊断”和“移动分析”两个能力背后的架构演进和选型思考。 支付宝移动端技术服务框架:数据分析框架 如图所示,即数据分析能力的技术架构图,其中“数据同步”、“埋点SDK”、“日志网关”是移动端专属的能力,其余部分是所有的数据分析平台都必须具备的数据结构。 1. 日志采集 接下来我们重点分析支付宝移动端的日志采集框架,首先第一部分是“日志 SDK”,日志 SDK 会向业务层提供一个埋点接口,使用起来就和 Java 里面的 logger.info 的感觉一样:业务层只需要把想记录的信息传递给日志 SDK。日志 SDK 会在拿到业务日志后,去系统内部获取相关的系统级别的上下文信息,比如机型、操作系统版本、App 版本、手机分辨率、用户ID (如果用户登录了)、设备ID、上一个页面、当前页面等,接着把这些信息与业务日志内容整合成一个埋点,然后记录到设备的硬盘上。对,只是记录到硬盘上,并没有上报到服务端。 日志 SDK 会在合适的时机,去和日志网关交互,判断获取什么样的日志、什么级别的日志可以上报。如果可以上报,是以什么频率上报、在什么网络条件下上报。因此通过日志 SDK 与日志网关的交付,我们可以来实现日志的策略式降级。日志的策略式降级这点对于支付宝特别重要,因为目前支付宝的体量,日常的日志上报量为约 30W 条日志/s;而在大促的时候,日志量会是日常的几十倍! 所以,如果大促期间不采用任何的日志降级策略的话,我们的带宽会被日志打包,支付宝的正常业务功能就不可用了。 由此,我们可以总结,在大促高并发场景下,我们需要只保留关键日志的上传,其余日志统统降级。即使是日常业务处理,我们也只允许日志在 WIFI 条件下上报,防止发生流量相关的投诉。 埋点网关除了提供日志上报的策略开关能力之外,就是接收客户端的日志。它在接受到客户端日志之后,会对日志内容进行校验,发现无效的日志会丢弃掉。而对有效合法的埋点,会根据客户端上报的公网 IP 地址,反解出城市级别的地址位置信息并添加到埋点中,然后将埋点存放在它自己的硬盘上。 2. 埋点分类 经过多年的实践,支付宝把日志埋点分为了四类。 (1)行为埋点:用于监控业务行为,即业务层传递的日志埋点属于行为埋点,行为埋点属于“手动埋点”,需要业务层开发同学自己开发。不过也不是全部的业务行为都需要业务方手动开发,有一些具备非常通用性的业务事件,支付宝把它们的埋点记录放到了框架层,如报活事件、登录事件。因此,行为埋点也可以叫做 "半自动埋点"。 (2)自动化埋点:属于“全自动化埋点”,用于记录一些通用的页面级别、组件级别的行为,比如页面打开、页面关闭、页面耗时、组件点击等。 (3)性能埋点:属于“全自动化埋点”,用于记录 App 的电量使用情况、流量使用、内存使用、启动速度等。 (4)异常埋点:属于“全自动化埋点”,严格上讲,也算是性能埋点的一种。但是它记录的是最关键的最直接影响用户的性能指标,比如 App 的闪退情况、卡死、卡顿情况等。这类埋点,就属于即时大促期间也不能降级的埋点! 图中的代码示例即为一条行为埋点样例,大家可以看到,埋点实际上就是一条 CSV 文本。我们可以看到里面有日志网关添加进行的地址位置信息内容,也有日志 SDK 给添加的客户端设备信息。 3. 日志处理模型 下面我们来整体了解支付宝内部日志处理的通用流程: (1)日志切分 我们已经了解到,埋点实际上即为一段 CSV 文本。而所谓日志切分呢,即将 CSV 格式的文本转成 KV,通俗点说就是内存里面的 HASHMAP。这个切分的过程,可以直接根据逗号进行切换,当然也还有很多其他的办法。 ...

May 30, 2019 · 2 min · jiezi

容器监控实践Cortex

一.概述cortex:一个支持多租户、水平扩展的prometheus服务。 当时调研cortex其实是因为看到了Weave Cloud这个商业产品中的监控模块介绍,weave也叫weave works,官方地址是:https://cloud.weave.works,是一个专注于容器微服务的paas平台。 WeaveCloud在监控模块最大化利用了Prometheus,并在其基础上添加了很多组件,实现了多租户管理、高可用的监控集群。其使用的核心监控组件就是cortex。 本文主要分享的是cortex的运行机制,关于Weave Cloud的产品定位和功能可以看下后续的文章:[商业方案-weave work]() Cortex是一个CNCF的沙盒项目,目前被几个线上产品使用:Weave Cloud、GrafanaCloud和FreshTracks.io 为什么不直接运行Prometheus,而用Cortex? ps:来自cortex kubecon大会演讲 作为服务,cortex提供了鉴权和访问控制数据永久保留,状态能够被管理提供持久化、高可用、伸缩性提供更好的查询效率,尤其是长查询二.主要功能针对以上需求,Cortex提供的主要功能或特色如下: 支持多租户:Prometheus本身没有的租户概念。这意味着,它无法对特定于租户的数据访问和资源使用配额,提供任何形式的细粒度控制。Cortex可以从多个独立的prometheus实例中获取数据,并按照租户管理。长期存储:基于远程写入机制,支持四种开箱即用的长期存储系统:AWS DynamoDB、AWS S3、Apache Cassandra和Google Cloud Bigtable。全局视图:提供所有prometheus server 整合后的时间序列数据的单一,一致的“全局”视图。高可用:提供服务实例的水平扩展、联邦集群等最大化利用了Prometheus相似的竞品: Prometheus + InfluxDB:使用InfluxDataPrometheus + Thanos:长期存储、全局视图Timbala:多副本、全局视图,作者是Matt BostockM3DB:自动扩缩容,来自uber产品形态ps:来自weave work上试用监控模块时的截图 1.安装监控的agent: 2.概览视图 3.资源监控面板 4.监控详情页面 5.添加监控 6.配置报警 在k8s集群中部署所需要的yaml列表为: [https://github.com/weaveworks...](https://github.com/weaveworks...) 部署的agent时的脚本内容是: #!/bin/shset -e# Create a temporary file for the bootstrap binaryTMPFILE="$(mktemp -qt weave_bootstrap.XXXXXXXXXX)" || exit 1finish(){ # Send only when this script errors out # Filter out the bootstrap errors if [ $? -ne 111 ] && [ $? -ne 0 ]; then curl -s >/dev/null 2>/dev/null -H "Accept: application/json" -H "Authorization: Bearer $token" -X POST -d \ '{"type": "onboarding_failed", "messages": {"browser": { "type": "onboarding_failed", "text": "Installation of Weave Cloud agents did not finish."}}}' \ https://cloud.weave.works/api/notification/external/events || true fi # Arrange for the bootstrap binary to be deleted rm -f "$TMPFILE"}# Call finish function on exittrap finish EXIT# Parse command-line argumentsfor arg in "$@"; do case $arg in --token=*) token=$(echo $arg | cut -d '=' -f 2) ;; esacdoneif [ -z "$token" ]; then echo "error: please specify the instance token with --token=<TOKEN>" exit 1fi# Notify installation has startedcurl -s >/dev/null 2>/dev/null -H "Accept: application/json" -H "Authorization: Bearer $token" -X POST -d \ '{"type": "onboarding_started", "messages": {"browser": { "type": "onboarding_started", "text": "Installation of Weave Cloud agents has started"}}}' \ https://cloud.weave.works/api/notification/external/events || true# Get distributionunamestr=$(uname)if [ "$unamestr" = 'Darwin' ]; then dist='darwin'elif [ "$unamestr" = 'Linux' ]; then dist='linux'else echo "This OS is not supported" exit 1fi# Download the bootstrap binaryecho "Downloading the Weave Cloud installer... "curl -Ls "https://get.weave.works/bootstrap?dist=$dist" >> "$TMPFILE"# Make the bootstrap binary executablechmod +x "$TMPFILE"# Execute the bootstrap binary"$TMPFILE" "--scheme=https" "--wc.launcher=get.weave.works" "--wc.hostname=cloud.weave.works" "--report-errors" "$@"三.实现原理Cortex与Prometheus的交互图: ...

May 27, 2019 · 2 min · jiezi

容器监控实践Dockbix

一.概述Dockbix意为docker+zabbix,即使用zabbix来监控docker容器的插件或者模块,既然有专业的cadvisor、prometheus等容器监控方案,为什么还要用传统的zabbix呢? 在docker刚出现时,还没有专业的容器监控方案公司已有zabbix的成熟实践,想直接集成到zabbix中(虽然不太优雅)使用zabbix来监控docker有几种方案,比如: 自己写agent,利用docker的api获取stats信息,暴露api接口给zabbix采集使用zabbix的Module,将docker的采集展示集成到现有的zabbix系统中如何使用写APIpython sdk:https://docker-py.readthedocs.io/en/stable/containers.html#docker.models.containers.Container.stats stats(**kwargs)Stream statistics for this container. Similar to the docker stats command.Parameters: decode (bool) – If set to true, stream will be decoded into dicts on the fly. Only applicable if stream is True. False by default.stream (bool) – If set to false, only the current stats will be returned instead of a stream. True by default.Raises: docker.errors.APIError – If the server returns an error.如计算cpu: ...

May 27, 2019 · 1 min · jiezi

借助混沌工程工具-ChaosBlade-构建高可用的分布式系统

在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战。在可控范围或环境下,使用 ChaosBlade 工具,对系统注入各种故障,持续提升分布式系统的容错和弹性能力,以构建高可用的分布式系统。 ChaosBlade 是什么?ChaosBlade 是一款遵循混沌工程实验原理,建立在阿里巴巴近十年故障测试和演练实践基础上,并结合了集团各业务的最佳创意和实践,提供丰富故障场景实现,帮助分布式系统提升容错性和可恢复性的混沌工程工具。点击这里,了解详情。 ChaosBlade 无需编译,下载解压即可使用,支持基础资源、Java 应用、容器服务类的混沌实验,特点是操作简洁、无侵入、扩展性强。 ChaosBlade @GitHub,点击进入 下面我们以微服务分布式系统举例,一步一步构建高可用的分布式系统。 构建高可用的分布式系统ChaosBlade 的使用方式 ChaoBlade 通过 CLI 方式调用,比如我们模拟 A 服务调用 B 提供的 com.alibaba.demo.HelloService 服务下的 hello 服务延迟 3 秒,我们可以在 B 应用上注入延迟故障,仅需两步操作:第一步:准备阶段。由于 Java 应用的故障注入是通过 Java Agent 机制实现,所以首先要先挂载 agent,执行的命令是 blade prepare jvm --process <PROCESS NAME OF B APPLICATION>第二步:执行阶段,注入故障。执行命令是 blade create dubbo delay --time 3000 --service com.alibaba.demo.HelloService --methodname hello --provider,即对 B 服务提供方提供的 com.alibaba.demo.HelloService#hello 服务注入 3 秒延迟。 ChaosBlade 使用简洁,如果想了解命令的如何使用,可在命令后面添加 -h 参数,比如 blade create dubbo delay -h。更详细的 chaosblade 操作,可详见新手指南 ...

May 14, 2019 · 2 min · jiezi

处理网络超时问题的最佳实践

对于云上的用户来说,业务日志里面报超时问题处理起来往往比价棘手,因为1) 问题点可能在云基础设施层,也有可能在业务软件层,需要排查的范围非常广;2) 这类问题往往是不可复现问题,抓到现场比较难。在本文里就分析下如何来分辨和排查这类问题的根本原因。 业务超时 != 网络丢包由于业务的形态不同,软件实现语言和框架的不同,业务日志中打印出的信息可能是各不相同,比如如下关键字: "SocketTimeOut", "Read timed out", "Request timeout" 等从形式看都属于网络超时这一类,但是需要明确一个概念:这类问题是发生的原因是请求超过了设定的timeout时间,这个设置有可能来自客户端,服务器端或者网络中间节点,这是直接原因。网络丢包可能会导致超时,但是并不是充分条件。总结业务超时和网络丢包的关系如下: 网络丢包可能造成业务超时,但是业务超时的原因不一定是丢包。明确了这个因果关系后,我们再来看怎么分析业务超时。如果武断地将业务超时等同于网络抖动丢包,那这个排查分析过程就完全错过了业务软件层本身的原因,很容易进入困局。 本文会从云基础设施层和业务软件层对业务超时做分析,总体来讲基础设置层面的丢包原因相对容易排查,阿里云有完善的底层监控,根据业务日志报错的对应时间段,从监控数据中可以确定是否有基础设施网络问题。而业务层的超时通常是软件层面的设置,和软件实现及业务形态都有关系,这种往往是更加难以排查的。 网络丢包为什么导致业务超时网络抖动可能造成业务超时,其主要原因是网络抖动会带来不同程度的延迟。本文以互联网大部分应用以来的TCP为对象来介绍,一个丢包对数据传输的完整性其实是没有影响的,因为TCP协议本身已经有精密的设计来处理丢包,乱序等异常情况。并且所有重传的处理都在内核TCP协议栈中完成,操作系统用户空间的进程对这个处理实际上是不感知的。丢包唯一的副作用的就是会增加延迟,如果这段延迟的时间足够长,达到了应用进程设置的某个Timeout时间,那么在业务应用侧表现出来的就是业务超时。 丢包出现时会不会发生超时,取决于应用进程的Timeout设置。比如数据传输中的只丢了一个TCP数据包,引发200 ms后的超时重传: 如果应用设置的Timeout为100 ms,TCP协议栈没有机会重传,应用就认为超时并关闭连接;如果应用设置的Timeout为500 ms,则TCP协议栈会完成重传,这个处理过程对应用进程透明。应用唯一的感知就是处理这次报文交互比基线处理时长多了200 ms,对于时间敏感度不是非常高的应用来说这个影响非常小。延迟到底有多大?在设置应用进程Timeout时间时有没有可以参考的定量值呢?虽然TCP中的RTT/RTO都是动态变化的,但TCP丢包的产生的影响可以做一定的定量总结。 对丢包产生的延迟主要有如下两类: TCP建连超时。如果网络抖动不幸丢掉了TCP的第一个建连SYN报文,对与不太老的内核版本来说,客户端会在1秒(Draft RFC 2988bis-02中定义)后重传SYN报文再次发起建连。1秒对于内网环境来说非常大,对于阿里云一个区域的机房来说,正常的RTT都是小个位数毫秒级别,1秒内如果没有丢包足够完成百个数据报的交互。TCP中间数据包丢包。TCP协议处理中间的数据丢包有快速重传和超时重传两种机制。快速重传通常比较快,和RTT相关,没有定量的值。超时重传 (RTO, Retrasmission Timeout) 也和RTT相关,但是Linux中定义的RTO的最小值为,TCP_RTO_MIN = 200ms。所以在RTT比较小的网络环境下,即使RTT小于1ms,TCP超时重传的RTO最小值也只能是200ms。这类丢包带来的延迟相对小。除了丢包,另外一类比较常见的延迟是TCP Delayed ACK带来的延迟。这个和协议设计相关,和丢包其实没有关系,在这里一并总结如延迟定量部分。在交互式数据流+Nagle算法的场景下比较容易触发。Linux中定义的Delayed ACK的最小值TCP_DELACK_MIN是40 ms。 所以总结下来有如下几个定量时间可以供参考: 40 ms, 在交互数据流中TCP Delayed ACK + Nagle算法开启的场景,最小delay值。200 ms,在RTT比较小的正常网络环境中,TCP数据包丢包,超时重传的最小值。1 s,较新内核版本TCP建立的第一个SYN包丢包时的重传时间,RFC2988bis中定义的initial RTO value TCP_TIMEOUT_INIT。3 s, 较老内核版本TCP建立的第一个SYN包丢包时的重传时间,RFC 1122中定义的initial RTO value TCP_TIMEOUT_INIT。云基础设施网络丢包基础设施网络丢包的原因可能有多种,主要总结如下3类: 云基础设施网络抖动 网络链路,物理网络设备,ECS/RDS等所在的宿主机虚拟化网络都有可能出现软硬件问题。云基础设施已经做了完备的冗余,来保证出现问题时能快速隔离,切换和恢复。 现象: 因为有网络冗余设备并可以快速恢复,这类问题通常表现为某单一时间点网络抖动,通常为秒级。抖动的具体现象是在那个时段新建连接失败,已建立的连接中断,在业务上可能表现为超时。影响面: 网络设备下通常挂很多主机,通常影响面比较大,比如同时影响多个ECS到RDS的连接。 云产品的限速丢包 很多网络云产品在售卖的时候有规格和带宽选项,比如ECS, SLB, NAT网关等。当云产品的流量或者连接数超过规格或者带宽限制时,也会出现丢包。这种丢包并非云厂商的故障,而是实际业务流量规模和选择云产品规格时的偏差所带来。这种问题通常从云产品提供的监控中就能分辨出来。 现象: 当流量或者连接数超过规格时,出现流量或者连接丢弃。问题可能间断并持续地出现,网络流量高峰期出现的概率更大。影响面: 通常只影响单一实例。但对于NAT网关做SNAT的场景,可能影响SNAT后的多个实例。 运营商网络问题在走公网的场景中,客户端和服务器之间的报文交互往往要经过多个AS (autonomous system)。若运营商中间链路出现问题往往会导致端到端丢包。 ...

May 14, 2019 · 1 min · jiezi

全流程上线平台

整体:https://segmentfault.com/a/11...。服务化建设,服务多,上线和部署成本高,本文介绍全流程上线部署平台的设计方案。 架构 线上接入层:nginx攻防(白名单,黑名单,封禁,限流),机房切换。运行层:包(一个完整 可运行的业务代码+基础环境+基础包)+容器+资源隔离+部署。容器见:运行层和接入层联动平台代码版本,配置存储;回滚;分级发布,跑case,监控文件发送:产品线生产数据①之后,调用文件飞线的客户端(图中为orp_scp.sh),指定好数据源,发到服务端(图中为中控机),服务端从ORP的基础设施NamingService读取产品线所在的机器及相关路径,然后进行部署(③④⑤)。产品线用户可以通过查看ORP平台,获得部署的进度和部署的结果(成功或失败) 定时任务:添加任务:发到任务平台,注册到计时器,存到任务集独立计时器触发,任务平台去任务集中取任务部署到任务平台,工作。日志重建线上日志采集agent。发到传输集群。消费到日志机器集群管理机器 backpool->online->故障池->backpool容器 创建资源(更新nameserver,新增ip)->迁移/释放=》更新nameserver(监控)=》更改接入层router这里做机房切换。节点监控改router内部可以服务发现+rpc,每次获取nameserver转发,或Pushnameserver 发给mq 发给接入层/监控等部署提交到任务队列(有序)-》mq=》部署拉取=》线上脚本执行重启等deploy会先将任务存进任务队列,然后推给消息中间件。消息中间件后端会重新发回deploy(如果失败,消息中间件负责重试)。Deploy会对文件进行下载、打包封装,然后调用archer将文件分发到机器上的临时目录上。最终调用deploy的后置脚本进行最终的部署。详细公司内部部署方案过程0.外部请求输1.打包,打包机将部署包存放在指定的Artifact上2.发起上线Api实现上线的控制逻辑,相当于传统的中控Api向部署Agent发送上线指令3.执行上线部署Agent下载部署包部署Agent指定上线业务部署Agent向Api上报 上线的执行结果agentbuild:完成 源文件的build,产出可执行文件完成 配置管理的替换,产出可用配置文件完成 进程托管配置supervisord.conf的生成完成 服务描述文件me.json的生成监控架构 日志agentcollector是用户上传数据等另一种输入nsq:负责接收,排队,消息投递;消息缓存存储transfer:按照一致性哈希规则进行数据分片,并将分片后的数据推送到graph中存储,基于RRD规则,对数据进行简单处理,包括时间戳按照step对齐、添加必须的字段(MAX/MIN等)graph,接收transfer上报的数据,raph推送数据到index,中间通过nsqd 做消息队列(没有proxy转发),减轻index的实时压力Round Robin是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置RRDtool 要求定时获取数据,如果在一个时间间隔内(heartbeat)没有收到值,则会用 UNKN (unknow)代替报警1).monitor-judge通过config获取报警配置策略通过index获取索引,通过query查询数据judge数据直接推送到nsqd的4151端口(nsqd广播数据到lookupd的4160端口)judge产生报警事件2).odin-monitor-alarm通过monitor-web接口获取报警策略、屏蔽策略通过nsq的lookupd(4161端口)查询对应nsqd地址并消费报警事件通过本机部署的redis(监听端口6379),作缓存报警事件写入到后端数据库中(dba维护)报警通知 经过nginx做中转,转发到notify集群

May 14, 2019 · 1 min · jiezi

大侦探福老师幽灵Crash谜踪案

闲鱼Flutter技术的基础设施已基本趋于稳定,就在我们准备松口气的时候,一个Crash却异军突起冲击着我们的稳定性防线!闲鱼技术火速成立侦探小组执行嫌犯侦查行动,经理重重磨难终于在一个隐蔽的角落将其绳之以法! 幽灵Crash问题要从闲鱼Flutter基础设施上一次大规模升级说起。2018年我们对闲鱼的Flutter基建作了比较大的重构,目标在于提高基建的稳定性和可扩展性。这个过程当然是挑战重重,在上一次大规模的重构集成发版后,我们虽然没有发现非常明显的异常问题,但是Crash率却出现了一个比较明显的增长。虽然总体数值还在可控范围之内,但这一个Crash却占据了几乎一大半。这个问题引起了我们警觉,我们立刻成立专项小组重点进行排查。 一般Crash Log能够为我们定位Crash提供主要信息,我们一起看看这个Crash的Log: Thread 0 Crashed:0 libobjc.A.dylib 0x00000001c1b42b00 objc_object::release() :16 (in libobjc.A.dylib)1 libobjc.A.dylib 0x00000001c1b4338c (anonymous namespace)::AutoreleasePoolPage::pop(void*) :676 (in libobjc.A.dylib)2 CoreFoundation 0x00000001c28e8804 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ :28 (in CoreFoundation)3 CoreFoundation 0x00000001c28e8534 __CFRunLoopDoTimer :864 (in CoreFoundation)4 CoreFoundation 0x00000001c28e7d68 __CFRunLoopDoTimers :248 (in CoreFoundation)5 CoreFoundation 0x00000001c28e2c44 __CFRunLoopRun :1880 (in CoreFoundation)6 CoreFoundation 0x00000001c28e21cc _CFRunLoopRunSpecific :436 (in CoreFoundation)7 GraphicsServices 0x00000001c4b59584 _GSEventRunModal :100 (in GraphicsServices)8 UIKitCore 0x00000001efb59054 _UIApplicationMain :212 (in UIKitCore)9 Runner 0x0000000102df4eb4 main main.m:49 (in Runner)10 libdyld.dylib 0x00000001c23a2bb4 _start :4 (in libdyld.dylib)这是一个很典型的野指针Crash Log,是其中一种俗称的Over released问题。但是具体是哪个对象和方法,很难直接从Log上面得知,况且ARC下面的野指针更令人费解。 ...

May 10, 2019 · 2 min · jiezi

阿里云栖开发者沙龙PHP技术专场聊聊服务稳定性保障这些事

摘要:本文主要带大家了解服务稳定性的重要性和相关策略。策略大概分两部分,第一方面从架构层面介绍保障服务稳定性的常见策略(限流,降级,隔离,超时,重试和集群)。第二个方面是从流程方面(code review, 压测,灰度和监控)讲解怎么去保证稳定性。演讲嘉宾简介: 信海龙(花名沧龙),十余年的互联网开发经验,2013年加入阿里巴巴,深耕于电商、社区相关应用开发与架构。同时也是多个开源项目的开发者和维护者。代表开源作品,tclip,基于人脸识别的图片裁剪扩展。 本次直播视频精彩回顾,戳这里!直播回顾:https://yq.aliyun.com/live/965PPT分享:https://yq.aliyun.com/download/3530以下内容根据演讲嘉宾视频和PPT分享整理而成。 本次的分享主要围绕以下三个方面: 稳定性的重要性保障策略架构篇保障策略流程篇稳定性的重要性对很多企业来说服务稳定性非常重要,首先稳定性问题会对企业带来直接的经济损失。举例来说,亚马逊的“Prime Day”当天出现的一个故障,给亚马逊带来了高达9900万美元的损失。这一个故障损失就可能是其它小公司市值的几倍。所以服务稳定性对公司影响是特别大的。而对于个人来说,服务不稳定性会影响员工的绩效,甚至影响个人前程。 保障策略架构篇从架构层面保障稳定性,常见的策略包括限流,降级,隔离,超时,重试和集群等。 1.限流限流目的 限流的目的主要有两点,第一点是防止系统高负荷运行,第二点是有效利用服务器资源。为什么要做限流?假如不封锁请求,可能会导致服务器报警,如果平时服务器只能处理100个请求,突然多出两个请求服务器或许勉强能够处理,但突然多了500个请求的话,后面的400个请求只处在积压状态,等服务器处理到第500个请求的时候,用户等待时间就会过长,而且最后积压部分的请求可能根本就是无效的处理,因为用户早已流失。 限流算法 常见限流的算法包括漏桶算法和令牌桶算法。漏桶算法如下图,图中的例子有个小桶,桶下面有个孔,每流一滴水就可以认为是一个请求进去。滴水的速率是一样的,孔的高度也是固定的。漏桶算法能保证每个请求的负载时长,即确定每秒能处理的请求数量。 漏痛算法实现如下图,可以设定桶的高度是5个,每秒漏两个。执行效果中前面5次结果都是true,之后中间一次结果是false,这说明桶已经装满,之后又漏了两滴水,因为false的时候sleep了一秒,所以下面又有两个true出来。 令牌桶算法 如下图,令牌桶算法也是有一个桶,但是桶不漏,桶里面放了一些令牌,每来一个请求就在桶里拿一个令牌,如果没有令牌它就可以等待,令牌满了就不再往里面加令牌。这样方法基本上也可以达到一个限流的目的。令牌桶算法和漏桶算法的一个显著区别是漏桶算法在后端取请求量时,基本上漏的速率是一样的,但是令牌桶算法中后端部分可以有突发请求,如果桶满了,可以将桶里所有令牌都拿走。 下图是令牌桶算法lua代码实现部分,当然读者还可以使用Nginx,Java脚本或者php脚本来实现。 2.降级社区降级案例 一般情况下,系统上线之后总会遇到一些不稳定情况,比如redis挂掉,甚至后端数据库My SQL挂掉。当出现不稳定情况之后,系统如何保证继续提供这些服务。以社区案例为例,即便是My SQL挂掉,也要能够保证社区为用户提供基本的可读服务。其中一个策略是将一些热点数据,即用户经常浏览的信息或者最新的信息缓存起来,当后端服务不可用的时候,把这些数据展现给用户。大概流程如下图,数据存储部分后端会有一个脚本去分析Nginx里面的日志,然后去请求Vanish,Vanish再去请求后端,这样的话Vanish会有一个有效期,能够保证Vanish存进去的数据都是用户经常访问的一些数据。第二步,如何保证后端数据库挂掉的数据时候能迁过去?下图可以看到,Nginx中使用lua脚本进行实现,它会检测后端服务返回的一些状态,使用计数器计算失败次数,如果频繁的达到一定程度的失败次数,就切换到从Vanish获取数据,最后推送给用户。这样能保证即便是后端的数据库挂掉,甚至即便所有的php进程都挂掉的时候,社区也能给用户提供一些基本的服务。 降级目的 降级的目的比较简单,第一个是保障服务器基本可用,第二个是保障服务的核心服务可用。降级是怎么一个思路呢?一般降级的每个策略都是针对一个场景,预想特定场景下需要要解决什么问题;然后再梳理在这个场景下需要保留哪些核心基本服务;最后才选定技术方案,系统化的进行实现。简单讲就是先确定需要达到什么目的,再去了解是什么样的情况,最后制定策略或者计划。比如,系统会调用第三方服务,而第三方服务有可能挂掉,这是一种典型的场景。再比如,系统本身调用推荐服务,但是推荐服务也会挂掉,这种场景下不能够因为没有推荐数据就不显示数据,还是需要展示一些数据,这是一种基本的核心服务。每年的双11或者一些大型活动中基本都会存在降级。降级不仅仅是存在于资源故障场景下,资源不够用时也可能会需要降级,因为资源不够用需要关注重点。如大促活动中,需要先保证交易服务正常运行,其它消耗资源的服务(如对账)可以后续再去处理。 3.超时超时案例 社区对外提供接口服务,对方的反馈是接口服务较慢。接口部分流程是查一段数据,然后将数据反映过去,其问题点在于系统中超时时间设置过长。比如调用Memcache,但是Memcache已经挂掉,由于超时设置过长,数据需要等到超时时间结束以后再返回,导致接口一直在等待。那如何设置超时时间才合理?要注意超时时间并不是固定的值,而是需要针对整个业务,根据特定场景设置超时时间值。 如何设置超时时间 大体的思路如下图。第一步,识别业务需要的服务响应时间。比如,需要100毫秒去响应数据,之后统计业务里面可能需要调多少服务。第二步,统计服务日常的响应时间。第三步,分清主次,即分出哪些是核心服务。因为核心服务一旦失败,整个链路便不可用,所以可以对核心服务的时间设置的宽松一些。如果一些服务调不通,但又不影响整个链路,可以对它的时间设置的相对严格。 设置完超时之后需要验证,借助模拟手段封端口(如下图),模拟故障,然后检查数据返回时间是否在指定的时间内。 4.隔离隔离案例 下2013年左右,手机客户端开始逐渐升级起来,很多项目既有PC端也有客户端,所以同一个服务即要为PC端又要为客户端提供API接口。一旦遇到大型活动或者需要手机推送,服务会遇到不稳定情况,服务的不稳定会导致PC端也受影响,所以需要将服务进行物理隔离,从原先耦合到一块的服务器分到不同的机器组。隔离目的非常简单,要限制住不稳定因素导致的风险,停止传播。 隔离形式 隔离的常见形式包括几种。第一是秒杀场景,秒杀场景一个高并发的场景,可能带来的问题也比较多,在高并发场景下秒杀的时候,需要和一些正常的业务区分开来,不建议一台机器既提供秒杀也提供进程服务。另外,秒杀的时候会产生热点数据,如售卖数据。数据库更新比较频繁,从数据库层面也可以进行隔离,将热点部分和正常服务部分从资源上隔离。第二个场景是慢SQL隔离,一个资源隔离。一条慢SQL会导致整个服务不稳定。每请求一次线程,慢SQL会一直耗着当前线程,所以资源占用非常大。第三个场景是机房隔离。一般大公司都会做多机房部署,其目的就是确保稳定性。确保稳定性时不要做跨机房调用,否则耦合度会比较高,假如A调B,B挂掉,A服务也会受影响。一般确保稳定性都是做本机房的调用。而且本机房的调用性能也比较快。最后一个场景是进程隔离,因为进程比线程更加稳定。 5.集群对小公司而言,一台机器就提供一个服务,如果机器挂掉服务恢复就会成为一个问题。一般解决方法是做一个集群,从原来的一台机器提供服务变为可以用多台机器提供服务。集群的目的是为了解决单点的问题。集群的形式主要有主备,即同时只有一台机器提供整个服务,可以有一台或者多台提供备份,备份不仅要包含代码层面,整个服务运行所依赖的资源都要有备份。另外一个形式是主从。主是提供一个完整的服务,从是提供部分的服务。还有一种是多主,多主指的是每一台机器的决策是对等的,都会对外提供一些服务。随着集群形式的不同,对代码编写的并发性上有一定要求。主备只需要考虑单机的并发控制,主从是考虑同时提供服务的部分。比如加锁,主备上只要加一个本地的技能锁就可以,主从或者多主则需要加分布式锁。 保证策略流程篇保证稳定性策略的流程方面上分为下图中四个点,code review, 压测,灰度和监控。 1.Code reviewcode review目的是在项目上线前及时发现一些问题。经验比较丰富的人可以将经验进行分享。code review基本经过三个阶段。第一个阶段是头脑风暴式,一群开发人员围着代码做code review,虽然时间成本较高,效果也不太理想,但是这种方式也有好处,在前期可以将大家的意见进行整理,制定code review的规范。第二种code review形式是演讲式,专家事先把代码做一下review,整理一些点,然后进行分享。演讲式可以按照轮岗制,相对头脑风暴式大大节约了时间。目前常见的code review 形式是结对式,由一个或者两个专家结对,相互review,时间上比较灵活,也不需要占据会议室资源。 2.压测压测目的 压测的目的,第一是保证系统稳定性。在高并发的时候,检测系统是否稳定,因为一些问题在流量比较低的时候发现不了,只有在高并发的时候才能发现这个问题。第二是检测性能的抗压能力,检查系统能承受多大的QPS。 压测关注点 首先,压测机器和被压测服务在同一网段,尽量避免因为网络原因导致压测的结果不准确。第二点是关注服务器的负载,注意不要把服务器压到100%,服务器快要崩的时候,得到的值意义不大。应该是服务器负载达到60%~70%的时候,看QPS是多少。另外,压测并发数据是逐步递增的过程,到一个点的时候,并发数据越多代表QPS越低。最后,根据测试环境的压测结果估算线上的承载能力。估算的公式是线上QPS = 单机QPS 机器数 0.7。后面会乘以一个系数(0.7)是因为线上put上去的时候总会存在一些损耗。 ...

April 29, 2019 · 1 min · jiezi

走近科学探究阿里闲鱼团队通过数据提升Flutter体验的真相

背景闲鱼客户端的flutter页面已经服务上亿级用户,这个时候Flutter页面的用户体验尤其重要,完善Flutter性能稳定性监控体系,可以及早发现线上性能问题,也可以作为用户体验提升的衡量标准。那么Flutter的性能到底如何?是否像官方宣传的那么丝滑?Native的性能指标是否可以用来检测Flutter页面?下面给大家分享我们在实践中总结出来的Flutter的性能稳定性监控方案。 目标过度的丢帧从视觉上会出现卡顿现象,体现在用户滑动操作不流畅;页面加载耗时过长容易中断操作流程;Flutter部分exception会导致发生异常代码后面的逻辑没有走到从而造成逻辑bug甚至白屏。这些问题很容易考验用户耐心,引起用户反感。 所以我们制定以下三个指标作为线上Flutter性能稳定性标准: 页面滑动流畅度页面加载耗时(首屏时长+可交互时长)Exception率最终目标是让这些数据指标驱动Flutter用户体验升级。 页面滑动流畅度我们先大概了解下屏幕渲染流程:CPU先把UI对象转变GPU可以识别的信息存储进displaylist列表,GPU执行绘图指令来执行displaylist,取出相应的图元信息,进行栅格化渲染,显示到屏幕上,这样一个循环的过程实现屏幕刷新。 闲鱼客户端采用的Native、Flutter混合技术方案,Native页面FPS监控采用集团高可用方案,Flutter页面是否可以直接采用这套方案监控? 普遍的FPS检测方案Android端采用的是Choreographer.FrameCallBack,IOS采用的是CADisplayLink注册的回调,原理是类似的,在每次发出Vsync信号,并且CPU开始计算的时候执行到对应的回调,这个时候表示屏幕开始一次刷新,计算固定时间内屏幕渲染次数来得到fps。(这种方式只能检测到CPU卡顿,对于GPU的卡顿是无法监控到的)。由于这两种方法都是在主线程做检测处理,而flutter的屏幕绘制是在UI TaskRunner中进行,真正的渲染操作是在GPU TaskRunner中,关于详细的Flutter线程问题可以参考闲鱼之前的文章:深入理解Flutter引擎线程模式。 这里我们得出结论:Native的FPS检测方法并不适用于Flutter。 Flutter官方给我们提供了 Performance Overlay (具体参考 Flutter performance profiling) 作为检测帧率工具,可否直接拿来用? 上图显示了Performance Overlay模式下的帧率统计,可以看到,Flutter分开计算GPU 和UI TaskRunner。UI Task Runner被Flutter Engine用于执行Dart root isolate代码,GPU Task Runner被用于执行设备GPU的相关调用。通过对flutter engine源码分析,UI frame time是执行window.onBeginFrame所花费的总时间。GPU frame time是处理CPU命令转换为GPU命令并发送给GPU所花费的时间。 这种方式只能在debug和profile模式下开启,没有办法作为线上版本的fps统计。但是我们可以通过这种方式获得启发,通过监听Flutter页面刷新回调方法handleBeginFrame()、handleDrawFrame()来计算实际FPS。 具体实现方式:注册WidgetsFlutterBinding监听页面刷新回调handleBeginFrame()、handleDrawFrame() handleBeginFrame: Called by the engine to prepare the framework to produce a new frame.handleDrawFrame: Called by the engine to produce a new frame.通过计算handleBeginFrame和handleDrawFrame之间的时间间隔计算帧率,主要流程如下图: 效果到这里,我们完成Flutter中页面帧率的统计,这种方式统计的是UI TaskRunner中的CPU操作耗时,GPU操作在Flutter引擎内部实现,要修改引擎来监控完整的渲染耗时,我们目前大部分的场景没有复杂到gpu卡顿,问题主要还是集中在CPU,所以说可以反应出大部分问题。从线上数据来看,release模式下Flutter的流畅度还是蛮不错的,ios的主要页面均值基本维持在50fps以上,android相对ios略低。这里需要注意的是帧率的均值fps在反复滑动过程中会有一个稀释效果,导致一些卡顿问题没有暴露出来,所以除了fps均值,需要综合掉帧范围、卡顿秒数、滑动时长等数据才能反应出页面流畅度情况。 页面加载时长集团内部高可用方案统计Native页面加载时长是通过容器初始化后开启定时器在容器layout的时候检查屏幕渲染程度,计算可见组件的屏幕覆盖率,满足条件水平>60%,垂直>80%以上认为满足页面填充程度,再检查主线程心跳判断是否加载完成 再来看看weex页面加载流程和统计数据的定义 ...

April 26, 2019 · 1 min · jiezi

基于Tablestore管理海量快递轨迹数据架构实现

快递轨迹管理对于一个快递公司,在全国范围内有着大量的快递点、快递员、运输车辆以及仓储中心。而快递自产生后,就会在这些地点、人物之间流转。因而,一套完善的快递管理追踪系统是快递公司的重要管理工具;用户通过平台客户端下单后,产生唯一的快递单号作为唯一身份标识。快递除了订单号,还会有很多属性信息,如:邮寄人、邮寄人手机、邮寄人地址、收件人、快递类型等信息。生成快递订单后,用户的邮寄物品才会成为“快递”。快递公司配合扫码机器,将快递的流转事件、地点、时间等信息不定期推送至系统。快递流转信息不仅可以是简单的量化数据,也可以是描述性文字、地理位置等特殊信息。系统将流转信息记录成快递的监控数据,同时修改快递状态、实时位置等。直至快递送达收件人手中,结束快递生命周期。通过系统,用户可以管理自己的历史邮寄单列表、收件列表,掌握自己邮寄中的快递轨迹。快递公司也可以查询、修改快递信息、追踪快递时效,并借助海量轨迹监控数据,掌握快递产生、收件的高频路线,在高频位置铺设更多的基础设施、转移调度快递员;功能需求面向用户:1、用户在线下单生成快递单,等候快递员上门取件;2、管理历史订单列表,了解快递明细;3、追踪特定快递周转状态、运送轨迹;面向平台:1、借助扫码器,实现快递周转事件采集、存储;2、统计、查询所有快递订单,实现全订单的管理:CRUD;3、掌握所有邮寄中快递的实时位置;4、掌握任意一个订单的周转状态、运送轨迹;5、基于历史快递数据,分析快递时效;6、方便掌握高频地域、路线,为增设基础设施、快递员提供依据;等等…系统样例,如下所示:官网控制台地址:项目样例实现方案MySQL方案与难点通常,用户会选用MySQL作为方案数据库,因为MySQL作为数库在查询、分析等功能上有优势,用户创建两个表:订单表、事件追踪表实现对快递数据的存储。但是快递场景有几个强需求:第一、需要有强大的查询、统计能力,实现快递单的管理;第二、对于海量快递,有着高并发写入需求,对写入性能要求较高;第三、数据持续膨胀,但历史快递订单、事件数据多为冷数据,存储成本需要尽可能低;第四、数据未来挖掘潜在价值较高,需要有较好的计算生态;而MySQL方案在面对第二、第三个强需求时,劣势凸显,海量并发、不断的数据膨胀、存储成本高一直以来都是关系型数据库的痛点;表格存储方案选择表格存储有以下优势:其一、表格存储的多元索引(SearchIndex)功能轻松满足用户的多维查询、GEO检索、统计等功能需求;其二、基于LSM tree打造的分布式NoSQL数据库,轻松支持海量高并发读、写,零运维轻松应对数据量的不断膨胀,理论上无上限。其三、表格存储按量计费,提供容量型、高性能型两种实例,容量型对冷数据更适宜,提供了更低存储成本。其四、更重要的,表格存储拥有较为完善的计算生态,提供全、增量通道服务,提供流计算、批计算一体的计算体系,对未来监控数据价值挖掘提供渠道。表格存储在时序场景需求的技术点上拥有极高的匹配,而基于时序场景打造的Timestream模型更是将时序场景通用功能,封装成易用的场景接口,使用户更容易的基于表格存储,根据自身需求设计、打造不同特点的轨迹追踪系统;数据结构设计基于快递的时序,将快递的属性信息作为meta数据,而快递的周转路径、状态、位置等则为data数据,下面对两类数据做简单介绍。快递元数据meta数据管理着快递的属性信息,支持指标、标签、属性、地理位置、更新时间等参数,模型会为所有属性创建相应的索引,提供多维度条件组合查询(包含GEO查询)。其中Identifier是时间线的标识,包含两部分:name部分(监控指标标识)、tags部分(固有不可变参数集合)。在快递场景中,用户通常是基于快递单号直接定位快递,因而tags使用空的。而属性信息则存储快递的邮寄人信息、收件人信息、邮寄起/止地址等,location字段,用于最新位置追踪,可不定期根据产生新的状态周转数据时更新。快递轨迹数据data数据记录着快递的状态周转信息,主要为量化数据、地理位置、文字表述等任意类型。data数据按照+有序排列,因而同一快递的所有数据物理上存在一起,且基于时间有序。这种数据存储方式,极大的提升了时间线的查询效率。对应到快递轨迹,监控数据主要记录了:【who】do【something】@【where】with the location【geo】以及联系方式等。读写接口使用介绍写数据写接口根据数据类型分为两类:meta写入(新增快递)、data写入(快递周转数据)新增快递:当用户通过系统直接下快递单后,产生唯一订单号,加上用户填写的快递单信息组成必要的凯迪数据。此时,就会生成一个时间线,产生一个meta数据;快递周转:当快递发生取件、运输周转、派送、取件是,产生的状态转变数据时,就会产生一条追踪数据,通过data数据的写接口不定期的写入;读数据与写数据一样,针对两类数据提供了两类读接口:meta读取(快递查询)、data读取(查询快递轨迹)查询快递:根据快递号、寄件人手机、收件人手机等信息,获取对应快递的列表,掌握所有快递的最新动态;查询快递轨迹:基于单个meta的Identifier,获取该快递从产生到结束整个生命周期内的轨迹周转数据,可以通过列表、地图轨迹展示等方式,直观的了解快递的周转过程;方案核心代码SDK与样例代码SDK使用:时序模型Timestream模型集成于表格存储的SDK中,目前已在4.11.0版本中支持;<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>tablestore</artifactId> <version>4.11.0</version></dependency>代码开源:https://github.com/aliyun/tablestore-examples/tree/master/demos/MailManagement建表准备在创建完成实例后,用户需要通过时序模型的sdk创建相应的meta表(快递元数据)、data表(快递周转数据):private void init() { AsyncClient asyncClient = new AsyncClient(endpoint, accessKeyId, accessKeySecret, instance); //快递抽象Timestream TimestreamDBConfiguration mailConf = new TimestreamDBConfiguration(“metaTableName”); mailDb = new TimestreamDBClient(asyncClient, mailConf);}public void createTable() { mailDb.createMetaTable(Arrays.asList(//自定义索引 new AttributeIndexSchema(“fromMobile”, AttributeIndexSchema.Type.KEYWORD), new AttributeIndexSchema(“fromName”, AttributeIndexSchema.Type.KEYWORD), new AttributeIndexSchema(“toMobile”, AttributeIndexSchema.Type.KEYWORD), new AttributeIndexSchema(“toName”, AttributeIndexSchema.Type.KEYWORD), new AttributeIndexSchema(“toLocation”, AttributeIndexSchema.Type.GEO_POINT) )); mailDb.createDataTable(“dataTableName”);}写数据数据写入主要分两部分,meta表创建新快递、data表采集快递周转信息创建快递单(meta表写入)//metaWriter对应meta表,提供读、写接口TimestreamMetaTable mailMetaWriter = mailDb.metaTable();//identifier作为时间线的身份标识(unique),仅含:快递单号ID,TimestreamIdentifier identifier = new TimestreamIdentifier.Builder(“mail-id-001”) .build();//基于identifier创建meta对象,并为meta设置更多属性,Attributes为属性参数TimestreamMeta meta = new TimestreamMeta(identifier) .addAttribute(“fromName”, whos.get(Rand.nextInt(whos.size()))) .addAttribute(“fromMobile”, “15812345678”) .addAttribute(“toName”, whos.get(Rand.nextInt(whos.size()))) .addAttribute(“toMobile”, “15812345678”) .addAttribute(“toLocation”, “30,120”);//创建新的时间线,然后写入监控数据mailMetaWriter.put(meta);采集快递周转事件(data表写入)//dataWriter分别对应data表,提供读、写接口TimestreamDataTable mailDataWriter = mailDb.dataTable(“mailDataTableName”);TimestreamMeta meta;//meta上一步已经构建//创建新的时间线,然后写入监控数据mailDataWriter.write( meta.getIdentifier(), new Point.Builder(14500000000, TimeUnit.MILLISECONDS) .addField(“who”, “张三”) .addField(“do”, “取件”) .addField(“where”, “云栖小镇”) .addField(“location”, “30,120”) .build());数据读取数据读取分为两类:快递订单多维查询(meta表读取)//reader对应meta表,提供读、写接口,此处名字为突出读功能TimestreamMetaTable metaReader = mailDb.metaTable();//构建筛选条件Filter filter = AndFilter( Name.equal(“mail-id-001”), Attribute.equal(“fromMobile”, “15812345678”));Iterator<TimestreamMeta> metaIterator = mailDb.metaTable() .filter(filter) .fetchAll();while (iterator.hasNext()) { TimestreamMeta meta = iterator.next();//deal with metas}快递轨迹追踪(data表读取)//dataWriter分别对应data表,提供读、写接口TimestreamDataTable dataReader = db.dataTable(“dataTableName”);TimestreamMeta meta;//基于已获取的meta列表,分别获取每个快递的轨迹追踪Iterator<Point> dataIterator = mailDb.dataTable(mailDataTableName) .get(meta.getIdentifier()) .fetchAll();while (iterator.hasNext()) { Point point = iterator.next();//deal with points long timestamp = point.getTimestamp(TimeUnit.MILLISECONDS);//毫秒单位时间戳 String location = point.getField(“location”).asString();//获取该点String类型的位置信息}本文作者:潭潭阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

April 18, 2019 · 1 min · jiezi

基于MaxCompute的数仓数据质量管理

声明本文中介绍的非功能性规范均为建议性规范,产品功能无强制,仅供指导。参考文献《大数据之路——阿里巴巴大数据实践》——阿里巴巴数据技术及产品部 著。背景及目的数据对一个企业来说已经是一项重要的资产,既然是资产,肯定需要管理。随着业务的增加,数据的应用越来越多,企业在创建的数仓过程中对数据的管理也提出了更高的要求,而数据质量也是数仓建设过程不容忽视的环节。本文针对MaxCompute数仓建设过程中如何做数据质量给出规范建议,为实际数据治理提供依据及指导。数据质量保障原则评估数据质量的好坏不同行业甚至不同企业有不同标准,在此我们主要从四个方面进行评估,即完整性、准确性、一致性和及时性。完整性。完整性是指数据的记录和信息是否完整,是否存在缺失情况。数据缺失主要包括记录的缺失和记录中某个字段信息的缺失,两者都会造成统计结果不准确,可以说,完整性是数据质量最基础的保障。如某个相对稳定的业务数据量每天的都有100万条记录,某天突然下降1万条,那么可能就是记录缺失。而对于记录中某个字段信息缺失,如某科高考成绩表中一个考卷分数要对应一个准考证号,这个字段的空值数就该为0,一旦大于0,说明该信息缺失了。准确性。准确性是指数据中记录的信息和数据是否准确,是否存在异常或者错误的信息。比如成绩单中分数出现负数,比如订单没有买家信息等,这些都是有问题的。确保记录的准确性也是抱着数据质量必不可少的一个原则。一致性。一致性一般体现在跨度很大的数据仓库体现中。 比如公司中有很多业务数仓分支,对于同一份数据必须保证一致性。例如用户ID,从在线业务库加工到数据仓库,再到各个数据应用节点,必须都是同一种类型、长度保持一致。因此在《MaxCompute数仓建设规范指南》中有了“公共层”的加工,确保数据的一致性。及时性。保障数据的及时产出,体现数据的价值。如决策的分析师一般都希望当天可以看到前一天的数据而不是要等三五天才能看到某一个数据分析结果,否则就失去了数据及时性的价值,使得数据分析工作变得毫无意义。数据质量管理流程要做数据质量管理,制定满足以上数据质量原则集基础上的质量管理规范,需要考虑几方面:什么数据需要做质量管理。什么环节进行数据质量管理。数据质量管理具体怎么做。数据质量定义定义哪些数据需要做质量管理一般可以通过数据资产等级划分和元数据的应用链路分析得出。根据应用的影响程度,确定数据资产等级;根据数据链路血缘,将数据资产等级上推至各数据生产加工的各个环节,确定链路上所涉及的数据的资产等级和在各个加工环节上根据资产等级的不同所采取的不同处理方式。数据资产等级定义对于数据的资产等级,在质量管理方向,可以从数据质量“不满足四个原则”情况下对业务的影响性质,比如可以划分为5个等级的性质,即毁灭性质、全局性质、局部性质、一般性质、未知性质,不同性质的重要性一次降低,具体定义如下:毁灭性质,即数据一旦出错,将会引起重大资产损失,面临重大收益损失等。全局性质,即数据直接或间接用于企业级业务和效果评估、重要决策等。局部性质,即数据直接或间接用于某些业务线的运营、报告等,若出现问题会给业务线造成影响或者造成工作效率损失。一般性质,即数据主要用于日常数据分析,出现问题带来的影响极小。未知性质,即无法明确数据的应用场景。如table的label等级,资产等级可以用Asset进行标记:毁灭性质-A1,全局性质-A2,局部性质-A3,一般性质-A4,未知性质-Ax。重要程度为:A1>A2>A3>A4>Ax。若一份数据出现在多个应用场景汇总则遵循就高原则。数据资产等级落地方法定义划分好数据资产等级后,接下来就考虑怎么落地,对数仓中庞大的数据量进行资产等级打标。可以从数据流转链路着手。MaxCompute进行数据加工基本基本流程:数据从业务系统上产生,通过同步工具(DataWorks的数据集成或阿里云DTS)进入数据数仓系统(MaxCompute),数据在数仓中进行清洗、加工、整合、算法、模型等一系列运算后,再通过同步工具输出到数据产品中进行消费。整个流程数据都是以存放在表的形式体现,流转链路大致如下图:从数据流转链路上,整理哪些表是被哪些应用业务产品消费,通过给这些应用业务产品划分数据资产等级,再结合数据的上下游血缘,将整个链路打上某一类资产等级的标签。如,一个A2等级的的数据应用产品,对应导入这个数据产品的table即数仓(MaxCompute)的导出表Table1、Table2、Table3,几个表都打上A2-xxx数据产品标记,根据血缘往上追溯,将这几个表的上有都打上A2的标记,一直标记到源数据业务系统。通过如上方式完成数据资产等级的确认,给不同的数据定义不同的重要程度。知道了数据的重要等级针对不同的等级,采取不同的保障措施,接下来我们介绍在基于MaxCompute的数据仓库中针对不同等级的数据的保障方法。数据加工过程卡点校验在线系统卡点校验在线系统数据加工过程卡点校验,主要是指在业务系统的数据生成过程中进行的卡点校验。在线业务系统产生的数据也是数据仓库的数据来源,然而在线业务系统普遍都是复杂多变,且每次变更不可避免会带来数据的变化,数仓需要适应多变的业务发展,及时做到数据的准确性。因此,在线业务的变更如何高效的通知到基于MaxCompute的离线数据仓库,也是需要考虑的问题。这里我们介绍两个方法拱参考:工具和人员双管齐下。纪要在工具上自动捕捉每一次业务的变化,同时也要求开发人员在意识上自动进行业务变更通知。工具——发布平台。在业务进行重大变更时,订阅这个发布过程,通知到离线开发人员,使其知晓此次变更内容。当业务系统足够繁杂,日常发布变更频繁的情况下,若每次变更都通知离线业务,势必会造成不必要的浪费,同时也影响业务迭代效率。此时,可以通过数据资产等级的标识,对业务进行打标后,针对高等级的数据资产,整理出什么变更会影响数据的加工,如相关财务报表,如果业务系统的改造影响到财务报表的计算,使得约定好的计算口径被业务系统发布变更修改了,这种情况必须要告知离线业务,而离线开发人员也必须主动关注这类发布变更通知。注意:这里指的发布平台非阿里云提供发布平台,只是一种统称,指各个企业自己在线业务的相关发布平台。工具——数据库的变化感知。随着业务的发展,业务数据库(MaxCompute数仓的数据源)不可避免会出现数据库扩容或者DDL变更,这些变更都要主动通知到离线开发人员。基于MaxCompute的数据仓库在进行离线数据抽取时,通过DataWorks的数据集成工具,可能会限制某个业务数据库表,如果该数据库表发生扩容或者迁移等,数据集成工具感知不到,会可能导致数据抽取错漏,而一旦错漏,会影响下游一系列依赖该表的应用,因此建议业务数据库也需要有库表变更通知。工具只是一种辅助手段,操作工具的人员才是核心。数据资产等级的上下游打通,同样也将这个过程给到在线开发人员,使其知晓哪些是重要的核心数据资产,提高在线开发人员的数据风险意识。通过培训等方式将离线数据的诉求、离线数据的加工过程、数据产品的应用方式告诉在线业务开发人员,让其了解数据的重要性,了解数据的价值,同时也告知出错后果。让在线开发人员在完成业务目标时,也要考虑数据的目标,做到业务端和数据端一致。离线系统卡点校验首先我们再次认识MaxCompute进行数据加工的基本流程:数据从业务系统上产生,通过同步工具(DataWorks的数据集成或阿里云DTS)进入数仓系统(MaxCompute),数据在数仓中进行清洗、加工、整合、算法、模型等一系列运算后,再通过同步工具输出到数据产品中进行消费。整个流程中,有了数据加工,才有了数据仓库模型和数据仓库代码的建设,如何保障数据加工过程中的质量是离线数据仓库保障数据质量的一个重要环节。MaxCompute进行数据加工,可以通过DataWorks、也可以通过MaxCompute studio、或者直接通过MaxCompute SDK提交各种任务进行加工。无论用什么工具,都会经历代码开发->测试、发布->运维、变更 的过程,可以对这个过程每个环节进行卡点校验。代码提交的卡点校验。即在sql提交前进行相关规则校验。这个校验目前公共云没有直接可用的工具辅助,有能力的用户可以自己开发相关的工具。规则分类如:代码规范类规则,如表命名规范、生命周期设置、表注释等。代码质量类规则,如分母为0提醒、NULL值参与计算影响结果提醒、插入字段顺序错误等。代码性能类规则,如分区裁剪失效、扫描大表提醒、重复计算检测等。任务发布上线时的卡点校验。为了保障线上数据的准确性,每一次变更都需要测试后再发布到线上生产环境,且生产环境测试通过后才算发布成功。任务变更或者数据重跑,在离线数据加工过程中不可避免都会出现的操作。针对这个操作,在进行更新前,需要通知下游,将变更原因、变更逻辑、变更时间等信息表明,下游对此次变更没有异议后再按照约定时间执行发布变更,将变更对下游的影响降到最低。数据风险点监控前一章节主要介绍通过数据加工过程的卡点校验保障在线数据和离线数据的一致性问题,本章节主要通过对数据风险点的监控来介绍如何保障数据的准确性。在线数据风险点监控在线业务系统的数据生成过程需要保证数据质量,主要根据业务规则对数据进行监控。MaxCompute本身没有配套的工具,需用户自己实现,在此只能给出一些建议拱参考。如针对数据库表的记录进行规则校验,制定一些监控规则,在业务系统中,每个业务过程进行数据落库时对数据进行校验。监控规则如交易系统中,订单拍下时间、订单完结时间、订单支付金额、订单状态流转都配置校验规则,订单拍下时间不会大于当天时间,也不会小于业务系统上线时间,一旦出现异常校验就不通过。当业务繁杂且规则繁多,规则配置等运行成本高时,同样根据数据资产等级进行监控。离线数据风险点监控本小节将介绍基于MaxCompute的数据仓库建设过程中离线数据的风险点监控,主要报对数据准确性和数据产出及时性的监控。数据准确性数据准确性是数据质量的关键,因此数据准确成为数据直连的重中之重,是所有离线系统加工时的第一保障要素,在此我们主要介绍通过DataWorks的数据质量工具——DQC来保障MaxCompute离线数据的准确性。注意,要用DQC,必须是使用DataWorks进行任务调度执行。我们先来认识DQC工具架构:DQC以数据集(DataSet)为监控对象,当离线MaxCompute数据发生变化时,DQC会对数据进行校验,并阻塞生产链路,以避免问题数据污染扩散。同时,DQC提供了历史校验结果的管理,以便对数据质量分析和定级。由上图我们看出DQC主要是通过配置数据质量校验规则,自动在数据处理过程中进行数据质量监控。DQC能监控数据质量并报警,本身不对数据产出进行处理,需要报警接收人判断并决定如何处理。DQC数据监控规则有强规则和弱规则之分。强规则,一旦触发报警就会阻断任务的执行(将任务置为失败状态,使下游任务不会被触发执行);弱规则,只告警不会阻断任务的执行。DQC根据阿里内部的经验,提供了一些常用的规则模板,包括:表行数较N天前波动率、表空间大小较N天前波动率、字段最大/最小/平均值相比N天前波动率、字段空值/唯一个数等等,更多请参考DataWorks用户手册中数据质量模块介绍。DQC的工作流程如下图所示:由此看出DQC的检查其实也是运行SQL任务,只是这个任务是嵌套在主任务中,若检查的太多也会影响整体的任务执行性能,因此哪些数据需要配置DQC规则,应该配置什么规则,也要根据数据资产等级来确定。如A1、A2类数据监控率要达到90%以上,规则类需要3种以上,而不重要的数据资产不做强要求。类似的规则都是有离线开发人员进行配置来确保数据准确性,当然不同的业务会有业务规则的约束,这些规则来源于数据产品或者消费的业务需求,有消费节点进行配置,然后上推到离线系统的起点进行监控,做到规则影响最小化。数据的及时性在确保数据准确性的前提下,需要进一步让数据能够及时的提供服务,否则数据的价值将大幅降低,甚至无价值,所以确保数据及时性也是保障数据质量重中之重的一环。基于MaxCompute的离线任务,如常见的以天作为时间间隔,对于天任务,一些重要的业务会对数据产出有时间要求,比如一些决策报表要求9:00或更早必须产出。为确保数据完整性,天任务一般都是0点开始执行,计算刚过去的一天的数据,这些任务大多在夜里运行,要确保数据按时产出,需要考虑任务的优先执行(当Project里任务很多而资源有限的时候不得不考虑)和任务执行失败或时长过长时的告警问题。这里说的重要业务的“重要性”同样是前面所说的数据资产等级的划分,等级越高保障优先级越高。任务优先级。MaxCompute平台上任务优先级都是一样,无法配置。因此要对MaxCompute的任务实现“优先级”功能,只能从调度平台入手,优先调度下发重要的任务。DataWorks平台的调度任务,当对应的Project是使用预付费资源(预购固定的计算资源仅供当前项目使用)时,可以通过“智能监控”工具进行优先级设置。DataWorks的调度是一个树形结构,当配置了叶子节点的优先级,这个优先级会传递到所有的上游节点,而叶子节点往往就是服务业务的消费节点。因此在优先级的设置上,先确定业务的资产等级,等级越高的业务对应的消费节点优先级配置越高,优先调度从而优先占用计算资源,确保高等级业务准时产出。当DataWorks的节点任务所属的Project使用的是MaxCompute的后付费资源(计算按量付费,无固定资源使用),智能监控配置的优先级无效,因此,需要评估是否要购买预付费资源,同时对任务进行优化,减少不必要的资源浪费,力争在有限的资源下更高效的完成计算。任务报警。任务报警和优先级类似,通过DataWorks的“智能监控”工具进行配置,只需要配置叶子节点即可向上游传递。任务执行过程中出错或者可能出现延迟都是不可避免的,为了保障最重要数据(资产等级高)产出,我们需要“出错”立即处理、“可能”延迟必须知晓并介入。DataWorks—智能监控。MaxCompute的离线任务,通过DataWorks进行离线任务调度时,DataWorks提供智能监控工具,对调度任务进行监控告警。智能监控是DataWorks任务运行的监控及分析系统。根据监控规则和任务运行情况,智能监控决策是否报警、何时报警、如何报警以及给谁报警。智能监控会自动选择最合理的报警时间,报警方式以及报警对象。智能监控旨在:降低您的配置成本。杜绝无效报警。自动覆盖所有重要任务(数量已经多到您自己无法梳理)。数据质量衡量前面章节给出了保障基于MaxCompute的数据仓库数据质量的方案,但是这些方案是否真的合适,或者哪些点需要改进,这些需制定一套指标进行度量。比如:频繁的接到DataWorks的智能监控发出的告警;每一个数据质量事件发生,必须分析有原因、处理过程、后续同类事件预防方案;严重的数据质量事件升级为故障,并对故障进行定义、等级划分、处理、review。相关工具链接DataWorks-数据质量管理工具,文档,工具界面。DataWorks—智能监控工具,文档,工具界面。本文作者:海清阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 12, 2019 · 1 min · jiezi

更效率、更优雅 | 阿里巴巴开发者工具不完全盘点

从人工到自动化,从重复到创新,技术演进的历程中,伴随着开发者工具类产品的发展。阿里巴巴将自身在各类业务场景下的技术积淀,通过开源、云上实现或工具等形式对外开放,本文将精选了一些阿里巴巴的开发者工具,希望能帮助开发者们提高开发效率、更优雅的写代码。由于开发者涉及的技术领域众多,笔者仅从自己熟悉的领域,以后端开发者的视角盘点平时可能有得到的工具。每个工具按照以下几点进行介绍:工具名称和简介使用场景使用教程获取方式一、Java 线上诊断工具 ArthasArthas 阿里巴巴2018年9月开源的一款Java线上诊断工具。工具的使用场景:这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!是否有一个全局视角来查看系统的运行状况?有什么办法可以监控到JVM的实时运行状态?Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。使用教程:基础教程:https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=arthas-basics进阶教程:https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=arthas-advanced获取方式:(免费)开源地址:https://github.com/alibaba/arthas二、IDE 插件 Cloud ToolkitCloud Toolkit 是一款 IDE 插件,可以帮助开发者更高效地开发、测试、诊断并部署应用。通过 Cloud Toolkit,开发者能够方便地将本地应用一键部署到任意机器(本地或云端),并内置 Arthas 诊断、高效执行终端命令和 SQL 等。工具的使用场景:每次修改完代码后,是否正在经历反复地打包?在 Maven 、Git 以及其他运维脚本和工具的之间频繁切换?采用 SCP 工具上传?使用XShell或SecureCRT登陆服务器?替换部署包?重启?文件上传到服务器指定目录,在各种 FTP、SCP 工具之间频繁切换 ?使用教程:IntelliJ IDEA 版:https://help.aliyun.com/document_detail/98762.htmlEclipse 版:https://help.aliyun.com/document_detail/29970.htmlPyCharm 版:https://help.aliyun.com/document_detail/112740.htmlMaven 版:https://help.aliyun.com/document_detail/108682.html获取方式:(免费)工具地址:https://www.aliyun.com/product/cloudtoolkit三、混沌实验注入工具 ChaosBladeChaosBlade 是一款遵循混沌工程实验原理,提供丰富故障场景实现,帮助分布式系统提升容错性和可恢复性的混沌工程工具,可实现底层故障的注入,提供了延迟、异常、返回特定值、修改参数值、重复调用和try-catch 块异常等异常场景。工具的使用场景:微服务的容错能力不易衡量?容器编排配置是否合理无法验证?PaaS 层健壮性的测试工作无从入手?使用教程:https://github.com/chaosblade-io/chaosblade/wiki/新手指南获取方式:(免费)开源地址:https://github.com/chaosblade-io/chaosblade/wiki/新手指南四、Java 代码规约扫描插件该插件用于检测 Java 代码中存在的不规范的位置,并给予提示。规约插件是采用kotlin语言开发。使用教程:IDEA插件使用文档:https://github.com/alibaba/p3c/wiki/IDEA插件使用文档Eclipse插件使用文档:https://github.com/alibaba/p3c/wiki/Eclipse插件使用文档获取方式:(免费)开源地址:https://github.com/alibaba/p3c五、应用实时监控工具 ARMSARMS 是一款 APM 类的监控工具,提供前端、应用、自定义监控 3 类监控选项,可快速构建实时的应用性能和业务监控能力。工具的使用场景:晚上10点收到37条报警信息,你却无从下手?当我们发现问题的时候,客户/业务方已经发起投诉?每个月花几十万买服务器,却无法保障用户体验?使用教程:前端监控接入:https://help.aliyun.com/document_detail/106086.html应用监控接入:https://help.aliyun.com/document_detail/63796.html自定义监控:https://help.aliyun.com/document_detail/47474.html获取方式:(收费)工具地址:https://www.aliyun.com/product/arms六、静态开源站点搭建工具 DocsiteDocsite 一款集官网、文档、博客和社区为一体的静态开源站点的解决方案,具有简单易上手、上手不撒手的特质,同时支持 react 和静态渲染、PC端和移动端、支持中英文国际化、SEO、markdown文档、全局站点搜索、站点风格自定义、页面自定义等功能。使用教程:https://docsite.js.org/zh-cn/docs/installation.html获取方式:(免费)项目地址:https://github.com/txd-team/docsite七、Android 平台上的秒级编译方案 FreelineFreeline 可以充分利用缓存文件,在几秒钟内迅速地对代码的改动进行编译并部署到设备上,有效地减少了日常开发中的大量重新编译与安装的耗时。Freeline 最快捷的使用方法就是直接安装 Android Studio 插件。使用教程:https://github.com/alibaba/freeline/blob/master/README-zh.md获取方式:(免费)项目地址:https://github.com/alibaba/freeline八、性能测试工具 PTSPTS 可以模拟大量用户访问业务的场景,任务随时发起,免去搭建和维护成本,支持 JMeter 脚本转化为 PTS 压测,同样支持原生 JMeter 引擎进行压测。使用教程:https://help.aliyun.com/document_detail/70290.html获取方式:(收费)工具地址:https://www.aliyun.com/product/pts九、云效开发者工具KTKT 可以简化在 Kubernetes 下进行联调测试的复杂度,提高基于Kubernetes的研发效率。使用教程:https://yq.aliyun.com/articles/690519获取方式:(免费)工具地址:https://yq.aliyun.com/download/3393十、架构可视化工具 AHASAHAS 为 K8s 等容器环境提供了架构可视化的功能,同时,具有故障注入式高可用能力评测和一键流控降级等功能,可以快速低成本的提升应用可用性。工具的使用场景:服务化改造过程中,想精确的了解资源实例的构成和交互情况,实现架构的可视化?想引入真实的故障场景和演练模型?低门槛获得流控、降级功能?使用教程:https://help.aliyun.com/document_detail/90323.html获取方式:(免费)工具地址:https://www.aliyun.com/product/ahas本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

April 11, 2019 · 1 min · jiezi

阿里小程序云应用上线了,有哪些看点?

3月21日,在2019阿里云峰会·北京上,阿里巴巴旗下的阿里云、支付宝、淘宝、钉钉、高德等联合发布“阿里巴巴小程序繁星计划”:提供20亿元补贴,扶持200万+小程序开发者、100万+商家。凡入选“超星”的小程序,入驻支付宝、淘宝、钉钉、高德后还能得到流量重点支持。阿里云近期发布小程序云应用,提供一站式云服务,为开发者提供稳定和便捷的后端云服务,包括 Serverless 开发套件、应用托管服务、函数计算等。开发者可在这些小程序端上进行统一的应用发布、资源管理、数据管理。接下来,我带大家来了解一下小程序云应用的具体内容:小程序云应用限量免费申请入口云应用产品架构产品价值通过一站式的资源编排、应用托管、DevOps 的能力降低企业和个人对小程序后端的开发成本。产品特色直接搭建和初始化好运行环境。支持 Node.js、Spring Boot 等主流框架应用托管。一站式的发布、运维、监控操作。方案优势资源编排通过对 ECS、RDS、SLB、EIP 等资源进行编排,帮助用户根据自身的业务情况提供不同规格配置自动搭建好符合业务场景的最优运行环境,低成本、高效率。应用托管为开发者提供主流应用框架的运行环境,直接上传 Node.js、Spring Boot、Java Web 部署包发布,开箱即用,极大的降低了前后端开发者对云服务的开发成本。一站式 DevOps支持开发者一站完成测试环境、生产环境的版本发布、扩容、资源监控等操作。无需运维即可高效进行线上服务的自动扩容、业务指标监控等。产品操作指引查看详情:https://yq.aliyun.com/activity/820?utm_content=g_1000051340扶持计划 - 云应用篇扶持计划说明:https://help.aliyun.com/document_detail/113009.html申请入口:https://yq.aliyun.com/activity/820?utm_content=g_1000051340本文作者:管理贝贝 阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 10, 2019 · 1 min · jiezi

云应用监控指南

原文: https://victorops.com/blog/cl…翻译: 祝坤荣DevOps和It团队已习惯于常年对内部服务器,网络和应用进行监控和报警处理。而同样的,由于基于云服务的使用率的增长,现在理解团队怎样对于云基础设施和应用的监控也变得同样重要。事实上,据估计2020年83%的企业计算会在云上。在DevOps世界里,是没有一个监控你云应用或服务的单一解决方案的。但是,还是有很多可以用的技术和工具。所以,如果你对于监控云服务的时间是个新手,或者你就是想学点东西 - 我们写了这个云应用监控指南来帮你。不同类型的云服务与内部监控方案一样,有效的云监控就是提高你基础设施的可视能力并通过服务健康检查让问题浮出水面。团队使用更多的第三方云应用来管理他们的负载和维护他们基于AWS,GCP或Azure的服务器。所以,对于IT和DevOps团队来说不止需要监控内部应用,网络和服务器,也需要关注团队成员使用的第三方应用程序。让我们看下哪些不同类型的云服务可以被监控。SaaS(软件即服务):提供某种服务给最终用户使用的web应用。例如,GoogleDrive,Dropbox,Salesforce等。PaaS(平台即服务):SQL数据库,存储,和缓存工具都在这个类目下。IaaS(基础设施即服务): IaaS是指通过AWS,GCP或Azure提供的基于云上的主机服务。FaaS(函数即服务): 类似AWS Lambda,Azure Functions,或Google Cloud Functions的Serverless应用应用托管: 在云环境托管应用的方式。例如Heroku, Amazon EC2, Kubernetes,或Google App Engine都在这里。云服务的关注点安全:由于云服务的本质,IT和DevOps团队很担心当安全漏洞出现时缺少控制和可见性。监控,安全和编排/自动化工具可以帮助检测这些漏洞,在他们还没有造成大问题时快速定位。合规:取决于你的行业或业务,使用云服务可能有合规风险。你得确定你对于平台和服务都很了解,保证合规。高度集成的服务:云服务是被高度集成的,会依赖其他服务,云或内部的,才能运转正常。你得注意当问题发生时,他们可能会影响你技术栈中大量的其他服务。运维人员:如果你经常使用云服务,这条可能让你惊讶。但是,许多管理人员担心他们无法为团队配备这些知识来构建和维护可靠的基于云的服务。有效云监控的最佳实践确定盲点:深度检查你的技术栈来发现薄弱点或缺乏可视化的痛点。这篇之前的事后复盘可以帮你确定你基础设施的盲点。核心性能指标(KPIs):一旦你知道你需要监控什么了,现在你可以确定什么样的指标可以用来标识系统监控。使用工具来监控不同等级的服务,并优化KPIs保证当故障出现时可以精确指示出来。对于你KPIs的良好理解可以让你值班时更少的在凌晨2点发出假报警。中心化可视:中心化所有监控数据可以改善事件检测,响应和团队协作。这样,你可以得到一个对于系统健康的全面视图,可以将故障事件间更简单的关联起来,并可以更简单的将其他团队也引入到问题处理里。成本: 与你的应用性能或系统健康无关,但跟踪你在云服务上的开销很重要。许多服务开销是基于使用情况的,所以很有必要认识到服务为团队提供的价值。终端用户监控: 更好的了解用户是怎么样在你的服务间移动的,以及他们的体验,可以帮你打造一个更简便的产品。拿到关于页面加载次数或服务器响应速度的数据可以帮你发现你平台的痛点,帮你打造更强壮的系统。混沌测试 时刻记得面向故障构建系统。规划故障转移和后备计划的问题。使用工具来测试当停机或出错时系统会出现什么,并重复该过程以便改进它。优化报警: 基于你从以上步骤学到的中心化的数据和知识,调整你的报警阈值并保证报警是可操作的并是相关的。云监控可用的工具现在你知道了当监控云服务时需要做什么,你现在需要知道怎么做。所以,我们会介绍一些在使用云服务时常用的监控工具。Splunk:我们可能有偏爱,Splunk云监控提供你云基础设施的可视性和详细日志分析以及搜索功能。通过监控你技术栈里从应用托管到SaaS的 所有方案,你可以生动描绘出你产品里正在发生的事情。AppDynamics:作为真正的APM, AppDynamics聚焦于优化你云应用的性能。基于许多产品和服务,AppDynamics可以帮你进行终端用户监控,基础设施可视化,商业智能,与整体服务可靠性监控。New Relic:动态地, 持续集成云环境, New Relic可以帮你监控应用和基础设施。无论你运行的是一个简单架构或使用的是容器,微服务,serverless函数式,New Rlic可以帮你解决云监控的需求。Solarwinds:Solarwinds 云给你一个关于你云基础设施,应用和整体数字化情况的中心化大图。识别你系统的缺陷点并可构造一个更好的集成,建壮的使用Solarwinds的基于云的解决方案。Amazon CloudWatch:当你使用AWS,Amazon CloudWatch 是一个首选解决方案。它是专门为AWS的云化应用打造的监控,你可以使用它监控基础设施,平台和应用。结论无论你是私有云,混合云还是全公有云,都需要合适的监控。更好的理解你系统的盲点和薄弱点可以帮你更好的监控你服务的健康度和使用需要的工具。所以,实施事后复盘,规划失败,测试你的监控工具和应用,并持续优化你的流程来帮助你构建的产品增加可见性和可靠性。本文来自微信公众号「麦芽面包,id「darkjune_think」转载请注明。交流Email: zhukunrong@yeah.net

April 2, 2019 · 1 min · jiezi

Kubernetes Ingress 日志分析与监控的最佳实践

Ingress 主要提供 HTTP 层(7 层)路由功能,是目前 K8s 中 HTTP/HTTPS 服务的主流暴露方式。为简化广大用户对于 Ingress 日志分析与监控的门槛,阿里云容器服务和日志服务将 Ingress 日志打通,只需要应用一个 yaml 资源即可完成日志采集、分析、可视化等一整套 Ingress 日志方案的部署。前言目前 Kubernetes(K8s)已经真正地占领了容器编排市场,是默认的云无关计算抽象,越来越多的企业开始将服务构建在K8s集群上。在 K8s 中,组件通过 Service 对外暴露服务,常见的包括 NodePort、LoadBalancer、Ingress 等。其中 Ingress 主要提供 HTTP 层(7 层)路由功能,相比 TCP(4 层)的负载均衡具备非常多的优势(路由规则更加灵活、支持金丝雀、蓝绿、A/B Test 发布模式、SSL 支持、日志、监控、支持自定义扩展等),是目前 K8s 中 HTTP/HTTPS 服务的主流暴露方式。Ingress 简介K8s 中 Ingress 只是一种 API 资源的声明,具体的实现需要安装对应的 Ingress Controller,由 Ingress Controller 接管 Ingress 定义,将流量转发到对应的 Service。目前 Ingress Controller 的实现有非常多种(具体可以参考 Ingress Controller官方文档),比较流行的有 Nginx、Traefik、Istio、Kong 等,在国内接受度最高的是 Nginx Ingress Controller。日志与监控日志和监控是所有 Ingress Controller 都会提供的基础功能,日志一般包括访问日志(Access Log)、控制日志(Controller Log)和错误日志(Error Log),监控主要从日志以及 Controller 中提取部分 Metric 信息。这些数据中访问日志的量级最大、信息最多、价值也最高,一般7层的访问日志包括:URL、源 IP、UserAgent、状态码、入流量、出流量、响应时间等,对于 Ingress Controller 这种转发型的日志,还包括转发的 Service 名、Service 响应时间等额外信息。从这些信息中,我们能够分析出非常多的信息,例如:网站访问的 PV、UV;访问的地域分布、设备端分布;网站访问的错误比例;后端服务的响应延迟;不同 URL 访问分布。我们的开发、运维、运营、安全等人员可以基于这些信息完成各自的需求,例如:新老版本发布前后的数据指标对比;网站质量监控、集群状态监控;恶意攻击检测、反作弊;网站访问量统计、广告转化率统计。然而手动搭建、运维一整套的 Ingress 日志分析与监控系统非常复杂,系统所需要的模块有:部署日志采集 Agent 并配置采集、解析规则;由于 K8s 集群中,访问量相对较大,因此需要搭建一个缓冲队列,例如 Redis、Kafka 等;部署实时数据分析引擎,例如 Elastic Search、clickhouse 等;部署可视化组件并搭建报表,例如 grafana、kibana 等;部署告警模块并配置告警规则,例如 ElastAlert、alertmanager 等。阿里云日志服务Ingress解决方案为简化广大用户对于 Ingress 日志分析与监控的门槛,阿里云容器服务和日志服务将 Ingress 日志打通(官方文档https://help.aliyun.com/document_detail/86532.html)),只需要应用一个 yaml 资源即可完成日志采集、分析、可视化等一整套 Ingress 日志方案的部署。Ingress 可视化分析日志服务默认为 Ingress 创建 5 个报表,分别是:Ingress 概览、Ingress 访问中心、Ingress 监控中心、Ingress 蓝绿发布监控中心、Ingress 异常检测中心。不同角色的人员可根据需求使用不同的报表,同时每个报表均提供筛选框用于筛选特定的 Service、URL、状态码等。所有的报表均基于日志服务提供的基础可视化组件实现,可根据公司实际场景进行定制化调整。Ingress 概览Ingress 概览报表主要展示当前 Ingress 的整体状态,主要包括以下几类信息:整体架构状态(1 天),包括:PV、UV、流量、响应延迟、移动端占比、错误比例等;网站实时状态(1 分钟),包括:PV、UV、成功率、5XX 比例、平均延迟、P95/P99 延迟等;用户请求类信息(1 天),包括:1天/7天访问PV对比、访问地域分布、TOP访问省份/城市、移动端占比、Android/IOS 占比等;TOPURL 统计(1 小时),包括:访问 TOP10、延迟 TOP10、5XX 错误 TOP10、404 错误 TOP10。Ingress 访问中心Ingress 访问中心主要侧重于用于访问请求相关的统计信息,一般用于运营分析,包括:当日 UV/PV、UV/PV 分布、UV/PV 趋势、TOP 访问省份/城市、TOP 访问浏览器、TOP 访问IP、移动端占比、Android/IOS 占比等。Ingress 监控中心Ingress 监控中心主要侧重于网站实时监控数据,一般用于实时监控与告警,包括:请求成功率、错误比例、5XX 比例、请求未转发比例、平均延迟、P95/P99/P9999 延迟、状态码分布、Ingress 压力分布、Service 访问 TOP10、Service 错误 TOP10、Service 延迟 TOP10、Service 流量 TOP10 等。Ingress 蓝绿发布监控中心Ingress 蓝绿发布监控中心主要用于版本发布时的实时监控与对比(版本前后对比以及蓝绿版本当前对比),以便在服务发布时快速检测异常并进行回滚。在该报表中需要选择进行对比的蓝绿版本(ServiceA 和 ServiceB),报表将根据选择动态显示蓝绿版本相关指标,包括:PV、5XX 比例、成功率、平均延迟、P95/P99/P9999 延迟、流量等。Ingress 异常检测中心Ingress 异常检测中心基于日志服务提供的机器学习算法,通过多种时序分析算法从 Ingress 的指标中自动检测异常点,提高问题发现的效率。实时监控与告警Ingress 作为 K8s 网站请求的主要入口,实时监控与告警是必不可少的 Ops 手段之一。在日志服务上,基于上述的报表,只需 3 个简单的步骤即可完成告警的创建。下述示例为 Ingress 配置 5XX 比例的告警,告警每 5 分钟执行一次,当 5XX 比例超过 1% 时触发。除了通用的告警功能外,日志服务还额外支持:多维度数据关联,即通过多组 SQL 结果交叉判断进行告警,增加告警准确度;除支持短信、语音、通知中心、email 外,还支持钉钉机器人通知、自定义 WebHook 扩展;告警的记录也以日志的形式记录,可以实现对告警失败进行告警的双保险。订阅报告日志服务除支持通过告警方式通知外,还支持报表订阅功能,可使用该功能将报表定期渲染成图片并通过邮件、钉钉群等方式发送。例如每天早上 10 点向运营群中发送昨日网站访问情况、每周发送报告到邮件组中存档、新版本发布时每 5 分钟发送一次监控报表…自定义分析如果容器服务 Kubernetes 版提供的默认报表无法满足你的分析需求,可以直接使用日志服务 SQL、仪表盘等功能进行自定义的分析和可视化。尝鲜为了让大家可以体验 Kubernetes 审计日志功能,我们特别开通了体验中心,大家可以通过 https://promotion.aliyun.com/ntms/act/logdoclist.html 进入,该页面提供了非常多和 Kubernetes相关的报表。参考文档[1]https://www.aliyun.com/product/sls[2]https://www.aliyun.com/product/kubernetes[3]https://help.aliyun.com/document_detail/86532.html[4]https://help.aliyun.com/document_detail/48162.html[5]https://help.aliyun.com/document_detail/107758.html[6]https://kubernetes.io/docs/concepts/services-networking/ingress/[7]https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/本文作者:jessie筱姜阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

March 27, 2019 · 1 min · jiezi

UAVStack的慢SQL数据库监控功能及其实现

作者: 王林林 出处:UAVStack智能运维 来源:宜信技术学院技术沙龙001期|AI中台:一种敏捷的智能业务支持方案|宜信技术沙龙 3月28日晚8点线上直播,点击报名UAVStack是一个全维监控与应用运维平台。UAV.Monitor具备监控功能,包含基础监控、应用/服务性能监控、日志监控、业务监控等。在应用监控中,UAV可以根据应用实例画像;其中应用实例组件可以对日志、服务、客户端等进行画像;基于客户端的画像又分为Http、Dubbo、MQ、Kafka、JDBC、Redis、MongoDB等等。一、背景作为一个工作多年的程序员或运维人员,相信你一定遇到过以下情况:· 场景一:系统出现异常情况,运维人员没能在第一时间发现,反而是业务方在使用过程中反馈系统崩溃、页面点不开。查看系统日志,发现一直在报连接数据库异常;· 场景二:新功能上线稳定运行一段时间后,用户反馈页面响应越来越慢,打开一个页面要等好久。排查问题,发现是一个慢SQL影响了整个功能的体验。为此,UAVStack开发了数据库监控功能。最初,数据库监控功能只是对数据源、数据库连接池进行了指标采集,通过客户端画像可以查看实时的数据库连接池信息以及操作计数。最近UAVStack又解锁了一项新功能——慢SQL监控,使数据库监控功能更加完善。今天小编就向大家介绍一下数据库监控的具体实现。文章中出现的以下关键字全部用简称代替:· 中间件增强框架:英文MonitorFramework,简称MOF· 健康管理服务:英文HealthManager,简称HM· 监控代理程序:英文MonitorAgent,简称MA二、关键技术&UAV自研框架· MOF Agent注入机制:MOF Agent的注入机制以Java agent以及Javaassit技术作为基础支撑。Java agent负责拦截和转换字节码流,转换过程中使用Javaassist进行解析和修改,在应用服务器生命周期的关键位置注入切点,为MOF框架初始化、应用的画像信息和实时监控数据信息捕获提供基础。· InterceptFramework框架:在应用启动的特定生命周期内改写字节码,植入特定的逻辑处理代码,即画像数据采集,采集的数据包含服务画像以及客户端画像;客户端画像包含Http、Dubbo、MQ、Kafka、JDBC、Redis、MongoDB等常见的开源组件,系统中调用的第三方服务都会被列为是客户端的对象,比如系统中调用了第三方系统的接口都属于客户端的范畴。· CaptureFramework框架:通过InterceptFramework框架在特定的生命周期改写字节码植入特定的逻辑代码,在植入的逻辑代码中可以通过CaptureFramework画像的Monitor捕获体系的能力采集数据以及数据存储。具体实现为采用doCapture来实现在特定的捕获点执行抓取数据行为,采用doPreStore来实现在存储数据结构之前的一些捕获动作,对抓取的数据进行特殊数据的处理,获取到处理完成后的数据再通过UAVServer调用具体的Supporter,最后实现数据落地。三、组成部分慢SQL监控的实现分为四个组成部分:· 慢SQL的动态启停:慢SQL的监控启/停依赖于MOF的Global Filter机制。在应用初始化时,UAV对应用的Filter进行了改写,提供了向MOF下发指令的接口。只要调用接口传入规定的参数便可以实现对慢SQL监控的动态启停。UAV系统中并不存在其它服务直接调用MOF的操作,都是通过MA来完成的。大家可以把MA理解为服务请求方与MOF之间的媒介。· 慢SQL数据采集:依赖InterceptFramework框架在特定的生命周期改写字节码植入特定逻辑,同时采用MOF的CaptureFramework框架进行数据抓取并生成抓取结果。MA会对生成结果的文件进行定时采集并封装成固定的数据结构发送至MQ。· 数据存储:在HM中创建独立的feature进行数据处理,消费MA推送至MQ中的数据,完成数据清洗再存储至ES。由于数据采集的结果进行了特殊的约定,从MQ拿到的数据并不能直接转换成相应的结果,需要进行相应的解析处理才能进行存储(由于采集的数据中字段较多、可能含有特殊的字符会影响对数据的解析,在生成数据结果时有规则约束才能实现数据的正确解析)。数据库监控的feature还提供了查询、统计慢SQL操作的相关接口。· 页面展示:操作页面可自主启停数据库监控,设置慢SQL的时间阈值。启停以及时间阈值的设置依赖于MA向MOF发送指令。页面展示的SQL统计、追踪等信息则通过HM的接口获取;四、功能展示数据库监控目前已实现的功能有SQL分类统计、数据库连接池监控、慢SQL耗时分布统计、慢SQL统计、慢SQL追踪以及调用链/日志关联功能。SQL分类统计:· 数据来源:OpenTSDB(通过画像采集指标)· 针对插入、删除、更新、查询、批量操作进行分类统计· 根据时间分布展示数据库的访问情况,根据时间分布展示数据库的访问情况,展示所选时间段的总访问计数(累计值)· 可以自定义时间条件查询历史数据数据库连接池监控:· 数据来源:OpenTSDB(通过画像采集指标)· 可以查看连接池总连接数、活动连接数、空闲连接数的变化曲线慢SQL耗时分布统计:· 数据来源:ES· 慢SQL统计可根据分类进行展示统计· 针对慢SQL的耗时分布统计,最多查询100条· 根据时间分布展示数据库慢SQL的访问情况,展示当前时间点的慢SQL访问时间、SQL、耗时· 可以根据设置查询历史数据慢SQL统计:· 数据来源:ES· 针对所有类型的SQL· 根据时间分布展示数据库某时间段的慢SQL统计· 可以根据设置查询历史数据慢SQL追踪:· 数据来源:ES· 查询条件为:关键字、是否慢SQL追踪、时间范围· 根据搜索条件查询SQL追踪列表,列表展示内容为:SQL语句、总执行次数、执行总时间、平均执行时间、操作-可查看详情 慢SQL追踪-详情查看:· 数据来源:ES· 慢SQL详情:点击某一条慢SQL统计可查看详情:包含开始执行时间、执行时长、入参、执行结果、影响条数慢SQL追踪-调用链关联:· 应用监控中需开启轻度调用链· 点击某一行详细的执行时间,可以跳转至调用链页面,查看调用链的详细内容(相关的调用链高亮显示)慢SQL追踪-日志关联:· 应用监控中需开启日志归集· 点击某一行详细的调用链内容的日志关联,可查看相应的日志信息,相关的日志行数高亮显示五、总结数据库监控是不容忽视的,好的数据库监控可以帮助优化系统并进行实时预警。通过文中介绍的数据库连接池监控,运维人员可以随时关注数据库连接池的状态,有效防止系统出现连接池活动连接数占满无法连接数据库的情况;而慢SQL监控功能可以动态展示一个系统的SQL情况,帮助优化SQL语句,让系统更稳定。

March 25, 2019 · 1 min · jiezi

Kubernetes Ingress 日志分析与监控的最佳实践

摘要: Ingress主要提供HTTP层(7层)路由功能,是目前K8s中HTTP/HTTPS服务的主流暴露方式。为简化广大用户对于Ingress日志分析与监控的门槛,阿里云容器服务和日志服务将Ingress日志打通,只需要应用一个yaml资源即可完成日志采集、分析、可视化等一整套Ingress日志方案的部署。前言目前Kubernetes(K8s)已经真正地占领了容器编排市场,是默认的云无关计算抽象,越来越多的企业开始将服务构建在K8s集群上。在K8s中,组件通过Service对外暴露服务,常见的包括NodePort、LoadBalancer、Ingress等。其中Ingress主要提供HTTP层(7层)路由功能,相比TCP(4层)的负载均衡具备非常多的优势(路由规则更加灵活、支持金丝雀、蓝绿、A/B Test发布模式、SSL支持、日志、监控、支持自定义扩展等),是目前K8s中HTTP/HTTPS服务的主流暴露方式。Ingress简介K8s中Ingress只是一种API资源的声明,具体的实现需要安装对应的Ingress Controller,由Ingress Controller接管Ingress定义,将流量转发到对应的Service。目前Ingress Controller的实现有非常多种(具体可以参考Ingress Controller官方文档),比较流行的有Nginx、Traefik、Istio、Kong等,在国内接受度最高的是Nginx Ingress Controller。日志与监控日志和监控是所有Ingress Controller都会提供的基础功能,日志一般包括访问日志(Access Log)、控制日志(Controller Log)和错误日志(Error Log),监控主要从日志以及Controller中提取部分Metric信息。这些数据中访问日志的量级最大、信息最多、价值也最高,一般7层的访问日志包括:URL、源IP、UserAgent、状态码、入流量、出流量、响应时间等,对于Ingress Controller这种转发型的日志,还包括转发的Service名、Service响应时间等额外信息。从这些信息中,我们能够分析出非常多的信息,例如:网站访问的PV、UV;访问的地域分布、设备端分布;网站访问的错误比例;后端服务的响应延迟;不同URL访问分布。我们的开发、运维、运营、安全等人员可以基于这些信息完成各自的需求,例如:新老版本发布前后的数据指标对比;网站质量监控、集群状态监控;恶意攻击检测、反作弊;网站访问量统计、广告转化率统计。然而手动搭建、运维一整套的Ingress日志分析与监控系统非常复杂,系统所需要的模块有:部署日志采集Agent并配置采集、解析规则;由于K8s集群中,访问量相对较大,因此需要搭建一个缓冲队列,例如Redis、Kafka等;部署实时数据分析引擎,例如Elastic Search、clickhouse等;部署可视化组件并搭建报表,例如grafana、kibana等;部署告警模块并配置告警规则,例如ElastAlert、alertmanager等。阿里云日志服务Ingress解决方案为简化广大用户对于Ingress日志分析与监控的门槛,阿里云容器服务和日志服务将Ingress日志打通(官方文档),只需要应用一个yaml资源即可完成日志采集、分析、可视化等一整套Ingress日志方案的部署。Ingress可视化分析日志服务默认为Ingress创建5个报表,分别是:Ingress概览、Ingress访问中心、Ingress监控中心、Ingress蓝绿发布监控中心、Ingress异常检测中心。不同角色的人员可根据需求使用不同的报表,同时每个报表均提供筛选框用于筛选特定的Service、URL、状态码等。所有的报表均基于日志服务提供的基础可视化组件实现,可根据公司实际场景进行定制化调整。Ingress概览Ingress概览报表主要展示当前Ingress的整体状态,主要包括以下几类信息:整体架构状态(1天),包括:PV、UV、流量、响应延迟、移动端占比、错误比例等;网站实时状态(1分钟),包括:PV、UV、成功率、5XX比例、平均延迟、P95/P99延迟等;用户请求类信息(1天),包括:1天/7天访问PV对比、访问地域分布、TOP访问省份/城市、移动端占比、Android/IOS占比等;TOPURL统计(1小时),包括:访问TOP10、延迟TOP10、5XX错误TOP10、404错误TOP10。Ingress访问中心Ingress访问中心主要侧重于用于访问请求相关的统计信息,一般用于运营分析,包括:当日UV/PV、UV/PV分布、UV/PV趋势、TOP访问省份/城市、TOP访问浏览器、TOP访问IP、移动端占比、Android/IOS占比等。Ingress监控中心Ingress监控中心主要侧重于网站实时监控数据,一般用于实时监控与告警,包括:请求成功率、错误比例、5XX比例、请求未转发比例、平均延迟、P95/P99/P9999延迟、状态码分布、Ingress压力分布、Service访问TOP10、Service错误TOP10、Service延迟TOP10、Service流量TOP10等。Ingress蓝绿发布监控中心Ingress蓝绿发布监控中心主要用于版本发布时的实时监控与对比(版本前后对比以及蓝绿版本当前对比),以便在服务发布时快速检测异常并进行回滚。在该报表中需要选择进行对比的蓝绿版本(ServiceA和ServiceB),报表将根据选择动态显示蓝绿版本相关指标,包括:PV、5XX比例、成功率、平均延迟、P95/P99/P9999延迟、流量等。Ingress异常检测中心Ingress异常检测中心基于日志服务提供的机器学习算法,通过多种时序分析算法从Ingress的指标中自动检测异常点,提高问题发现的效率。实时监控与告警Ingress作为K8s网站请求的主要入口,实时监控与告警是必不可少的Ops手段之一。在日志服务上,基于上述的报表,只需3个简单的步骤即可完成告警的创建。下述示例为Ingress配置5XX比例的告警,告警每5分钟执行一次,当5XX比例超过1%时触发。除了通用的告警功能外,日志服务还额外支持:多维度数据关联,即通过多组SQL结果交叉判断进行告警,增加告警准确度;除支持短信、语音、通知中心、email外,还支持钉钉机器人通知、自定义WebHook扩展;告警的记录也以日志的形式记录,可以实现对告警失败进行告警的双保险。订阅报告日志服务除支持通过告警方式通知外,还支持报表订阅功能,可使用该功能将报表定期渲染成图片并通过邮件、钉钉群等方式发送。例如每天早上10点向运营群中发送昨日网站访问情况、每周发送报告到邮件组中存档、新版本发布时每5分钟发送一次监控报表…自定义分析如果容器服务Kubernetes版提供的默认报表无法满足你的分析需求,可以直接使用日志服务SQL、仪表盘等功能进行自定义的分析和可视化。尝鲜为了让大家可以体验Kubernetes审计日志功能,我们特别开通了体验中心,大家可以通过 https://promotion.aliyun.com/ntms/act/logdoclist.html 进入,该页面提供了非常多和Kubernetes相关的报表。参考文档阿里云日志服务阿里云容器服务Kubernetes版Ingress日志分析与监控告警配置订阅报表Ingress官方文档Ingress Controller官方文档一站式开发者服务,海量学习资源0元起!阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中–》https://www.aliyun.com/acts/product-section-2019/developer?utm_content=g_1000047140本文作者:元乙阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 19, 2019 · 1 min · jiezi

揭秘:蚂蚁金服bPaaS究竟是什么?

摘要: 分布式金融核心套件,蚂蚁金服bPaaS究竟是什么东东?去年9月,蚂蚁金服在杭州云栖ATEC发布了分布式金融核心套件bPaaS( Business Platform As a Service ),对外开放自身沉淀的“产品合约”、“资产交换”、“资产核心”、“会计核算”、“计价” 等金融核心组件,而这款号称源自于蚂蚁金服十余年业务和技术积累的bPaaS,也被视为是2018年初蚂蚁金服决定将分布式金融核心能力对外输出后,蚂蚁金服推出的第一款重量级的产品。今年3月,蚂蚁金服与南京润和软件联合推出基于分布式金融核心套件bPaaS能力的“新一代分布式金融业务核心平台”。这也意味着蚂蚁金服科技开放进入新阶段,不仅有自主研发的技术输出,也推出了生态互集成模式的新型产品。那么,这款据称能够最快在3个月内复制蚂蚁金服核心技术能力的分布式核心金融套件bPaaS到底都有何神奇之处?它又能给金融行业带来哪些改变?对于蚂蚁金服又意味着什么?这些恐怕还都得从bPaaS的初衷说起。为什么会有bPaaS?蚂蚁金服高级技术专家李玄表示,bPaaS的初衷是为了加速金融行业客户的数字化转型,如果没有bPaaS,金融行业客户要从零开始摸索和开发自己的分布式业务系统,通常会是一个漫长的过程,因为其中要涉及很多分布式的关键技术,以及金融业务模型的抽象等数字化转型中的问题和痛点,非常的复杂和具有挑战性。而bPaaS则重新定义了金融业务领域模型,尽可能规避了分布式技术在核心业务中的落地复杂度,集成了分布式应用场景下的一系列支撑性能力,如全链路核对,业务监控信息标准,全链路压测等,最终形成一个打包方案,开放给金融行业的客户使用。更为重要的是,bPaaS中整合的是蚂蚁金服在十几年的金融业务实践中经过无数次的实际应用验证和检验的切实可行的技术和解决方案,说是“复制蚂蚁金服的核心技术能力”,其实并不夸张。简言之,不同金融机构存在着差异和特色,一套“通用”产品已经不能满足金融行业用户不同的业务需求。而bPaaS能够提供可复用、可运营的共享金融业务处理能力。在保持银行传统核心稳定的前提下,可以根据不同银行差异化的业务场景快速定制新业务场景,支撑银行业务快速发展,敏捷创新。bPaaS的本质说起bPaaS,实际上可以先从bPaaS在软件分层中所处的位置看起,bPaaS实际上是处于SaaS层和PaaS层之间的一个服务,它集成了资产、客户、产品、支付、账务等多个金融业务领域核心引擎组件,整合了金融业务核心领域服务能力,形成一个高度聚合的金融核心能力引擎,赋予了金融行业用户将业务能力引擎与分布式架构平台融于一体,向下能屏蔽分布式事务、底层数据库、中间件等分布式架构平台技术复杂性,向上能支撑银行客户运营和服务创新需求,标准化、可重用的金融核心领域服务能力。李玄表示,bPaaS本质上是一种为用户赋能的服务模式。其核心是将业务中公共的、通用的业务功能沉淀出来形成能力,避免功能的重复建设和维护,更合理地利用技术资源。实际上,bPaaS的精髓就在于,以非常强大的可编排、可组合、可配置、可扩展的技术服务能力,来支撑业务的快速敏捷和灵活多变。为什么要用bPaaS?在谈及为何要使用bPaaS时,李玄认为,金融行业数字化转型的敏捷诉求,是促使金融行业采用分布式金融核心套件的最主要驱动力,而bPaaS具备的三大特点,恰恰能够满足金融行业用户加速数字化转型的需求。首先,bPaaS可以为用户提供业务敏捷能力,所谓业务敏捷能力是指,bPaaS可以非常快速的支撑对业务的创新,它将底层的业务能力进行了抽象和组合编排,并且对于上层的产品是透明的,这使得用户的业务创新可以更加快速敏捷。其次,bPaaS整合了蚂蚁金服的大数据能力。众所周知,蚂蚁金服的众多业务都需要大数据进行赋能,也有众多的业务系统需要用到实时计算和离线计算等大数据技术,而蚂蚁金服将这套业务应用与大数据完美结合的技术预置到了bPaaS之中。此外,bPaaS屏蔽了整个分布式服务的复杂性。例如,蚂蚁金融云上有很多PaaS组件、中间件,单独使用并没有太高门槛,但如果想要把它们整合,去构建一个高效、敏捷、灵活的业务应用最佳实践的话,还是具有相当的难度的。而bPaaS则屏蔽了这样的复杂度,还携带了一些技术风险工具在其中,并内置了蚂蚁金服的各种规范标准,业务监控、技术监控的分析识别,基本上企业用户可以达成“拿来即用”,而如果没有bPaaS,用户可能需要走很多弯路。基于这些特点,金融行业用户通过bPaaS搭建新的新一代分布式金融核心系统,花费时间将可从过去的三年甚至更长时间缩短至3到6个月,并快速配齐弹性伸缩、敏捷开发、秒级容灾等云原生分布式能力,从而大大加速金融行业用户的数字化转型。bPaaS,金融科技开放承载者蚂蚁金服副总裁刘伟光曾如此阐述实行金融科技开放战略的初衷,“我们希望蚂蚁金服的技术开放能够和金融机构的顶层战略相结合,将我们的技术应用到客户最重要或者更创新的场景当中,让科技真正推动业务的腾飞,加速金融机构数字化转型的进程。”而作为承载蚂蚁金服金融科技开放战略的一款拳头产品,bPaaS的意义远非仅仅是一款产品那样简单,也不仅仅是蚂蚁金服金融科技开放战略的实际成果,它更大程度上展示的是蚂蚁金服要长期坚决执行金融科技开放战略的意志和决心,而此次与南京润和的合作也是蚂蚁金服将金融科技开放战略继续深入推进、共建金融行业生态的标志。“这次合作只是一个开始,我们将通过合作与更多生态伙伴一起,共同探索百花齐放、有竞争力的金融科技产品与服务。”刘伟光说。关于蚂蚁金服bPaaS:https://tech.antfin.com/products/DFAS?chInfo=zx一站式开发者服务,海量学习资源0元起!阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中–》https://www.aliyun.com/acts/product-section-2019/developer?utm_content=g_1000047140本文作者:华蒙阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 19, 2019 · 1 min · jiezi

阿里巴巴复杂搜索系统的可靠性优化之路

背景搜索引擎是电商平台成交链路的核心环节,搜索引擎的高可用直接影响成交效率。闲鱼搜索引擎作为闲鱼关键系统,复杂度和系统体量都非常高,再加上闲鱼所有导购场景都依靠搜索赋能,搜索服务的稳定可靠成为了闲鱼大部分业务场景可用能力的衡量标准;如何保障搜索服务的稳定和高可用成为了极大的挑战。闲鱼搜索作为闲鱼核心系统,有以下几个突出的特点:数据体量大:对接闲鱼数十亿的商品,引擎有效商品数亿;索引庞大:闲鱼非结构化商品需要与算法团队合作,预测抽取有价值的结构化信息,建立索引;已创建数百的索引字段,整个引擎索引数据量为T级别;增量消息多:日常增量消息QPS 数十万,峰值QPS可以达到 数百万;查询复杂:很多特殊业务场景,查询条件要求苛刻而复杂;比如召回GROUP分组统计,聚合/打散/去重,关键词复合运算查询等;实时性性要求高:闲鱼中都是二手商品,卖家商品的库存都是1;商品上下架频繁,对引擎数据的同步更新实时性要求非常高;智能化扩展:由于闲鱼商品非结构化特性,为保障召回数据的效果以及相关性;需要引擎具备智能插件扩展的能力,能与算法开发人员协同;鉴于闲鱼商品搜索引擎以上主要特点,本文详细介绍闲鱼搜索在系统高可用上做的各种努力,希望能给读者一些启发。闲鱼搜索整体架构正式引出搜索稳定性保障方案之前,我们需要对闲鱼搜索技术有一个简单大致的了解;我们比较过很多外部开源的搜索引擎,都不能完美支持背景中所列的需求点;闲鱼使用的是阿里巴巴最新研发的搜索引擎平台Ha3,Ha3是一款非常高效,智能强大的搜索引擎,它完全满足闲鱼搜索的要求;Elasticsearch是基于Lucene的准实时搜索引擎,也是比较常用的开源搜索引擎,但是其在算法扩展支撑/绝对实时的能力上与Ha3相差甚远;在同等硬件条件下,基于1200万数据做单机性能对比测试发现,Ha3比ElasticSearch开源系统的QPS高4倍,查询延迟低4倍;Elasticsearch在大规模数据量场景下的性能和稳定性与HA3相比尚有很大的差距。01闲鱼搜索体系运行流程下图是闲鱼搜索体系系统结构图,主要分在线和离线两个流程;索引构建流程索引构建即我们所谓的离线流程,其执行者BuildService①,负责将不同存储类型的纯文本商品数据构建成搜索引擎格式的索引文件。原始的商品数据有两类,一类是存放在存储上的全量商品数据,这个定期(一般以天为周期)通过DUMP②产出,另一类为实时变更的数据,在商品信息变更后,由业务系统即时同步给消息系统Swift③。最终分发给在线服务的Searcher④更新索引。搜索查询流程搜索查询即我们所谓的在线流程;闲鱼搜索服务应用A发起搜索请求,通过SP⑤进行服务能力编排;首先SP发起QP⑥算法服务调用,进行用户意图预测,并获取排序辅助信息;然后结合QP返回的结果加上业务系统的查询参数,向Ha3搜索引擎发起查询请求;Ha3搜索引擎QueryService⑦中Qrs⑧接收到查询请求后,分发给QueryService中的Searcher进行倒排索引召回、统计、条件过滤、文档打分及排序、摘要生成;最后Qrs将Searcher返回的结果进行整合后返回给SP,SP经过去重再返回给业务系统;02闲鱼搜索体系团队构成闲鱼搜索的运维体系,是一个相当复杂的构成;其中涉及很多团队的鼎力协作;首先必须有Ha3搜索引擎团队在底层提供核心的搜索引擎能力支持;主要负责Ha3搜索引擎核心能力的建设维护;提供并维护引擎运维操作平台和实时引擎搜索服务。然后是算法团队,在Ha3搜索引擎上进行定制,优化用户搜索体验;对闲鱼非结构化的商品通过算法模型进行理解,预测抽取出结构化信息,供搜索引擎商品索引使用;监控维护QP集群服务;开发并使用Ha3引擎排序插件,进行召回数据分桶实验,验证调优。最后是我们业务工程团队,串联整个搜索流程,监控维护整个搜索链路的可用性;主要维护搜索对接的数据,Ha3搜索引擎接入管理,进行SP搜索服务编排,制定合理的查询计划;以及闲鱼搜索统一在线查询服务的研发维护工作。本文亦是从业务工程团队的工作角度出发,阐述如何对复杂搜索业务系统进行稳定性的保障;稳定性治理01部署架构优化独立网关部署Ha3引擎通过SP提供基于HTTP协议的搜索服务API,对类似闲鱼这样复杂的搜索场景,每个闲鱼上层的业务如果都通过拼接SP HTTP接口参数的形式来使用搜索服务,所有上游业务都需要关心SP的拼接语法,会使开发成本剧增,而且如果由于特殊原因SP进行了语法调整或者不兼容升级,那么所有上层业务都需要修正逻辑,这样的设计不合理;为了让业务系统与搜索系统完全解耦,并且提高搜索服务的易用性,闲鱼搜索通过统一的业务搜索网关来提供简单一致的分布式服务,供闲鱼各上层搜索业务使用,并与SP对接,屏蔽掉SP对上游业务系统的穿透;最开始闲鱼搜索服务与其他很多不相关的业务场景共建在一个比较庞大的底层应用中;这种部署方式对稳定性要求很高的业务模块来说有非常大的安全隐患;1.各业务模块会相互影响;存在一定程度的代码耦合,同时还涉及机器资源的竞争,风险比较高;2.应用太过庞大,严重影响开发协作的效率和代码质量;于是将闲鱼搜索服务部署到独立的容器分组,新增应用A供闲鱼搜索服务专用,作为各业务使用搜索服务的独立网关,同时对接下游的SP搜索服务;保证服务是隔离和稳定的。前后部署图如下所示;多机房容灾部署在最初,闲鱼商品搜索服务对接的Ha3搜索引擎只部署在一个机房;当此机房出现比较严重的问题时,对上游业务影响非常大,甚至会引发故障;鉴于此,对闲鱼商品搜索引擎的在线离线集群进行双机房部署容灾;在详细展开之前,我们先大致理解下Ha3引擎DUMP流程的原理;如上图所示,Ha3引擎DUMP流程大致流程可以简单分为以下几步:准备源数据:评估业务需求,将需要接入引擎的数据准备好;一般业务数据大部分都是DB数据表,也有少数的ODPS⑨离线数据表;算法团队提供的数据绝大部分都是ODPS离线数据表;DUMP拉取数据:通过Ha3引擎团队提供的运维平台,可以将这些表的某些数据字段接入到创建好的搜索引擎中,后续DUMP执行的时候,Ha3离线引擎会拉取这些接入的表字段数据,形成一份引擎自用的镜像数据表,在这一步中,我们可以使用引擎团队提供的UDF工具,对数据进行清洗/过滤等处理;数据Merge:引擎将所有的镜像表数据,通过我们指定的主键进行Join;最终形成一份数据大宽表;供引擎创建索引使用;这一步数据Join后,还可以对最终的数据通过UDF进行进一步的清洗/过滤处理,验证通过的数据才会进入到大宽表;创建更新索引:Ha3离线引擎通过buildService,使用大宽表的数据,与事先我们在Ha3引擎运维平台指定好的索引Schame对齐,重新构建索引;以上流程可以通过Ha3引擎运维平台手动触发执行,执行完上述流程后,会生成一份新的索引;新的索引集群服务可用后,在线实时模块会将查询服务切换到新的索引集群上,完成一次索引的更新;这个完整流程我们将其称之为"全量";全量完成后,当系统有新的商品信息变动,且相应的数据表有启用实时更新(我们称之为增量功能,DB表是通过binlog/ODPS表是通过Swift消息通知的方式实现),则离线DUMP引擎会感知到此次变动,进而将相应的镜像数据表中商品数据更新,并会按上述离线DUMP流程中的步骤,将这个改动信息一直向引擎上层投递,直至成功更新引擎索引中的相应数据,或者中途被系统规则丢弃为止;这个实时数据更新的流程我们称之为"增量";增量更新还有一条通道:算法同学可以使用特殊的方式,通过Swift增量消息的方式直接将需要更新的数据不通过DUMP流程,直接更新到Ha3引擎索引中。闲鱼商品量飞速增长,目前已经达到数十亿;接入了数百的索引字段,由于闲鱼商品非结构化的原因,索引字段中只有一小部分供业务使用;另外大部分都是算法接入的索引,比如大量抽出来的标签数据,向量化数据等,这些向量化数据非常大;最终的情形表现为闲鱼商品搜索引擎的DUMP处理逻辑比较复杂,而且索引数据总量异常庞大,增量消息量也处在非常高的水位,再加上闲鱼商品单库存的现状;因此对数据更新的实时性要求非常高,这些都给稳定性带来了极大的制约。索引数据是搜索引擎的内容核心,如果进入引擎的索引数据有问题,或者新变更的数据没有更新到引擎索引中,将直接影响搜索服务的质量;搜索引擎单机房部署期间,时常会因为一些不稳定的因素,导致DUMP全量失败,或者增量延迟,甚至停止;一旦引擎DUMP出现问题,需要恢复基本都很困难,很多场景下甚至需要重新跑全量才能解决问题;但是闲鱼商品索引数据体量较大,做一次全量往往要大半天,没有办法快速止血,对业务造成了较大的影响;于是对搜索引擎进行双机房部署容灾(M/N机房),互为备份;两个离线DUMP机房采用相同的引擎配置和相同的数据源,产出相同的索引数据,分别供两个在线机房使用,两个机房的在线流量比例也可以按需实时调整;当M机房出现不可逆问题时,自动或手动将流量全部切换到N机房,实现线上快速止血,然后再按部就班排查解决M机房的问题。下图为最终的搜索机房部署情况;进行引擎双机房部署虽然增大了机器资源成本,但是除了上述业务容灾优点外,还有以下好处;引擎需求的发布,之前缺乏有效的灰度流程;当搜索引擎有重大变更/升级,出现高风险的发布时,可以先在单机房小流量beta测试,数据对比验证通过后,再发布到另一个机房;平常单机房能支撑全部搜索查询业务的流量,当遇到大促或大型活动时,将两个机房同时挂载提供服务,这样搜索服务能力和容量直接能翻倍;避免了单机房频繁扩缩容的困扰;性能评估时,可以单独对未承载流量的机房进行压测,即使由于压测导致宕机也不会对线上业务造成影响;02流量隔离上文独立网关部署一节中讲到,闲鱼搜索通过统一的业务搜索网关来提供简单一致的分布式服务,供闲鱼各上层搜索业务使用;使用统一的微服务,就必然带来上游不同业务优先级和可靠性保障的问题。闲鱼搜索服务支撑了种类繁多的上游业务,为了统一对各业务场景的流量/服务质量进行度量和管理,在上游业务接入闲鱼搜索服务时,需要申请使用相应的业务来源,这个业务来源标示会伴随着整个搜索查询的生命周期;在日志采集时直接使用,从而可以针对业务维度进行监控告警,实时感知业务运行的健康情况(简单监控视图如下图),也可以对具体业务进行流量管控,降级限流等;搜索业务来源生命周期图03分级监控体系对高稳定性系统,当出现问题,或者即将产生问题时,能即时感知,显得尤为重要;方便实时进行跟踪处理,防止继续扩大;目前使用的主要手段是建立健全完善的多维度监控告警体系;引擎基础服务监控使用监控可以快速发现问题,如果监控的粒度够细还能进行问题的快速定位;不过有时也会存在误报或者漏报的情况,因此真实的监控一定要结合每个业务自身系统的特性,梳理出关键链路,针对关键链路进行多维度360度无死角监控,并且进行合理的预警规则设置,监控预警才会比较有效;闲鱼搜索引擎在线离线流程/各上游重要应用系统的核心链路上,建立了完备的日志数据采集模块,对关键指标进行了精准的监控预警设置;做到任何问题都能及时被感知到。下图是搜索服务相应核心日志以及监控告警情况。模拟用户行为的在线业务监控上文提到,闲鱼搜索引擎索引体量比较大,需要很多团队共同协作,搜索流程复杂度比较高;而且有算法同学的加入,对闲鱼非结构化的商品做了很多AI识别,加上闲鱼都是单库存商品,对引擎实时性要求非常高;前面已经做了一些容灾的保障方案;但是对实时性的感知上还需要更进一步,才能及时知道数据的准确情况,是否存在更新延迟,以及延迟时间大概是多久等一系列健康度信息;解法是从业务层面进行实时性的监控告警;提取出闲鱼商品量比较大更新也比较频繁的类目K,在闲鱼的后台业务系统中,通过jkeins间隔一定时间(时间步长可以实时调整),使用类目K作为关键词和品类,根据商品更新时间索引降序招回,模拟用户轮询的方式发送搜索查询请求,召回满足要求的第一页商品;然后根据引擎召回数据的商品更新时间与当前系统时间进行差值比对,大于阈值时长(可以实时调整)说明存在较严重的数据更新延迟,则进行告警信息发送;04压测全链路压测对搜索服务以及各上游业务系统进行全链路压测改造;并使用线上真实的用户请求构造大批量的压测数据,在保证不影响线上业务正常进行的前提下,验证链路在超大流量模型下系统的容量和资源分配是否合理,找到链路中的性能瓶颈点,验证网络设备和集群容量。引擎单链路压测Ha3搜索引擎在线流程,支持通过回放线上高峰时段查询流量的方式,进行引擎在线服务性能压测。Ha3搜索引擎离线流程,支持通过回放一段时间Swift增量消息的方式,进行引擎DUMP增量性能压测。05灰度发布闲鱼商品的非结构化特性,离不开算法赋能;在我们的研发周期中,与两个算法团队,相当多的算法同学保持着深度合作;给闲鱼搜索带来了跨越式的发展,但是在团队协作和研发效率上也给我们带来了极大的挑战。算法团队、引擎团队、加上业务工程团队,非常大的搜索项目开发小组,每周都有非常多的新算法模型,新的引擎改造,新的业务模块需要上线。大量的新增逻辑改动直接上线,会带来很多问题;首先是代码层面,虽然预发环境有做充分测试,但也难保没有边缘逻辑存在测试遗漏的情况;即使预发测试都完全覆盖,但线上和预发终究环境不同,线上大流量环境及有可能会暴露一些隐藏的代码问题;第二方面,假使代码没有任何质量问题,但所有功能全部绑定上线,所有逻辑都混杂在一起,如何评定某个模块上线后的效果成为极大的困扰,特别是算法模型的优化,和业务上新模式的尝试,都需要根据详细的效果反馈数据指标来指导进行下一步的优化方向;因此急需一套灰度实验保障体系,不仅可以用来协调和隔离整个搜索业务中各个模块,做到对各模块进行单独的效果评估;并且还能提高大家的协作效率,让各模块能进行快速试错,快速迭代;为了解决以上非常重要的问题,业务工程团队开发了一套实验管理系统,用来进行搜索实验灰度调度管理,系统功能如上图所示;其具有以下特点。实验灵活方便,一个实验可以包含多个实验组件,一个实验组件可供多个实验使用;一个实验组件又可以包含多个实验分桶;各页面模块的实验都可以在系统中实时调控,包括实验的开/关;以及实验之间的关系处理;搜索实验埋点全链路打通,统计各种实验数据报表;统计数据接入了闲鱼门户和通天塔,可查看各个指标不同分桶的实验曲线;提升实验迭代速度,提升算法/业务效率,快速试错,加速搜索成交转化的增长;06应急预案根据评估分析或经验,对搜索服务中潜在的或可能发生的突发事件的关键点,事先制定好应急处置方案;当满足一定的条件时进行多维度多层级的自动降级限流,或者配置手动预案进行人工干预;任何时候发现线上问题,首先需要快速止血,避免问题的扩大;具有自动预案会自动发现问题,自动熔断,我们需要密切关注系统的运行情况,防止反弹;若出现反弹,并且对业务有较大影响时,快速人工介入执行降级预案;完成止血后再详细排查具体原因,当短时间无法确定问题根源时,如在问题出现时有过变更或发布,则第一时间回滚变更或发布。对系统中各级的依赖服务,熔断降级已经系统负载保护,我们使用的是阿里巴巴自主研发的资源调用控制组件Sentinel[4],目前已经开源;或者也可以使用Hytrix降级限流工具;07问题排查将闲鱼搜索链路接入阿里搜索问题排查平台,搜索实时查询请求的各个步骤输入的参数信息/产出的数据信息都会在此工具平台详细展示,方便各种问题的排查跟进,以及数据信息对比;可以对各查询条件下各个分桶的实验召回数据进行可视化显示,方便各个实验间的效果对比;以及每个召回商品的各类细节信息查看,包括业务数据和算法标签数据,还包含每个商品对应的各引擎插件算分情况,都能详细阅览;还可以根据商品Id,卖家Id,卖家Nick进行商品索引信息的披露;可以排查相应商品在引擎索引中的详细数据,如果数据和预想的有出入,具体是离线DUMP哪一步的处理逻辑导致的状态异常,都能一键查询。接入此问题排查平台后,能非常直观的掌握引擎的运行状况,搜索召回的链路状态;对快速发现问题根源,即时修复问题都有非常重大的作用!总结与展望本文主要介绍闲鱼如何保障复杂场景下搜索引擎服务的稳定性,主要从架构部署,隔离性,容量评估,风险感知&管控等方面进行阐述,介绍了如何稳定支撑20+线上搜索业务场景,做到了快速发现恢复线上问题,高效提前预知规避风险案例50+,极大程度提升了搜索服务的用户体验,保障了闲鱼搜索全年无故障;经过上述治理方案后,闲鱼搜索系统稳定性得到了极大的保障,同时我们也会继续深耕,在搜索能力的高可用、更易用上更进一步,让上游业务更加顺滑;希望给各位读者带来一些思考和启发。本文作者:元茂阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

March 18, 2019 · 1 min · jiezi

我们总结了每个技术团队都会遇到的 4 个难题

阿里巴巴 2019 年实习生校园招聘已经启动,为此,我们整理了一篇《每个技术团队都会遇到的4个难题》,帮助即将从校园进入公司实习的后端程序员,以实践的视角,看看一个后端技术团队会遇到的一些难题。虽然,技术上的难题远不止于此,但如果能从这篇文章中获得一些职业体感,也许对你的实习面试会有所帮助。- 正文开始 -从单个应用到多个应用,从百千级别的访问流量到十万、百万级别,从两三个人的创业技术团队到上千人的技术团队矩阵,这些过程中,技术团队都避不开了以下 4 个问题:如何预测业务峰值时的容量如何提升业务的稳定性如何提高业务的监控能力如何提高开发效率如何预测业务峰值时的容量早期的做法是在开发测试环境进行压测,来评估线上容量,但线下环境的机器规模,和线上差距很大,很难通过线下推导线上。根据经验,将采购的机器加入不同的应用里面,这时候就会遇到一个问题: 最大业务峰值容量是多少?这个问题,其实挺难回答的。这个应用多加几台,那个应用少加几台,整体的业务峰值承受能力就会不一样,加减的规则很难通过人的经验来确定,最多只能作为一些辅助判断。另外,核心交易链路的梳理,也是一个体力活,如果依赖人为处理,有可能会漏掉一些看起来不那么重要的”分支”,这是整个容量不确定的地方,可变的因子很多。比较有效的方式, 是在生产系统部署全链路压测,来验证各个生产环节是否能经受住各类流量的访问,让真实的流量来访问生产环境,实现全方位的真实业务场景模拟,确保各个环节的性能、容量和稳定性均可做到万无一失。如何提升业务的稳定性日常的各种运营活动,都有可能带来巨大的流量高峰,除了通过引入全链路压测来验证各个生产环节是否能经受住各类流量的访问, 构建系统的高可用保障能力也很关键,涉及多个组件或模块,例如软负载和配置中心、服务接入和调度编排、消息接收和发送、容器和调度、限流和降级 等。运营一次活动,最大的流量峰值是可以预测的,这就是服务的最大接待能力,比如50万笔的交易创建峰值,那超过的怎么办?这时候,采用限流的方式,被限流的客户在某一段时间内无法进行购物,一旦系统恢复服务能力,就可以继续服务被限流的客户,从而避免因流量超过上限,而影响整个平台的客户。如何提高业务的监控能力分布式应用系统在协作性,扩展性和一定的容错性方面,体现出了优势,但是在监控、运维和诊断层面,面临相当大的挑战。早期,架构师可以画出整个应用系统的交互架构图,随着业务的发展,当拥有大量的应用、微服务和容器,即便整理了一幅交互架构关系图,也会因为应用系统的变更,新需求的实现,整个应用系统的交互又会发生变化,这种变化无处不在,每天都在发生。因此,随着业务量的增加,需要覆盖面广且深的全链路跟踪监控系统 ,来诊断调用链的问题。越是复杂的业务形态,定位的难度越大,就越需要全方位、360度无死角的监控,因此,建立一个平台化、跨领域和立体化的监控,能极大的缩短业务遇到问题时的恢复时间。如何提高开发效率开发效率是一个很广泛的话题。不同的开发岗位,不同的使用场景,会有不一样的开发效率工具。这里,我们介绍几款后端工程师经常会用到的效率工具。云端部署效率工具:Cloud Toolkit 是一款 IDE插件,可以帮助开发者更高效地开发、测试、诊断并部署应用。借助这个工具,开发者能够方便地将本地应用一键部署到任意机器,或 ECS、EDAS、Kubernetes,并支持高效执行终端命令和 SQL 等。点此了解详情。MacOS 搜索利器:MacOS 自带的聚焦搜索(Spotlight),可以将文稿、邮件、应用等整合在一起,通过关键词匹配来进行搜索。Alfred 可以看作是Spotlight的增强版,是计算机依赖者的效率神器,支持添加自定义网络搜索引擎,指定规则精准定位本地文件,以及在命令框内使用计算器、词典等实用工具。画图效率工具:系统架构图是为了抽象的表示软件系统的整体轮廓和各个组件之间的相互关系和约束边界,以及软件系统的物理部署和软件系统的演进方向的整体视图。通过架构图,可以让干系人理解、遵循架构决策,就需要把架构信息传递出去。架构图就是一个很好的载体,所谓一图胜千言。点此了解详情。JSON 浏览效率插件对于 JSON 的数据,如果不编排,格式查看起来会很费劲。JSON-handle 是一款对 JSON 格式的内容进行浏览和编辑,以树形图样式展现 JSON 文档的插件,支持实时编辑。Java 代码规约扫描效率插件这是一款 Java 代码规约扫描工具,旨在以工具的手段进行代码规约的落地,项目包含三部分:PMD规则实现、IntelliJ IDEA 插件、Eclipse 插件,帮助开发人员在工程研发的多个阶段进行代码规约检查, 降低故障率、提升编码效率和质量。点此了解详情。当然,除了这些现成的效率工具,提升整个技术团队的开发效率,需要单独开发或改造一些系统,例如团队协作平台、服务化改造等,当你以实习生的身份加入公司后,若有机会参与到这些提升开发效率的项目过程中。由此形成的效率意识,将会影响到你今后的工作习惯和理念。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 14, 2019 · 1 min · jiezi

NoSQL最新现状和趋势:云NoSQL数据库将成重要增长引擎

NoSQL最早起源于1998年,但从2009年开始,NoSQL真正开始逐渐兴起和发展。回望历史应该说NoSQL数据库的兴起,完全是十年来伴随互联网技术,大数据数据的兴起和发展,NoSQL在面临大数据场景下相对于关系型数据库运用,这一概念无疑是一种全新思维的注入。接下来本文重点梳理下NoSQL领域最新发展趋势以及阿里云NoSQL最新现状,以飨读者。云NoSQL数据库成为数据库领域重要增长引擎云化趋势不可避免,根据Gartner的报告,2017年超过73%的DBMS增长来自云厂商,Gartner象限里面AWS在领导者象限上升趋势明确,老牌厂商下滑严重。在2018年Gartner报告中,阿里云数据库更是中国唯一首次入围远见者象限。而在众多云厂商里面增长最快的又是NoSQL数据库,云NoSQL成为数据库领域重要增长引擎。阿里云覆盖了主流的NoSQL引擎阿里云集团是国内最早提出数据战略,本身也拥有最大体量的数据,是最早投入NoSQL数据库技术研发,目前也拥有国内最大的专家团队。在持续十年技术加持下,阿里云NoSQL目前覆盖了所有主流的NoSQL数据库,如Redis/mongodb/HBase/图等等。下表是目前阿里云目前覆盖的主流的NoSQL数据库。NoSQL数据库存储类型典型场景Redis/MemcacheKey/Value缓存,搭配所有数据库使用;直播、视频等各种在线场景。MongoDB文档非常适合游戏、地图、基于位置的数据查询等等场景。HBase Wide Column风控、画像、用户行为数据,用户详单,对象存储等等。ElasticSearch/Solr倒排索引文本模糊查询JanusGraph/GDB图关系分析和挖掘,金融、风控阿里云NoSQL数据库多项独家关键技术领先竞争对手,是国内当之无愧的NoSQL数据库排头兵。拥有业界最全的产品的形态以Redis为例,全系覆盖全系列支持2.X, 3.X 4.X, 支持从适合开发者的单节点到多中心的各种产品形态,架构任意变换, 自动容灾, 全面监控。通过各种产品形态,阿里云有能力服务从开发者、中小企业、大企业各种客户,满足不同客户对性价比,SLA,可靠性,管控的各种需求。在最新版本跟进上,阿里云NoSQL也一直在走云厂商前列,18年6月6日全球首发HBase 2.0,同年10月份又全球第一家云厂商支持MongoDB 4.0版本。另外预告一下,这个月我们会推出全新redis 5.0版本,满足众多企业对新版本的诉求,敬请期待!把数据可靠性作为重中之重对大多数公司来说数据的安全性以及可靠性是非常重要的,如何保障数据的安全以及数据的可靠是大多数数据库必须考虑的。2016 IDC的报告表示数据的备份(data-protection)和数据恢复(retention)是NoSQL的最基础的需求之一,阿里云NoSQL数据库也一直把怎么保障客户的数据安全放在首位。以云HBase为例,传统数据库备份恢复的能力都是TB级别,在交易等场景下面是足够的,但面向大数据场景就捉襟见肘了。云HBase通过垂直整合高压缩、内核级优化等能力,将备份恢复的量级成功推高百倍以上,做到 百TB级别甚至更高 ,让客户在大数据量场景下也无后顾之忧。云HBase支持全量(备份集)备份、全量(备份集)恢复、增量(实时)备份、增量(时间点)恢复完整备份恢复能力。全球分布式能力助力企业解决业务出海、地域级灾备、全球同服/多活、跨域数据迁移等关键业务云厂商之所以有这么强大的活力,除了在数据库内核本身长足的进步之外,结合云服务整体生态的创新是重要的一环。阿里云NoSQL数据库持续发力和覆盖了全球分布式能力,助力企业参与全球业务竞争。是否具备全球扩展和分布式的能力,是云NoSQL数据库重要的入门门槛。以Redis为例,我们再18年8月份全球云厂商首家推出Redis全球多活,解决多媒体、游戏、电商等多行业客户业务出海、地域级灾备、全球同服/多活、跨域数据迁移的诉求。多项关键能力独步领域内:全球多活:内核级别支持,实现多节点全球容灾。高可用:同步通道支持断点续传,容忍天级别的隔断,子实例HA自动切换
高性能:单通道10万TPS,高于Redis处理速度;延迟低、洲际内百毫秒延迟
支持数据最终一致性:CRDT冲突解决方案+数据一致性检测,基于Redis内核改造,原生Redis内核无此功能。融合多模和多负载能力,提供一站式低成本数据处理平台2018年12月13日第8届中国云计算标准和应用大会隆重发布X-Pack,在云HBase基础上新增多模型和多负载支持。
多模型支持:同时支持KV、时序、时空、图、文档等多种数据模型,内置丰富处理能力,让业务开发效率提升百倍。多负载支持:ApsaraDB HBase在在线能力的基础上,融合流处理、批处理、OLAP,OLTP、高速对象存储,全文检索等能力,提供客户业务开箱即用的能力。通过多模型和多负载的支持,基于Apache HBase及HBase生态构建的 低成本、一站式 数据处理平台,支持Spark、二级索引、全文查询、图、时序、时空、分析等能力,是物联网、风控推荐、对象存储、AI、Feeds等场景首选数据库。多项独家企业级能力,领域内领先,不负重托客户选择NoSQL数据库服务,一个非常看重的关键点是就是企业级能力,解决企业生产开发过程中,管理,维护各个方案的瓶颈。NoSQL数据库服务深度结合企业应用场景,经过长期的发展,目前具备了多项独家企业级能力,以MongoDB为例:跨域双活:数据双向同步,相比现有通道产品提升100%效率,业界领先。首创物理+逻辑备份双能力:物理备份,相比开源版本备份效率提升100%,恢复效率提升300%。创新性提供逻辑snapshot能力,解决政企等定期大批量数据更新需求,同架构下性价比提升100%。秒级监控及智能诊断能力:提供每秒粒度的监控数据采集,监控精度提升数十倍。结合监控、审计等数据提供智能诊断,分析系统运行瓶颈并自动化提供优化建议。下面是云MongoDB和自建的社区版本的一个对比,云服务再搭建、安全、优化、运维、定制等各个方面全面胜出,全面降低客户的TCO。即将重磅发布CloudNative图数据库随着企业的数据越来越多,业务越来越复杂,客户提出了很多实时在线的高性能图数据存储和查询服务的诉求。我们也将再本月重磅发布阿里云首款Cloud Native专业的图数据库。新的图数据库将会支持丰富的能力,并在易用性,高可用站上一个新的高度,非常适合拥有社交网络、金融欺诈检测、实时推荐引擎、知识图谱、网络/IT运营方面诉求的客户。展望未来,阿里云NoSQL数据库也会持续围绕客户业务,成本,运维各个方面进行优化和创新,成就客户,争做最好的NoSQL数据库而持续努力!最后,阿里即将召开2019阿里云峰会 北京站有专门的数据库专场《数据库专场:云时代的企业级数据库架构与实践》,进一步分享数据库的最新发展趋势,欢迎大家报名:
https://www.yunqi.org/goPage?page=bj_signup_mb&activeId=2&ticketTypeId=39&channelId=12本文作者:所在jason阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 12, 2019 · 1 min · jiezi

SpringBoot使用SOFA-Lookout监控

本文介绍SpringBoot使用蚂蚁金服SOFA-Lookout配合Prometheus进行监控。1.SOFA-Lookout介绍上一篇已经介绍使用Prometheus进行暴露SpringBoot的一些指标进行监控,传送门,这一篇介绍如何使用SOFA-Lookout配合Prometheus。SOFA-Lookout是蚂蚁金服开源的一款解决系统的度量和监控问题的轻量级中间件服务。它提供的服务包括:Metrics 的埋点、收集、加工、存储与查询等。正如介绍的,SOFA-Lookout提供了一些常用的监控指标,比如JVM线程,JVM类加载,JVM内存,JVM垃圾回收,机器文件系统信息和机器信息。在1.5.0版本之后默认也提供了一些Linux操作系统的信息。具体可以查看:https://www.sofastack.tech/sofa-lookout/docs/client-ext-metrics2.SpringBoot使用SOFA-Lookout2.1 配置依赖新建项目,在项目中加入SOFA依赖,完整pom如下所示。<?xml version=“1.0” encoding=“UTF-8”?><project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> <groupId>com.dalaoyang</groupId> <artifactId>springboot2_sofa_lookout</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot2_sofa_lookout</name> <description>springboot2_sofa_lookout</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alipay.sofa.lookout</groupId> <artifactId>lookout-sofa-boot-starter</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>com.alipay.sofa.lookout</groupId> <artifactId>lookout-reg-prometheus</artifactId> <version>1.5.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>2.2 配置SOFA-Lookout端口这里需要配置一个SOFA-Lookout的端口,生产环境使用的话一定要查看这个端口是不是被占用了。配置如下,这里配置的端口是8081。spring.application.name=springboot2_sofa_lookoutcom.alipay.sofa.lookout.prometheus-exporter-server-port=8081其实到这里,SpringBoot项目已经配置完成了,当然还可以自定义一些指标,这里不做介绍。3.Prometheus配置Prometheus需要配置一下刚刚SOFA-Lookout的端口,如下: - job_name: ‘springboot2_sofa_lookout’ scrape_interval: 5s static_configs: - targets: [’localhost:8081’]4.Grafana这里也可以将Prometheus展示给Grafana,我也查询了很多,但是貌似目前Grafana还没有默认推荐的Dashboard,大家可以根据情况自行构建,当然,如果有好的也希望可以推荐一下。5.测试启动SpringBoot应用,控制台如下所示。看到红框部分就是启动成功了。接下来查看Prometheus界面,如下。这里Grafana在看一下Grafana界面,如图。6.源码源码地址:https://gitee.com/dalaoyang/springboot_learn/tree/master/springboot2_sofa_lookout本文作者:dalaoyang阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 12, 2019 · 1 min · jiezi

SpringBoot使用prometheus监控

本文介绍SpringBoot如何使用Prometheus配合Grafana监控。1.关于PrometheusPrometheus是一个根据应用的metrics来进行监控的开源工具。相信很多工程都在使用它来进行监控,有关详细介绍可以查看官网:https://prometheus.io/docs/in…。2.有关GrafanaGrafana是一个开源监控利器,如图所示。从图中就可以看出来,使用Grafana监控很高大上,提供了很多可视化的图标。官网地址:https://grafana.com/3.SpringBoot使用Prometheus3.1 依赖内容在SpringBoot中使用Prometheus其实很简单,不需要配置太多的东西,在pom文件中加入依赖,完整内容如下所示。<?xml version=“1.0” encoding=“UTF-8”?><project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!– lookup parent from repository –></parent><groupId>com.dalaoyang</groupId><artifactId>springboot2_prometheus</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot2_prometheus</name><description>springboot2_prometheus</description><properties> <java.version>1.8</java.version></properties><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> <version>1.1.3</version> </dependency></dependencies><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins></build></project>3.2 配置文件配置文件中加入配置,这里就只进行一些简单配置,management.metrics.tags.application属性是本文配合Grafana的Dashboard设置的,如下所示:spring.application.name=springboot_prometheusmanagement.endpoints.web.exposure.include=*management.metrics.tags.application=${spring.application.name}3.3 设置application修改启动类,如下所示.@SpringBootApplicationpublic class Springboot2PrometheusApplication {public static void main(String[] args) { SpringApplication.run(Springboot2PrometheusApplication.class, args);}@BeanMeterRegistryCustomizer<MeterRegistry> configurer( @Value("${spring.application.name}”) String applicationName) { return (registry) -> registry.config().commonTags(“application”, applicationName);}}SpringBoot项目到这里就配置完成了,启动项目,访问http://localhost:8080/actuator/prometheus,如图所示,可以看到一些度量指标。4.Prometheus配置4.1 配置应用在prometheus配置监控我们的SpringBoot应用,完整配置如下所示。my global configglobal: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s).Alertmanager configurationalerting: alertmanagers:static_configs:targets: # - alertmanager:9093Load rules once and periodically evaluate them according to the global ’evaluation_interval’.rule_files: # - “first_rules.yml” # - “second_rules.yml"A scrape configuration containing exactly one endpoint to scrape:Here it’s Prometheus itself.scrape_configs:job_name: ‘prometheus’ static_configs:targets: [‘127.0.0.1:9090’]以下内容为SpringBoot应用配置job_name: ‘springboot_prometheus’ scrape_interval: 5s metrics_path: ‘/actuator/prometheus’ static_configs:- targets: [‘127.0.0.1:8080’]4.2 启动Prometheus启动Prometheus,浏览器访问,查看Prometheus页面,如图所示。点击如图所示位置,可以查看Prometheus监控的应用。列表中UP的页面为存活的实例,如图所示。也可以查看很多指数,如下所示。5.Grafana配置启动Grafana,配置Prometheus数据源,这里以ID是4701的Doshboard为例(地址:https://grafana.com/dashboard…)如图。在Grafana内点击如图所示import按钮在如图所示位置填写4701,然后点击load。接下来导入Doshboard。导入后就可以看到我们的SpringBoot项目对应的指标图表了,如图。6.源码源码地址:https://gitee.com/dalaoyang/s…本文作者:dalaoyang阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

March 8, 2019 · 1 min · jiezi

阿里云TSDB在大数据集群监控中的方案与实战

目前大部分的互联网企业基本上都有搭建自己的大数据集群,为了能更好让我们的大数据集群更加高效安全的工作,一个优秀的监控方案是必不可少的;所以今天给大家带来的这篇文章就是讲阿里云TSDB在上海某大型互联网企业中的大数据集群监控方案中的实战案例,希望能为感兴趣的同学提供一些帮助。背景和需求阿里云时序时空数据库 (原阿里云时间序列数据库, 简称 TSDB) 是一种高性能,低成本,稳定可靠的在线时序数据库服务;提供高效读写,高压缩比存储、时序数据插值及聚合计算,广泛应用于物联网(IoT)设备监控系统 ,企业能源管理系统(EMS),生产安全监控系统,电力检测系统等行业场景。 TSDB 提供百万级时序数据秒级写入,高压缩比低成本存储、预降采样、插值、多维聚合计算,查询结果可视化功能;解决由于设备采集点数量巨大,数据采集频率高,造成的存储成本高,写入和查询分析效率低的问题。Elastic MapReduce(EMR)是阿里云提供的一种大数据处理的系统解决方案。EMR基于开源生态,包括 Hadoop、Spark、Kafka、Flink、Storm等组件,为企业提供集群、作业、数据管理等服务的一站式企业大数据平台。上海某大型互联网企业是阿里云EMR的Top客户,在阿里云上购买的EMR实例有近千台hadoop机器,这些机器目前除了阿里云本身ECS级别的监控以外,没有一套成熟的这对大数据的监控运维告警系统,对大数据业务来讲存在很大的风险。现在客户的需求是对购买的EMR集群做监控和告警,单台有20多个监控指标,采集精度可以根据客户需求调整,另外还要求对原有的业务无侵入,不需要业务层做太多的配置重启类操作。痛点和挑战该大型互联网企业客户最初计划采用的是Prometheus作为监控和告警解决方案,并且基于Prometheus的监控方案也在该企业内部其他系统应用了。这里提到了Prometheus,就多说几句。随着业内基于Kubernetes的微服务的盛行,其生态兼容的开源监控系统Prometheus也逐渐被大家热捧。Prometheus是一个开源监控系统,它前身是SoundCloud的监控系统,在2016年继Kurberntes之后,加入了Cloud Native Computing Foundation。目前许多公司和组织开始使用Prometheus,该项目的开发人员和用户社区非常活跃,越来越多的开发人员和用户参与到该项目中。下图就是prometheus方案的架构:这个方案在实际部署过程中发现Prometheus在存储和查询上存在性能的问题,主要是Prometheus本身采用的local storage方案在大数据量下的扩展性写入查询性能存在瓶颈。另外在这个方案的适配性不强,要改很多参数重启才行,这对于线上正在运行的业务来说,是不可接受的,需要重新设计解决方案。阿里云TSDB解决方案监控和告警整体上来说包括三个环节:1.采集指标2.存储指标3.查询告警因此基本方案就可以简化为:采集工具 + 数据库 + 查询告警。其中,数据库可以通过阿里云TSDB来解决存储和查询上的性能问题,查询告警可以通过成熟的开源工具Grafana。由于该互联网企业客户的要求对原有的业务无侵入,不需要业务层做太多的配置重启类操作,因此解决方案的调研就重点落在了采集工具的调研上了。对于采集工具而言,结合该互联网企业客户已经部署的Prometheus,且阿里云TSDB兼容开源时序数据库OpenTSDB的写入和查询协议,因此从减少成本和工作量的角度来看,可以考虑的方式是有两种:1. 使用Prometheus官方提供的开源的OpenTSDB Adapter 对接原生的Prometheus ,实现数据写入到TSDB。基本架构为:这种方案和该互联网企业客户的开发同学沟通后,发现满足不了对业务无侵入,不重启的需求,因此选择放弃;2. 采用其他开源工具,实现数据采集写入到TSDB。开源社区较为活跃,已经提供了不少开源的采集工具,因此我门评估了以下几个开源的采集工具:Collectd,https://collectd.orgtelegraf, https://github.com/influxdata/telegraf* statsd, https://github.com/etsy/statsdtcollector, http://opentsdb.net/docs/build/html/user_guide/utilities/tcollector.html从开发语言、部署方式以及是否支持定制开发等角度,我们初步选择tcollector作为采集工具。tcollector是一个客户端程序,用来收集本机的数据,并将数据发送到OpenTSDB。tcollector可以为你做下面几件事:运行所有的采集者并收集数据;完成所有发送数据到TSDB的连接管理任务;不必在你写的每个采集者中嵌入这些代码;是否删除重复数据;处理所有有线协议,以后今后的改进;因此,基于tcollector + TSDB + Grafana的监控告警架构如下,其中tcollector以http协议从目标结点上拉取监控指标,并以http的OpenTSDB协议将指标推送至阿里云TSDB。这个方案在不修改tcollector源码的基础上,能够满足客户对hadoop的监控。但是在PoC后,客户增加了对EMR实例中其他大数据组件的监控需求,如Hive, Spark, Zookeeper, HBase, Presto, Flink, azkaban, kafka, storm等。经过我们调研,tcollector对于这些组件的支持程度如下:原生支持:hbase;需定制化开发,不重启实例:Hive, Spark, Zookeeper;需定制化开发,需重启实例:Flink, azkaban, kafka, storm;经过一定工作量的制化开发,基于tcollector的方案基本可以满足用户的需求。最终我们在该互联网企业客户的EMR大数据集群的监控告警方案架构为:tcollector非常简单易部署,可以简单高效地完成了客户的需求。而且配置部署时,可以不用区分大数据组件的角色,解决了之前开源采集工具需要针对不同角色,来手动配置并启动相应插件的问题。至此,TSDB完美得解决了该互联网企业客户大数据集群监控接入TSDB的案例,让TSDB在迈向完善生态的路上更进一步了。另外值得一提的是,为了解决目前广泛使用的Prometheus开源系统在大量时序数据的存储、写入和查询存在性能瓶颈问题,阿里云TSDB也已经开始兼容了Prometheus生态,并且已经在多个客户场景进行了实战。后面我们会推出针对Prometheus的系列文章,对Prometheus感兴趣或者已经是Prometheus用户但是遇到性能问题的同学可以持续关注我们。阿里云时序时空数据库TSDB 1元购!立即体验:https://promotion.aliyun.com/ntms/act/tsdbtry.html?spm=5176.149792.775960.1.dd9e34e2zgsuEM&wh_ttid=pc本文作者:焦先阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 6, 2019 · 1 min · jiezi

使用Grab的实验平台进行混沌实验编排

Roman Atachiants · Tharaka Wijebandara · Abeesh Thomas原文: https://engineering.grab.com/chaos-engineering译:时序背景对每个用户来说,Grab是一个可以叫车,叫外卖或付款的一个APP。对工程师来说,Grab是一个有许多服务并通过RPC交互的分布式系统,有时也可以叫做微服务架构。在数千台服务器上运行的数百个服务每天都有工程师在上面进行变更。每次复杂的配置,事情可能都会变糟。 幸运的是,很多Grab App的内部服务不像用户叫车那样的动作这么重要。例如,收藏夹可以帮用户记住之前的位置,但如果它们不工作,用户仍然可以得到较合理的用户体验。服务部分可用并不是没有风险。工程师需要对于RPC调用非核心服务时需要有有备用计划。如果应急策略没有很好地执行,非核心服务的问题也可能导致停机。所以我们如何保证Grab的用户可以使用核心功能,例如叫车,而此时非核心服务正在出问题?答案是混沌工程。在Grab,我们通过在整体业务流的内部服务或组件上引入故障来实践混沌工程。但失败的服务不是实验的关注点。我们感兴趣的是测试依赖这个失败服务的服务。照理来说,上游服务应该有弹性并且整体业务流应该可以继续工作。比如,叫车流程就算在司机地址服务上出现故障时仍应该可以工作。我们测试重试和降级是否配置正确,是否熔断器被正确的设置。为了将混沌引入我们的系统,我们使用了我们的实验平台(ExP)和Grab-Kit.混沌实验平台Exp将故障注入到处理流量服务的中间件(gRPC或HTTP服务器)。如果系统的行为与期望一致,你将对非核心服务故障时服务会平稳降级产生信心。混沌实验平台ExP在Grab的基础设施中模拟不同的混沌类型,如延迟和内存泄漏。这保证了每个组件在系统的依赖不响应或响应很高时仍能返回一些东西。它能保证我们对于实例级失败有弹性,因为微服务级别的中断对于可用性也是一个威胁。配置混沌实验为了构建我们的混沌工程系统,我们认为需要在两个主要领域引入混沌:基础设置:随机关闭基础设施的实例和其他部分应用: 在较粗粒度引入运行时故障(如endpoint/request级别)你可以稍后启用有意的或随机的混沌实验:随机的比较适合‘一次性’基础设施(如EC2实例)测试冗余的基础设施对最终用户的影响当影响面已经十分确定实验精确度量影响使用实验参数控制对最终用户有限的影响适用于对于影响不十分确定的复杂故障(如延迟)最后,你可以将故障模式按以下分类:资源:CPU,内存,IO,磁盘网络:黑洞,延迟,丢包,DNS状态:关机,时间,杀进程这些模型都可以在基础设施或应用级别使用或模拟:对于Grab,进行应用级别的混沌实验并仔细度量影响面很重要。我们决定使用一个已有的实验平台来对围绕系统的应用级别混沌实验进行编排,即紫色部分,通过对下层像Grab-Kit这样的中间件进行注入来实现。为什么使用实验平台?现在有一些混沌工程工具。但是,使用它们经常需要较高级的基础设施和运维技巧,有能力设计和执行实验,以受控的方式有资源手工编排失败场景。混沌工程不是简单的在生产环境搞破坏。将混沌工程理解成受控的实验。我们的ExP SDK提供弹性和异步追踪。这样,我们可以将潜在的业务属性度量对应到混沌失败上。比如,在订车服务上进行10秒延迟的混沌故障,我们可以知道多少辆车被影响了进而知道损失了多少钱。使用ExP作为混沌工程的工具意味着我们可以基于应用或环境精确定制,让它可以像监控和部署管道一样与其他环境紧密集成。在安全上也可以获得收益。使用ExP,所有的连接都在我们的内部网络中,给我们攻击表面区域的能力。所有东西都可以掌控在手中,对外部世界没有依赖。这也潜在的使监控和控制流量变容易了。混沌故障可以点对点,编程式的,或定期执行。你可以让它们在特定日期的特定时间窗口来执行。你可以设定故障的最大数量并定制它们(比如泄漏的内存MB数量,等待的秒)。ExP的核心价值是让工程师可以启动,控制和观察系统在各种失败条件下的行为。ExP提供全面的故障原子集,用来设计实验并观察问题在复杂分布式系统发生时的表现。而且,将混沌测试集成到ExP,我们对于部署流水线或网络基础设施不需要任何改动。因此这种组合可以很容易的在各种基础设施和部署范式上使用。我们如何打造Chaos SDK和UI要开发混沌工程SDK,我们使用我们已有ExP SDK的属性 - single-digit , 不需要网络调用。你可以看这里对于ExP SDK的实现。现在我们要做两件事:一个在ExP SDK之上的很小的混沌SDK。我们将这个直接集成在我们的已有中间件,如Grab-Kit和DB层。一个专门的用来创建混沌实验的基于web的UI归功于我们与Grab-Kit的集成,Grab工程师不需要直接使用混沌SDK。当Grab-Kit处理进入的请求时,它先使用ExP SDK进行检查。如果请求“应该失败”,它将产生适合的失败类型。然后它被转发到特定endpoint的处理器。我们现在支持以下失败类型:Error - 让请求产生errorCPU Load - 在CPU上加大load内存泄漏 - 产生一些永远不能释放的内存延迟 - 在一小段随机时间内停止请求的处理磁盘空间 - 在机器上填入一些临时文件Goroutine泄漏 - 创建并泄漏goroutinesPanic -限流 - 在请求上设置一个频率限制并在超过限制时拒绝请求举个例子,如果一个叫车请求到了我们的叫车服务,我们调用GetVariable(“chaosFailure”)来决定请求是否应该成功。请求里包含所有需要用来做决定的信息(如请求ID,实例的IP地址等)。关于实验SDK的实现细节,看这篇博客。为了在我们的工程师中推广混沌工程我们围绕它建立了很好的开发者体验。在Grab不同的工程团队会有很多不同的技术和领域。所以一些人可能没有对应的知识和机能来进行合适的混沌实验。但使用我们简化过的用户界面,他们不需要担心底层实现。并且,运行混沌实验的工程师是与像产品分析师和产品经理不同的实验平台用户。所以我们使用一种简单和定制化UI配置新的混沌实验来提供一种不同的创建实验的体验。在混沌工程平台,一个实验有以下四步:定义系统正常情况下的理想状态。创建一个控制组的配置和一个对比组的配置。控制组的变量使用已有值来赋值。对比组的变量使用新值来赋值。引入真实世界的故障,例如增加CPU负载。找到区分系统正确和失败状态标志性不同。要创建一个混沌实验,标明你想要实验破坏的服务。你可以在以后通过提供环境,可用区或实例列表来更细化这个选择范围。下一步,指定一组会被破坏的服务影响的服务列表。你在试验期间需要仔细监控这些服务。尽管我们持续跟踪表示系统健康的整体度量指标,它仍能帮助你在稍后分析实验的影响。然后,我们提供UI来指定目标组和对比组的策略,失败类型,每个对比组的配置。最后一步,提供时间周期并创建实验。你已经在你的系统中加入了混沌故障并可以监控它对系统的影响了。结论在运行混沌实验后,一般会有两种可能输出。你已经确认了在引入的故障中系统保持了足够的弹性,或你发现了需要修复的问题。如果混沌实验最初被运行在预发环境那么两种都是不错的结果。在第一种场景,你对系统的行为产生了信心。在另一个场景,你在导致停机故障前发现了一个问题。混沌工程是让你工作更简单的工具。通过主动测试和验证你系统的故障模式你减轻了你的运维负担,增加了你的弹性,在晚上也能睡个好觉。本文作者:时序阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 6, 2019 · 1 min · jiezi

基于Blink构建亲听项目以及全链路debug项目实时响应能力

案例与解决方案汇总页:阿里云实时计算产品案例&解决方案汇总本文全面总结了大数据项目组在亲听项目以及全链路debug项目上进行的实时流处理需求梳理,架构选型,以及达成效果一、背景介绍1.1亲听项目亲听项目专注于帮助用户收集、展示、监控和处理用户体验问题,是保证产品的主观评价质量的利器,关于其具体功能可参考在ata搜索"亲听"查看系列文章。目前亲听项目的实时流处理需求来自算法效果监控,算法效果监控需要对上游TimeTunnel日志进行解析后经过处理得到一些关键指标,亲听通过对这些指标的前端展示和阈值监控报警达到算法效果监控目的。需求要点可以总结如下:上游需要处理的TimeTunnel日志的实时数据量大约在日常峰值每秒数万条记录,大促峰值每秒几十万条记录从用户搜索行为到亲听系统得到搜索行为指标数据秒级的低延时数据的处理逻辑较为复杂且会随着算法迭代需要发生变化1.2全链路debug全链路debug专注于帮助用户在线上搜索结果出现异常和问题时帮助开发者复现搜索后端各子系统的中间结果,定位并解决子系统存在的问题,是系统层级质量保证和测试的有力工具。关于其具体功能可参考在ata搜索"全链路debug"查看系列文章。全链路debug的实时流处理需求是实时从TimeTunnel日志中提取出帮助排除搜索线上问题的关键内容,全链路debug利用这些内容帮助进行问题排查。全链路debug的实时流处理需求模型可以用下图描述:需求要点可以总结如下:上游需要处理的TimeTunnel日志的实时数据量大约在日常峰值每秒数万条记录,大促峰值每秒几十万条记录需要保存的单条记录较大,平均达到几K左右对上游TimeTunnel日志解析逻辑大部分为字段提取和透传且不会频繁变化二、解决方案2.1整体架构应对以上需求,亲听以及全拉链路debug的实时流处理系统的最终架构如下:亲听:全链路debug:对于亲听和全链路debug的实时流处理需求最终选择上述架构主要出于实时性和扩展性两方面考虑2.2实时性亲听和全链路debug的实时流处理需求在实时性要求上是类似的,即要对接tt日志,在tt日志记录写入到对于亲听和全链路debug的使用方可见延时要控制在秒级,这种实时性的需求可以分解为两个部分,第一是对实时流数据的处理,而是对实时流数据处理结果的存储和查询服务。对于实时流数据的处理,目前公司内的中间件产品blink能很好满足我们的需求,blink提供对接TimeTunnel的api接口,同时具备很好的实时流处理性能和运维体验;对于实时流处理结果的存储和查询,需要支持几万到几十万qps的写压力以及在每天累计几十T数据量情况下毫秒级延时的读性能,hbase能够基本满足对读写的需求,但是druid和drill能够在满足读写性能的同时提供更好的数据查询体验和实时流处理逻辑的可扩展性,所以对于实时流数据处理结果的存储和查询服务我们是优先考虑druid和drill的,但是全链路debug的实时流处理结果有一个特点就是单条记录数据大小平均为几K左右,这么大的单条记录的大小将导致druid需要的内存量过大且查询性能低下而不可用,所以对于全链路debug的实时流处理结果的存储和查询服务选择了hbase。2.3扩展性在亲听实时流处理系统的下游引入tt->druid,然后使用drill查询druid提供查询服务,是出于对扩展性的考虑。druid是一种支持实时流处理和查询的olap系统(ATA),对接druid使得可以把一部分实时流数据的处理逻辑交给druid,这样当实时流处理逻辑需要修改时,很多情况下就可以通过修改查询逻辑(只要修改一个请求druid时的json配置文件)而不需要修改blink任务(需要修改代码、打包、编译、调参、上线)实现,大幅提升实时流处理系统的扩展性,而亲听实时流处理需求频繁变化的业务特点非常需要这种扩展性;drill是高性能的SQL查询引擎,通过drill对接druid提供查询服务不但使查询语法从druid的json文件变为sql可读性大幅增强,同时drill对druid查询结果具有的二次处理能力也进一步增强了通过修改查询逻辑可以满足的实时流处理逻辑变化,进一步增强系统可扩展性。在blink和druid之间增加了TimeTunnel进行数据中转以保证blink产出流数据被转化为下游druid支持的流数据源形式。2.4经验总结使用table api编写stream api作为blink的底层api,具有较高的灵活性,但是可读性很不好,进而非常影响代码的可维护性和扩展性,当要在实时任务中加入新需求时经常要改动很多地方并且很容易出错,所有实时任务我们选择使用table api编写,table api使用类sql语法描述实时流处理逻辑,使得数据流处理逻辑变得非常清晰,可读性大幅增强,进而节约代码的维护和扩展成本。进行字段归类合并我们通过梳理业务方最终需要使用的字段内容,将blink任务输出到TimeTunnel中记录的字段进行了分类合并,除了出于druid查询性能考虑将若干需要进行group by以及count distinct查询的原有字段保留,其余全部按照诸如搜索请求相关信息、用户相关信息、搜索返回宝贝相关信息这样的概念将原有字段分组后合并为多值字段,而每个合并后的多值字段又会在blink代码中用一个udtf函数统一处理。这样做的好处在于代码逻辑上变得更清晰,当实时流处理需求发生变化,需要产出新的内容或修改现有内容产出逻辑时,只需找到新增内容或待修改内容对应的多值字段,修改对应udtf逻辑并重新上线blink任务即可,下游的druid build无需进行任何修改;同时用有限的几个udtf对整个实时流输出记录的处理逻辑进行归类,避免了记录处理逻辑频繁变化可能导致的代码中过时字段和udf泛滥,可读性下降,修改易出错的问题。drill处理逻辑前移请看下面这个sql:select * from druid.sqa_wireless_search_pv where INSTR(auction_tag, ‘15’)这个sql drill的处理逻辑是从druid表中召回druid.sqa_wireless_search_pv表中全部记录后逐条进行auction_tag字段的比对,过滤出包含‘15’字符串的记录,这种召回全部记录进行处理的操作对于drill来说会造成很大的性能问题,占用集群资源急剧上升,查询延时大幅提高,甚至导致集群oom使查询服务中断服务。在使用drill进行查询时应尽量避免执行类似召回大量记录进行处理的sql,我们对亲听算法效果监控现有sql进行了梳理,找到召回记录数目可能会过高的sql,通过将处理逻辑前移到blink任务阶段大幅优化drill查询性能(例如上面的sql只要将比对auction_tag字段是否含有‘15’的逻辑交给blink处理,并让blink任务新增产出一个tag字段,这样druid就可以针对tag字段建索引,通过where tag==‘true’这样的语句就可以直接召回需要的记录)三、成果总结目前tt->blink->hbase和tt->blink->tt->druid是在公司内使用非常广泛的两种实时流处理架构,能以秒级延时完成线上实时日志处理,这两种实时流处理架构比较好地满足了亲听和全链路debug项目的实时数据处理需求,极大提升了项目价值四、作者简介鸷鸟,来自搜索事业部-工程效率&技术质量-算法工程平台-实时大数据平台15年加入阿里,主要从事电商体系实时数据研发以及实时大数据平台研发本文作者:付空阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 4, 2019 · 1 min · jiezi

容器监控实践—Prometheus的配置与服务发现

本文将分析Prometheus的常见配置与服务发现,分为概述、配置详解、服务发现、常见场景四个部分进行讲解。一. 概述Prometheus的配置可以用命令行参数、或者配置文件,如果是在k8s集群内,一般配置在configmap中(以下均为prometheus2.7版本)查看可用的命令行参数,可以执行 ./prometheus -h也可以指定对应的配置文件,参数:–config.file 一般为prometheus.yml如果配置有修改,如增添采集job,Prometheus可以重新加载它的配置。只需要向其进程发送SIGHUP或向/-/reload端点发送HTTP POST请求。如:curl -X POST http://localhost:9090/-/reload二. 配置详解2.1 命令行参数执行./prometheus -h 可以看到各个参数的含义,例如:–web.listen-address=“0.0.0.0:9090” 监听端口默认为9090,可以修改只允许本机访问,或者为了安全起见,可以改变其端口号(默认的web服务没有鉴权)–web.max-connections=512 默认最大连接数:512–storage.tsdb.path=“data/” 默认的存储路径:data目录下–storage.tsdb.retention.time=15d 默认的数据保留时间:15天。原有的storage.tsdb.retention配置已经被废弃–alertmanager.timeout=10s 把报警发送给alertmanager的超时限制 10s–query.timeout=2m 查询超时时间限制默认为2min,超过自动被kill掉。可以结合grafana的限时配置如60s–query.max-concurrency=20 并发查询数 prometheus的默认采集指标中有一项prometheus_engine_queries_concurrent_max可以拿到最大查询并发数及查询情况–log.level=info 日志打印等级一共四种:[debug, info, warn, error],如果调试属性可以先改为debug等级…..在prometheus的页面上,status的Command-Line Flags中,可以看到当前配置,如promethues-operator的配置是:2.2 prometheus.yml从官方的download页下载的promethues二进制文件,会自带一份默认配置prometheus.yml-rw-r–r–@ LICENSE-rw-r–r–@ NOTICEdrwxr-xr-x@ console_librariesdrwxr-xr-x@ consoles-rwxr-xr-x@ prometheus-rw-r–r–@ prometheus.yml-rwxr-xr-x@ promtoolprometheus.yml配置了很多属性,包括远程存储、报警配置等很多内容,下面将对主要属性进行解释:# 默认的全局配置global: scrape_interval: 15s # 采集间隔15s,默认为1min一次 evaluation_interval: 15s # 计算规则的间隔15s默认为1min一次 scrape_timeout: 10s # 采集超时时间,默认为10s external_labels: # 当和其他外部系统交互时的标签,如远程存储、联邦集群时 prometheus: monitoring/k8s # 如:prometheus-operator的配置 prometheus_replica: prometheus-k8s-1# Alertmanager的配置alerting: alertmanagers: - static_configs: - targets: - 127.0.0.1:9093 # alertmanager的服务地址,如127.0.0.1:9093 alert_relabel_configs: # 在抓取之前对任何目标及其标签进行修改。 - separator: ; regex: prometheus_replica replacement: $1 action: labeldrop # 一旦加载了报警规则文件,将按照evaluation_interval即15s一次进行计算,rule文件可以有多个rule_files: # - “first_rules.yml” # - “second_rules.yml”# scrape_configs为采集配置,包含至少一个jobscrape_configs: # Prometheus的自身监控 将在采集到的时间序列数据上打上标签job=xx - job_name: ‘prometheus’ # 采集指标的默认路径为:/metrics,如 localhost:9090/metric # 协议默认为http static_configs: - targets: [’localhost:9090’]# 远程读,可选配置,如将监控数据远程读写到influxdb的地址,默认为本地读写remote_write: 127.0.0.1:8090# 远程写remote_read: 127.0.0.1:8090 2.3 scrape_configs配置prometheus的配置中,最常用的就是scrape_configs配置,比如添加新的监控项,修改原有监控项的地址频率等。最简单配置为:scrape_configs:- job_name: prometheus metrics_path: /metrics scheme: http static_configs: - targets: - localhost:9090完整配置为(附prometheus-operator的推荐配置):# job 将以标签形式出现在指标数据中,如node-exporter采集的数据,job=node-exporterjob_name: node-exporter# 采集频率:30sscrape_interval: 30s# 采集超时:10sscrape_timeout: 10s# 采集对象的path路径metrics_path: /metrics# 采集协议:http或者httpsscheme: https# 可选的采集url的参数params: name: demo# 当自定义label和采集到的自带label冲突时的处理方式,默认冲突时会重名为exported_xxhonor_labels: false# 当采集对象需要鉴权才能获取时,配置账号密码等信息basic_auth: username: admin password: admin password_file: /etc/pwd# bearer_token或者文件位置(OAuth 2.0鉴权)bearer_token: kferkhjktdgjwkgkrwgbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token# https的配置,如跳过认证,或配置证书文件tls_config: # insecure_skip_verify: true ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt server_name: kubernetes insecure_skip_verify: false# 代理地址proxy_url: 127.9.9.0:9999# Azure的服务发现配置azure_sd_configs:# Consul的服务发现配置consul_sd_configs: # DNS的服务发现配置dns_sd_configs:# EC2的服务发现配置ec2_sd_configs:# OpenStack的服务发现配置openstack_sd_configs:# file的服务发现配置file_sd_configs:# GCE的服务发现配置gce_sd_configs:# Marathon的服务发现配置marathon_sd_configs:# AirBnB的服务发现配置nerve_sd_configs:# Zookeeper的服务发现配置serverset_sd_configs:# Triton的服务发现配置triton_sd_configs:# Kubernetes的服务发现配置kubernetes_sd_configs: - role: endpoints namespaces: names: - monitoring# 对采集对象进行一些静态配置,如打特定的标签static_configs: - targets: [’localhost:9090’, ’localhost:9191’] labels: my: label your: label # 在Prometheus采集数据之前,通过Target实例的Metadata信息,动态重新写入Label的值。如将原始的__meta_kubernetes_namespace直接写成namespace,简洁明了relabel_configs: - source_labels: [__meta_kubernetes_namespace] separator: ; regex: (.) target_label: namespace replacement: $1 action: replace - source_labels: [__meta_kubernetes_service_name] separator: ; regex: (.) target_label: service replacement: $1 action: replace - source_labels: [_meta_kubernetes_pod_name] separator: ; regex: (.) target_label: pod replacement: $1 action: replace - source_labels: [__meta_kubernetes_service_name] separator: ; regex: (.) target_label: job replacement: ${1} action: replace - separator: ; regex: (.*) target_label: endpoint replacement: web action: replace# 指标relabel的配置,如丢掉某些无用的指标metric_relabel_configs: - source_labels: [name] separator: ; regex: etcd(debugging|disk|request|server).* replacement: $1 action: drop # 限制最大采集样本数,超过了采集将会失败,默认为0不限制sample_limit: 0三. 服务发现上边的配置文件中,有很多*sd_configs的配置,如kubernetes_sd_configs,就是用于服务发现的采集配置。支持的服务发现类型:// prometheus/discovery/config/config.gotype ServiceDiscoveryConfig struct { StaticConfigs []*targetgroup.Group yaml:"static_configs,omitempty" DNSSDConfigs []*dns.SDConfig yaml:"dns_sd_configs,omitempty" FileSDConfigs []*file.SDConfig yaml:"file_sd_configs,omitempty" ConsulSDConfigs []*consul.SDConfig yaml:"consul_sd_configs,omitempty" ServersetSDConfigs []*zookeeper.ServersetSDConfig yaml:"serverset_sd_configs,omitempty" NerveSDConfigs []*zookeeper.NerveSDConfig yaml:"nerve_sd_configs,omitempty" MarathonSDConfigs []*marathon.SDConfig yaml:"marathon_sd_configs,omitempty" KubernetesSDConfigs []kubernetes.SDConfig yaml:"kubernetes_sd_configs,omitempty" GCESDConfigs []gce.SDConfig yaml:"gce_sd_configs,omitempty" EC2SDConfigs []ec2.SDConfig yaml:"ec2_sd_configs,omitempty" OpenstackSDConfigs []openstack.SDConfig yaml:"openstack_sd_configs,omitempty" AzureSDConfigs []azure.SDConfig yaml:"azure_sd_configs,omitempty" TritonSDConfigs []triton.SDConfig yaml:"triton_sd_configs,omitempty"}因为prometheus采用的是pull方式来拉取监控数据,这种方式需要由server侧决定采集的目标有哪些,即配置在scrape_configs中的各种job,pull方式的主要缺点就是无法动态感知新服务的加入,因此大多数监控都默认支持服务发现机制,自动发现集群中的新端点,并加入到配置中。Prometheus支持多种服务发现机制:文件,DNS,Consul,Kubernetes,OpenStack,EC2等等。基于服务发现的过程并不复杂,通过第三方提供的接口,Prometheus查询到需要监控的Target列表,然后轮询这些Target获取监控数据。对于kubernetes而言,Promethues通过与Kubernetes API交互,然后轮询资源端点。目前主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。对应配置文件中的role: node/role:service如:动态获取所有节点node的信息,可以添加如下配置:- job_name: kubernetes-nodes scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: node namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - separator: ; regex: _meta_kubernetes_node_label(.+) replacement: $1 action: labelmap - separator: ; regex: (.) target_label: address replacement: kubernetes.default.svc:443 action: replace - source_labels: [__meta_kubernetes_node_name] separator: ; regex: (.+) target_label: metrics_path replacement: /api/v1/nodes/${1}/proxy/metrics action: replace就可以在target中看到具体内容对应的service、pod也是同样的方式。需要注意的是,为了能够让Prometheus能够访问收到Kubernetes API,我们要对Prometheus进行访问授权,即serviceaccount。否则就算配置了,也没有权限获取。prometheus的权限配置是一组ClusterRole+ClusterRoleBinding+ServiceAccount,然后在deployment或statefulset中指定serviceaccount。ClusterRole.yamlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: namespace: kube-system name: prometheusrules:- apiGroups: [""] resources: - configmaps - secrets - nodes - pods - nodes/proxy - services - resourcequotas - replicationcontrollers - limitranges - persistentvolumeclaims - persistentvolumes - namespaces - endpoints verbs: [“get”, “list”, “watch”]- apiGroups: [“extensions”] resources: - daemonsets - deployments - replicasets - ingresses verbs: [“get”, “list”, “watch”]- apiGroups: [“apps”] resources: - daemonsets - deployments - replicasets - statefulsets verbs: [“get”, “list”, “watch”]- apiGroups: [“batch”] resources: - cronjobs - jobs verbs: [“get”, “list”, “watch”]- apiGroups: [“autoscaling”] resources: - horizontalpodautoscalers verbs: [“get”, “list”, “watch”]- apiGroups: [“policy”] resources: - poddisruptionbudgets verbs: [“get”, list", “watch”]- nonResourceURLs: ["/metrics"] verbs: [“get”]ClusterRoleBinding.yamlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: namespace: kube-system name: prometheusroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheussubjects:- kind: ServiceAccount name: prometheus namespace: kube-systemServiceAccount.yamlapiVersion: v1kind: ServiceAccountmetadata: namespace: kube-system name: prometheusprometheus.yaml….spec: serviceAccountName: prometheus….完整的kubernete的配置如下:- job_name: kubernetes-apiservers scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: endpoints namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] separator: ; regex: default;kubernetes;https replacement: $1 action: keep- job_name: kubernetes-nodes scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: node namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - separator: ; regex: _meta_kubernetes_node_label(.+) replacement: $1 action: labelmap - separator: ; regex: (.) target_label: address replacement: kubernetes.default.svc:443 action: replace - source_labels: [__meta_kubernetes_node_name] separator: ; regex: (.+) target_label: metrics_path replacement: /api/v1/nodes/${1}/proxy/metrics action: replace- job_name: kubernetes-cadvisor scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: node namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: false relabel_configs: - separator: ; regex: _meta_kubernetes_node_label(.+) replacement: $1 action: labelmap - separator: ; regex: (.) target_label: address replacement: kubernetes.default.svc:443 action: replace - source_labels: [__meta_kubernetes_node_name] separator: ; regex: (.+) target_label: metrics_path replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor action: replace- job_name: kubernetes-service-endpoints scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: http kubernetes_sd_configs: - api_server: null role: endpoints namespaces: names: [] relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] separator: ; regex: “true” replacement: $1 action: keep - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] separator: ; regex: (https?) target_label: scheme replacement: $1 action: replace - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] separator: ; regex: (.+) target_label: metrics_path replacement: $1 action: replace - source_labels: [address, __meta_kubernetes_service_annotation_prometheus_io_port] separator: ; regex: ([^:]+)(?::\d+)?;(\d+) target_label: address replacement: $1:$2 action: replace - separator: ; regex: _meta_kubernetes_service_label(.+) replacement: $1 action: labelmap - source_labels: [__meta_kubernetes_namespace] separator: ; regex: (.) target_label: kubernetes_namespace replacement: $1 action: replace - source_labels: [__meta_kubernetes_service_name] separator: ; regex: (.) target_label: kubernetes_name replacement: $1 action: replace配置成功后,对应的target是:四. 常见场景1.获取集群中各节点信息,并按可用区或地域分类如使用k8s的role:node采集集群中node的数据,可以通过"meta_domain_beta_kubernetes_io_zone"标签来获取到该节点的地域,该label为集群创建时为node打上的标记,kubectl decribe node可以看到。然后可以通过relabel_configs定义新的值relabel_configs:- source_labels: [“meta_domain_beta_kubernetes_io_zone”] regex: “(.)” replacement: $1 action: replace target_label: “zone"后面可以直接通过node{zone=“XX”}来进行地域筛选2.过滤信息,或者按照职能(RD、运维)进行监控管理对于不同职能(开发、测试、运维)的人员可能只关心其中一部分的监控数据,他们可能各自部署的自己的Prometheus Server用于监控自己关心的指标数据,不必要的数据需要过滤掉,以免浪费资源,可以最类似配置;metric_relabel_configs: - source_labels: [name] separator: ; regex: etcd(debugging|disk|request|server).* replacement: $1 action: dropaction: drop代表丢弃掉符合条件的指标,不进行采集。3.搭建prometheus联邦集群,管理各IDC(地域)监控实例如果存在多个地域,每个地域又有很多节点或者集群,可以采用默认的联邦集群部署,每个地域部署自己的prometheus server实例,采集自己地域的数据。然后由统一的server采集所有地域数据,进行统一展示,并按照地域归类配置:scrape_configs: - job_name: ‘federate’ scrape_interval: 15s honor_labels: true metrics_path: ‘/federate’ params: ‘match[]’: - ‘{job=“prometheus”}’ - ‘{name=“job:.*”}’ - ‘{name=“node.*”}’ static_configs: - targets: - ‘192.168.77.11:9090’ - ‘192.168.77.12:9090’本文为容器监控实践系列文章,完整内容见:container-monitor-book ...

March 4, 2019 · 4 min · jiezi

阿里云发布时间序列数据库TSDB,关于时序你了解多少?

摘要: 阿里云发布时间序列数据库TSDB,专家帮你解答时序那些事。概要介绍时间序列数据是一种表示物理设备,系统、应用过程或行为随时间变化的数据,广泛应用于物联网,工业物联网,基础运维系统等场景。阿里云TSDB 时间序列数据库可以解决大规模时序数据的可靠写入,降低数据存储成本,实时灵活的完成业务数据聚合分析。什么是时序数据我们来看感受一下平时自己特别熟悉的场景,就会发现时序和每个人都存在非常紧密的关系:电商系统获取每笔订单交易金额和支付金额数据以及商品库存和物流数据;智能电表,会实时记录每个小时的用电量数据,比给出账单数据;高山上的风车的获取实时转速,风速数据,发电量数据。应用服务调用量有没有异常,服务器的负载和资源使用率如何?这些应用程序均依赖一种衡量事物随时间的变化的数据形式,每一个数据源定期发送新的读数,创建一系列随时间推移收集到的测量结果,这就是时序数据,时序数据数据集主要有以下三个特点:新入库数据几乎总是作为新条目被记录数据通常按照产生时间顺序入库所有的数据都自带时间戳,因此,我们这样定义时间序列数据:统一表示系统、过程或行为随时间变化的数据时序数据的价值相较域非时序数据,核心区别在于时序数据能够反映“变化”本身。当你为某个物联网设备收集新数据时,是覆盖以往的读数,还是在新的一行创建全新的读数?尽管这两种方法都能为你提供系统的当前状态,但只有第二种方法才能跟踪系统的所有状态。所以时序数据的价值在于将系统的每个变化都记录为新的一行,从而可以去衡量变化,分析过去的变化,监测现在的变化,以及预测未来将如何变化。时序数据库TSDB 的价值为什么不能用常规数据库来管理时序数据呢,为什么需要时序数据库呢?事实上答案是你可以使用非时间序列数据库,如同你可以为航天飞行器配备一个普通的汽车发动机,虽然也可以飞起来,但是终究不能实现航天飞行的“梦想”。而更多业务场景选择择时序数据库而非通用数据库技术也是类似的原因归结起来就是两个核心点:规模和可用性。(1)规模:时间序列数据累计速度非常快。例如,一辆联网汽车每小时产生几百GB 的数据。关系型数据库处理大数据集的效果非常糟糕;NoSQ数据库可以很好地处理规模数据,但是仍然比不上一个针对时间序列数据微调过的数据库。相比之下,时间序列数据库将时间作为最高优先级来处理,通过提高区间数据实时查询效率来处理这种大规模数据,并带来性能的提升,包括:每秒写入速度,能够支撑的设备指标量,读取数据效率和非常高的存储压缩比。而时间序列数据在技术领域的关注度也日益提升。数据来源:DBengine 2018.9月报告(2)可用性:TSDB通常还包括一些共通的对时间序列数据分析的功能和操作:数据保留策略、连续查询、灵活的时间聚合等。以及很好的扩展性。比如常见的时序降精度和聚合计算,而非时序数据库都不具备这个能力。这就是为什么企业开发人员越来越多地采用时间序列数据库,并将它们用于各种使用场景。使用阿里云TSDB 的理由阿里巴巴业务覆盖面广,诸如 电商交易跟踪, 容器指标监控, 服务监控,物流配送跟踪,智慧园区的智能设备监控等对时序数据库存在强烈的需求,选择阿里云 TSDB 是因为具备如下的优势:高性能TSDB具有高效的吞吐能力,实际压测对比,TSDB 的读取效率比开源的OpenTSDB 和InfluxDB 读取效率要高出一个数量级,实际业务上过用TSDB 来代替传统的基于Hbase的方案,整体机器成本缩减了50%以上。数据存储成本更低 时序数据都是持续写入的,任何一个数据的变化都会记录到时序数据库,所以相比较OLTP类的数据库,对于数据库的容量要求是PB级别。TSDB 可以做到最高10:1的无损压缩效率。大大降低了业务的存储成本。分析能力强 时序最核心的能力在于数据分析能力,TSDB 提供专业全面的时序数据计算函数,支持降采样、数据插值和空间聚合计算,能满足各种复杂的业务数据查询场景。百万级别数据点聚合分析秒级完成。功能完备时序数据库支持丰富的计算能力,如降精度和聚合计算。降精度我们看一个降精度例子, 园区管理员要把园区所有的照明灯的用电量数据采集起来,进行统一的监控分析,达到节能管控的目的。如果管理员要查看最近24小时耗电量的时候,那么可以直接从TSDB里获取原始数据查看用电量趋势。 而管理员要查看最近3年的用电量趋势的时候,管理员可以随机按照“天”,“周”,“月”这些比较粗粒度的时间精度来进行数据计算,所有降精度的数据通过原始小时数据按照时序提供的函数(如平均求和,最大值,最小值等)计算出来,而所有的计算过程由时序数据库“包办”,应用可以直接获取计算结果。聚合计算如果管理员要查看某个具体楼层的用电量的时候,那么只需把楼层信息请求到TSDB,就可以实时获取所需楼层所有灯的用电量。 那么如果管理员查看飞利浦品牌的耗电量的时候,只需传递品牌值到TSDB即可,按照园区名称也可以统计。所以时序聚合提供了强大非常灵活的能力,完全可以随机定义查询聚合的纬度,实时的获取不同分析纬度的查询结果。而不要用户主动创建任何索引信息。时空分析随着车联网以及智能交通和新零售配送相关行业发展,地理位置信息类型的数据存储和分析场景也日渐显现,技术领域称为“时空分析”。车联网的管理人员需要清楚的知道在当天有多少车辆在运营区域内行使,有多少车辆驶出了运营区域,每个车辆的行使轨迹是怎样的,进行全局的车辆管理。政府的管理人员需要清楚当天城区内人员流动的热力分布趋势,以提升城市管理的效率。新零售的配送管理员需要知道配送员是否按照规定在区域内配送,配送员的配送轨迹如何,以便于做管理和配送路径的优化。这些都依赖时空分析能力。TSDB 即将发布时空分析功能,提供地理位置信息类型数据的存储和分析。满足轨迹追踪,空间位置统计分析的业务需求。时序洞察数据可视化是呈现数据分析结果的重要一环,TSDB 提供了基础的可视化功能时序洞察,可以实时的提供给用户交互式的数据分析过程。用户无需开发任何的代码,就可以完成数据查询和分析,同时直观的看到数据的趋势效果。快速体验阿里云TSDBTSDB 新发布的时序洞察,能够通过demo 数据的导入,只需三个步骤,就可以快速体验交互式的时序数据分析能力:第一步,创建TSDB 实例第二步,进行demo数据导入第三步,创建时序洞察, 进行数据分析了解更多时序洞察,万物互联>>立即报名直播>>本文作者:lyrewu阅读原文本文为云栖社区原创内容,未经允许不得转载。

February 26, 2019 · 1 min · jiezi

Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel

摘要: 本文对Hystrix、Resilience4j、Sentinel进行对比,并探讨如何使用一行代码这种极简的方式,将Hystrix迁移到Sentinel。 Hystrix 自从前段时间 宣布停止维护之后,社区推荐了 resilience4j。自 Spring Cloud 官方宣布 Spring Cloud Netflix 进入维护状态后,我们开始制作《Spring Cloud Alibaba迁移指南》系列文章,向开发者提供更多的技术选型方案,并降低迁移过程中的技术难度。第一篇,我们对Hystrix、Resilience4j 和 Sentinel 三个开源项目进行对比,并探讨如何使用一行代码这种极简的方式,将Hystrix迁移到Sentinel。Hystrix 自从前段时间 宣布停止维护之后,社区推荐了 resilience4j。这 3 款产品各有优劣势,具体的功能差异参考下表(该表来源 Sentinel Wiki): SentinelHystrixresilience4j隔离策略信号量隔离(并发线程数限流)线程池隔离/信号量隔离信号量隔离熔断降级策略基于响应时间、异常比率、异常数基于异常比率基于异常比率、响应时间实时统计实现滑动窗口(LeapArray)滑动窗口(基于 RxJava)Ring Bit Buffer动态规则配置支持多种数据源支持多种数据源有限支持扩展性多个扩展点插件的形式接口的形式基于注解的支持支持支持支持限流基于 QPS,支持基于调用关系的限流有限的支持Rate Limiter流量整形支持预热模式、匀速器模式、预热排队模式不支持简单的 Rate Limiter 模式系统自适应保护支持不支持不支持控制台提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等简单的监控查看不提供控制台,可对接其它监控系统目前 Sentinel 在 Spring Cloud Alibaba 项目中已经适配了 Spring Cloud 体系,可以用来完全替代 Hystrix 的功能了。Spring Cloud Alibaba Sentinel 功能介绍Spring Cloud Alibaba Sentinel 主要是为了整合 Sentinel 和 Spring Boot/Cloud 技术栈。目前完成了如下功能:自动适配 Servlet 容器。只需要配置 url-pattern(默认拦截所有请求),即可对拦截的这些 url 进行限流降级操作整合了 RestTemplate,使用 RestTemplate 进行操作的时候会被限流降级整合了 Feign,兼容了原先的 Hystrix 支持 Feign 的编程模型数据源可配置化,只需在配置文件中配置数据源信息,即可动态加载规则Endpoint 暴露各种元数据,比如配置信息,规则数据HealthIndicator 检查 Sentinel 健康状态 (整合中)支持 Spring Cloud Gateway 和 Zuul (整合中)Spring Cloud Alibaba Sentinel 代替 Hystrix想要使用 Spring Cloud Alibaba Sentinel,需要加上依赖信息:<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel</artifactId> <version>0.2.1.RELEASE</version></dependency>0代码修改兼容 Feign加上 Feign 的依赖:<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>${latest.version}</version></dependency>把 hystrix 的配置改成 sentinel 的即可使用 Sentinel 的限流降级功能:# feign.hystrix.enabled: truefeign.sentinel.enabled: true@FeignClient(name = “service-provider”)public interface EchoService { @RequestMapping(value = “/echo/{str}”, method = RequestMethod.GET) String echo(@PathVariable(“str”) String str); @RequestMapping(value = “/echo/save”, method = RequestMethod.POST) String save(Foo foo);}对于这个 EchoService,echo 方法对应的资源名是 GET:http://service-provider/echo/{str}, save 方法对应的资源名是 POST:http://service-provider/echo/save。只需配置这些规则,限流降级操作即可立即生效。一行代码支持 RestTemplateSentinel 还跟 Spring 生态的 RestTemplate 做了整合,可以对 RestTemplate 请求过程进行限流和降级操作,只需要在构造 RestTemplate 的时候加上 @SentinelRestTemplate 注解即可:@Bean@SentinelRestTemplatepublic RestTemplate restTemplate() { return new RestTemplate();}@SentinelRestTemplate 注解还暴露出了对应的属性可进行限流降级后的自定义错误,默认的行为是返回 “RestTemplate request block by sentinel” 信息。关于 @SentinelRestTemplate 的详细信息可以参考 Wiki。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

February 26, 2019 · 1 min · jiezi

罗辑思维在全链路压测方面的实践和工作笔记

业务的知名度越高,其背后技术团队承受的压力就越大。一旦出现技术问题,就有可能被放大,尤其是当服务的是对知识获取体验要求颇高的用户群体。提供知识服务的罗辑思维主张“省时间的获取知识”,那么其技术团队在技术实践方面是如何践行省时间的理念的呢?本文将还原罗辑思维技术团队在全链路压测上的构建过程,为您一探究竟。全链路压测知多少保障服务的可用性和稳定性是技术团队面临的首要任务,也是技术难题之一。例如,罗辑思维提供的是知识服务,服务的是在高铁、地铁和公交车等场所利用碎片时间进行学习,在凌晨、深夜都有可能打开App,以及分布在海外的全球用户。这就需要得到App提供7*24的稳定高性能的服务和体验。在实际生产环境中,用户的访问行为一旦发生,从CDN到接入层、前端应用、后端服务、缓存、存储、中间件整个链路都面临着不确定的流量,无论是公有云、专有云、混合云还是自建IDC,全局的瓶颈识别、业务整体容量摸底和规划都需要高仿真的全链路压测来检验。这里的不确定的流量指的是某个大促活动、常规高并发时间段以及其他规划外的场景引起的不规则、大小未知的流量。众所周知,应用的服务状态除了会受到自身稳定性的影响,还会受到流量等环境因素的影响,并且影响面会继续传递到上下游,哪怕一个环节出现一点误差,误差在上下游经过几层累积后会造成什么影响谁都无法确定。因此,在生产环境里建立起一套验证机制,来验证各个生产环节都是能经受住各类流量的访问,成为保障服务的可用性和稳定性的重中之重。最佳的验证方法就是让事件提前发生,即让真实的流量来访问生产环境,实现全方位的真实业务场景模拟,确保各个环节的性能、容量和稳定性均做到万无一失,这就是全链路压测的诞生背景,也是将性能测试进行全方位的升级,使其具备“预见能力”。可见,全链路压测做得好,遇到真实环境的流量,系统仅仅只是再经历一次已经被反复验证过的场景,再考一遍做“做过的考题”,不出问题在意料之中将成为可能。压测的核心要素实施完整的业务压测,路径很重要。要达成精准衡量业务承接能力的目标,业务压测就需要做到一样的线上环境、一样的用户规模、一样的业务场景、一样的业务量级和一样的流量来源,让系统提前进行“模拟考”,从而达到精准衡量业务模型实际处理能力的目标,其核心要素是:压测环境、压测基础数据、压测流量(模型、数据)、流量发起、掌控和问题定位。生产环境上基础数据基本分为两种方式,一种是数据库层面不需要做改造,直接基于基础表里的测试账户(相关的数据完整性也要具备)进行,压测之后将相关的测试产生的流水数据清除(清除的方式可以固化SQL脚本或者落在系统上);另一种就是压测流量单独打标(如单独定义的Header),然后业务处理过程中识别这个标并传递下去,包括异步消息和中间件,最终落到数据库的影子表或者影子库中。这种方式详见阿里的全链路压测实践,我们也是选用了这种方式。此外,生产环境的压测尽量在业务低峰期进行从而避免影响生产的业务。全链路压测的构建过程目前,罗辑思维已经提供了得到APP、少年得到、和微信公众号得到里的得到商城等多个流量入口。每一年,罗辑思维都会举办跨年演讲,第一年是在优酷,有200多万人的在线观看,第二年是在深圳卫视合作直播,并在优酷等视频网站同步,直播过程中当二维码放出来的时候,我们就遇到了大量的用户请求,在同一时刻。这就意味着,如果没有对这个期间的流量做好准确的预估,评估好性能瓶颈,那么在直播过程中就有可能出现大面积服务中断。对整体系统进行全链路压测,从而有效保障每个流量入口的服务稳定性成为技术团队的当务之急。因此,我们在2017年,计划引入全链路压测。期间,也对系统做了服务化改造,对于服务化改造的内容之前在媒体上传播过,这次我们主要是讲下保障服务稳定性的核心 - 全链路压测。大致的构建过程如下:2017年10月启动全链路压测项目,完成商城的首页、详情、购物车、下单的改造方案设计、落地、基础数据准备和接入,以及得到APP首页和核心功能相关的所有读接口接入,并在进行了得到APP的第一次读接口的全链路压测。2017年11月商城核心业务和活动形态相对稳定,进入全面的压测&攻坚提升期,同时拉新、下单和支付改造开始,得到APP开始进入写改造,活动形态初具雏形,读写覆盖范围已经覆盖首页、听书、订阅、已购、拉新、知识账本,并启动用户中心侧用户部分的底层改造,包括短信等三方的业务挡板开发。2017年12月商城进行最后的支付改造补齐,然后是全链路压测&优化的整体迭代;得到APP全链路压测接入范围继续增加,覆盖全部首页范围和下侧5个tab,同时开始部分模块组合压测和性能调优的迭代;完成底层支付和用户中心配合改造,以及支付和短信所有外部调用的挡板改造;行了多轮次的全链路形态完整压测,并从中发现发现,给予问题定位,提升体系稳定性;梳理对焦了风险识别、预案和值班等等。经过3个多月的集中实施,我们将全链路压测接入链路174个,创建44个场景,压测消耗VUM1.2亿,发现各类问题200多个。如果说2017年全链路压测的设施在罗辑是从0到1,那么2018年就是从1到N了。从2018年开始,全链路压测进入比较成熟的阶段,我们的测试团队基于PTS和之前的经验,迅速地将全链路压测应用于日常活动和跨年活动中,并应用于新推出的业务「少年得到」上。目前,全链路压测已经成为保障业务稳定性的核心基础设施之一。全链路压测的构建与其说是一个项目,不如说是一项工程。仅凭我们自己的技术积累和人员配置是无法完成的,在此特别感谢阿里云PTS及其他技术团队提供的支持,帮助我们将全链路压测在罗辑思维进行落地。下面我们将落地过程中积累的经验以工作笔记的方式分享给大家。工作笔记A. 流量模型的确定:流量较大的时候可以通过日志和监控快速确定。但是往往可能日常的峰值没有那么高,但是要应对的一个活动却有很大的流量,有个方法是可以基于业务峰值的一个时间段内统计各接口的峰值,最后拼装成压测的流量模型。B. 脏数据的问题:无论是通过生产环境改造识别压测流量的方式还是在生产环境使用测试帐号的方式,都有可能出现产生脏数据的问题,最好的办法是:在仿真环境或者性能环境多校验多测试:有个仿真环境非常重要,很多问题的跟进、复现和debug不需要再上生产环境,降低风险。有多重机制保障:比如对了压测流量单独打标还需要UID有较强的区分度,关键数据及时做好备份等等。C. 监控:由于是全链路压测,目的就是全面的识别和发现问题,所以要求监控的覆盖度很高。从网络接入到数据库,从网络4层到7层和业务的,随着压测的深入,你会发现监控总是不够用。D. 压测的扩展:比如我们会用压测进行一些技术选型的比对,这个时候要确保是同样的流量模型和量级,可以通过全链路压测测试自动扩容或者是预案性质的手工扩容的速度和稳定性。在全链路压测的后期,也要进行重要的比如限流能力的检验和各种故障影响的实际检验和预案的演练。E. 网络接入:如果网络接入的节点较多,可以分别做一些DIS再压测,逐个确定能力和排除问题,然后整体enable之后再一起压测确定整体的设置和搭配上是否有能力对不齐的情况。比如,网络上使用了CDN动态加速、WAF、高防、SLB等等,如果整体压测效果不理想的时候建议屏蔽掉一些环节进行压测,收敛问题,常见的比如WAF和SLB之间的会话保持可能带来负载不匀的问题。当然这些产品本身的容量和规格也是需要压测和验证的,如SLB的CPS、QPS、带宽、连接数都有可能成为瓶颈,通过在PTS的压测场景中集成相关SLB监控可以方便地一站式查看,结合压测也可以更好的选择成本最低的使用方式。另外负载不匀除了前面说的网络接入这块的,内部做硬负载的Nginx的负载也有可能出现不匀的现象,特别是在高并发流量下有可能出现,这也是全链路、高仿真压测的价值。特别是一些重要活动的压测,建议要做一下业务中会真实出现的流量脉冲的情况。阿里云PTS是具备这个能力的,可以在逐级递增满足容量的背景下再观察下峰值脉冲的系统表现,比如验证限流能力,以及看看峰值脉冲会不会被识别为DDOS。F. 参数调优:压测之后肯定会发现大量的参数设置不合理,我们的调优主要涉及到了这些:内核网络参数调整(比如快速回收连接)、Nginx的常见参数调优、PHP-FPM的参数调整等等,这些网上相关的资料非常多。G. 缓存和数据库:重要业务是否有缓存;Redis CPU过高可以重点看下是否有模糊匹配、短连接的不合理使用、高时间复杂度的指令的使用、实时或准实时持久化操作等等。同时,可以考虑升级Redis到集群版,另外对于热点数据考虑Local Cache的优化机制(活动形态由于K-V很少,适合考虑Local Cache);重要数据库随着压测的进行和问题的发现,可能会有索引不全的情况;H. Mock服务:一般在短信下发、支付环节上会依赖第三方,压测涉及到这里的时候一般需要做一些特殊处理,比如搭建单独的Mock服务,然后将压测流量路由过来。这个Mock服务涉及了第三方服务的模拟,所以需要尽量真实,比如模拟的延迟要接近真正的三方服务。当然这个Mock服务很可能会出现瓶颈,要确保其容量和高并发下的接口延时的稳定性,毕竟一些第三方支付和短信接口的容量、限流和稳定性都是比较好的。I. 压测时系统的CPU阈值和业务SLA我们的经验是CPU的建议阈值在50到70%之间,主要是考虑到容器的环境的因素。然后由于是互联网性质的业务,所以响应时间也是将1秒作为上限,同时压测的时候也会进行同步的手工体感的实际测试检查体验。(详细的指标的解读和阈值可以点击阅读原文)J. 其他限流即使生效了,也需要在主要客户端版本上的check是否限流之后的提示和体验是否符合预期,这个很重要;全链路压测主要覆盖核心的各种接口,除此以外的接口也要有一定的保护机制,比如有默认的限流阈值,确保不会出现非核心接口由于预期外流量或者评估不足的流量导致核心系统容量不足(如果是Java技术栈可以了解下开源的Sentinel或者阿里云上免费的限流工具 AHAS)核心的应用在物理机层面要分开部署;省时间的技术理念目前,全链路压测已成为罗辑思维的核心技术设施之一,大幅提升了业务的稳定性。借助阿里云PTS,全链路压测的自动化程度得以进一步提高,加速了构建进程、降低了人力投入。我们非常关注技术团队的效率和专注度,不仅是全链路压测体系的构建,还包括其他很多业务层面的系统建设,我们都借助了合作伙伴的技术力量,在可控时间内支撑起业务的快速发展。当业务跑的快的时候,技术建设的路径和方式,是团队的基础调性决定的。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。

February 22, 2019 · 1 min · jiezi

蚂蚁金服核心技术:百亿特征实时推荐算法揭秘

小叽导读:文章提出一整套创新算法与架构,通过对TensorFlow底层的弹性改造,解决了在线学习的弹性特征伸缩和稳定性问题,并以GroupLasso和特征在线频次过滤等自研算法优化了模型稀疏性。在支付宝核心推荐业务获得了uvctr的显著提升,并较大地提升了链路效率。0.综述在线学习(Online learning)由于能捕捉用户的动态行为,实现模型快速自适应,进而成为提升推荐系统性能的重要工具。然而它对链路和模型的稳定性,训练系统的性能都提出了很高的要求。但在基于原生TensorFlow,设计Online推荐算法时,我们发现三个核心问题:一些资讯推荐场景,需要大量长尾词汇作为特征,需使用featuremap对低频特征频次截断并连续性编码,但耗时且方法aggressive。使用流式数据后,无法预知特征规模,而是随训练逐渐增长。因此需预留特征空间训练几天后重启,否则会越界。模型稀疏性不佳,体积达到数十GB,导致上传和线上加载耗时长且不稳定。更重要的是,在线学习如火如荼,当流式特征和数据都被打通后,能按需增删特征,实现参数弹性伸缩的新一代训练平台成为大势所趋。为了解决这些问题,从2017年底至今,蚂蚁金服人工智能部的同学,充分考虑蚂蚁的业务场景和链路,对TensorFlow进行了弹性改造, 解决了以上三大痛点,简化并加速离线和在线学习任务。其核心能力如下:弹性特征伸缩体系,支持百亿参数训练。group_lasso优化器和频次过滤,提高模型稀疏性,明显提升线上效果。模型体积压缩90%,完善的特征管理和模型稳定性监控。在与业务线团队的共同努力下,目前已在支付宝首页的多个推荐场景全流量上线。其中某推荐位的个性化online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 某个性化资讯推荐业务最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%,模型体积压缩90%,链路效率提升50%。1. 弹性改造及优势背景:在原生TensorFlow中,我们通过Variable来声明变量,若变量超过了单机承载的能力,可使用partitioned_variables来将参数分配到不同机器上。 但必须指定shape,声明后即不可改变,通过数组索引查找。由于推荐系统中大量使用稀疏特征,实践中一般采取embedding_lookup_sparse一类的方法在一个巨大的Dense Variable中查找向量并求和,来代替矩阵乘法。开源Tensorflow限定了Variable使用前必须声明维度大小,这带来了两个问题:1)需要预先计算特征到维度范围内的int值的映射表,这一步操作通常在ODPS上完成。因为需要扫描所有出现的特征并编号,计算非常缓慢;2)在online learning场景下,为了容纳新出现的特征,需要预留一部分维度空间,并在线上不断修改映射表,超过预留空间则需要重新启动在线任务。为了突破固定维度限制,实现特征的动态增加和删除,最朴素的优化想法是在TensorFlow底层实现模拟字典行为的Variable,并在此基础上重新实现Tensorflow上层API。由此我们进行了优化,在server新增了基于HashMap的HashVariable,其内存结构如下:在声明该变量时,只需增加一句,其他训练代码皆不需改动:每个特征都通过hash函数映射到一个2的64次方大小的空间内。当需要计算该特征时,PS会按需惰性创建并返回之。但其上层行为与原生TF一致。由于去掉了featuremap转ID的过程,我们内部形象地将其称为“去ID化”。在此之上我们实现了Group Lasso FTRL,频次过滤和模型压缩等一系列算法。备注:弹性特征带来一个显著的优势:只要用足够强的L1稀疏性约束,在单机上就能调试任意大规模的特征训练,带来很多方便。我们的hashmap实现是KV化的,key是特征,value是vector的首地址。离线训练优化经过这样的改造后,在离线批量学习上,带来了以下变化:在线训练优化online learning上,能带来如下变化:除了性能有明显的提升之外,其最大的优势是不需提前申请空间,训练可以无缝稳定运行。2. 特征动态增删技术弹性架构,主要目的就是特征优选,让模型自适应地选择最优特征,进而实现稀疏化,降低过拟合。本节介绍特征优选的两个核心技术:使用流式频次过滤, 对特征进入进行判定。使用Group Lasso优化器,对特征进行筛选和删除。2.1 Group Lasso 优化器稀疏化是算法追求的重要模型特性,从简单的L1正则化和Truncated Gradient[9], 再到讨论累积梯度平均值的RDA(Regularized Dual Averaging)[10], 再到目前常见的 FTRL[2] 。 然而它们都是针对广义线性模型优化问题提出的稀疏性优化算法,没有针对sparse DNN中的特征embedding层做特殊处理。把embedding参数向量当做普通参数进行稀疏化,并不能达到在线性模型中能达到的特征选择效果,进而无法有效地进行模型压缩。例如:当包含新特征的样本进入时,一个特征对应的一组参数(如embedding size为7,则参数数量为7)被激活,FTRL判定特征中的部分参数无效时,也不能安全地将该特征删除。如图:因此,在L1和L2正则的基础上,人们引入L21正则(group lasso)和L2正则(exclusive sparsity),分别表示如下:L21早在2011年已经引入,它最初目的是解决一组高度关联特征(如男女)应同时被保留或删除的问题,我们创新地扩展到embedding的表示上,以解决类似的问题。在L21中,由于内层L2正则将一个特征的所有参数施加相同的约束,能将整组参数清除或保留,由此决定embedding层中的某些特征对应的embedding向量是否完全删除,提升模型泛化性。因此称为group lasso。而L12则正好相反,它迫使每组参数中的非0参数数量一致但值又尽可能不同,但使输出神经元互相竞争输入神经元,进而使特征对目标更具区分性。对于DNN分类网络,底层表示要求有足够的泛化性和特征抽象能力,上层接近softmax层,需要更好的区分性。因此我们通常在最底层的embedding层使用group lasso。即如下的优化目标:直接将L21正则项惩罚加入loss,模型最终也能收敛,但并不能保证稀疏性。因此Group lasso优化器参考了FTRL,将梯度迭代分成两个半步,前半步按梯度下降,后半步微调实现稀疏性。通过调节L1正则项(即公式中的),能有效地控制模型稀疏性。Group lasso是弹性计算改造后,模型性能提升和压缩的关键。值得指出:在我们实现的优化器中,Variable,以及accum和linear两个slot也是KV存储。L12和L21正则相结合的方法也已经有论文讨论[8],但我们还未在业务上尝试出效果。由于篇幅限制,本节不打算详细介绍Group lasso的原理和推导2.2 流式频次过滤讨论完特征动态删除的方法后,我们再分析特征的准入策略。2.2.1 频次过滤的必要性在Google讨论FTRL的文章1中提到, 在高维数据中大部分特征都是非常稀疏的,在亿级别的样本中只出现几次。那么一个有趣的问题是,FTRL或Group FTRL优化器能否能删除(lasso)极低频特征?在RDA的优化公式中,满足以下条件的特征会被置0:若在t步之前,该特征只出现过几次,未出现的step的梯度为0,随着步数增大,满足上述条件变得越来越容易。由此RDA是可以直观处理极稀疏特征的。 但对于FTRL,要满足:其中,不仅和历史梯度有关,还与历史学习率和权重w有关。 因此FTRL虽然也能处理极稀疏特征,但并没有RDA那么aggressive(此处还待详细地分析其下界,Group FTRL与此类似)。由于FTRL在设计和推导时并未明确考虑极低频特征,虽然通过增大,确实能去除大量极低频特征,但由于约束太强,导致部分有效特征也被lasso,在离线实验中被证明严重影响性能。其次,对这些巨量极低频特征,保存历史信息的工程代价是很高昂的(增加几倍的参数空间和存储需求),如下图:因此我们提出,能否在实时数据流上模拟离线频次过滤,为特征提供准入门槛,在不降低模型性能的基础上,尽量去除极低频特征,进一步实现稀疏化?2.2.2 频次过滤的几种实现注意: 由于默认的embedding_lookup_sparse对特征执行了unique操作(特征归一化以简化计算),因此在PS端是不可能获取真实特征和label频次的。需要Python端对placeholder统计后,上传给server端指定的Variable,优化器通过slot获得该Variable后作出联合决策。最naive的思路是模拟离线频次过滤,对特征进行计数,只有达到一定阈值后再进入训练,但这样破坏了数据完整性:如总频次6,而阈值过滤为5,则该特征出现的前5次都被忽略了。为此我们提出了两种优化方案:基于泊松分布的特征频次估计在离线shuffle后的特征满足均匀分布,但对在线数据流,特征进入训练系统可看做泊松过程,符合泊松分布:其中n为当前出现的次数,t为当前的步数,为单位时间发生率,是泊松分布的主要参数,T为训练总步数。为特征最低门限(即最少在T时间内出现的次数)。因此我们能通过前t步的特征出现的次数n,将t时刻当做单位时间,则。 根据泊松分布,我们可以算出剩余时间内事件发生大于等于次的概率。 每次该特征出现时,都可按该概率做伯努利采样,特征在t步进入系统的概率用下式计算:通过真实线上数据仿真,它能接近离线频次过滤的效果,其是随每次特征进入时动态计算的。它的缺陷是:当t越小时,事件发生在t内的次数的variance越大,所以会以一定概率误加或丢弃特征。未来总的训练步数T在在线学习中是未知的。频次过滤与优化器相分离,导致不能获得优化器的统计信息。动态调L1正则方案在经典的FTRL实现中,L1正则对每个特征都是一致的。这导致了2.2.1 中提到的问题:过大的L1虽然过滤了极低频特征,但也影响的了模型的性能。参考各类优化器(如Adam)对learning_rate的改进,我们提出:通过特征频次影响L1正则系数,使得不同频次的特征有不同的lasso效果。特征频次和基于MLE的参数估计的置信度相关,出现次数越低置信度越低。如果在纯频率统计基础上加入一个先验分布(正则项),当频率统计置信度越低的时候,越倾向于先验分布,相应的正则系数要更大。我们经过多个实验,给出了以下的经验公式:其中c是惩罚倍数,为特征最低门限,这两者皆为超参,是当前特征出现的频次。我们在线上环境,使用了动态调节L1正则的方案 。在uvctr不降甚至有些微提升的基础上,模型特征数比不使用频次过滤减少75%,进而从实验证明了频次过滤对稀疏化的正向性。它的缺点也很明显:特征频次和正则系数之间的映射关系缺少严谨证明。频次过滤作为特征管理的一部分,目前还少有相关论文研究,亟待我们继续探索。3. 模型压缩和稳定性3.1 模型压缩在工程上,由于做了优化,如特征被优化器lasso后,只将其置0,并不会真正删除;在足够多步数后才删除。同时引入内存池,避免特征的反复创建和删除带来的不必要的性能损失。 这就导致在训练结束后,模型依然存在大量0向量。导出时要进一步做模型压缩。由于引入了HashPull和HashPush等非TF原生算子,需要将其裁剪后转换为原生TF的op。 我们将这些步骤统称图裁剪(GraphCut), 它使得线上inference引擎,不需要做任何改动即可兼容弹性改造。由于有效特征大大减少,打分速度相比原引擎提升50%以上。我们将图裁剪看做TF-graph的静态优化问题,分为3个步骤:第一遍遍历Graph,搜索可优化子结构和不兼容的op。第二遍遍历,记录节点上下游和元数据,裁剪关键op,并将Variable的非0值转存至Tensorflow原生的MutableDenseHashTable。本步骤将模型体积压缩90%。拼接新建节点,重建依赖关系,最后递归回溯上游节点,去除与inference无关的子图结构我们实现了完整简洁的图裁剪工具,在模型热导出时调用, 将模型从原先的8GB左右压缩到几百兆大小,同时保证模型打分一致。3.2 模型稳定性和监控online learning的稳定性非常重要。我们将线上真实效果,与实时模型生成的效果,进行了严密的监控,一旦样本偏差过多,就会触发报警。由于需捕捉时变的数据变化,因而不能用固定的离线数据集评估模型结果。我们使用阿里流式日志系统sls最新流入的数据作为评估样本,以滑动窗口先打分后再训练,既维持了不间断的训练,不浪费数据,同时尽可能高频地得到最新模型效果。我们对如下核心指标做了监控:样本监控: 正负比例,线上打分值和online-auc(即线上模型打分得到的auc),产出速率,消费速率。训练级监控: AUC, User-AUC(参考备注),loss, 模型打分均值(与样本的正负比例对齐),异常信息。特征级管理: 总特征规模,有效/0/删除特征规模,新增/插入/删除的速率。整体模型和调度:模型导出的时间,大小,打分分布是否正常,是否正常调度。业务指标:uvctr,pvctr(小时级更新,T+1报表)。线上与训练指标之间的对应关系如下表:通过http接口,每隔一段时间发送监控数据,出现异常会及时产生钉钉和邮件报警。下图是对9月20日到27号的监控,从第二张图表来看,模型能较好的适应当前数据流的打分分布。User-AUC:传统的AUC并不能完全描述uvctr,因为模型很可能学到了不同用户间的偏序关系,而非单个用户在不同offer下的点击偏序关系。为此,我们使用了User-AUC,它尽可能地模拟了线上uvctr的计算过程,在真实实验中,监控系统的uvctr小时报表,与实时模型输出的User-AUC高度一致。4. 工程实现和效果目前算法已经在支付宝首页的多个推荐位上线。推荐系统根据用户的历史点击,融合用户画像和兴趣,结合实时特征,预估用户CTR,进而提升系统整体点击率。我们以推荐位业务为例说明,其采用了经典的wide&deep的网络结构,其sparse部分包含百级别的group(见下段备注1)。 一天流入约百亿样本,label的join窗口为固定时长。由于负样本占大多数,上游链路对正负样本做了1:8的降采样(见下文备注2)。训练任务采用蚂蚁统一训练平台构建,并使用工作流进行定时调度,离线和在线任务的其他参数全部一致。Batchsize为512,每200步(即20万样本)评估结果,定时将模型通过图裁剪导出到线上系统。当任务失败时,调度系统会自动拉起,从checkpoint恢复。该推荐业务的online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 另一资讯推荐业务其最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%。实验效果相比有较大的提升。备注1: group embedding是将相似emb特征分组,各自lookup求和后再concat,使得特征交叉在更高层进行。其设计是考虑到不同group的特征差异很大(如user和item),不应直接对位求和。备注2: inference打分仅做pointwise排序,采样虽改变数据分布但不改变偏序关系,因此并未在训练上做补偿。5. 未来工作弹性特征已经成为蚂蚁实时强化深度学习的核心要素。它只是第一步,在解决特征空间按需创建问题后,它会带来一个充满想象力的底层架构,众多技术都能在此基础上深挖: 在工程上,可继续从分钟级向秒级优化,进一步提升链路实时性并实现模型增量更新; 在算法上,我们正在探索如样本重要性采样,自动特征学习,在线线性规划与DNN的结合,实现优化器联合决策等技术。由于在线学习是个复杂的系统工程,我们在开发和调优时遇到了大量的困难,涉及样本回流,训练平台,模型打分,线上评估等一系列问题,尤其是稳定性,但基本都一一克服。为了保证线上结果稳定可信,我们在观察和优化两三个月后才发布这篇文章。本文作者为蚂蚁金服人工智能部认知计算组的基础算法团队,团队涉及图像、NLP、推荐算法和知识图谱等领域,带头人为国家知名算法专家褚崴,拥有定损宝和理赔宝等核心业务。本文作者:墨眀阅读原文本文来自云栖社区合作伙伴“ 阿里巴巴机器智能”,如需转载请联系原作者。 ...

February 22, 2019 · 1 min · jiezi

优酷IPv6改造纪实:视频行业首家拥抱下一代网络技术

阿里妹导读:2018年双11前,优酷开启了IPV6的大门。9月份PC端业务开启灰度,迎来首位IPV6 VIP用户后,优酷移动客户端也马不停蹄地加入灰度大军。从0到1,花了几个月;从10到1000,花了几天;从1000到50W,只要几小时。IPV6灰度的马车一旦起跑,将再也不需要停止。IPV6在优酷,技术驱动产品的验证2018 世界杯期间,我们验证了IPV6的改造方案和技术可行性,双11期间优酷PC端和App在国内教育网及一线重点城市都有一定比例的IPV6用户,享受着高清直播点播服务,体验着一条刚刚建完的高速大道却没有几辆车的快感。专属的用户身份标识,专属的客户端网络检测能力,专属的会员卡,专属的红包,这一切可能不知不觉中就属于你了。随着双11后阿里集团几大应用相继开启灰度,我们迎来了中国首次IPv6大规模应用上线,优酷不仅能跑而且跑得快。这象征着优酷大家庭通过双11、世界杯等的洗礼,已经拥有了一支能战敢战,战则必胜的技术团队。IPV6不是一个人的功劳,是所有技术人努力的结晶。今天,我们采用专访问答的形式,带你走进优酷IPV6从立项到实践的全过程。优酷IPV6改造项目,由优酷应用架构吴灵晓(盖优)负责。应用架构部主要负责整体架构设计实施优化工作,探索从DEVOPS向AIOPS转变,智能运维、深度学习、大数据分析、智能机器人等新技术也有大量的成熟运用。立项Q:IPV4和IPV6有哪些区别呢?安全:IPv6把IPSec作为必备协议,保证了网络层端到端通信的完整性和机密性。业务无限扩展:不受地址短缺的影响。个性化服务:流标签的使用让我们可以为数据包所属类型提供个性化的网络服务,并有效保障相关业务的服务质量。减少开销:报头格式大大简化,从而有效减少路由器或交换机对报头的处理开销。万物互联:大容量的地址空间能够真正地实现无状态地址自动配置。Q:为什么想到要做IPV6改造?第一,IPV4环境恶化:第二,政策驱动:2017-11-26 中共中央办公厅 国务院办公厅印发《推进互联网协议第六版(IPv6)规模部署行动计划》。2018-05-03 工业和信息化部关于贯彻落实《推进互联网协议第六版(IPv6)规模部署行动计划》的通知。第三,技术驱动产品业务:IPv6在客户端-服务端-阿里云CDN-优酷直播点播业务的全线贯通应用,优酷完成了新网络技术到产品应用的实现,改写技术服务产品,服务倒逼技术升级的局面,使得IPV6网络技术能够支撑优酷今后几年甚至十几年的业务需求,5G、P2P、人工智能、AI、物联网等,在网络技术上已经没有障碍。第四,天时地利俱备,差人和:政策支持,集团推动,技术展现为一体,这么好的机会,不能错过。拥有一群打过双11,打过春晚,打过世界杯的战友们,没有什么事是做不好的。Q:决定做之后,怎么列的计划呢?目标是什么?这还真是前无古人,后有来者。谁都没有经验,没有相似可参照的案例,涉及团队众多。各种调查与讨论,以及集团相关的计划安排,整个IPV6项目将分成三步走,包括外网阶段,用户端与接入层支持 v6、内网阶段,服务端内部v4/v6双栈、以及内外网IPv6-only 。外网改造:实现应用快速对外服务,以web/App请求服务为核心,满足IPv6生态发展的需求,并且以外网拉动应用的不同需求;内网改造:应用逐渐扩大到爬虫、邮箱、DB、存储等V6直接交互,需要内网服务器部分采用IPv6,需要整网双栈交付;IPv6 Only:当超过50%应用逐步迁移到IPv6后,新应用默认采用v6开发,遗留一些老旧应用、用户继续采用IPv4服务,内网采用4over6进行封装。相对双栈而言,IPv6 only成本更低,查表转发速度更快,只需维护一套协议栈。阿里网络演进从外到内,从用户到应用逐层迭代,尽量做到成本最低,效率最高。核心目标18自然年底,实现全量灰度。还是那句话,要么不做,要做就做最好。评估后全量灰度目标虽然风险偏大,但努力一把还是可控的。过程Q:对研发同学来说,需要关心哪些?怎么确认哪些要改哪些不要改?对研发的同学来说,只需要关心客户端APP/PC端网页及服务端的改造。客户端基本上涉及到基础网络包NetworkSDK等集团二方包的升级。使用httpdns解析的,需要改造实现客户端网络的判断和接收httpdns服务端下发的AAAA记录;使用localdns解析的,需要改造实现DNS服务请求参数中添加AAAA记录解析的标识。使用三方库的,要升级至最新版并确认支持IPV6,不支持的需要考虑更换三方库。IP 字段是否正确extra : {‘firstIp’: ‘xxxxx’} 是否正确携带探测埋点弱网、DNS耗时的情况下,探测能否正常网络切换特别频繁的场景PC端/服务端要关心的就多一点了,只要你的业务处理中有以下任意一点的,都是要做业务改造的,也就是写Bug。1.IP地址库使用:是否有用到地址库,对用户IP进行地域来源等判断。有的话需要升级到IPV6地址库,并更新调用方法。2.IP地址格式判断:是否对用户IP进行验证,有的话需要加入IPV6地址格式的正则表达式判断。3.IP地址保存:是否对IP有存库等保存操作,需要修改相应字段的长度,IPV6长于IPV4,MySQL 建议字段类型 VARBINARY(16)。4.依赖链路上的修改:是否会将IP作为接口参数传递给下游依赖业务。有的话,下游依赖业务也需要改造。5.客户端IP地址的取得方式:是否从客户端请求的头部获取。是的话,那么在双栈环境中,同一请求,你只能获取到V4和V6地址中的一个,不可能两个都获取。如果是通过请求正文中的某个字段,把客户端地址传上来的,那么,你需要考虑是否需要获取客户端的v4v6的所有地址。是的话,那么就需要扩展请求字段,将v4,v6分成两个字段提交,同时服务端也需要做接收改造处理。6.日志,数据的采集等数据产品的改造:是否用了第三方的采集工具,如果采集工具不支持IPV6的话,那么采集上来的数据会和服务端的请求日志无法对齐,产生GAP。类似还包括广告投放与监测等分别属于多方的业务场景。从业务上来看,需要区分IPv4用户请求和IPv6用户请求,并分开进行数据分析。所以数据产品数据存储等都需要能够支持用户IPv6数据的采集。7.安全产品:内容安全:文本安全过滤,七层流量清洗等等,安全产品改造,业务升级二方包/客户端。8.监控:以用户IP作为判断条件/统计条件的监控配置,需要改造。9.大数据统计:以用户IP作为判断条件/统计条件的内容,需要业务改造。10.依赖服务:原有阿里云产品需要更新为支持IPV6的产品,VPC,ECS,OSS,CDN等都是更换范围。Q:改造中主要遇到哪些问题呢?1.没有IPV6环境:办公网不具备IPv6接入环境,阻塞业务开发;内网尚未改造,无法打通日常(测试)环境。一开始,基础环境还没有具备的时候,我们使用IPV6 over ipv4链路VPN的方式连入测试环境 ,需要PC/客户端加证书改hosts,移动端无法改hosts的,需要root,越狱,各种凌乱,但至少业务测试可以开始启动。然后,我们加强了基础网络和IT合作,在多个园区部署多个IPV6的接入环境,打通IPV6出口,打通办公网和机房的IPV6链路,慢慢实现外网IPV6,日常环境通,预发通,正式通,慢慢使业务能够测试逐步提升到IPV4相同的测试体验,通过域名劫持等手段,跳过了Hosts配置的尴尬,达到标准的测试效率。2.OS网络模块问题:需要让容器支持从请求头部获取IPV6地址,那么就需要把用户IP一级一级透传过来,就需要在各级的服务器上升级网络模块,扩展报文头部。例如toa模块,toa模块是为了让后端的realserver能够看到真实的clientip而不是lvs的dip。同时,tengine/nginx等应用需要升级到支持IPV6的版本(支持新toa模块等),由于历史原因存在各种老版本无法升级,导致升级受阻。我们通过推动应用接入统一接入改造,避免自行升级网络模块带来的风险。通过老版本应用的升级,去nginx的方式,统一升级安装tengine-proxy(安装在ecs测试机器或宿主机上都可以),为了能减少业务改造工作量,在接入层架构我们做了大量的改造。3.地址库特殊需求:优酷有自己的地域编码,优酷广告业务还有广协提供的地域编码,还有业务使用集团的地址库,总之地址库各种不统一。首先,统一地址库,要求所有业务必须统一使用集团地址库。并且协调集团地址库生产方,满足优酷使用场景需求,使统一过程中业务改造工作量减少。再次,对于广告等必须要使用行业统一地址库的场景,我们也制定了多套方案去解决。兜底方案: 将广协地址库中的地区编码,加入到集团地址库中,使集团库具备行业库的能力,在行业库没有完全产出之前,广告业务可以临时使用集团地址库进行改造和测试,保障业务不受损。后续方案: 主动出击,联系广协等行业协会,加快产出IPV6地址库,并且主动无偿提供集团地址库数据,体验了阿里的企业责任,更加快了整个行业的改造进度。最终行业协会从立项到产出地址库的时间,只用了不到1个月,而集团收集这些数据花费了一年半的时间。4.MTU问题:IPV4时代,中间网络三层设备会进行分片,所以一般设置为1500的最大值,以降低网络开销。但IPV6协议为了减轻中间网络层设备繁杂度及成本,中间设备不再分片,由两端的协商指定。导致默认mtu1500的情况下,中间设备出现大量丢包,原因是NAT转换,TCP Option等额外叠加,实际超过1500。短期解决办法是,开启SYN Proxy,通过MSS与端进行协商。调整MTU为最小值1280。发现中间层MTU小于1280时,进行网络报障等办法 。5.客户端是否IPV6,如何验证问题:这是一个很现实的问题,我的网络已经是IPV6了,业务也能正常运行,但怎么确认网络是运行在IPV6上,没有被降级呢?主要有以下两个手段:1)抓取客户端日志:这也是最笨最准确的手段,具体抓日志的方法有很多,就不再重复介绍了。2)业务改造,加入网络检测能力,将优酷客户端当做网络测试的工具。6.协议回落问题7.安全问题:有运营商的出口能力,黑洞能力进展缓慢或者暂不具备。有安全基础产品的存在绑定域名后就能直接访问任意服务,灰度放大。8.CDN灰度问题:CDN域名由阿里云进行调度控制,无法和业务同一灰度范围。增加IPV6专属CDN域名,通过业务侧增加业务逻辑,分别下发不同的域名来实现同一灰度节奏能力。结果Q:灰度是如何操作执行的?通过httpdns方式 ,提供两种灰度能力:基于用户设备的白名单基于地域+运营商+百分比+用户设备白名单基于app版本的全量百分比通过localdns(ADNS),提供一种能力:ADNS新开发并上线了一个能力,支持一个域名下配置多CNAME解析功能,并且每条解释都可以配置权重,通过修改IDNS的cname权重配置来达到比例控制。同时加上自有的线路和运营商的选择能力,满足地域级的灰度需求。我们也开发了自动化的灰度系统,根据起始参数和灰度目标,自动安排灰度比例和时间节奏,实现完全自动化的灰度引流。监控预警+自动回滚能力,边喝咖啡边看灰度量,就是这么实现的。Q:如何确认业务是否正常呢?业务层:业务配置的IPV6监控平台,IPV4与IPV6监控曲线对比。接入层:IPV6流量大盘,分域名,分接口展示成功量,成功率及RT。数据平台:业务指标的大数据分析及报表展示。基础网络:省份运营商的链路成功率,IPV6用户占比,链路质量链路延迟,IPV6降级IPV4比例等数据。有了这些,还怕业务有问题吗?我们知道,视频的生命周期,是从采集到制作到生产,最后到视频的呈现,这里有很多环节,每个环节上都有非常专业的团队来保障。在制作环节会做调音、调色,在生产环节会做编码压缩,在呈现环节的会做解码和后处理,每个环节独立来看都做得不错。但如果我们站在链条的两端来看,制作侧和呈现侧看到的视频效果存在比较大的差异。但是今天,我们的场景发生了改变,我们有形形色色的终端,有手机、Pad、PC、电视、投影,呈现场景已经不可控的,所以今天我们看到的画面,已经不是我们的导演原本希望呈现的画面了。这是今天我们想去解决的问题,当然整个链条上的联动不是靠优酷一家可以解决的,因此我们需要更多产业链上的朋友和我们一起来解决这个问题。当每个人都是导演、演员、编辑、美工的时候,缺少的是什么?空间容量,没有创作空间,没有办公空间,没有消费空间,可持续增量空间。这些不全都是IPV4的错,但确实IPV4是瓶颈,当一个人有上百个设备的时候,IPV4肯定满足不了。有了IPV6,再多设备都OK,每个设备都能互联互通,万物互联。那么,智能化的后期制作变得可能。快速将优酷内容库批量处理为适合视频互联网传播的版本,我们使用了自适应调整映射曲线的算法,根据内容明暗程度,有时提升暗区对比度,有时提升亮区对比度。任何端设备都能干。那么,内容版权将变得容易控制,不用花精力去防盗版了。区块链技术+IPV6+5G,每个设备都记录播放信息,要串改内容必须修改超过51%的设备,盗版成本无限放大。没有了防盗成本后,版权不再昂贵,都能接受。展望技术的价值在于帮助人,不是替代人。通过技术保障项目成功,项目成功也推动技术落地。这一切都在IPV6改造项目中体验。随着灰度扩大,下一期改造来临。普通用户根据不知道IPV6是什么的情况下,通过业务,通过产品去更好地展现出来,让用户能有感知。例如:视频变快变清晰了,走到哪里看到哪里了。会员时间增长了,不用花钱了。技术驱动业务,将会更美好。本文作者:期待被关注的阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

January 30, 2019 · 1 min · jiezi

如何使用阿里云ARMS轻松重现用户浏览器问题

客户投诉不断,本地却无法重现?页面加载较慢是用户经常会反馈的问题,也是前端非常关注的问题之一。但定位、排查解决这类问题就通常会花费非常多的时间,主要原因如下:页面是在用户端的浏览器上加载执行,复现困难页面上线前,开发同学都会进行测试,在测试环境下页面加载一般都是正常的才会正式上线。用户在访问页面时,页面的加载是在用户端的浏览器上进行的,由于页面的加载耗时与地域、网络情况、浏览器或者运营商等有关系,想知道用户在访问页面时的具体情况,复现是非常困难的。监控信息缺少,导致无法深入排查大部分前端监控会通过PerformanceTiming对象,获取完整的页面加载耗时信息,但这类监控就缺失了页面静态资源的加载情况,无法直接复现现场,从而无法深入定位性能瓶颈。为了方便用户更快地定位性能瓶颈,阿里云ARMS前端监控推出一新功能: 会话追踪,提供页面静态资源加载的性能瀑布图,根据页面性能数据可深入定位页面资源加载情况。如何通过会话追踪帮助你快速定位问题在阿里云ARMS前端监控SDK上将sendResource配置为true,重新部署应用后,在页面onload时会上报当前页面加载的静态资源信息。从而在阿里云前端监控平台即可以对慢页面加载问题快速进行定位。SDK配置在阿里云ARMS前端监控SDK部分,默认是不上报页面加载的静态资源信息的,如果想获取页面加载的静态资源信息,只需在SDK的config部分将sendResource配置为true,重新部署后,就可以上报相关信息。具体配置如下:<script>!(function(c,b,d,a){c[a]||(c[a]={});c[a].config={pid:“atc889zkcf@8cc3f63543da641”,imgUrl:“https://arms-retcode.aliyuncs.com/r.png?",sendResource:true};with(b)with(body)with(insertBefore(createElement("script"),firstChild))setAttribute("crossorigin","",src=d)})(window,document,"https://retcode.alicdn.com/retcode/bl.js","__bl");</script>注意:静态资源加载信息的上报是在页面onload时会触发,上报信息量较大,如果对于页面性能要求很高的应用,可以不开启该配置。问题排查过程1. 发现问题进入访问速度菜单后,发现页面的性能较差,11点钟的页面完全加载时间达到35s,如下:2. 慢页面会话追踪在慢页面会话追踪模块,提供该页面在指定时间段内加载较慢的TOP20,这样可以快速发现哪些会话加载较慢,如下图所示。在该模块,你可以快速发现在11点钟有一次会话的页面加载时间在36.72s,这次访问应该是直接导致页面加载时间详情中折线图突然暴增的原因了。其中在在模块有7次会话访问的页面加载时间在7s以上,点击对应的页面,可以直接进入到会话详情页面,从而直观查看页面静态资源加载的瀑布图。通过页面资源加载的瀑布图,可以快速定位到资源加载的性能瓶颈,同时可以查看本次访问的客户端IP地址、浏览器、操作系统等UA信息,从而进一步确认是由于网络原因还是其他原因导致的,针对性进行相应的优化。3. 其他发现问题入口会话追踪也可以进入“会话追踪”菜单,可以看到该应用下的会话列表。会话列表中会根据页面完全加载时间排序,展示TOP100,帮助用户可以快速发现耗时较长的会话信息。同时支持按照页面、会话Id、浏览器、浏览器版本号进行过滤,展示相关的会话信息。点击操作后,是该会话的页面资源加载详情。访问明细如果当前会话列表中无法找到你要排查的会话信息,可以通过访问明细查找到相应的日志详细信息,在param中找到对应的sid即会话Id,然后在会话列表中查找相应的会话Id,即可以定位到想排查的会话信息。例如:在已知用户的客户端IP的情况下,想定位相应的会话信息,即可以在访问明细中,通过t=res and 117.136.32.110 进行搜索,找到对应的会话Id。根据查找到的会话Id, 就可以在会话列表中进行过滤,定位到具体的会话内容。使用入口指南进入访问速度菜单,如果发现页面性能较差,可以在"慢页面会话追踪Top20"中查看访问较慢的会话情况点击详情后,可以查看具体的页面资源加载瀑布图如果Top20不满足,可以点击"更多”,从而进入"会话列表"进入会话追踪菜单,展示的是TOP100的会话列表信息,根据页面完全加载时间从高到底排序,排查页面资源加载情况至此,慢页面会话追踪功能及使用方法介绍完成。该功能可以帮助你复现用户在访问页面时的页面资源加载情况,快速定位性能瓶颈问题。附录官网文档介绍阿里云ARMS前端监控官网本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 23, 2019 · 1 min · jiezi

容器监控实践—node-exporter

概述Prometheus从2016年加入CNCF,到2018年8月毕业,现在已经成为Kubernetes的官方监控方案,接下来的几篇文章将详细解读Promethues(2.x)Prometheus可以从Kubernetes集群的各个组件中采集数据,比如kubelet中自带的cadvisor,api-server等,而node-export就是其中一种来源Exporter是Prometheus的一类数据采集组件的总称。它负责从目标处搜集数据,并将其转化为Prometheus支持的格式。与传统的数据采集组件不同的是,它并不向中央服务器发送数据,而是等待中央服务器主动前来抓取,默认的抓取地址为http://CURRENT_IP:9100/metricsnode-exporter用于采集服务器层面的运行指标,包括机器的loadavg、filesystem、meminfo等基础监控,类似于传统主机监控维度的zabbix-agentnode-export由prometheus官方提供、维护,不会捆绑安装,但基本上是必备的exporter功能node-exporter用于提供NIX内核的硬件以及系统指标。如果是windows系统,可以使用WMI exporter如果是采集NVIDIA的GPU指标,可以使用prometheus-dcgm 根据不同的NIX操作系统,node-exporter采集指标的支持也是不一样的,如:diskstats 支持 Darwin, Linuxcpu 支持Darwin, Dragonfly, FreeBSD, Linux, Solaris等,详细信息参考:node_exporter我们可以使用 –collectors.enabled参数指定node_exporter收集的功能模块,或者用–no-collector指定不需要的模块,如果不指定,将使用默认配置。部署二进制部署:下载地址:从https://github.com/prometheus…解压文件:tar -xvzf .tar.gz开始运行:./node_exporter./node_exporter -h 查看帮助usage: node_exporter [<flags>]Flags: -h, –help –collector.diskstats.ignored-devices –collector.filesystem.ignored-mount-points –collector.filesystem.ignored-fs-types –collector.netdev.ignored-devices –collector.netstat.fields –collector.ntp.server=“127.0.0.1” ……/node_exporter运行后,可以访问http://${IP}:9100/metrics,就会展示对应的指标列表Docker安装:docker run -d \ –net=“host” \ –pid=“host” \ -v “/:/host:ro,rslave” \ quay.io/prometheus/node-exporter \ –path.rootfs /hostk8s中安装:node-exporter.yaml文件:apiVersion: v1kind: Servicemetadata: annotations: prometheus.io/scrape: ’true’ labels: app: node-exporter name: node-exporter name: node-exporterspec: clusterIP: None ports: - name: scrape port: 9100 protocol: TCP selector: app: node-exporter type: ClusterIP—-apiVersion: extensions/v1beta1kind: DaemonSetmetadata: name: node-exporterspec: template: metadata: labels: app: node-exporter name: node-exporter spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/tryk8s/node-exporter:latest name: node-exporter ports: - containerPort: 9100 hostPort: 9100 name: scrape hostNetwork: true hostPID: truekubectl create -f node-exporter.yaml得到一个daemonset和一个service对象,部署后,为了能够让Prometheus能够从当前node exporter获取到监控数据,这里需要修改Prometheus配置文件。编辑prometheus.yml并在scrape_configs节点下添加以下内容:scrape_configs: # 采集node exporter监控数据 - job_name: ’node’ static_configs: - targets: [’localhost:9100’]也可以使用prometheus.io/scrape: ’true’标识来自动获取service的metric接口- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]配置完成后,重启prometheus就能看到对应的指标查看指标:直接查看:如果是二进制或者docker部署,部署成功后可以访问:http://${IP}:9100/metrics会输出下面格式的内容,包含了node-exporter暴露的所有指标:# HELP go_gc_duration_seconds A summary of the GC invocation durations.# TYPE go_gc_duration_seconds summarygo_gc_duration_seconds{quantile=“0”} 6.1872e-05go_gc_duration_seconds{quantile=“0.25”} 0.000119463go_gc_duration_seconds{quantile=“0.5”} 0.000151156go_gc_duration_seconds{quantile=“0.75”} 0.000198764go_gc_duration_seconds{quantile=“1”} 0.009889647go_gc_duration_seconds_sum 0.257232201go_gc_duration_seconds_count 1187# HELP node_cpu Seconds the cpus spent in each mode.# TYPE node_cpu counternode_cpu{cpu=“cpu0”,mode=“guest”} 0node_cpu{cpu=“cpu0”,mode=“guest_nice”} 0node_cpu{cpu=“cpu0”,mode=“idle”} 68859.19node_cpu{cpu=“cpu0”,mode=“iowait”} 167.22node_cpu{cpu=“cpu0”,mode=“irq”} 0node_cpu{cpu=“cpu0”,mode=“nice”} 19.92node_cpu{cpu=“cpu0”,mode=“softirq”} 17.05node_cpu{cpu=“cpu0”,mode=“steal”} 28.1Prometheus查看:类似go_gc_duration_seconds和node_cpu就是metric的名称,如果使用了Prometheus,则可以在http://${IP}:9090/页面的指标中搜索到以上的指标:常用指标类型有:node_cpu:系统CPU使用量node_disk:磁盘IOnode_filesystem:文件系统用量node_load1:系统负载node_memeory*:内存使用量node_network*:网络带宽node_time:当前系统时间go_:node exporter中go相关指标process_:node exporter自身进程相关运行指标Grafana查看:Prometheus虽然自带了web页面,但一般会和更专业的Grafana配套做指标的可视化,Grafana有很多模板,用于更友好地展示出指标的情况,如Node Exporter for Prometheus在grafana中配置好变量、导入模板就会有上图的效果。深入解读node-exporter是Prometheus官方推荐的exporter,类似的还有HAProxy exporterCollectd exporterSNMP exporterMySQL server exporter….官方推荐的都会在https://github.com/prometheus下,在exporter推荐页,也会有很多第三方的exporter,由个人或者组织开发上传,如果有自定义的采集需求,可以自己编写exporter,具体的案例可以参考后续的[自定义Exporter]文章版本问题因为node_exporter是比较老的组件,有一些最佳实践并没有merge进去,比如符合Prometheus命名规范(https://prometheus.io/docs/pr…,目前(2019.1)最新版本为0.17一些指标名字的变化(详细比对)* node_cpu -> node_cpu_seconds_total* node_memory_MemTotal -> node_memory_MemTotal_bytes* node_memory_MemFree -> node_memory_MemFree_bytes* node_filesystem_avail -> node_filesystem_avail_bytes* node_filesystem_size -> node_filesystem_size_bytes* node_disk_io_time_ms -> node_disk_io_time_seconds_total* node_disk_reads_completed -> node_disk_reads_completed_total* node_disk_sectors_written -> node_disk_written_bytes_total* node_time -> node_time_seconds* node_boot_time -> node_boot_time_seconds* node_intr -> node_intr_total解决版本问题的方法有两种:一是在机器上启动两个版本的node-exporter,都让prometheus去采集。二是使用指标转换器,他会将旧指标名称转换为新指标对于grafana的展示,可以找同时支持两套指标的dashboard模板Collectornode-exporter的主函数:// Package collector includes all individual collectors to gather and export system metrics.package collectorimport ( “fmt” “sync” “time” “github.com/prometheus/client_golang/prometheus” “github.com/prometheus/common/log” “gopkg.in/alecthomas/kingpin.v2”)// Namespace defines the common namespace to be used by all metrics.const namespace = “node"可以看到exporter的实现需要引入github.com/prometheus/client_golang/prometheus库,client_golang是prometheus的官方go库,既可以用于集成现有应用,也可以作为连接Prometheus HTTP API的基础库。比如定义了基础的数据类型以及对应的方法:Counter:收集事件次数等单调递增的数据Gauge:收集当前的状态,比如数据库连接数Histogram:收集随机正态分布数据,比如响应延迟Summary:收集随机正态分布数据,和 Histogram 是类似的switch metricType { case dto.MetricType_COUNTER: valType = prometheus.CounterValue val = metric.Counter.GetValue() case dto.MetricType_GAUGE: valType = prometheus.GaugeValue val = metric.Gauge.GetValue() case dto.MetricType_UNTYPED: valType = prometheus.UntypedValue val = metric.Untyped.GetValue()client_golang库的详细解析可以参考:theory-source-code本文为容器监控实践系列文章,完整内容见:container-monitor-book ...

January 20, 2019 · 2 min · jiezi

利用神器BTrace 追踪线上 Spring Boot应用运行时信息

概述生产环境中的服务可能会出现各种问题,但总不能让服务下线来专门排查错误,这时候最好有一些手段来获取程序运行时信息,比如 接口方法参数/返回值、外部调用情况 以及 函数执行时间等信息以便定位问题。传统的日志记录方式的确可以,但有时非常麻烦,甚至可能需要重启服务,因此代价太大,这时可以借助一个牛批的工具:BTrace !BTrace 可用于动态跟踪正在运行的 Java程序,其原理是通过动态地检测目标应用程序的类并注入跟踪代码 ( “字节码跟踪” ),因此可以直接用于监控和追踪线上问题而无需修改业务代码并重启应用程序。BTrace 的使用方式是用户自己编写符合 BTrace使用语法的脚本,并结合btrace命令,来获取应用的一切调用信息,就像下面这样:<btrace>/bin/btrace <PID> <trace_script>其中 <PID>为被监控 Java应用的 进程ID<trace_script> 为 根据需要监控的信息 而自行编写的 Java脚本本文就来实操一波 BTrace工具的使用,实验环境如下:OS:CentOS 7.4 64bitBTrace版本:1.3.11.3被追踪的 Java应用:Spring Boot 2.1.1 应用,这里使用我的文章《Spring Boot应用缓存实践之:Ehcache加持》一文中的 Spring Boot工程BTrace 安装部署下载 二进制文件并解压这里我解压到目录:/home/btrace配置系统环境变量vim /etc/profileBTRACE_HOME=/home/btraceexport BTRACE_HOMEexport PATH=$PATH:$BTRACE_HOME/bin验证 BTrace安装情况btrace –version编译 BTrace源码克隆源码git clone git@github.com:btraceio/btrace.git编译源码./gradlew build构建完成的生成物路径位于:build/libs目录下我们取出构建生成的 jar包供下文使用。利用btrace追踪 Spring Boot应用例析首先我们得构造一个 Spring Boot的模拟业务 用于下文被追踪和分析,这里我就使用文章 《Spring Boot应用缓存实践之:Ehcache加持》中的实验工程。我们在此工程里再添加一个 scripts包,用于放置 btrace 脚本文件:由于 btrace脚本中需要用到 btrace相关的组件和函数库,因此我们还需要在工程的 pom.xml中引入 btrace的依赖,所使用的 jar包就是上文编译生成的 btrace-1.3.11.3.jar <dependency> <groupId>com.sun.btrace</groupId> <artifactId>btrace</artifactId> <version>1.3.11.3</version> </dependency>Talk is cheap ,Show you the code !接下来就用四五个实验来说明一切吧:0x01 监控方法耗时情况btrace 脚本:@BTracepublic class BtraceTest2 { @OnMethod(clazz = “cn.codesheep.springbt_brace.controller.UserController”, method = “getUsersByName”, location = @Location(Kind.RETURN)) public static void getFuncRunTime( @ProbeMethodName String pmn, @Duration long duration) { println( “接口 " + pmn + strcat(“的执行时间(ms)为: “, str(duration / 1000000)) ); //单位是纳秒,要转为毫秒 }}接下来开始运行 btrace脚本来拦截方法的参数,首先我们用 jps命令取到需要被监控的 Spring Boot应用的进程 Id为 27887,然后执行:/home/btrace/bin/btrace 27887 BtraceTest2.java这里我总共对 /getusersbyname接口发出了 12次 POST请求,情况如下:接下来我们再看看利用btrace脚本监控到的 /getuserbyname接口的执行时间:这样一对比很明显,从数据库取数据还是需要 花费十几毫秒的,但从缓存读取数据 几乎没有耗时,这就是为什么要让缓存加持于应用的原因!!!0x02 拦截方法的 参数/返回值btrace 脚本: @OnMethod( clazz = “cn.codesheep.springbt_brace.controller.UserController”, method = “getUsersByName”, location = @Location(Kind.ENTRY) ) public static void getFuncEntry(@ProbeClassName String pcn, @ProbeMethodName String pmn, User user ) { println(“类名: " + pcn); println(“方法名: " + pmn); // 先打印入参实体整体信息 BTraceUtils.print(“入参实体为: “); BTraceUtils.printFields(user); // 再打印入参实体每个属性的信息 Field oneFiled = BTraceUtils.field(“cn.codesheep.springbt_brace.entity.User”, “userName”); println(“userName字段为: " + BTraceUtils.get(oneFiled, user)); oneFiled = BTraceUtils.field(“cn.codesheep.springbt_brace.entity.User”, “userAge”); println(“userAge字段为: " + BTraceUtils.get(oneFiled, user)); }接下来开始运行 btrace脚本来拦截方法的参数,首先我们用 jps命令取到需要被监控的java应用的进程 Id为 27887,然后执行:/home/btrace/bin/btrace -cp springbt_brace/target/classes 27887 BtraceTest4.java此时正常带参数 {“userName”:“codesheep.cn”} 去请求业务接口:POST /getusersbyname,会得到如下输出:很明显请求参数已经被 btrace给拦截到了同理,如果想拦截方法的返回值,可以使用如下 btrace脚本: @OnMethod( clazz = “cn.codesheep.springbt_brace.controller.UserController”, method = “getUsersByName”, location = @Location(Kind.RETURN) //函数返回的时候执行,如果不填,则在函数开始的时候执行 ) public static void getFuncReturn( @Return List<User> users ) { println(“返回值为: “); println(str(users)); }运行 btrace命令后,继续请求想要被监控的业务接口,则可以得到类似如下的输出:0x03 监控代码是否到达了某类的某一行btrace 脚本如下:@BTracepublic class BtraceTest3 { @OnMethod( clazz=“cn.codesheep.springbt_brace.service.UserService”, method=“getUsersByName”, location=@Location(value= Kind.LINE, line=28) // 比如拦截第28行, 28行是从数据库取数据操作 ) public static void lineTest( @ProbeClassName String pcn, @ProbeMethodName String pmn, int line ) { BTraceUtils.println(“ClassName: " + pcn); BTraceUtils.println(“MethodName: " + pmn); BTraceUtils.println(“执行到的line行数: " + line); }}执行 btrace追踪命令/home/btrace/bin/btrace 28927 BtraceTest3.java接着用 POSTMAN工具连续发出了对 /getuserbyname接口的 十几次POST请求,由于只有第一次请求没有缓存时才会从数据库读,因此也才会执行到 UserService类的第 28行 !0x04 监控指定函数中所有外部调用的耗时情况btrace脚本如下:@BTracepublic class BtraceTest5 { @OnMethod (clazz = “cn.codesheep.springbt_brace.service.UserService”,method = “getUsersByName”, location=@Location(value= Kind.CALL, clazz=”/./”, method=”/./”, where = Where.AFTER) ) public static void printMethodRunTime(@Self Object self,@TargetInstance Object instance,@TargetMethodOrField String method, @Duration long duration) { if( duration > 5000000 ){ //如果外部调用耗时大于 5ms 则打印出来 println( “self: " + self ); println( “instance: " + instance ); println( method + “,cost:” + duration/1000000 + " ms” ); } }}执行监控命令:/home/btrace/bin/btrace 28927 BtraceTest5.java然后再对接口 /getuserbyname发出POST请求,观察监控结果如下:我们发现最耗时的外部调用来源于 MyBatis调用。0x05 其他追踪与监控除了上面四种典型的追踪场景之外,其他的 btrace追踪与监控场景还比如 查看谁调用了System.gc(),调用栈如何,则可以使用如下 btrace脚本进行监控@BTracepublic class BtraceTest { @OnMethod(clazz = “java.lang.System”, method = “gc”) public static void onSystemGC() { println(“entered System.gc()”); jstack(); }}很明显,因为btrace 内置了一系列诸如 jstack等十分有用的监控命令。当然最后需要说明的是 btrace内置了很多语法和命令,可以应对很多线上 Java应用监控场景,大家可以去研究一下官方文档后记由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!My Personal Blog:CodeSheep 程序羊程序羊的 2018年终总(gen)结(feng) ...

January 17, 2019 · 2 min · jiezi

高可用、弹性动态的金融级移动架构在蚂蚁金服的演进之路

摘要: 支付宝作为国民级应用,当前全球用户已经超过 10 亿,提供了超过 200 项以上的服务,而崩溃率始终维持在万分之五以下,而且每天支付宝都上线新的功能和改进。做到今天这样的成绩,并不容易,是经过长时间的实践经验积累下来的。导语本文基于重岳在 2018 年 Arch Summit 北京站的分享内容进行总结,希望通过本篇文章介绍近些年来支付宝在移动端架构的上演进和思考,期冀能给读者们带来些许帮助。支付宝作为国民级应用,当前全球用户已经超过 10 亿,提供了超过 200 项以上的服务,而崩溃率始终维持在万分之五以下,而且每天支付宝都上线新的功能和改进。做到今天这样的成绩,并不容易,是经过长时间的实践经验积累下来的。支付宝的架构演进主要经历了三个阶段,如果用比喻的话,可以分为独木舟、战列舰和航空母舰三个阶段。独木舟时代支付宝刚推出移动端时,它的结构非常之简单,除了一些工具组件被划分为模块,业务代码都是糅合在一起。刚开始并没有太大问题,但是当我们的研发人员迅速增长时,问题开始变得棘手起来,仅仅举几个例子便可见一斑。研发同学晚上提交的可以运行的代码,到第二天早上来更新一下就完全不能用,原因是其他不相干团队提交代码覆盖或者污染了自己的代码。临近发布点的时候,通常是最忙的,但不是忙着赶功能,而是忙着解决合并代码产生的各种问题,不仅浪费时间,还耽误测试同学的宝贵时间。即使最后勉强发布了,稳定性和性能也是非常糟糕的,因为各个模块只管自己的,没有统一的规范,也缺乏统一的监控。最令 Android 开发头痛的是 65535 的问题,彼时 Google 还没有推出 multi-dex 的方案。这些严重的问题让我们的产品研发迭代变得无法持续下去,因此我们决定来一次彻底的重构,于是步入了战列舰时代。战列舰时代当设计新一代的客户端架构时,我们从三个方向进行思考:团队协作、研发效率、性能与稳定。团队协作方面,我们希望整个架构分层合理,基础层面,将通用能力下沉,为更多的上层业务服务,避免重复创造轮子;业务层面,各个业务团队能够独立开发管理,不会对不相关的业务造成影响。基于这个初衷,我们形成了下图这样的架构:整个客户端架构总共分成四层:业务层、服务层、组件层、框架层。业务层:只需专注于业务逻辑与界面的实现,当需要调用如支付这样的通用能力时,研发同学直接使用下层提供的服务能力,不需自己开发,如此能够保证核心能力有收口,方便监控。服务层:常用模块,如登录、支付、营销等,它们不仅自己是业务,也向其他业务提供自己的服务,我们将此类模块归类到服务层。组件层:这一层提供的是客户端通用能力,如安全、网络、多媒体、存储这些,它们提供稳定的接口给上层使用者,同时不断优化自身内部的性能和稳定性,作为客户端的基石,它们至关重要。框架层:最为关键的部分,包括容器、微应用、服务框架以及 Pipeline,客户端的微应用化、启动管理都依赖框架层的运作。我们将服务层、组件层和框架层合称为 mPaaS,即移动端上的 PaaS 服务。这些 PaaS 服务可以复用,我们不仅在支付宝里使用它们,也在其他集团应用,如蚂蚁财富、网商银行等中使用。业务分治要实现业务分治,最好的方式就在代码上能够进行隔离,大家不必在同一个 Codebase 中开发,避免代码合并冲突的现象,这个通常在 Android 上通常可以 aar 的方式来实现,但是可惜的是我们重构的时候 aar 还没出来,而且即使有 aar,也存在打包时间随代码体积增大线性增长的问题。我们的解决方案借鉴 OSGi 的概念,将整个客户端以 Bundle 为单位划分,每个 Bundle 可以包含自己的代码、页面和资源。读者可能会想,这究竟和 aar 有什么分别呢?其实区别很大!首先,Bundle 里的代码部分是已编译的 dex,当编译 apk 时,我们只需要合并 dex 即可,不需要像 aar 那样将 class 编译成 dex 再进行合并,这样大大节省了打包时间;其次,Bundle 是可以独立运行于自己的 ClassLoader 中的,并且我们可以通过壳代理的方式加载 Activity 等基础组件,使得动态下发业务成为可能;最后,Bundle 里还包含微应用、服务和 Pipeline 相关的配置信息,框架会根据这些信息启动相应的组件。mPaaS 的服务,即 Service 类似于 Spring 框架中的 Service,它对外提供接口服务,而使用者不需要知道如何初始化服务的实例以及生命周期管理,这些完全由框架来托管。使用者只需要知道目标服务接口类的方法参数即可,调用时通过框架提供的 API 来获取实例。对于服务的发布者来说,他在自己的 bundle 中声明接口类以及实现接口类派生的实例类,并注册相关信息到 bundle 的 manifest 文件中。这种做法的本质思想是 Inversion of Control,减少类之间的复杂依赖,避免繁琐的初始化工作。以依赖接口的方式进行开发,能够解除服务使用者对服务提供者的依赖,在服务提供者尚未完全开发完成时,使用者可以完全以 mock 的方式来模拟服务,而不需要修改自己的业务代码,当然,前提是双方协商好服务接口的协议。支付宝中的页面非常多,直接启动 Activity 或者 ViewController 对我们来说远远不够,我们选择在它们上面增加 MicroApp,即微应用的概念。微应用具备唯一的应用 ID,在框架中标识自己的存在。微应用具有统一的入口,根据使用方传入的字典参数来管理 Activity 或 ViewController。这样能够带来很多好处:只要应用 ID 和参数协议不变,使用方不需担心目标应用内部重构带来的影响,直接使用 Activity 或者 ViewController 类名造成的引用泛滥的问题不复存在。微应用的 ID 和字典参数特性,很容易生成 URL,从而实现外部应用使用 URL 跳转应用内页面。从数据的角度,我们可以按业务维度来统计用户行为数据。微应用的概念不仅适用于原生页面,同样也适用于 H5 和小程序。注册为 H5 或者小程序类型的应用 ID,框架会自动将启动过程 delegate 给 H5 或者小程序容器,而使用者完全不必关心应用 ID 对应的应用类型。综上所述,微应用化和服务接口所赋予的特性极大提高团队间协作效率,各研发小组之间的依赖更加简单,可以各行其道,更关注于自身服务的打造建设。性能优化我们一方面在架构上作出重大改变来提高研发效率,另一方面也在不断的进行性能优化,改善用户体验。我们主要从三个层面来着手:框架层面制定统一开发规范,业务方使用统一的线程池、存储、网络等组件,并按需进行加载,避免不必要的启动和耗时操作。引入 Pipeline 机制,业务模块如需在应用启动时进行初始化工作,必须使用 Pipeline。框架依据业务优先级确定业务初始化实际。利用 AOP 切面,对常用路径进行耗时统计,追踪性能瓶颈。基础指标对于常用指标,如闪退、ANR、内存、存储、电量、流量等,进行长期追踪。我们能够明确获悉每个版本之间这些指标上的差异,并进行采样分析,定位并解决问题。向下突破我们不仅仅在应用层面进行优化,同时也向下探索性能提升的可能性。在这方面,我们也收获颇丰,比如在 Android 上某些系统版本,通过在启动阶段禁用 GC 的方式获得 20%~30% 的启动时间缩减;在 iOS 上,利用系统本身的 Background Fetch 机制提高进程活跃时间,实现应用秒起。航母时代随着移动支付的不断普及,面对海量的用户和业务需求,高可用、弹性动态成为支付宝客户端更为艰巨的挑战。支付宝作为集支付、金融、生活为一体的服务平台,需要能够快速稳定的发布服务和引入第三方服务,同时对于用户的反馈和诉求必须能够积极迅速的响应。动态研发模式我们在研发模式上作出改变以业务快速迭代的要求,业务逐步由原生页面向 Web 混合页面迁移。原有的研发模式能够很好的满足团队协作的要求,但是随着业务规模的不断增大,代码量相应膨胀导致安装包太大,在iOS上一度超过代码段上限,无法通过 AppStore 审核,另外基于集中时间点的迭代发布,通常是一个月发布一个版本,远不能满足业务的更新速度要求。相较于原生应用开发,Web应用的优势非常明显:只需要一套代码,Web 应用可以在 iOS 和 Android 客户端中运行,能够相对减少人员的投入。每个用户日常使用的功能仅仅是支付宝庞大平台中的一小部分,H5 应用可以做到动态下发,因此可以消除冗余的存储,降低包大小。近些年来 React Native,Weex 等动态渲染引擎在社区非常活跃,但经过小范围的应用以及考虑到 Web 技术的不断发展以及其在业界公认的地位,我们最终还是选择 Web 技术作为动态研发模式的基础。Web 应用迭代摆脱了客户端集中时间点发布的束缚,各业务线迭代计划变得自主可控。打磨 Web 体验尽管 Web 应用优势明显,但在移动端上的短板也是显而易见的,它提供的用户体验、性能以及能力上的限制与原生应用有相当大的差距。为了弥补这些差距,我们做了大量的改进,主要在以下几个方面:前后端分离,我们将页面资源离线化,这样节省了资源请求消耗的时间,使得页面打开速度提升明显,解决了在网络环境较差下容易出现白屏的问题。同时,数据请求使用 native 网络通道,可优化的空间更大,安全性更高。差量更新,客户端更新某业务应用版本时,不需下载完整的新版本资源包,而是下载由发布平台根据客户端本地安装版本计算生成的体积更小的差量包,这样不仅能够节省带宽和流量,也提升了业务更新的速度。推拉结合,解决业务最新版本覆盖率的问题,每次发布新版本时,业务可主动触发消息到客户端,客户端收到通知后会更新该业务应用版本。同时,客户端会定时去检查服务端是否有版本发布,这样能够保证版本发布后大多数用户在短时间内获得最新的应用。容错补偿,客户端可能由于网络、安全或者存储权限等原因,不能使用或者及时获得离线包,这种情况我们也考虑进来了。我们在发布离线资源时,发布平台会自动生成对应的在线 URL 并配置到应用信息中,当客户端加载 Web 应用时发现离线包不可用,会立刻启用该url加载内容,能够最大程度保证业务可用性。Android 独立浏览器内核,Android 碎片化的问题自其诞生之初业已存在,而且目前看上去没有得以解决的迹象。不同系统、不同厂商中的浏览器内核同样存在差异,这导致层出不穷的兼容性问题令研发同学头疼不已,这也违背 Web 一统天下的愿景。为了彻底解决并掌控这些问题,我们引入了独立的 UC 浏览器内核并集成在应用中,这样所有的问题都集中到UC团队解决,变得非常可控,根据数据统计,使用 UC 浏览器内核后浏览器相关的闪退和 ANR 有明显的下降。同时,安全上出现的漏洞,我们可以在第一时间修复并发布,远比厂商升级更有效率。Web 应用全方位监控,资源加载异常、JS执行异常、白屏、加载耗时等性能数据会被收集上报至后台,可以及时发现异常。小程序我们不仅自身提供各种各样的服务,也需要引入第三方服务来服务更多的人群,以往我们只能引入简单的第三方 H5 页面,它们只能使用支付宝提供的少量功能,而且开发人员能力的差异导致用户体验不是很理想。小程序将支付宝的能力全面开放出来,从开发到测试皆有完整的 IDE 等工具链支持,同时 DSL 简单易用,对于第三方来说,能够快速开发上线一款体验和功能比以往更强大的小程序。本文作者:josephjin阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 15, 2019 · 1 min · jiezi

容器监控实践—Custom Metrics

概述上文metric-server提到,kubernetes的监控指标分为两种:Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboard、HPA 控制器等使用。Custom Metrics(自定义指标):由Prometheus Adapter提供API custom.metrics.k8s.io,由此可支持任意Prometheus采集到的指标。核心指标只包含node和pod的cpu、内存等,一般来说,核心指标作HPA已经足够,但如果想根据自定义指标:如请求qps/5xx错误数来实现HPA,就需要使用自定义指标了,目前Kubernetes中自定义指标一般由Prometheus来提供,再利用k8s-prometheus-adpater聚合到apiserver,实现和核心指标(metric-server)同样的效果。以下是官方metrics的项目介绍:Resource Metrics API(核心api)HeapsterMetrics ServerCustom Metrics API:Prometheus AdapterMicrosoft Azure AdapterGoogle StackdriverDatadog Cluster Agent部署Prometheus可以采集其它各种指标,但是prometheus采集到的metrics并不能直接给k8s用,因为两者数据格式不兼容,因此还需要另外一个组件(kube-state-metrics),将prometheus的metrics数据格式转换成k8s API接口能识别的格式,转换以后,因为是自定义API,所以还需要用Kubernetes aggregator在主API服务器中注册,以便直接通过/apis/来访问。文件清单:node-exporter:prometheus的export,收集Node级别的监控数据prometheus:监控服务端,从node-exporter拉数据并存储为时序数据。kube-state-metrics:将prometheus中可以用PromQL查询到的指标数据转换成k8s对应的数k8s-prometheus-adpater:聚合进apiserver,即一种custom-metrics-apiserver实现开启Kubernetes aggregator功能(参考上文metric-server)k8s-prometheus-adapter的部署文件:其中创建了一个叫做cm-adapter-serving-certs的secret,包含两个值: serving.crt和serving.key,这是由apiserver信任的证书。kube-prometheus项目中的gencerts.sh和deploy.sh脚本可以创建这个secret包括secret的所有资源,都在custom-metrics命名空间下,因此需要kubectl create namespace custom-metrics以上组件均部署成功后,可以通过url获取指标基于自定义指标的HPA使用prometheus后,pod有一些自定义指标,如http_request请求数创建一个HPA,当请求数超过每秒10次时进行自动扩容apiVersion: autoscaling/v2beta1kind: HorizontalPodAutoscalermetadata: name: podinfospec: scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: podinfo minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metricName: http_requests targetAverageValue: 10查看hpa$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEpodinfo Deployment/podinfo 899m / 10 2 10 2 1m对pod进行施压#install hey$ go get -u github.com/rakyll/hey#do 10K requests rate limited at 25 QPS$ hey -n 10000 -q 5 -c 5 http://PODINFO_SVC_IP:9898/healthzHPA发挥作用:Events: Type Reason Age From Message —- —— —- —- ——- Normal SuccessfulRescale 5m horizontal-pod-autoscaler New size: 3; reason: pods metric http_requests above target Normal SuccessfulRescale 21s horizontal-pod-autoscaler New size: 2; reason: All metrics below target关于k8s-prometheus-adapter其实k8s-prometheus-adapter既包含自定义指标,又包含核心指标,即如果按照了prometheus,且指标都采集完整,k8s-prometheus-adapter可以替代metrics server。在1.6以上的集群中,k8s-prometheus-adapter可以适配autoscaling/v2的HPA因为一般是部署在集群内,所以k8s-prometheus-adapter默认情况下,使用in-cluster的认证方式,以下是主要参数:lister-kubeconfig: 默认使用in-cluster方式metrics-relist-interval: 更新metric缓存值的间隔,最好大于等于Prometheus 的scrape interval,不然数据会为空prometheus-url: 对应连接的prometheus地址config: 一个yaml文件,配置如何从prometheus获取数据,并与k8s的资源做对应,以及如何在api接口中展示。config文件的内容示例(参考文档)rules: - seriesQuery: ‘{name="^container_.",container_name!=“POD”,namespace!="",pod_name!=""}’ seriesFilters: [] resources: overrides: namespace: resource: namespace pod_name: resource: pod name: matches: ^container_(.)_seconds_total$ as: "" metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!=“POD”}[1m])) by (<<.GroupBy>>) - seriesQuery: ‘{name="^container_.",container_name!=“POD”,namespace!="",pod_name!=""}’ seriesFilters: - isNot: ^container_.seconds_total$ resources: overrides: namespace: resource: namespace pod_name: resource: pod name: matches: ^container(.)total$ as: "" metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!=“POD”}[1m])) by (<<.GroupBy>>) - seriesQuery: ‘{name=~"^container.",container_name!=“POD”,namespace!="",pod_name!=""}’ seriesFilters: - isNot: ^container_.total$ resources: overrides: namespace: resource: namespace pod_name: resource: pod name: matches: ^container(.)$ as: "" metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container_name!=“POD”}) by (<<.GroupBy>>)问题为什么我看不到自定义的metric检查下config配置文件,是否有选择你的metric检查下采集的信息是否正确,如foo{namespace=“somens”,deployment=“bar”},foo这个名称的数据来自于somens的命名空间+bar这个部署启动的时候加上–v=6,可以打出adapter实际的query信息参考k8s-prometheus-adapter,可以实现自己的adapter,比如获取已有监控系统的指标,汇聚到api-server中,k8s-prometheus-adapter的实现逻辑会在后续文章中专门来讲。本文为容器监控实践系列文章,完整内容见:container-monitor-book ...

January 13, 2019 · 1 min · jiezi

容器监控实践—Metrics Server

概述从 v1.8 开始,资源使用情况的监控可以通过 Metrics API的形式获取,具体的组件为Metrics Server,用来替换之前的heapster,heapster从1.11开始逐渐被废弃。Metrics-Server是集群核心监控数据的聚合器,从 Kubernetes1.8 开始,它作为一个 Deployment对象默认部署在由kube-up.sh脚本创建的集群中,如果是其他部署方式需要单独安装,或者咨询对应的云厂商。Metrics API介绍Metrics-Server之前,必须要提一下Metrics API的概念Metrics API相比于之前的监控采集方式(hepaster)是一种新的思路,官方希望核心指标的监控应该是稳定的,版本可控的,且可以直接被用户访问(例如通过使用 kubectl top 命令),或由集群中的控制器使用(如HPA),和其他的Kubernetes APIs一样。官方废弃heapster项目,就是为了将核心资源监控作为一等公民对待,即像pod、service那样直接通过api-server或者client直接访问,不再是安装一个hepater来汇聚且由heapster单独管理。假设每个pod和node我们收集10个指标,从k8s的1.6开始,支持5000节点,每个节点30个pod,假设采集粒度为1分钟一次,则:10 x 5000 x 30 / 60 = 25000 平均每分钟2万多个采集指标因为k8s的api-server将所有的数据持久化到了etcd中,显然k8s本身不能处理这种频率的采集,而且这种监控数据变化快且都是临时数据,因此需要有一个组件单独处理他们,k8s版本只存放部分在内存中,于是metric-server的概念诞生了。其实hepaster已经有暴露了api,但是用户和Kubernetes的其他组件必须通过master proxy的方式才能访问到,且heapster的接口不像api-server一样,有完整的鉴权以及client集成。这个api现在还在alpha阶段(18年8月),希望能到GA阶段。类api-server风格的写法:generic apiserver有了Metrics Server组件,也采集到了该有的数据,也暴露了api,但因为api要统一,如何将请求到api-server的/apis/metrics请求转发给Metrics Server呢,解决方案就是:kube-aggregator,在k8s的1.7中已经完成,之前Metrics Server一直没有面世,就是耽误在了kube-aggregator这一步。kube-aggregator(聚合api)主要提供:Provide an API for registering API servers.Summarize discovery information from all the servers.Proxy client requests to individual servers.详细设计文档:参考链接metric api的使用:Metrics API 只可以查询当前的度量数据,并不保存历史数据Metrics API URI 为 /apis/metrics.k8s.io/,在 k8s.io/metrics 维护必须部署 metrics-server 才能使用该 API,metrics-server 通过调用 Kubelet Summary API 获取数据如:http://127.0.0.1:8001/apis/metrics.k8s.io/v1beta1/nodeshttp://127.0.0.1:8001/apis/metrics.k8s.io/v1beta1/nodes/<node-name>http://127.0.0.1:8001/apis/metrics.k8s.io/v1beta1/namespace/<namespace-name>/pods/<pod-name>Metrics-ServerMetrics server定时从Kubelet的Summary API(类似/ap1/v1/nodes/nodename/stats/summary)采集指标信息,这些聚合过的数据将存储在内存中,且以metric-api的形式暴露出去。Metrics server复用了api-server的库来实现自己的功能,比如鉴权、版本等,为了实现将数据存放在内存中吗,去掉了默认的etcd存储,引入了内存存储(即实现Storage interface)。因为存放在内存中,因此监控数据是没有持久化的,可以通过第三方存储来拓展,这个和heapster是一致的。Metrics server出现后,新的Kubernetes 监控架构将变成上图的样子核心流程(黑色部分):这是 Kubernetes正常工作所需要的核心度量,从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboard、HPA 控制器等使用。监控流程(蓝色部分):基于核心度量构建的监控流程,比如 Prometheus 可以从 metrics-server 获取核心度量,从其他数据源(如 Node Exporter 等)获取非核心度量,再基于它们构建监控告警系统。官方地址:https://github.com/kubernetes…使用如上文提到的,metric-server是扩展的apiserver,依赖于kube-aggregator,因此需要在apiserver中开启相关参数。–requestheader-client-ca-file=/etc/kubernetes/certs/proxy-ca.crt–proxy-client-cert-file=/etc/kubernetes/certs/proxy.crt–proxy-client-key-file=/etc/kubernetes/certs/proxy.key–requestheader-allowed-names=aggregator–requestheader-extra-headers-prefix=X-Remote-Extra—requestheader-group-headers=X-Remote-Group–requestheader-username-headers=X-Remote-User安装文件下载地址:1.8+,注意更换镜像地址为国内镜像kubectl create -f metric-server/安装成功后,访问地址api地址为:Metrics Server的资源占用量会随着集群中的Pod数量的不断增长而不断上升,因此需要addon-resizer垂直扩缩这个容器。addon-resizer依据集群中节点的数量线性地扩展Metrics Server,以保证其能够有能力提供完整的metrics API服务。具体参考:链接其他基于Metrics Server的HPA:参考链接kubernetes的新监控体系中,metrics-server属于Core metrics(核心指标),提供API metrics.k8s.io,仅提供Node和Pod的CPU和内存使用情况。而其他Custom Metrics(自定义指标)由Prometheus等组件来完成,后续文章将对自定义指标进行解析。本文为容器监控实践系列文章,完整内容见:container-monitor-book ...

January 13, 2019 · 1 min · jiezi

容器监控实践—kube-state-metrics

概述已经有了cadvisor、heapster、metric-server,几乎容器运行的所有指标都能拿到,但是下面这种情况却无能为力:我调度了多少个replicas?现在可用的有几个?多少个Pod是running/stopped/terminated状态?Pod重启了多少次?我有多少job在运行中而这些则是kube-state-metrics提供的内容,它基于client-go开发,轮询Kubernetes API,并将Kubernetes的结构化信息转换为metrics。功能kube-state-metrics提供的指标,按照阶段分为三种类别:1.实验性质的:k8s api中alpha阶段的或者spec的字段。2.稳定版本的:k8s中不向后兼容的主要版本的更新3.被废弃的:已经不在维护的。指标类别包括:CronJob MetricsDaemonSet MetricsDeployment MetricsJob MetricsLimitRange MetricsNode MetricsPersistentVolume MetricsPersistentVolumeClaim MetricsPod MetricsPod Disruption Budget MetricsReplicaSet MetricsReplicationController MetricsResourceQuota MetricsService MetricsStatefulSet MetricsNamespace MetricsHorizontal Pod Autoscaler MetricsEndpoint MetricsSecret MetricsConfigMap Metrics以pod为例:kube_pod_infokube_pod_ownerkube_pod_status_phasekube_pod_status_readykube_pod_status_scheduledkube_pod_container_status_waitingkube_pod_container_status_terminated_reason…使用部署清单: kube-state-metrics/ ├── kube-state-metrics-cluster-role-binding.yaml ├── kube-state-metrics-cluster-role.yaml ├── kube-state-metrics-deployment.yaml ├── kube-state-metrics-role-binding.yaml ├── kube-state-metrics-role.yaml ├── kube-state-metrics-service-account.yaml ├── kube-state-metrics-service.yaml主要镜像有:image: quay.io/coreos/kube-state-metrics:v1.5.0image: k8s.gcr.io/addon-resizer:1.8.3(参考metric-server文章,用于扩缩容)对于pod的资源限制,一般情况下:200MiB memory0.1 cores超过100节点的集群:2MiB memory per node0.001 cores per nodekube-state-metrics做过一次性能优化,具体内容参考下文部署成功后,prometheus的target会出现如下标志因为kube-state-metrics-service.yaml中有prometheus.io/scrape: ’true’标识,因此会将metric暴露给prometheus,而Prometheus会在kubernetes-service-endpoints这个job下自动发现kube-state-metrics,并开始拉取metrics,无需其他配置。使用kube-state-metrics后的常用场景有:存在执行失败的Job: kube_job_status_failed{job=“kubernetes-service-endpoints”,k8s_app=“kube-state-metrics”}==1集群节点状态错误: kube_node_status_condition{condition=“Ready”,status!=“true”}==1集群中存在启动失败的Pod:kube_pod_status_phase{phase=~“Failed|Unknown”}==1最近30分钟内有Pod容器重启: changes(kube_pod_container_status_restarts[30m])>0配合报警可以更好地监控集群的运行与metric-server的对比metric-server(或heapster)是从api-server中获取cpu、内存使用率这种监控指标,并把他们发送给存储后端,如influxdb或云厂商,他当前的核心作用是:为HPA等组件提供决策指标支持。kube-state-metrics关注于获取k8s各种资源的最新状态,如deployment或者daemonset,之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为他们的关注点本质上是不一样的。metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统。而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但他没有能力导出这些指标换个角度讲,kube-state-metrics本身是metric-server的一种数据来源,虽然现在没有这么做。另外,像Prometheus这种监控系统,并不会去用metric-server中的数据,他都是自己做指标收集、集成的(Prometheus包含了metric-server的能力),但Prometheus可以监控metric-server本身组件的监控状态并适时报警,这里的监控就可以通过kube-state-metrics来实现,如metric-serverpod的运行状态。深入解析kube-state-metrics本质上是不断轮询api-server,代码结构也很简单主要代码目录.├── collectors│ ├── builder.go│ ├── collectors.go│ ├── configmap.go│ ……│ ├── testutils.go│ ├── testutils_test.go│ └── utils.go├── constant│ └── resource_unit.go├── metrics│ ├── metrics.go│ └── metrics_test.go├── metrics_store│ ├── metrics_store.go│ └── metrics_store_test.go├── options│ ├── collector.go│ ├── options.go│ ├── options_test.go│ ├── types.go│ └── types_test.go├── version│ └── version.go└── whiteblacklist ├── whiteblacklist.go └── whiteblacklist_test.go所有类型:var ( DefaultNamespaces = NamespaceList{metav1.NamespaceAll} DefaultCollectors = CollectorSet{ “daemonsets”: struct{}{}, “deployments”: struct{}{}, “limitranges”: struct{}{}, “nodes”: struct{}{}, “pods”: struct{}{}, “poddisruptionbudgets”: struct{}{}, “replicasets”: struct{}{}, “replicationcontrollers”: struct{}{}, “resourcequotas”: struct{}{}, “services”: struct{}{}, “jobs”: struct{}{}, “cronjobs”: struct{}{}, “statefulsets”: struct{}{}, “persistentvolumes”: struct{}{}, “persistentvolumeclaims”: struct{}{}, “namespaces”: struct{}{}, “horizontalpodautoscalers”: struct{}{}, “endpoints”: struct{}{}, “secrets”: struct{}{}, “configmaps”: struct{}{}, })构建对应的收集器Family即一个类型的资源集合,如job下的kube_job_info、kube_job_created,都是一个FamilyGenerator实例metrics.FamilyGenerator{ Name: “kube_job_info”, Type: metrics.MetricTypeGauge, Help: “Information about job.”, GenerateFunc: wrapJobFunc(func(j *v1batch.Job) metrics.Family { return metrics.Family{&metrics.Metric{ Name: “kube_job_info”, Value: 1, }} }), },func (b *Builder) buildCronJobCollector() *Collector { // 过滤传入的白名单 filteredMetricFamilies := filterMetricFamilies(b.whiteBlackList, cronJobMetricFamilies) composedMetricGenFuncs := composeMetricGenFuncs(filteredMetricFamilies) // 将参数写到header中 familyHeaders := extractMetricFamilyHeaders(filteredMetricFamilies) // NewMetricsStore实现了client-go的cache.Store接口,实现本地缓存。 store := metricsstore.NewMetricsStore( familyHeaders, composedMetricGenFuncs, ) // 按namespace构建Reflector,监听变化 reflectorPerNamespace(b.ctx, b.kubeClient, &batchv1beta1.CronJob{}, store, b.namespaces, createCronJobListWatch) return NewCollector(store)}性能优化:kube-state-metrics在之前的版本中暴露出两个问题:/metrics接口响应慢(10-20s)内存消耗太大,导致超出limit被杀掉问题一的方案就是基于client-go的cache tool实现本地缓存,具体结构为:var cache = map[uuid][]byte{}问题二的的方案是:对于时间序列的字符串,是存在很多重复字符的(如namespace等前缀筛选),可以用指针或者结构化这些重复字符。优化点和问题1.因为kube-state-metrics是监听资源的add、delete、update事件,那么在kube-state-metrics部署之前已经运行的资源,岂不是拿不到数据?kube-state-metric利用client-go可以初始化所有已经存在的资源对象,确保没有任何遗漏2.kube-state-metrics当前不会输出metadata信息(如help和description)3.缓存实现是基于golang的map,解决并发读问题当期是用了一个简单的互斥锁,应该可以解决问题,后续会考虑golang的sync.Map安全map。4.kube-state-metrics通过比较resource version来保证event的顺序5.kube-state-metrics并不保证包含所有资源本文为容器监控实践系列文章,完整内容见:container-monitor-book ...

January 13, 2019 · 2 min · jiezi

监控Kubernetes,第一部分:挑战+数据来源

作者:Sean Porter我们的行业长期以来一直依赖基于微服务的架构来更快、更安全地交付软件。微服务的出现和无处不在自然为容器技术铺平了道路,使我们能够重新思考如何构建和部署我们的应用程序。Docker在2013年加入战场,对于专注于基础架构和云迁移现代化的公司而言,像Docker这样的工具对于大规模快速发布应用程序至关重要。但是,随着速度的提升带来了挑战,容器在编排方面引入了不小的复杂性。进入Kubernetes:一个开源容器编排系统,用于自动化容器化应用程序的部署、扩展和管理,Kubernetes控制平面命令和控制你的基础架构。Kubernetes最初由谷歌于2014年推出,现在由云原生计算基金会维护(顺便提一下,谷歌帮助组建了Kubernetes,以确保它保持自由免费和竞争力)。如果你使用Docker来容器化你的应用程序,那么你肯定会使用Kubernetes进行编排。(当然还有其他的编排器,比如Docker Swarm和Apache Mesos,但Kubernetes已成为容器编排领域的领导者。)在本系列的第一部分中,我将介绍监控Kubernetes的挑战和主要数据来源。稍后,我将深入探讨Kubernetes和Docker部署,并使用下面列出的数据源的实际示例。Kubernetes监控:挑战Kubernetes使团队更容易管理容器,在自动维护所需状态的同时调度和配置容器。核心价值观是它作为一个通用平台,Kubernetes可以在任何地方部署你的应用程序,无论是AWS、GCP、Azure还是裸机。同样,所有这些功能和自动化都带来了挑战,特别是在关注性能方面。无论部署的规模如何,你仍需要知道该部署中有多少可用资源,以及了解已部署应用程序和容器的运行状况。正如微服务使我们重新思考如何构建应用程序一样,Kubernetes要求我们改变传统的监控方法,容器编排的动态特性需要采用动态的监控方法。以下是我看到的挑战:在这个新的动态时代,你的应用程序在不断地移动。在Kubernetes之前,将应用程序分布在多个云(公共和私有云,以及不同的云提供商)中并非易事。现在分发应用程序很容易,我们遇到了一系列新问题。就像从单体到微服务架构的转变一样,采用Kubernetes意味着需要监控许多小块。你已经听说过像牛(cattle)一样处理你的基础设施而不是宠物(pet)的优点。Kubernetes是这种畜牧方法的缩影,可以轻松实现大量和短暂的基础设施。就这样,通过标签(label)和注释(annotation)等标识符跟踪您的Kubernetes pod及其容器变得至关重要。Kubernetes监控:数据来源基本上,监控工具从四个来源收集Kubernetes数据:运行着Kubelet的Kubernetes主机。Kubernetes主机的资源有限,因此监控它们尤其重要。有许多方法可以从这些主机中获取数据,但最常见的方法是使用Prometheus节点导出器(node exporter)从Kubernetes主机中获取数据,并在HTTP端点上公开系统资源遥测数据(例如CPU使用和内存)。Kubernetes进程,又叫做Kubelet指标,包括apiserver、kube-scheduler和kube-controller-manager的指标。 这些内容为你提供有关Kubernetes节点及其运行工作的详细信息。Kubelet的内置cAdvisor。这里有一个很好的总结,但基本上Kubelet附带了对cAdvisor的内置支持,它可以收集、聚合、处理和导出正在运行的容器的指标。cAdvisor(它还具有对Docker容器的原生支持)为你提供每容器使用、跟踪资源隔离参数和历史资源使用情况。因为Kubernetes是控制平面,它可以指定使用多少内存,并利用cAdvisor跟踪。kube-state-metrics,它为你提供集群级别的信息,可以全面了解Kubernetes集群上发生的情况,例如你配置的所有pod及其当前状态。kube-state-metrics覆盖所有Kubernetes服务并收集有关其当前状态的信息,例如运行的容器数量、处于特定状态的容器数量、是否有任何表明它们不健康或我们处于容量饱和状态等。从README,kube-state-metrics“监听Kubernetes API服务器”。接下来:容器状态和使用Prometheus收集数据如果你有跟踪这话题,你可能会注意到你可以使用Prometheus监控所有这四个数据源。你可能还注意到我们只讨论监控Kubernetes而不是监控它上面运行的应用程序(并且,这可能与你听到的有关Kubernetes监控的所有内容一致)。在我的下一篇文章中,我将以Prometheus展示Kubernetes和Docker监控,讨论它为什么能够很好地适应Kubernetes生态系统,并识别差距。

January 10, 2019 · 1 min · jiezi

容器监控实践—cAdvisor

概述为了解决docker stats的问题(存储、展示),谷歌开源的cadvisor诞生了,cadvisor不仅可以搜集一台机器上所有运行的容器信息,还提供基础查询界面和http接口,方便其他组件如Prometheus进行数据抓取,或者cadvisor + influxdb + grafna搭配使用。cAdvisor可以对节点机器上的资源及容器进行实时监控和性能数据采集,包括CPU使用情况、内存使用情况、网络吞吐量及文件系统使用情况Cadvisor使用Go语言开发,利用Linux的cgroups获取容器的资源使用信息,在K8S中集成在Kubelet里作为默认启动项,官方标配。安装1.使用二进制部署下载二进制:https://github.com/google/cadvisor/releases/latest本地运行:./cadvisor -port=8080 &>>/var/log/cadvisor.log2.使用docker部署docker run \ –volume=/:/rootfs:ro \ –volume=/var/run:/var/run:rw \ –volume=/sys:/sys:ro \ –volume=/var/lib/docker/:/var/lib/docker:ro \ –volume=/dev/disk/:/dev/disk:ro \ –publish=8080:8080 \ –detach=true \ –name=cadvisor \ google/cadvisor:latest注意:在Ret Hat,CentOS, Fedora 等发行版上需要传递如下参数,因为 SELinux 加强了安全策略:–privileged=true 启动后访问:http://127.0.0.1:8080查看页面,/metric查看指标* 常见指标:http://yjph83.iteye.com/blog/2394091* 指标分析:https://luoji.live/cadvisor/cadvisor-source-code-metrics-20160927.html`3.kubernetes中使用* Daemonset部署: https://github.com/google/cadvisor/tree/master/deploy/kubernetes* kubelet自带cadvisor监控所有节点,可以设置–cadvisor-port=8080指定端口(默认为4194)* kubernetes 在2015-03-10 这个提交(Run cAdvisor inside the Kubelet. Victor Marmol 2015/3/10 13:39)中cAdvisor开始集成在kubelet中,目前的1.6及以后均存在注意:从 v1.7 开始,Kubelet metrics API 不再包含 cadvisor metrics,而是提供了一个独立的 API 接口:* Kubelet metrics: http://127.0.0.1:8001/api/v1/proxy/nodes/<node-name>/metrics* Cadvisor metrics: http://127.0.0.1:8001/api/v1/proxy/nodes/<node-name>/metrics/cadvisorcadvisor 监听的端口将在 v1.12 中删除,建议所有外部工具使用 Kubelet Metrics API 替代。常用搭配1.cAdvisor+Heapster+influxdbHeapster:在k8s集群中获取metrics和事件数据,写入InfluxDB,heapster收集的数据比cadvisor多,却全,而且存储在influxdb的也少。Heapster将每个Node上的cAdvisor的数据进行汇总,然后导到InfluxDB。Heapster的前提是使用cAdvisor采集每个node上主机和容器资源的使用情况,再将所有node上的数据进行聚合。这样不仅可以看到Kubernetes集群的资源情况,还可以分别查看每个node/namespace及每个node/namespace下pod的资源情况。可以从cluster,node,pod的各个层面提供详细的资源使用情况。InfluxDB:时序数据库,提供数据的存储,存储在指定的目录下。Grafana:提供了WEB控制台,自定义查询指标,从InfluxDB查询数据并展示。cAdvisor+Prometheus+Grafana访问http://localhost:8080/metrics,可以拿到cAdvisor暴露给 Prometheus的数据其他内容参考后续的prometheus文章深入解析cAdvisor结构图cadvisor地址:https://github.com/google/cad…主函数逻辑:(cadvisor/cadvisor.go)通过new出来的memoryStorage以及sysfs实例,创建一个manager实例,manager的interface中定义了许多用于获取容器和machine信息的函数核心函数:生成manager实例的时候,还需要传递两个额外的参数,分别是maxHousekeepingInterval:存在内存的时间,默认60sallowDynamicHousekeeping:是否允许动态配置housekeeping,也就是下一次开始搜集容器信息的时间,默认true因为需要暴露服务,所以在handler文件中,将上面生成的containerManager注册进去(cadvisor/http/handler.go),之后就是启动manager,运行其Start方法,开始搜集信息,存储信息的循环操作。以memory采集为例:具体的信息还是通过runc/libcontainer获得,libcontainer是对cgroup的封装。在/sys/fs/cgroup/memory中包含大量的了memory相关的信息(参考docker原生监控文章)Prometheus的收集器(cadvisor/metrics/prometheus.go)更多源码参考文章:https://luoji.live/categories…总结优缺点:优点:谷歌开源产品,监控指标齐全,部署方便,而且有官方的docker镜像。缺点:是集成度不高,默认只在本地保存1分钟数据,但可以集成InfluxDB等存储备注:爱奇艺参照cadvisor开发的dadvisor,数据写入graphite,等同于cadvisor+influxdb,但dadvisor并没有开源container-monitor-book系列 : https://yasongxu.gitbook.io/container-monitor/ ...

January 8, 2019 · 1 min · jiezi

容器监控实践—Docker原生

前言传统虚机监控一般采用类似Zabbix的方案,但容器出现之后,再使用Zabbix agent来采集数据的话就显得有些吃力了,如果每个容器都像OS那样监控,则metric数量将会非常巨大,而且这些数据很可能几分钟之后就没有意义了(容器已经停止或漂移),且容器的指标汇总更应该是按照APP甚至POD维度。如果只是过渡方案,或者想将容器监控统一到公司现有的Zabbix中,可以参考zabbix-docker-monitoring,有很多模板如:zabbix-template-app-docker.xml参考文章:https://segmentfault.com/a/11…Docker原生监控常用方式:docker ps/top/logsdocker statsdocker Remote APIdocker 伪文件系统docker stats该命令默认以流式方式输出,如果想打印出最新的数据并立即退出,可以使用 no-stream=true 参数。可以指定一个已停止的容器,但是停止的容器不返回任何数据。例如:Remote APIDocker Remote API是一个取代远程命令行界面(rcli)的REST API如:curl http://127.0.0.1:4243/containers/json可以使用API来获取监控数据并集成到其他系统,注意不要给Docker daemon带来性能负担,如果你一台主机有很多容器,非常频繁的采集可能会大量占据CPU伪文件系统以下操作的环境为:Centos7系统 docker17.03版本docker stats的数据来自于/sys/fs/cgroup下的文件mem usage那一列的值,来自于/sys/fs/cgroup/memory/docker/[containerId]/memory.usage_in_bytes如果没限制内存,Limit = machine_mem,否则来自于/sys/fs/cgroup/memory/docker/[id]/memory.limit_in_bytes内存使用率 = memory.usage_in_bytes/memory.limit_in_bytes一般情况下,cgroup文件夹下的内容包括CPU、内存、磁盘、网络等信息:如memory下的文件有:几个常用的指标含义:memory.stat中的信息是最全的:更多资料参考:cgroup memory原理分析:Libcontainer 深度解析总结优缺点:优点:原生,很方便的看到当前宿主机上所有容器的CPU、内存、网络流量等数据。缺点:只能统计当前宿主机的所有容器,数据是实时的,没有存储,没有报警,没有可视化。备注:1.如果你没有限制容器内存,那么docker stats将显示您的主机的内存总量。但它并不意味着你的每个容器都能访问那么多的内存2.默认时stats命令会每隔1秒钟刷新一次,如果只看当前状态:docker stats –no-stream3.指定查看某个容器的资源可以指定名称或PID: docker stats –no-stream registry 1493container-monitor-book系列 : https://yasongxu.gitbook.io/container-monitor/

January 8, 2019 · 1 min · jiezi

基于Heapster的HPA

概述Horizontal Pod Autoscaling,简称HPA,是Kubernetes中实现POD水平自动伸缩的功能。自动扩展主要分为两种:水平扩展(scale out),针对于实例数目的增减垂直扩展(scal up),即单个实例可以使用的资源的增减, 比如增加cpu和增大内存HPA属于前者。它可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(支持 replication controller、deployment 和 replica set)监控数据获取Heapster: heapster收集Node节点上的cAdvisor数据,并按照kubernetes的资源类型来集合资源。但是在v1.11中已经被废弃(heapster监控数据可用,但HPA不再从heapster拿数据)metric-server: 在v1.8版本中引入,官方将其作为heapster的替代者。metric-server依赖于kube-aggregator,因此需要在apiserver中开启相关参数。v1.11中HPA从metric-server获取监控数据工作流程1.创建HPA资源,设定目标CPU使用率限额,以及最大、最小实例数, 一定要设置Pod的资源限制参数: request, 负责HPA不会工作。2.控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况3.然后与创建时设定的值和指标做对比(平均值之和/限额),求出目标调整的实例个数4.目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数如何部署:1.6-1.10版本默认使用heapster1.11版本及以上默认使用metric-server1.部署和运行php-apache并将其暴露成为服务2.创建HPA如果为1.8及以下的k8s集群,指标正常,如果为1.11集群,需要执行如下操作。4.向php-apache服务增加负载,验证自动扩缩容 启动一个容器,并通过一个循环向php-apache服务器发送无限的查询请求(请在另一个终端中运行以下命令)5.观察HPA是否生效container-monitor-book系列 : https://yasongxu.gitbook.io/container-monitor/

January 8, 2019 · 1 min · jiezi

容器监控实践—Heapster

概述该项目将被废弃(RETIRED)Heapster是Kubernetes旗下的一个项目,Heapster是一个收集者,并不是采集1.Heapster可以收集Node节点上的cAdvisor数据:CPU、内存、网络和磁盘2.将每个Node上的cAdvisor的数据进行汇总3.按照kubernetes的资源类型来集合资源,比如Pod、Namespace4.默认的metric数据聚合时间间隔是1分钟。还可以把数据导入到第三方工具ElasticSearch、InfluxDB、Kafka、Graphite5.展示:Grafana或Google Cloud Monitoring使用场景Heapster+InfluxDB+Grafana共同组成了一个流行的监控解决方案Kubernetes原生dashboard的监控图表信息来自heapster在HPA(Horizontal Pod Autoscaling)中也用到了Heapster,HPA将Heapster作为Resource Metrics API,向其获取metric,作为水平扩缩容的监控依据监控指标流程:1.Heapster首先从apiserver获取集群中所有Node的信息。2.通过这些Node上的kubelet获取有用数据,而kubelet本身的数据则是从cAdvisor得到。3.所有获取到的数据都被推到Heapster配置的后端存储中,并还支持数据的可视化。部署docker部署:k8s中部署:heapster.ymlinfluxdb.yml注意修改镜像地址,k8s.gcr.io无法访问的话,修改为内网镜像地址,如替换为registry.cn-hangzhou.aliyuncs.com/google_containersHeapster的参数source: 指定数据获取源,如kube-apiserverinClusterConfig:kubeletPort: 指定kubelet的使用端口,默认10255kubeletHttps: 是否使用https去连接kubelets(默认:false)apiVersion: 指定K8S的apiversioninsecure: 是否使用安全证书(默认:false)auth: 安全认证useServiceAccount: 是否使用K8S的安全令牌sink: 指定后端数据存储,这里指定influxdb数据库Metrics列表深入解析架构图:代码结构(https://github.com/kubernetes…)heapster主函数(heapster/metrics/heapster.go)主要流程:创建数据源对象创建后端存储对象list创建处理metrics数据的processors创建manager,并开启数据的获取及export的协程开启Heapster server,并支持各类APIcAdvisor返回的原始数据包含了nodes和containers的相关数据,heapster需要创建各种processor,用于处理成不同类型的数据,比如pod, namespace, cluster,node的聚合,求和平均之类,processor有如下几种:例如Pod的处理如下:详细解析参考: https://segmentfault.com/a/11…现状heapster已经被官方废弃(k8s 1.11版本中,HPA已经不再从hepaster获取数据)CPU内存、HPA指标: 改为metrics-server基础监控:集成到prometheus中,kubelet将metric信息暴露成prometheus需要的格式,使用Prometheus Operator事件监控:集成到https://github.com/heptiolabs…基于Heapster的HPA参考:基于Heapster的HPAcontainer-monitor-book系列 : https://yasongxu.gitbook.io/container-monitor/

January 8, 2019 · 1 min · jiezi

容器监控实践—开篇

概述随着越来越多的线上服务docker化,对容器的监控、报警变得越来越重要,容器监控有多种形态,有些是开源的(如promethues),而另一些则是商业性质的(如Weave),有些是集成在云厂商一键部署的(Rancher、谷歌云),有些是手动配置的,可谓百花齐放。本文将对现有的容器监控方案进行总结对比,监控解决方案的数量之多令人望而生畏,新的解决方案又不断涌现,下面将从开源方案(采集、展示、告警)、商业方案、云厂商、主机监控、日志监控、服务监控等方面进行列举,此篇为概述篇,包含汇总列表及脑图,具体分析将在后面补充更新,欢迎指正、补充。方案汇总一. 开源方案1.采集:Docker StatscAdvisorHeapstermetrics-serverCustom Metricskube-state-metricsnode-exporterPrometheusDockbix agentcortex2.展示:GrafanaKibanaVizceralmozaikZabbix dashboard3.报警:AlertManagerconsul-alertselastalertBosunCabot二. 商业方案SysdigDataDogdynatraceWeaveThanosCosalefreshtracksnewrelicSensunetsilpingdom三. 云厂商Google cloudAWS腾讯云阿里云百度云华为云四. 主机监控Zabbixnagiosnetdata五. 日志监控ELK StackEFK StackelastalertGraylogdocker_monitoring_logging_alerting六. 服务监控JaegerZipkinkubewatchriemann七. 存储后端InfluxDBKafkaGraphiteOpenTSDBElasticSearch脑图container-monitor-book系列 : https://yasongxu.gitbook.io/container-monitor/

January 8, 2019 · 1 min · jiezi

一场稳定、高清、流畅的大型活动直播是怎么炼成的?

双11猫晚是家喻户晓的综艺晚会,在今年的双11,阿里集团为2500万用户提供了一场在线直播视觉盛宴。网友评价这是一场既稳定流畅又高清的直播,当然在这背后离不开阿里云的技术支持。本次天猫晚会中,视频云首次采用4k和50帧的技术,把整个画质提升到接近肉眼极限,同时为用户提供了如丝般顺滑的直播体验。那么这么一场大型活动的直播究竟是如何炼成的呢?阿里云视频云技术专家裘良科带我们从稳定、画质、流畅、监控四个方面开始解读。如何做到100%稳定?裘良科认为:“最安全的做法就是做好500%的准备,以不便应万变。”下图是双11直播的技术架构,分为几大部分:直播源站、视频直播中心和CDN分发系统和客户端。简单的看这张图,所有的链路都是双备份的。直播源站部分,采用了多线收流、主备转码器、多线专线等策略,直播中心都是多机房接入,再采用多流合并,当任何一个机房出现问题的时候,输出的直播流是不会受任何影响的。在这之后,直播中心会对直播流进行转码、录制、智能处理、切片、时移回放等处理,中间所有模块都是专有资源池供大型活动使用,保证不会受其他活动影响。任何一个模块发生异常,都可以秒级进行切换。产生到的内容在分发之前,会先进行存储,中心主备。到了分发环节,会实时检查源站的质量,并进行切换。在这样的架构之下,任何单点、单机房、单线路、单模块的故障,都不会导致直播服务不可用,几乎做到绝对安全。当然,除了自身稳定之外,安全也十分重要。在安全方面,视频云在推流、播放和拉流等环节,采用多重鉴权、IP黑白名单、播放格式/地区/IP等限制、HTTPS、防劫持等能力,实现全链路安全保障。如何让用户享受到极致的画质?一、实时4K直播视频清晰度作为衡量用户体验的重要指标,也是视频云技术团队十分关注的方向。本次猫晚的视频清晰度再度升级,通过阿里云直播服务提供实时4K直播,将现场4K超高清、高帧率的视频实时处理,进行画质提升。在4K视频的处理上,直播服务大规模使用GPU进行视频处理及转码,大大提升了实时视频处理能力,保证了直播视频最高4K的HEVC实时转码。据悉,4K高清直播已在阿里云的众多游戏直播客户中广泛使用。二、50帧极清阿里云和优酷合力研发的50帧极清技术,可通过人工智能算法预测运动方向和轨迹,将原始的每秒25帧画面普通电视信号变换为每秒50帧画面的高帧率视频内容,给用户提供更加流畅的沉浸式观看体验。50帧极清的效果,就像去电影院看大片,动作效果非常丰富的情况下,也不存在顿挫感。今年夏天的世界杯和本次双11猫晚都采用50 帧技术,视觉上看是非常流畅的。三、码率(比特率)最佳配比除了4K技术,基于内容进行编码优化也是视频云的优势。裘良科表示:“阿里的窄带高清技术精髓就在于使每一个比特分配到最需要它的地方。”这里我们先来看几个概念:分辨率是图像精密度的概念,代表着质量的极限,是不是越大越好呢?是也不是。分辨率大,点就多,需要的码率就高,需要的带宽就会变大,传输成本和对网络的要求都会变大。码率,比就是比特率,它代表单位时间传送的数据位数,视频文件大小就是由码率决定的,而且是成正比。帧率,代表着视觉流畅度,在我国通常帧率在25帧左右。然而帧率达到50-60的时候,我们几乎肉眼察觉不到间隔和差异。那我们如何在帧间和帧内进行合理码率分配,以达到最优的平衡呢?1. 合理分配帧间码率每一帧都需要码率来显示图像,那么我们如何判断哪一帧需要较多的帧率?哪一帧需要较少呢?其实这就需要基于对内容的分析,提前进行预判,你认为这一帧是复杂的画面,比如好莱坞动作大片,就多分配帧率,如果这一阵比较简单,比如新闻联播,就少分配。以此来实现合理的帧间码率分配。2. 合理分配帧内码率在整个图像中,并不是全部都需要非常清楚的。比如说你在看晚会的时候,你看的是中间的人物嘉宾,所以把人物和脸识别出来,就是你眼睛聚焦的地方,多分配一些码率。同时,衣服的褶皱纹理也多分配一些码率,背景作为脱焦区域,就少分配一些码率了。通过帧间、帧内的码率分配,让整个视频的质量更高。在同等码率之下,获得更高的质量。同样质量之下,可以节省更多带宽。那在播放层面,如何保证流畅不卡顿呢?裘良科认为,在确保直播流畅度上,全球覆盖的CDN节点和精准调度系统缺一不可。CDN节点是采用分布式架构,拥有遍布全球的1500个节点和充足的带宽储备,单节点带宽 40Gbps+,全网带宽输出能力120 Tbps。同时采用四层智能调度架构(如下图),来确保整个分发的流畅。如何实现精准调度,确保大型活动突发峰值的流畅但是面对晚会等大型活动,突发峰值非常高,需要更精准的调度策略,来实现调度。打比方有一个装了很多冰块和水的杯子,如果我们要把杯子里面的狭小空间全部用上,我们先要把冰块放进去,再倒液态水。DNS的协议限制类似冰块。其他别的调度形式,比如IP调度,可以做好请求级别的调度,也就是支持任意比例的负载均衡,就像液态水一样。所以,在智能调度的场景里,把“固体”和“液体”结合起来考虑,才能做到所有的节点、水位的精准控制,实现更精准的调度。同时,在码率瞬间激增的情况下,常规的流量预测算法失算了,进而会干扰流控程序, 这个问题阿里云使用了基于AI流量预测进行预调度,在10分钟内的预测的精准度到98%,一小时的精准度95%以上。监控系统保驾护航在确保了稳定、画质和流畅之后,一场大型活动的直播离不开监控系统。我们肯定需要对当前的直播状态做监控,以确保及时调整策略。监控从以下四个方面进行:1、流监控:针对每一路流进行秒级实时监控,及时获得直播流的帧率、码率、时间戳等状态2、播放质量监控:实时获知服务端慢速比,用户端卡顿率3、可用性监控:实时返回视频5XX等播错误数据,及时定位视频失败原因4、业务量监控:实时获取当前在线用户数作为这场猫晚的唯一网络直播平台,优酷平台上直播观看人数近2500万,是去年的两倍。这也是阿里云视频云第四年支持双11猫晚网络直播,从作战室监控的数据上来看,猫晚直播期间各项系统数据指标运转平稳,一场稳定、高清、流畅的大型活动直播就就此实现。经过世界杯、双11猫晚等多次锤炼,视频云直播服务已经具备一整套大型赛事/活动/综艺直播的服务经验,并实现对阿里云各行业客户的赋能,为视频行业创造更多价值。本文作者:樰篱 阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 2, 2019 · 1 min · jiezi

蚂蚁金服核心技术:百亿特征实时推荐算法揭秘

阿里妹导读:本文来自蚂蚁金服人工智能部认知计算组的基础算法团队,文章提出一整套创新算法与架构,通过对TensorFlow底层的弹性改造,解决了在线学习的弹性特征伸缩和稳定性问题,并以GroupLasso和特征在线频次过滤等自研算法优化了模型稀疏性,在支付宝核心推荐业务获得了uvctr的显著提升,并较大地提升了链路效率。0.综述在线学习(Online learning)由于能捕捉用户的动态行为,实现模型快速自适应,进而成为提升推荐系统性能的重要工具。然而它对链路和模型的稳定性,训练系统的性能都提出了很高的要求。但在基于原生TensorFlow,设计Online推荐算法时,我们发现三个核心问题:一些资讯推荐场景,需要大量长尾词汇作为特征,需使用featuremap对低频特征频次截断并连续性编码,但耗时且方法aggressive。使用流式数据后,无法预知特征规模,而是随训练逐渐增长。因此需预留特征空间训练几天后重启,否则会越界。模型稀疏性不佳,体积达到数十GB,导致上传和线上加载耗时长且不稳定。更重要的是,在线学习如火如荼,当流式特征和数据都被打通后,能按需增删特征,实现参数弹性伸缩的新一代训练平台成为大势所趋。为了解决这些问题,从2017年底至今,蚂蚁金服人工智能部的同学,充分考虑蚂蚁的业务场景和链路,对TensorFlow进行了弹性改造, 解决了以上三大痛点,简化并加速离线和在线学习任务。其核心能力如下:弹性特征伸缩体系,支持百亿参数训练。group_lasso优化器和频次过滤,提高模型稀疏性,明显提升线上效果。模型体积压缩90%,完善的特征管理和模型稳定性监控。在与业务线团队的共同努力下,目前已在支付宝首页的多个推荐场景全流量上线。其中某推荐位的个性化online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 某个性化资讯推荐业务最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%,模型体积压缩90%,链路效率提升50%。1. 弹性改造及优势背景:在原生TensorFlow中,我们通过Variable来声明变量,若变量超过了单机承载的能力,可使用partitioned_variables来将参数分配到不同机器上。 但必须指定shape,声明后即不可改变,通过数组索引查找。由于推荐系统中大量使用稀疏特征,实践中一般采取embedding_lookup_sparse一类的方法在一个巨大的Dense Variable中查找向量并求和,来代替矩阵乘法。开源Tensorflow限定了Variable使用前必须声明维度大小,这带来了两个问题:1)需要预先计算特征到维度范围内的int值的映射表,这一步操作通常在ODPS上完成。因为需要扫描所有出现的特征并编号,计算非常缓慢;2)在online learning场景下,为了容纳新出现的特征,需要预留一部分维度空间,并在线上不断修改映射表,超过预留空间则需要重新启动在线任务。为了突破固定维度限制,实现特征的动态增加和删除,最朴素的优化想法是在TensorFlow底层实现模拟字典行为的Variable,并在此基础上重新实现Tensorflow上层API。由此我们进行了优化,在server新增了基于HashMap的HashVariable,其内存结构如下:在声明该变量时,只需增加一句,其他训练代码皆不需改动:每个特征都通过hash函数映射到一个2的64次方大小的空间内。当需要计算该特征时,PS会按需惰性创建并返回之。但其上层行为与原生TF一致。由于去掉了featuremap转ID的过程,我们内部形象地将其称为“去ID化”。在此之上我们实现了Group Lasso FTRL,频次过滤和模型压缩等一系列算法。备注:弹性特征带来一个显著的优势:只要用足够强的L1稀疏性约束,在单机上就能调试任意大规模的特征训练,带来很多方便。我们的hashmap实现是KV化的,key是特征,value是vector的首地址。离线训练优化经过这样的改造后,在离线批量学习上,带来了以下变化:在线训练优化online learning上,能带来如下变化:除了性能有明显的提升之外,其最大的优势是不需提前申请空间,训练可以无缝稳定运行。2. 特征动态增删技术弹性架构,主要目的就是特征优选,让模型自适应地选择最优特征,进而实现稀疏化,降低过拟合。本节介绍特征优选的两个核心技术:使用流式频次过滤, 对特征进入进行判定。使用Group Lasso优化器,对特征进行筛选和删除。2.1 Group Lasso 优化器稀疏化是算法追求的重要模型特性,从简单的L1正则化和Truncated Gradient[9], 再到讨论累积梯度平均值的RDA(Regularized Dual Averaging)[10], 再到目前常见的 FTRL[2] 。 然而它们都是针对广义线性模型优化问题提出的稀疏性优化算法,没有针对sparse DNN中的特征embedding层做特殊处理。把embedding参数向量当做普通参数进行稀疏化,并不能达到在线性模型中能达到的特征选择效果,进而无法有效地进行模型压缩。例如:当包含新特征的样本进入时,一个特征对应的一组参数(如embedding size为7,则参数数量为7)被激活,FTRL判定特征中的部分参数无效时,也不能安全地将该特征删除。如图:因此,在L1和L2正则的基础上,人们引入L21正则(group lasso)和L2正则(exclusive sparsity),分别表示如下:L21早在2011年已经引入,它最初目的是解决一组高度关联特征(如男女)应同时被保留或删除的问题,我们创新地扩展到embedding的表示上,以解决类似的问题。在L21中,由于内层L2正则将一个特征的所有参数施加相同的约束,能将整组参数清除或保留,由此决定embedding层中的某些特征对应的embedding向量是否完全删除,提升模型泛化性。因此称为group lasso。而L12则正好相反,它迫使每组参数中的非0参数数量一致但值又尽可能不同,但使输出神经元互相竞争输入神经元,进而使特征对目标更具区分性。对于DNN分类网络,底层表示要求有足够的泛化性和特征抽象能力,上层接近softmax层,需要更好的区分性。因此我们通常在最底层的embedding层使用group lasso。即如下的优化目标:直接将L21正则项惩罚加入loss,模型最终也能收敛,但并不能保证稀疏性。因此Group lasso优化器参考了FTRL,将梯度迭代分成两个半步,前半步按梯度下降,后半步微调实现稀疏性。通过调节L1正则项(即公式中的),能有效地控制模型稀疏性。Group lasso是弹性计算改造后,模型性能提升和压缩的关键。值得指出:在我们实现的优化器中,Variable,以及accum和linear两个slot也是KV存储。L12和L21正则相结合的方法也已经有论文讨论[8],但我们还未在业务上尝试出效果。由于篇幅限制,本节不打算详细介绍Group lasso的原理和推导2.2 流式频次过滤讨论完特征动态删除的方法后,我们再分析特征的准入策略。2.2.1 频次过滤的必要性在Google讨论FTRL的文章1中提到, 在高维数据中大部分特征都是非常稀疏的,在亿级别的样本中只出现几次。那么一个有趣的问题是,FTRL或Group FTRL优化器能否能删除(lasso)极低频特征?在RDA的优化公式中,满足以下条件的特征会被置0:若在t步之前,该特征只出现过几次,未出现的step的梯度为0,随着步数增大,满足上述条件变得越来越容易。由此RDA是可以直观处理极稀疏特征的。 但对于FTRL,要满足:其中,不仅和历史梯度有关,还与历史学习率和权重w有关。 因此FTRL虽然也能处理极稀疏特征,但并没有RDA那么aggressive(此处还待详细地分析其下界,Group FTRL与此类似)。由于FTRL在设计和推导时并未明确考虑极低频特征,虽然通过增大,确实能去除大量极低频特征,但由于约束太强,导致部分有效特征也被lasso,在离线实验中被证明严重影响性能。其次,对这些巨量极低频特征,保存历史信息的工程代价是很高昂的(增加几倍的参数空间和存储需求),如下图:因此我们提出,能否在实时数据流上模拟离线频次过滤,为特征提供准入门槛,在不降低模型性能的基础上,尽量去除极低频特征,进一步实现稀疏化?2.2.2 频次过滤的几种实现注意: 由于默认的embedding_lookup_sparse对特征执行了unique操作(特征归一化以简化计算),因此在PS端是不可能获取真实特征和label频次的。需要Python端对placeholder统计后,上传给server端指定的Variable,优化器通过slot获得该Variable后作出联合决策。最naive的思路是模拟离线频次过滤,对特征进行计数,只有达到一定阈值后再进入训练,但这样破坏了数据完整性:如总频次6,而阈值过滤为5,则该特征出现的前5次都被忽略了。为此我们提出了两种优化方案:基于泊松分布的特征频次估计在离线shuffle后的特征满足均匀分布,但对在线数据流,特征进入训练系统可看做泊松过程,符合泊松分布:其中n为当前出现的次数,t为当前的步数,为单位时间发生率,是泊松分布的主要参数,T为训练总步数。为特征最低门限(即最少在T时间内出现的次数)。因此我们能通过前t步的特征出现的次数n,将t时刻当做单位时间,则。 根据泊松分布,我们可以算出剩余时间内事件发生大于等于次的概率每次该特征出现时,都可按该概率做伯努利采样,特征在t步进入系统的概率用下式计算:通过真实线上数据仿真,它能接近离线频次过滤的效果,其是随每次特征进入时动态计算的。它的缺陷是:当t越小时,事件发生在t内的次数的variance越大,所以会以一定概率误加或丢弃特征。未来总的训练步数T在在线学习中是未知的。频次过滤与优化器相分离,导致不能获得优化器的统计信息。动态调L1正则方案在经典的FTRL实现中,L1正则对每个特征都是一致的。这导致了2.2.1 中提到的问题:过大的L1虽然过滤了极低频特征,但也影响的了模型的性能。参考各类优化器(如Adam)对learning_rate的改进,我们提出:通过[图片上传失败…(image-10f16c-1545974538974)]特征频次影响L1正则系数,使得不同频次的特征有不同的lasso效果。特征频次和基于MLE的参数估计的置信度相关,出现次数越低置信度越低。如果在纯频率统计基础上加入一个先验分布(正则项),当频率统计置信度越低的时候,越倾向于先验分布,相应的正则系数要更大。我们经过多个实验,给出了以下的经验公式:其中c是惩罚倍数,为特征最低门限,这两者皆为超参,是当前特征出现的频次。我们在线上环境,使用了动态调节L1正则的方案 。在uvctr不降甚至有些微提升的基础上,模型特征数比不使用频次过滤减少75%,进而从实验证明了频次过滤对稀疏化的正向性。它的缺点也很明显:特征频次和正则系数之间的映射关系缺少严谨证明。频次过滤作为特征管理的一部分,目前还少有相关论文研究,亟待我们继续探索。3.模型压缩和稳定性3.1 模型压缩在工程上,由于做了优化,如特征被优化器lasso后,只将其置0,并不会真正删除;在足够多步数后才删除。同时引入内存池,避免特征的反复创建和删除带来的不必要的性能损失。 这就导致在训练结束后,模型依然存在大量0向量。导出时要进一步做模型压缩。由于引入了HashPull和HashPush等非TF原生算子,需要将其裁剪后转换为原生TF的op。 我们将这些步骤统称图裁剪(GraphCut), 它使得线上inference引擎,不需要做任何改动即可兼容弹性改造。由于有效特征大大减少,打分速度相比原引擎提升50%以上。我们将图裁剪看做TF-graph的静态优化问题,分为3个步骤:第一遍遍历Graph,搜索可优化子结构和不兼容的op。第二遍遍历,记录节点上下游和元数据,裁剪关键op,并将Variable的非0值转存至Tensorflow原生的MutableDenseHashTable。本步骤将模型体积压缩90%。拼接新建节点,重建依赖关系,最后递归回溯上游节点,去除与inference无关的子图结构我们实现了完整简洁的图裁剪工具,在模型热导出时调用, 将模型从原先的8GB左右压缩到几百兆大小,同时保证模型打分一致。3.2 模型稳定性和监控online learning的稳定性非常重要。我们将线上真实效果,与实时模型生成的效果,进行了严密的监控,一旦样本偏差过多,就会触发报警。由于需捕捉时变的数据变化,因而不能用固定的离线数据集评估模型结果。我们使用阿里流式日志系统sls最新流入的数据作为评估样本,以滑动窗口先打分后再训练,既维持了不间断的训练,不浪费数据,同时尽可能高频地得到最新模型效果。我们对如下核心指标做了监控:样本监控: 正负比例,线上打分值和online-auc(即线上模型打分得到的auc),产出速率,消费速率。训练级监控: AUC, User-AUC(参考备注),loss, 模型打分均值(与样本的正负比例对齐),异常信息。特征级管理: 总特征规模,有效/0/删除特征规模,新增/插入/删除的速率。整体模型和调度:模型导出的时间,大小,打分分布是否正常,是否正常调度。业务指标:uvctr,pvctr(小时级更新,T+1报表)。线上与训练指标之间的对应关系如下表:通过http接口,每隔一段时间发送监控数据,出现异常会及时产生钉钉和邮件报警。下图是对9月20日到27号的监控,从第二张图表来看,模型能较好的适应当前数据流的打分分布。User-AUC:传统的AUC并不能完全描述uvctr,因为模型很可能学到了不同用户间的偏序关系,而非单个用户在不同offer下的点击偏序关系。为此,我们使用了User-AUC,它尽可能地模拟了线上uvctr的计算过程,在真实实验中,监控系统的uvctr小时报表,与实时模型输出的User-AUC高度一致。4. 工程实现和效果目前算法已经在支付宝首页的多个推荐位上线。推荐系统根据用户的历史点击,融合用户画像和兴趣,结合实时特征,预估用户CTR,进而提升系统整体点击率。我们以推荐位业务为例说明,其采用了经典的wide&deep的网络结构,其sparse部分包含百级别的group(见下段备注1)。 一天流入约百亿样本,label的join窗口为固定时长。由于负样本占大多数,上游链路对正负样本做了1:8的降采样(见下文备注2)。训练任务采用蚂蚁统一训练平台构建,并使用工作流进行定时调度,离线和在线任务的其他参数全部一致。Batchsize为512,每200步(即20万样本)评估结果,定时将模型通过图裁剪导出到线上系统。当任务失败时,调度系统会自动拉起,从checkpoint恢复。该推荐业务的online learning桶最近一周相比线上多模型融合最优桶提升4.23% , 相比随机对照提升达34.67% 。 另一资讯推荐业务其最近一周,相比DNN基准uv-ctr提升+0.77%,pv-ctr提升+4.78%。实验效果相比有较大的提升。备注1: group embedding是将相似emb特征分组,各自lookup求和后再concat,使得特征交叉在更高层进行。其设计是考虑到不同group的特征差异很大(如user和item),不应直接对位求和。备注2: inference打分仅做pointwise排序,采样虽改变数据分布但不改变偏序关系,因此并未在训练上做补偿。5. 未来工作弹性特征已经成为蚂蚁实时强化深度学习的核心要素。它只是第一步,在解决特征空间按需创建问题后,它会带来一个充满想象力的底层架构,众多技术都能在此基础上深挖: 在工程上,可继续从分钟级向秒级优化,进一步提升链路实时性并实现模型增量更新; 在算法上,我们正在探索如样本重要性采样,自动特征学习,在线线性规划与DNN的结合,实现优化器联合决策等技术。由于在线学习是个复杂的系统工程,我们在开发和调优时遇到了大量的困难,涉及样本回流,训练平台,模型打分,线上评估等一系列问题,尤其是稳定性,但基本都一一克服。为了保证线上结果稳定可信,我们在观察和优化两三个月后才发布这篇文章,希望和业界同仁一起交流探讨。本文作者为蚂蚁金服人工智能部认知计算组的基础算法团队,团队涉及图像、NLP、推荐算法和知识图谱等领域,拥有定损宝和理赔宝等核心业务。参考文献:[1] McMahan, Brendan. “Follow-the-regularized-leader and mirror descent: Equivalence theorems and l1 regularization.” Proceedings of the Fourteenth International Conference on Artificial Intelligence and Statistics. 2011.[2] McMahan, H. Brendan, et al. “Ad click prediction: a view from the trenches.” Proceedings of the 19th ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2013.[3]Yuan, Ming, and Yi Lin. “Model selection and estimation in regression with grouped variables.” Journal of the Royal Statistical Society: Series B (Statistical Methodology) 68.1 (2006): 49-67.[4] Andrew, Galen, and Jianfeng Gao. “Scalable training of L 1-regularized log-linear models.” Proceedings of the 24th international conference on Machine learning. ACM, 2007.[5]Scardapane, Simone, et al. “Group sparse regularization for deep neural networks.” Neurocomputing 241 (2017): 81-89.[6] Yang, Haiqin, et al. “Online learning for group lasso.” Proceedings of the 27th International Conference on Machine Learning (ICML-10). 2010.[7]Zhou, Yang, Rong Jin, and Steven Chu–Hong Hoi. “Exclusive lasso for multi-task feature selection.” Proceedings of the Thirteenth International Conference on Artificial Intelligence and Statistics. 2010.[8] Yoon, Jaehong, and Sung Ju Hwang. “Combined group and exclusive sparsity for deep neural networks.” International Conference on Machine Learning. 2017.[9] Langford, L. Li, and T. Zhang. Sparse online learning via truncated gradient.JMLR, 10, 2009.[10]L. Xiao. Dual averaging method for regularized stochastic learning and online optimization. In NIPS, 2009.本文作者:墨眀阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。 ...

December 28, 2018 · 2 min · jiezi

网易考拉在服务化改造方面的实践

导读:网易考拉(以下简称考拉)是网易旗下以跨境业务为主的综合型电商,自2015年1月9日上线公测后,业务保持了高速增长,这背后离不开其技术团队的支撑。微服务化是电商IT架构演化的必然趋势,网易考拉的服务架构演进也经历了从单体应用走向微服务化的整个过程,以下整理自网易考拉陶杨在近期Apache Dubbo Meetup上的分享,通过该文,您将了解到:考拉架构的演进过程考拉在服务化改造方面的实践考拉在解决注册中心性能瓶颈方面的实践考拉未来的规划考拉架构的演进过程考拉在2015年初上线的时候,线上只有七个工程,商品详情页、购物车下单页等都耦合在中间这个online的工程里面。在上线之初的时候,这种架构还是比较有优势的,因为当时考拉的开发人员也不是很多,把所有的功能都耦合在一个进程里面,利于集中开发、测试和上线,是一种比较高效和节省成本的方式。但是随着业务的不断发展,包括需求的逐步增多,开发团队的不断扩容,这时候,单体架构的一些劣势就逐渐的暴露出来了,例如开发效率低:功能之间的相互耦合,不同需求的不同分支也经常会修改同一块代码,导致合代码的过程非常痛苦,而且经常会出问题。再例如上线成本高:几乎所有的发布需求都会涉及到这些应用的上线,同时不断增长的业务需求,也会使得我们的代码越来越臃肿,造成维护困难、可用性差,功能之间相互耦合,都耦合在一个进程里面,导致一旦某一个业务需求涉及的代码或者资源出现问题,那么就会影响其他的业务。比如说我们曾经在online工程里面,因为优惠券兑换热点的问题,影响了核心的下单服务。这个架构在考拉运行的4到5个月的时间里,从开发到测试再到上线,大家都特别痛苦。所以我们就开始进行了服务化拆分的工作。这个是考拉现在的分布式服务架构。伴随着服务化的拆分,我们的组织架构也进行了很多调整,出现了商品中心、用户中心和订单中心等等。拆分其实是由业务驱动的,通过业务来进行一些横向拆分或者纵向拆分,同时,拆分也会面对一个拆分粒度的问题,比如怎么才算一个服务,或者说服务拆的过细,是不是会导致我们管理成本过高,又或者说是否会带来架构上的新问题。考拉的拆分由粗到细是一个逐步演进的过程。随着服务化的拆分,使得服务架构越来越复杂,随之而来产生了各种各样的公共技术,比如说服务治理、平台配置中心、分布式事务和分布式定时任务等等。考拉的服务化实践微服务框架在服务化中起到了很重要的作用,是服务化改造的基石,经过严格的技术选型流程后,我们选用了Dubbo来作为考拉服务改造的一个重要支柱。Dubbo可以解决服务化过程中服务的定义、服务的注册与发现、服务的调用和路由等问题,此外,Dubbo也具有一些服务治理的功能和服务监控的功能。下面我将介绍考拉基于Dubbo做的一些服务化实践。首先来说一下 熔断。在进行服务化拆分之后,应用中原有的本地调用就会变成远程调用,这样就引入了更多的复杂性。比如说服务A依赖于服务B,这个过程中可能会出现网络抖动、网络异常,或者说服务B变得不可用或者不好用时,也会影响到A的服务性能,甚至可能会使得服务A占满整个线程池,导致这个应用上其它的服务也受影响,从而引发更严重的雪崩效应。因此,服务之间有这样一种依赖关系之后,需要意识到服务的依赖其实是不稳定的。此时,需要通过采取一些服务治理的措施,例如熔断、降级、限流、隔离和超时等,来保障应用不被外部的异常拖垮。Dubbo提供了降级的特性,比如可以通过mock参数来配置一些服务的失败降级或者强制降级,但是Dubbo缺少自动熔断的特性,所以我们在Dubbo上引入了Hystrix。消费者在进行服务调用的时候会经过熔断器,当服务提供者出现异常的时候,比如暂时性的不可用,熔断器就会打开,对消费端进行调用短路,此时,消费端就不会再发起远程调用,而是直接走向降级逻辑。与此同时,消费端会持续的探测服务的可用性,一旦服务恢复,熔断器就会关闭,重新恢复调用。在Dubbo的服务治理平台上,可以对Hystrix上运行的各种动态参数进行动态的配置,包括是否允许自动熔断,是否要强制熔断,熔断的失败率和时间窗口等等。下面再说一下 限流。当用户的请求量,调用超过系统可承受的并发时系统QPS会降低、出现不可用甚至存在宕机的风险。这就需要一个机制来保护我们的系统,当预期并发超过系统可承受的范围时,进行快速失败、直接返回,以保护系统。Dubbo提供了一些基础的限流特性,例如可以通过信号量的配置来限制我们消费者的调用并发,或者限制提供者的执行并发。但是这些是远远不够的,考拉自研了限流框架NFC,并基于Dubbo filter 的形式,实现了对Dubbo的支持,同时也支持对URL等其他资源的限流。通过配置中心动态获取流控规则,对于资源的请求,比如Dubbo调用会经过流控客户端,进行处理并判断是否触发限流,一旦请求超出定义的阈值,就会快速失败。同时,这些限流的结果会上报到监控平台。上图中的页面就是考拉流控平台的一个监控页面,我们在页面上可以对每一个资源(URL、Dubbo接口)进行一个阈值的配置,并对限流进行准实时监控,包括流控比率、限流次数和当前的QPS等。限流框架除了实现基本的并发限流之外,也基于令牌桶和漏桶算法实现了QPS限流,并基于Redis实现了集群级别的限流。这些措施保障系统在高流量的情况下不会被打垮。考拉在监控服务方面的改造在服务化的过程中,系统变得越来越复杂,服务数量变得越来越多,此时需要引入更多维度的监控功能,帮助快速的去定位并解决系统中的各类问题。监控主要分为这四个方面,日志、Metrics、Trace和HealthCheck。在应用程序、操作系统运行的时候,都会产生各种各样的日志,通过日志平台对这些日志进行采集、分析和展示,并支持查询和操作。Metrics反映的是系统运行的基本状态,包括瞬时值或者聚合值,例如系统的CPU使用率、磁盘使用率,以及服务调用过程中的平均延时等。Trace是对服务调用链的一个监控,例如调用过程中的耗时分析、瓶颈分析、依赖分析和异常分析等。Healthcheck可以探测应用是否准备就绪,是否健康,或者是否还存活。接下来,围绕Dubbo来介绍一下考拉在监控方面的改造实践。第一个是服务监控。Dubbo提供了服务监控功能,支持定期上报服务监控数据,通过代码增强的方式,采集Dubbo调用数据,存储到时序数据库里面,将Dubbo的调用监控功能接入到考拉自己的监控平台。上图中的页面是对Dubbo提供者的服务监控,包括对服务接口、源集群等不同维度的监控,除了全局的调用监控,还包括不同维度的监控,例如监控项里的调用次数。有时候我们更关心慢请求的情况,所以会将响应时间分为多个范围,比如说从0到10毫秒,或是从10到50毫秒等,这样就可以看到在各个范围内请求的数量,从而更好地了解服务质量。同时,也可以通过各种报警规则,对报警进行定义,当服务调用出现异常时,通过邮件、短信和电话的形式通知相关人员。监控平台也会对异常堆栈进行采集,例如说这次服务调用的异常的原因,是超时还是线程满了的,可以在监控平台上直接看到。同时生成一些监控报表,帮助我们更好地了解服务的性能,推进开发去改进。第二个是Trace。我们参考了Dapper,自研了Trace平台,并通过代码增强的方式,实现了对Dubbo调用链路的采集。相关调用链参数如TarceID,SpanID 等是通过Dubbo的隐式传参来传递的。Trace可以了解在服务调用链路中的一个耗时分析和瓶颈分析等。Trace平台上可以展示一次服务调用,经历了哪些节点,最耗时的那个节点是在哪里,从而可以有针对性的去进行性能优化。Trace还可以进行依赖分析,这些依赖是否合理,能否通过一些业务手段或者其它手段去减少一些不合理的依赖。Trace对异常链路进行监控报警,及时的探测到系统异常并帮助我们快速的定位问题,同时和日志平台做了打通,通过TraceId可以很快的获取到关联的异常日志。第三个是健康检查。健康检查也是监控中很重要的一个方面,以更优雅的方式上线应用实例。我们和自动部署平台结合,实现应用的健康检查。服务启动的时候可以通过Readiness接口判断应用依赖的各种资源,包括数据库、消息队列等等是否已经准备就绪。只有健康检查成功的时候才会触发出注册操作。同时Agent也会在程序运行的过程中定时的检查服务的运行状态。同时,也通过这些接口实现更优雅的停机,仅依赖shutdownhook,在某些情况下不一定靠谱,比如会有shutdownhook执行先后顺序的问题。应用发布的时候,首先调用offline接口,将注册服务全部从注册中心反注册,这时不再有新的流量进来,等到一段时间后,再执行停机发布操作,可以实现更加优雅的停机。考拉在服务测试方面的改造下面来介绍一下考拉在服务测试方面的实践。服务测试分为接口测试、单链路压测、全链路压测和异常测试四个维度。接口测试通过接口测试,可以来验证对外提供的Dubbo服务是否正确,因此我们也有接口测试平台,帮助QA更好的进行接口测试,包括对接口的编辑(入参、出参),用例的编辑和测试场景的执行等,单链路压测单链路的压测,主要面对单个功能的压测,比如要上线一个重要功能或者比较重要的接口之前,必须通过性能测试的指标才可以上线。全链路压测考拉作为电商平台,在大促前都会做全链路压测,用以探测系统的性能瓶颈,和对系统容量的预估。例如,探测系统的各类服务的容量是否够,需要扩容多少,以及限流的阈值要定多少合适,都可以通过全链路压测来给出一些合理的值。异常测试对服务调用链路中的一些节点进行系统异常和服务异常的注入,也可以获取他们的强度依赖关系。比如一个非常重要的接口,可以从Trace获取的调用链路,然后对调用链的依赖的各个服务节点进行异常注入。通过接口的表现,系统就会判断这个接口的强度依赖关系,以改善这些不合理的强依赖关系。考拉在API网关方面的改造随着考拉服务化的发展,我们自研了API网关,API网关可以作为外部流量的统一接口,提供了包括路由转发、流控和日志监控等一些公共的功能。考拉的API网关是通过泛化调用的方式来调用后台Dubbo的服务的。Dubbo原生的泛化调用的性能比普通Api调用要差一些,所以我们也对泛化调用性能做了一些优化,也就是去掉了泛化调用在返回结果时的一次对象转换。最终压测的结果泛化的性能甚至比正常的调用性能还要好些。考拉在多语言方面的改造考拉在业务发展的过程中产生了不少多语言的需求,例如,我们的前端团队希望可以用Node应用调用Dubbo服务。对比了易用性,选用了开源的jsonrpc 方案,然后在后端的Dubbo服务上暴露了双协议,包括Dubbo协议和json rpc协议。但在实施的过程中,也遇到了一些小问题,比如说,对于Dubbo消费者来说,不管是什么样的协议提供者,都是invoker。通过一个负载均衡策略,选取一个invoker进行调用,这个时候就会导致原来的Java客户端选用一个jsonrpc协议的提供者。这样如果他们的API版本不一致,就有可能导致序列化异常,出现调用失败的情况。所以,我们对Dubbo的一些调用逻辑做了改造,例如在Java客户端的消费者进行调用的时候,除非显示的配置,否则默认只用Dubbo协议去调用。另外,考拉也为社区的jsonrpc扩展了隐式传参的功能,因为可以用Dubbo隐式传参的功能来传递一些全链路参数。考拉在解决注册中心性能瓶颈方面的实践注册中心瓶颈可能是大部分电商企业都会遇到的问题,考拉也不例外。我们现在线上的Dubbo服务实例大概有4000多个,但是在ZooKeeper中注册的节点有一百多万个,包括服务注册的URL和消费者订阅的URL。Dubbo应用发布时的惊群效应、重复通知和消费者拉取带来的瞬时流量一下就把ZooKeeper集群的网卡打满,ZooKeeper还有另外一个问题,他的强一致性模型导致CPU的利用率不高。就算扩容,也解决不了ZooKeeper写性能的问题,ZooKeeper写是不可扩展的,并且应用发布时有大量的请求排队,从而使得接口性能急剧下降,表现出来的现象就是应用启动十分缓慢。因此,在今年年初的时候就我们决定把ZooKeeper注册中心给替换掉,对比了现有的一些开源的注册中心,包括Consul、Eruka、etcd等,觉得他们并不适合Dubbo这种单进程多服务的注册模型,同时容量能否应对未来考拉的发展,也是一个问号。于是,我们决定自研注册中心,目前正在注册中心的迁移过程当中,采用的是双注册中心的迁移方案,即服务会同时注册ZooKeeper注册中心,还有新的注册中心,这样对原有的架构不会产生太大的影响。考拉新的注册中心改造方案和现在社区的差不多,比如说也做了一个注册数据的拆分,往注册中心注册的数据只包含IP, Port 等关键数据,其它的数据都写到了Redis里面,注册中心实现使用了去中心化的一个架构,包括使用最终一致性来换取我们接口性能的一个提升。后面如果接入Dubbo,会考虑使用Nacos而不是ZooKeeper作为注册中心。未来规划考拉最近也在进行第二机房的建设,通过两个机房独立部署相同的一套系统,以实现同城双活。针对双机房的场景,Dubbo会做一定的改造,例如同机房优先调用,类似于即将发布的Dubbo2.7.0中的路由特性。在Dubbo在服务注册的时候,读取系统环境变量的环境标或者机房标,再将这些机房标注册到注册中心,然后消费端会做一个优先级路由,优先进行同机房的服务调用。容器化也是我们在规划的一个方向。随着服务化进程的演进,服务数也变得越来越多,通过容器化、DevOps可以提升测试、部署和运维效率。Service Mesh在今年非常火,通过Service Mesh将服务框架的的能力比如注册发,路由和负载均衡,服务治理等下沉到Sidecar,使用独立进程的方式来运行。对于业务工程的一个解耦,帮助我们实现一个异构系统,对多语言支持,也可以解决中间件升级推动困难以及各种依赖的冲突,业务方也可以更好的关注于业务开发,这也会是未来探索的一个方向。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 20, 2018 · 1 min · jiezi

支付宝客户端架构分析:自动化日志收集及分析

小蚂蚁说:《支付宝客户端架构解析》系列将从支付宝客户端的架构设计方案入手,细分拆解客户端在“容器化框架设计”、“网络优化”、“性能启动优化”、“自动化日志收集”、“RPC 组件设计”、“移动应用监控、诊断、定位”等具体实现,带领大家进一步了解支付宝在客户端架构上的迭代与优化历程。本节将结合禾兮在 OSChina 珠海站现场的分享《移动端分析方案在蚂蚁金服 mPaaS 中的实践》,介绍支付宝客户端自动化日志收集与分析的具体思路。内容将分成三个部分展开:支付宝客户端分析方案的探索;MAS 移动分析框架浅析;mPaaS 技术架构与助力。支付宝客户端分析方案的探索正如我们在《开篇 | 模块化与解耦式开发在蚂蚁金服 mPaaS 深度实践探讨》已经对支付宝的架构演变与开发团队规模发展做过介绍:截止目前,在研发上面,支付宝仅 Android、iOS 客户端开发人员近千人,客户端代码行数超过了数百万行,按业务划分的工程数也已近千个,每个工程都有独立的开发 owner 负责某一个具体的模块。虽然工程师团队及工程量越发庞大,支付宝依旧能够做到日发布的频率以确保业务快速迭代,同时在业务功能日益复杂的环境,保证 App 闪退率仅 0.01%。那么,在如此大体量的用户规模和研发团队下,支付宝又是如何确保用户使用过程中的用户体验呢?我们主要从以下两个维度衡量客户端用户体验:静态:指应用开发过程中,关注 App 本身的安装包大小、存储、涉及到的用户隐私权限、安全策略等,决定用户是否愿意安装并使用你的应用。动态:指应用发布上线后,用户在使用过程中,App 的启动速度,闪退、卡死卡顿等稳定性数据,网络请求,内存以及电量流量等用户实际的使用感受。启动应用是用户使用任何一款应用最必不可少的操作,从点击 App 图标到首页展示,整个启动过程的性能,严重影响着用户的体验。支付宝客户端作为一个超级 App,启动速度当然是我们关注的重要指标之一。支付宝对于应用启动过程中的优化,主要分为以下四个方面:框架治理:梳理启动流程并重构,遵守启动过程中按需加载原则。引用 Pipeline 机制,根据业务优先级规定业务初始化时机。制定统一的开发规范,尽量降低业务方流程对启动性能的影响。业务治理:按需加载,延时执行。线程治理:统一管理已有线程,并调整线程优先级。I/O 治理:关注主线程 I/O,优化合并频繁读写的 I/O 操作,尽量使用统一存储。技术突破:防止启动过程中的 UI 重刷操作。虚拟机优化,包括 JIT 关闭,降低 GC 次数。基础模块调优,分析主线程耗时操作并优化。另外,用户使用过程中 App 的内存、存储、电量及流量等消耗,也是重要的衡量指标。具体的优化点如下:内存:内存分析:memtrace hprof 线下内存分析,遍历对象,根据生命周期标记内存泄露,同时根据 object 创建引用确定业务归属。Native 内存:图像库切换到 native 层,4.x bitmap 像素数据放到 ashme 共享内存,降低 GC。内存优化:对象池复用,减小 bitmap 对内存占用,使用更小的图,尤其注意三方 H5 页面。存储:存储分析:查看应用存储大小。存储优化:使用共享库,业务定向优化,压缩存储等。流量:耗流量原因:分析各种网络请求。流量异常捕获:hook 所有网络请求,根据host聚合流量,超过阈值确定异常。流量优化:PC 底层协议优化,资源增量按需下载,同时通过切面信息调用方。电量:耗电原因:监控 CPU 使用率,各种 sensor、gps、weaklock、网络连接等耗电操作。耗电异常捕获:遍历线程,获取所有线程运行时间,与主线程比较确定异常。耗电优化:高性能 dump 线程栈优化,通过线程映射调用方,评估调用逻辑进行优化。针对以上每个优化点,支付宝都投入了大量精力进行研究和实践,有关启动性能优化的详细内容可以查阅文档《支付宝客户端架构解析:iOS 客户端启动性能优化初探》和《支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」》,其他优化点请持续关注“客户端架构解析”系列文章。基于这些对用户体验优化的内容,支付宝构建了一套完整的超级 App 线上运维体系,实时监控线上 App 发生的异常问题,针对这些问题,以最快的时间定位问题原因并找到对应的解决方案,最后通过动态热修复的技术及时修复线上问题,最终形成一个线上质量保障的闭环,保障应用运行的稳定性。MAS移动分析框架浅析接下来,详细介绍超级 App 运维体系中的移动监控框架具体是如何实现的。移动分析 MAS(Mobile Analysis Service)通过对移动客户端、H5、小程序、PC等多端埋点数据的采集与分析,实现产品核心指标监控,提供页面、设备、留存、性能等基础分析,并支持自定义事件分析、漏斗分析等高阶分析,帮助企业更好地完成业务监控、用户洞察与行为分析,指导产品迭代,精细化产品运营,辅助营销决策,加速业务商业化。主要分为以下四个阶段:整个移动分析的完整链路从左往右看,就是客户端通过调用埋点 SDK 的接口进行数据埋点,埋点 SDK 对日志进行格式化后,先写入客户端本地文件,满足日志上报触发条件后,将本地日志上报到日志服务器并清理本地日志文件以减少存储大小;日志服务器接收到客户端上报的日志后同步到计算平台,经过离线计算和实时计算后,将结果进行展示,用来监控、分析、搜索、推荐等。接下来我们将从移动分析框架的四个阶段,详细介绍数据分析的整个链路逻辑。数据采集根据采集数据时机、应用场景,最终用途的不同,我们把客户端采集的数据分为了以下几类。其中结合 mPaaS 模块化开发框架,报活埋点、押后台埋点、页面自动化埋点、性能埋点及 H5 埋点,由客户端 SDK 自动采集,无需开发者手动调用接口实现,开发者只需要关注自己的业务逻辑,在需要监控的逻辑除埋点统计。为了降低频繁上报日志对应用性能的影响,客户端采集到数据后,会预先保存在应用本地,通过以下三种方式同步到日志服务器:自动上报:满足一定条件后客户端埋点 SDK 自动上报,包括程序每次冷启动都会触发检查日志上报的逻辑。程序进入后台会立即触发上报。写日志时,某种类型的日志默认到达 40 条就触发上报。实时监控:对于比较重要的客户端日志,如异常、应用闪退日志等,可实时上报,产生一条上报一条,便于后台实时监控。动态控制:在自动上报的基础上,通过服务端下发的开关值,修改客户端日志写入和日志上报触发的条件。如在大流量并发的情况下,为减少日志服务器的压力,控制客户端只写入并上报异常或闪退日志,忽略行为日志的统计。数据计算上报到日志服务器的日志,会同步到计算平台进行计算,后台主要包含以下几个系统:mdap:日志采集网关,负责收集客户端埋点日志,收到日志后,直接传输至 JStorm 集群进行计算。JStorm:实时计算引擎,根据处理规则对日志进行实时解析并将需要的数据存储入库。SSDB: kv 数据存储层,底层使用 leveldb,支持单表十亿级记录。ZooKeeper:集群管理、组件间服务发现。数据应用计算平台计算出来的结果,可以为用户提供用户分析、事件分析、行为、性能等数据分析服务。基础分析:关注于 App 的通用分析,包括每日登录用户、新增用户、使用时长、用户留存、页面分析、访问路径等基础分析。高阶分析:用于 App 专注业务的特定分析需求,提供一种灵活的多维分析能力;提供热修复报告,帮助您了解 RPC、修复、回滚相关信息等。性能分析:提供闪退、卡死、卡顿的统计功能。当客户端发生性能问题后,移动分析服务提供实时查看性能分析的统计数据。日志管理:支持按关键字实时搜索查询日志,或通过服务端开关实时控制客户端日志上报逻辑。数据决策在上一步数据应用的基础上,可以与大数据、营销平台及推送平台结合,根据移动分析得到的埋点数据,通过大数据平台进行打标、圈人、用户画像及建模后,可以在营销平台上发起一次营销活动,指定活动的类型,活动算法,参与人群及活动奖品,通过消息推送、数据同步,动态发布等形式,触达到客户端,实现客户端拉新促活、活动推广及操作引导的目的。同时结合运营活动的场景需求,形成了一套完整的数字化运营体系,监控一次运营活动的参与人数、活动发放率、核销率等,观察活动的有效性。mPaaS 技术架构与助力上面介绍的支付宝内移动端分析方案的技术积累和架构实践,已经通过 mPaaS 移动开发平台作为蚂蚁金服金融科技的一部分对外开放。mPaaS(Mobile Platform As A Service),源于支付宝 App 的移动开发平台,为移动开发、测试、运营及运维提供云到端的一站式解决方案,能有效降低技术门槛、减少研发成本、提升开发效率,协助企业快速搭建稳定高质量的移动 App。在 mPaaS 移动开放平台上,我们将移动分析框架中的本地日志、埋点、自动化埋点、性能监控、Crash报告、诊断日志等模块,作为一个个独立的组件来进行输出。任何一个 App 都可以通过 mPaaS 插件,添加对应的组件,在当前应用中集成这些功能,只需要这样简单的操作,就可以让你的应用具有和支付宝一样强大的移动端分析监控能力。客户端集成了这些移动分析相关的组件后,用户在使用APP过程中会产生相应的日志,经过数据采集、数据上报、数据计算等处理后,计算的结果会同步到 mPaaS 移动分析的大盘上展示,包括应用的基础应用概况、性能稳定数据、流量走向等等,方便开发者实时监控 APP 的概况大盘和稳定性等,实时发现线上问题并修复。目前,mPaaS 移动开发平台已经服务了众多企业,包括蚂蚁金服内部的香港支付宝、网商银行、口碑商家等,同时还有大量的外部蚂蚁生态合作伙伴,包括12306、上海地铁、广州地铁、广发银行等。秉承着「给世界带来小而美的变化」的理念,我们通过 mPaaS 帮助 12306 这样的国民级 App 重构了客户端,使得大家可以用上一个好的体验的 App 进行出行购票,用 mPaaS 这样成熟的底层框架搭建一个 12306 仅需要 2-3 个月的时间。除了 12306 还有支付宝香港版,广发银行手机银行和发现精彩多个客户端,同样在短短几个月的时间内便完成了业务重构。蚂蚁金服ATEC城市峰会·上海2019年1月4日,一场金融科技的前沿探索之旅——蚂蚁金服ATEC科技大会即将起航,你准备好了吗?小蚂蚁为大家准备了满满了攻略福利,等你来拿!了解蚂蚁金服ATEC科技大会更多信息,记得持续关注小蚂蚁(官微:蚂蚁金服科技)蚂蚁金服金融科技官网:https://tech.antfin.com/artic…ATEC科技大会:蚂蚁金服ATEC(Ant Technology Exploration Conference)科技大会是蚂蚁金服在中国举办的最大的技术盛会,旨在向遍布全球的合作伙伴与技术专业人群分享新技术的发展趋势与落地实践,通过对先进的前沿技术探索与讨论,为世界带来平等的机会。ATEC大会一直在路上。过去一年,蚂蚁金服ATEC科技大会走过杭州、硅谷、新加坡、伦敦等全球金融科技中心城市,之后将会造访国内各个金融科技中心城市,与当地受众分享蚂蚁金服对金融科技最前沿的洞察。ATEC科技大会报名方式 & 福利:本次大会门票采用审核制。嘉宾填写个人信息进行报名,报名后3天之内收到报名审核成功的短信,即为报名成功。大会报名截止日期为2018年12月31日24时,额满即止。前50位报名嘉宾将会优先审核通过,先到先得哦~小蚂蚁还为大家准备了本账号读者的专属福利邀请码: SF2B3A 还等什么,赶紧点击下方报名链接,小蚂蚁期待你的到来ATEC报名链接:https://alipaytech.mikecrm.co… 本文作者:平生栗子阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 19, 2018 · 1 min · jiezi

阿里巴巴智能监控新场景的探索

摘要: 智能监控是智能运维的子领域,详细分析。作者简介王肇刚:阿里巴巴全球运行指挥中心高级技术专家智能监控是智能运维的子领域,我们说的监控,探讨的更多是在监控策略,因为可能从数据采集、日志收集、包括计算等等产生数据,再设定一些判断的规则和策略,发送报警,这些都属于监控。我和我的团队在阿里内部的分工是横向去看阿里巴巴业务指标的监控,我们就以这个话题展开。分享分为五个环节,从阿里巴巴不同的业态,特别是新的业态带来的挑战讲起。对于我们之前已有的基于机器学习算法这样一个算法工程架构,我们做了哪些增强应对这些挑战。我们的监控也从单一指标监控延展到多个指标一起监控。监控完了之后,我们可能要分析定位,这时系统又能帮运维工程师做什么,这是第四方面的话题。最后是对智能运维整个领域做一些展望。一、新业态给业务监控带来的挑战上图是阿里巴巴不同的业态,有比较传统的电商业态,右上角是国际电商,蚂蚁金服还有阿里云。最近这段时间阿里在收购各种各样的公司,也是商业的布局,我们会看到优酷、钉钉等等。我们团队在阿里巴巴内部是负责横向的业务指标监控,这个有什么差异?技术层面也是通过日志的采集流程计算看一个指标下跌还是上涨,区别在于只要业务发生了不可用或者发生问题,我们希望都能够发现,而不是说阿里巴巴本身的系统出问题了。举个例子,如果阿里巴巴一点异常都没有,但是电信可能有问题,这个时候我们希望知道。它是从对于业务数据量实时的监控。因为阿里巴巴本身的业态是很丰富的,有这么多的业态,我们看到的数据也很丰富。上边这个图,大家可能看到的这些 Logo,看到购物或云计算的一些业务,但是团队做智能运维算法的同学,看到的就是右边这种奇形怪状的曲线。我们团队在阿里内部是横向团队,第一环节就是需要能够精确、及时的发现业务是否有异常。为了达到这个目标,我们引入了称之为智能基线的系统,这个系统可以在网上搜索到。这个系统效果还是不错的,能够在没有任何阈值或者规则输入的情况下,自觉做预测。同时有些业务发展比较迅速,我们可以比较好地在历史的长期趋势和短期的业务沟通之间,做出一个相对较优的折中。业务变化之后,假设你以前配了阈值还要改,智能基线不需要改。阿里巴巴几千项业务指标,通过人工的检查验收之后的准确率是在80%以上,这个数字每周都不一样。而对比传统的工程师通过传统的静态分段阈值或者环比的方式,准确率可能只有 40% 左右。大家可能也会看到特别对于业务量监控,可能 10 条报警里面,4 条真的觉得有问题已经不容易了。阿里有很多不同的业态,所以一套系统解决所有问题还是挺难的,因为不同业态之间的差异还是非常大,数量级、波动、周期均有差异,包括现在有新零售业务,它是把线上线下的业务结合起来,而且非常强调线下。比如盒马鲜生有几百家门店,这是个商业的尝试,对于做运维监控的同学也带来很多挑战。比如淘宝和天猫的某些交易量在分钟级别是万或十万或更高的数量级,这个可能就是百或几百,波动的量级和原始量级在一个量级上,这个就比较难处理。包括周期性,对于一般的在线服务,是7X24小时提供服务,每天什么时间流量最低?国内业务凌晨四点钟最低,这个会受门店的开关门影响,因为零售是有时间的。我们如果线上刷淘宝下单点一下就行,线下不一样,一对一排队结账。而且在量小的情况下,很多时候不能看单一指标,许多指标要一起看,所以就给我们之前的算法提出非常大的挑战,我们需要做新的算法演进。大家可能会问为什么整这么复杂的算法。配监控,配规则不就可以了吗?其实是可以的,但业务太复杂。作为一个横向团队,算法工程师可能只有三四人,七八个人要面对阿里巴巴集团成千上万的业务监控指标,不可能了解每个指标的所有细节,这个时候是没有办法用人,我们要用机器学习的方法去做。二、增强版的时间序列异常检测实战接下来讲讲怎么用机器算法解决问题,这是一年半以前我们采取的架构,我们能从业界很多文章上看到类似的架构。我们希望做一个基线拟合,这个曲线应该是什么样,我们说异常这两个字就是异于平常。我们第一步想知道正常的曲线是什么样子,所以我们做基线拟合,我们用STL做这样的方法,我们用比较传统的 N-sigma 做调整。这种架构其实能解决 60% 左右的问题,但是有些极端的情况解决不了,所以我们就把架构做了演进。我们第二代的架构做数据预处理,然后又做了比较简单的滑动平均,数据有时候会缺点,不管是采集侧的一些不稳定因素,还是计算一侧出现了问题,导致你希望一分钟出一个数据点,但是最后还没有算出来。这种情况应该从工程上解决,所以我们会在算法层面做一些脑部的算法策略,就是即使缺了能补回来,但是不能长时间缺数据。下面的逻辑就走了机器学习的思路,我们对曲线做特征工程。我们之前的基线拟合的这种预测只是我们特征工程中一部分,对于重要的部分,我们也会把一些统计特征编码进去,当然也会把一些时间特征编码进去。因为我们知道很多电商的业务是有定期促销的习惯,比如淘宝的交易量每天早晨十点一定会有阶峰,大家不知道在抢什么东西。算法层面怎么解决?我们把每天的这个时刻第几小时第几分钟,通过热度编码的方式做到里面去,就可以让算法学到这个时间点这样一下可能是正常的。我们后面采取了不同类型的统计学的判断和做法,最后做成集成策略,大家可以理解为简单的投票策略。它其实给我们带来了比较好的一些算法的效果,比如说基线拟合会更准,对于不同类型的异常进行判定。很多时候曲线有不一样的异常,如果用 N-sigma 的方式,你的刻画表现能力是不够的。即使是这样,对于遇到的新零售业态,我们觉得还是不够。因为你看刚才的算法能解决一般性的问题,但是对于曲线问题差异很大的时候,之前的预处理就需要增强,量级从十万左右到几百万,你的预处理策略需要变化。很多曲线不具备周期性,或者周期性非常零乱。比如我们有一个业务比较奇怪,大家在淘宝上有没有充话费?这个是天、周、月三重周期,天的话基本没有问题,周的话工作日和周末是有差异的,月这个周期,因为大部分人是在月末报警了或者月初充。最后一个线下的业务对这种异常很敏感,在这种情况下我们用一套算法策略是解决不了不同问题的,所以我们做了第三次优化。我们先引入了一层算法路由,希望能够通过机器学习的方式,把不同的曲线归到不同的算法路由里面去,这样的话不同的曲线走不同的处理路径,那么效果会很好。我举三个例子,比较周期性、非周期性、百分比的指标等等,这些不同类型的指标方法都不一样。在这些不同的方法之后,我们还是觉得算法也许解决不了所有的问题,因为算法对于大多数运维工程师来讲,不见得那么方便去调参数,所以我们也开放了三个参数,我们会看它不同的抑制时间、发布策略和敏感度。分开来看,算法路由,这个工作的目的就是说让算法自动把数据分类,这一块也不一定非得用算法,用人就可以,但是因为量太大,所以人工的成本很高。这里我们用了深度学习的算法,上面那个图是网络的图,我们使用了孪生网络,两边都是LSTM,所以我们用了双向的网络结构去把我们标记为一样和不一样的,最终能够区分开。在这个基础上,我们做了一个分类模型。这块从技术层面来讲,不用特别复杂的算法,我们用这个算法就是想探索一下,实际大家真正做的好的话,比如你用一般的分类方法,用我们最直接方法也可以达到类似的效果,但是我们这里尝试了一下。分好之后有个工程架构,以前是说不同的算法场景走的处理逻辑都是一样的,里面的参数可以不一样,后面不同的处理逻辑像插件一样可以去做组合,这个组合的变化频度不会太快,但是一般变化成本都很低。这样以前是三条通路,我把插件的参数和顺序和有没有插件做一个变化。有了这个之后,对于阿里巴巴成千上万条,但都是到万这个级别,不会再多。大家会想这个东西可能是从业务角度监控的,从惯性思维来看,我们可能会是想监控 CPU 或者某个接口调用的超时,这些也是可以的。我们也探索了在系统级指标或者非应用级指标做这个尝试。它的周期性不太明显,第二个这个指标的变化跟业务行为关系不那么大,运维的决策对它的曲线影响大于业务的影响。最后一个就是标准不统一,你觉得这个可能需要报警,别人可能觉得不需要报警。我们采取了一种轻量级的方式去做检测,可以做到自动学习。它跟上面那套算法相比在于它比较轻,可以做成一个包的形式,嵌到监控系统中去做监测。它的效果如上图右边显示,我们内存中有奇形怪状的异常,这个算法逻辑还是比较简单的,不用太在意算法本身的框架,因为这些算法你可以替换成其他的算法,但可能需要考虑在数据进来之前做比较好的预处理。第二个可能你需要基于统计特征和那些曲线本身的特征,影响你的特征工程。最后孤立森林不是说基于用户的标注去做的,因为实际场景中我们不可能像做人脸识别这样给我们标注。什么参数微调?第一个是说抑制报警的时间,这个很容易理解。第二个防抖动策略,这个也很容易理解,就跟过去 N 分钟有 N 条报警是一样的,所以我们概括成N/M。最后一个是报警灵敏度。这个在我们市场环境中测试的效果大于70%,现在这个数字可能稍微好一些。最终怎么评价算法?还是要看人标的。比如说我们有十几位同学评判,他们的标准也不统一。甚至一个人今天说这个点标的对,第二天忘了再看一遍就说标的不对。所以说以上是我们介绍的关于单个指标,不管是系统级的还是业务级的指标,怎么通过机器学习的方法,做不用任何监控阈值配置和维护成本的智能监控。三、多指标关联分析的探索刚才也提到了在新业态下,很多时候我们只看一个指标是没有办法判定业务有没有异常,或者我们发现指标和指标之间是有关联的,这个在实践当中也会遇到。有时候两个指标都出了问题,这时这个信息能不能被利用,我们也做了探索。这个东西有一个业务背景,就是我们刚才提到的看一个指标不够,我们经常在一些业态里看到会监控某一个业务的成功量、成功率、失败的错误请求数几个指标相关变化。有时候会发现指标有异常传播,这个传播有几种方向传播。比如说在不同的业务之间传播,比如因为两个程序之间有关联关系,A坏了B也影响了。还有就是混合部署的情况,同一个集群布两个业务,A被打爆,B也被压死了,也有这样的情况。我们怎么做这个事情?分为两步。第一步我们希望发现和维护相关的指标,就是哪些指标应该有关联的,发现之后要维护。一旦我们掌握这个信息之后就可以做两个事情。第一种我们能够把这些相关指标放在一起判定业务是不是异常,而不是只看一个指标。第二种我们单指标能看的很准,但这时候我想知道为什么会下跌,虽然给不出因果,但是可以给出相关。业务指标之间的相关性其实有不同的类型,比如上下游之间有监控项,比如我们在阿里做过一个实际情况,大家看淘宝搜商品,如果出现异常大家就搜不了东西,我们的淘宝详情页的浏览量和下单量都会下降。不是说搜索的程序或者应用服务掉了那个服务,它们之间没有关联,但是很多用户习惯了搜而买。一但搜挂了,很多用户不知道怎么买了。所以这样的关联靠系统内部是拿不到的。包括业务不同分量的监控,比如河南省播放成功率和河北省播放成功率之间的关联。这种关联我们怎么发现?一定是靠人工梳理,但是对于阿里的体量,一个是梳理不过来,第二个梳理以后过两天又变了。阿里集团可能每天的业务发布的频次是千级别的,那怎么办?还有第三种方式。第一种利用 CMDB,我们通过CMDB看到哪些应用之间可能相关。第二个通过 时间序列相关性 发现了方法,这个跟刚才提到的卵生网络的方法是类似的。但从实际来看,一般是在第一个检测的基础上,再在局部做第二个,而不是全局的检测。第三个我们利用关联规则挖掘看哪些项经常关联报警。我们可以通过算法发现这些关系,这三个方案其实是互补的方案。所以有了这三个方案后,就可以把很多相关的指标放在一起监控,方案取得了较好的效果。在盒马鲜生,基于我们上面做的新的算法,单指标架构和多指标关联架构,能够把监控发现率和误报量做非常好的提升,这就是我们在新业态下通过单个指标的算法和多个指标的算法取得关联效果。四、故障影响面和根因分析的探索之前都是关于监控的部分,监控是为了发现问题,但是发现完了问题,很多时候是需要想怎么能够解决问题的。我们在故障根因的推荐层面做过一些探索,但这个也只能是探索,供大家参考借鉴。首先我们看一下故障原因分析问题的范围和边界,我也跟很多工程师交流过,凡是做运维系统的工程师都有一个梦想,就是我想做一套系统,一旦我的业务出问题,告诉我问题原因在哪,这个非常理想化。但在实际过程中,这个事情是非常难解决的,探索来说在阿里内部也解决地不好。虽然解决的不好,我们也做了一些探索。为了避免我们做的事情不符合我们老板或者客户的预期,我们需要先把能做什么说清楚。我们很难做到淘宝交易量下跌了,我告诉你哪个代码有bug,这个做不到,但是我们能做到缩小影响范围。这个为什么有价值?因为阿里巴巴有两到三万名工程师,半夜两点出了问题,我打电话叫起来就是一个非常复杂的技术问题。首先要从阿里巴巴几万个应用程序里,先要看这个业务故障到底跟哪几个应用相关,这个都是非常典型的问题。我们的目标是能够从站点、产品线和业务功能指标出现问题的时候,能够定位到应用服务层,包括数据库这层。这个架构就是能够锁定这个范围,然后之后的事情可能需要更细致的方式解决。另外一个好处,我们可以对故障做一个结构化的快照,除了阿里巴巴,我看到很多公司也会对故障做复盘做改进措施,但是没有形成很好的流程。但是在阿里我看到过去大大小小非常严谨的复盘和故障记录,包括非常多的细分的环节和字段,这个非常好,因为以后的故障可以从中学些东西。但是有个遗憾,这些东西全是用汉语写成的,长篇大论几千字。人可以去读,但是比如阿里有另外一个工作叫全链度压测,我们要对去年的业务优先进行测试,这个时候我们要挖掘到底哪些有问题。挖不出来,为什么?都是汉字写的。汉字写的话,它的表述、格式,都是很难被机器理解的。如果做的这件事情以后出故障,我们尽可能地把故障做一个结构,这个不仅对这次故障的本身,对以后故障的防范都有非常大的价值。怎么做?如上图所示,我们会有一个主的抽象流程,当我们的前面算法发现问题之后,我们会尝试找到跟这个业务指标相关的应用和它的中间件以及数据库,以及相关的网络服务器IDC。我们建立了一个囊括阿里主流的所有运维相关事件的这样一个数据仓库,阿里内部可能有自己的这种事件存储的机制。这个数据仓库能够告诉我们在哪些运维的对象上发生了什么事情,最后我们对这个事情做一个排序和筛选,把可疑的挑出来。逻辑还是比较清晰的,但是真正做的时候发现有很多具体的环节需要考虑。比如你怎么找到监控项关联应用,淘宝交易下跌了,你怎么知道是阿里的几万个应用中哪个应用造成的问题?这个其实也是比较难的问题,我们也没有解决太好,但是可以看到思路。最直接来讲,我们通过监控系统本身的配置来得到。我们的业务指标能画成一张趋势图,能做监控,因为背后有逻辑计算,有日志的采集等等。这些系统的工作,是因为加监控的同学已经把监控怎么采集配置进去了。但是它有失效的时候,比如说两种情况。一种发现业务环境非常强,ABC三个程序不断做处理,最后把结果打到第四个程序上去了。所以你通过这个,能得到第四个应用的名字,前三个应用其实跟这个业务非常相关,但是你从这里读不到,所以这是我们要解决的。第二个有一些应用本身是用来监控的,比如阿里的客户端,它会上报到某一些监控系统,这时候监控系统画出来的曲线,其实跟监控系统本身相关的,而不是跟产生监控数据的应用相关的。这种情况下,这个方案就失效了。这个时候就需要通过人工配置的方式解决,目前是这两种方式结合在用。刚才说的第一个问题,我们也可以通过阿里巴巴的中间做的系统去解决这个问题,包括我们也可以通过算法,对于报警做平台挖掘,可以挖掘出来像刚才搜索框下跌,导致交易量下跌的关系等等都可以挖掘出来,这个东西也是补充的方式。但是最核心的不是算法,最核心的是CMDB如果维护得好,比什么都好。通过刚才那个思路,能够把我们的业务指标跟应用结合起来,但是很多时候应用经常是无状态的,状态存储在数据库集群里面,这个时候还是经常通过CMDB解决这个问题。还有比较难的问题,就是网络跟应用程序的关系,有一个机房出问题了,经常我们是混合部署的,所以这个时候问题其实是一个非常散的关联,这个问题上我们解决的也不好,所以我们只能把这个信息当成一个缺少的信息推荐出来,供大家去决策。比如说不管阿里什么业务出了问题,我们都会把网络最近出的一些异常点或者事情推送出来,提醒大家是不是这个问题,但是这块很难做到精细的管理。我们知道了哪些运维实体跟业务有关联之后,还要知道这些运维实体上、程序上、集群上、网络上发生了什么事情?那这个事情我们怎么知道?我们会建立一个在线的数据仓库,它能够不断地抓取来自于各个运维平台和系统中的不同格式的事件。这个抓取之后不是简单放一块存,还要建立关联索引。阿里有很多不同的横向纵向的系统,他们的数据格式的字段都不一样。我们尝试做一个翻译,在当中找到了两三个大家都能看懂的词。比如钉钉应用,这在阿里内部非常稳定的。第二个IP地址,这个也是很稳定的。但是这两个之外,格式语言是不一样的。我们把数据仓库建好之后,输入开始时间、结束时间和应用列表三个关键词,就可以查到这段时间内实体发生了什么事情。我把事情都推荐出来是不是就解决了?还不够。我给大家分享一个数字,在阿里巴巴内部,像这样的事情一分钟发生四千到六千次,也就是说一个故障如果持续了十分钟,就是几万个事件,所以我们还要再做筛选。这个时候就会通过一些方式做筛选,我们会根据哪些运维实际上发生了报警,把这些实体的信息优先放在前面。怎么知道有跳变?我们会对怀疑的对象做系统级指标的扫描,扫描出来跳变就排到前面去,所以有了这个之后就可以相对精确地缩小范围,当阿里巴巴淘宝天猫有异常的时候,我就可以知道。我们能够从上面看到,最上面这个环节是同一个时间内有多少业务的多少点在报警,红颜色的时候,可能就是某些业务出现短暂的异常了。我们会感觉 CMDB 加平台化算法对报警压缩合并,看到了集中在优酷、集团客户体验、菜鸟这三个业务功能上。这个其实就是刚才讲的多指标关联分析的作用,这时候我也不知道是不是因为它导致的,但是他们之间是相关的,这个可以帮助我们定位。最后我们能够根据刚才说的逻辑,把跟这个事情相关的前五个或者前十个应用程序推荐给你。为什么推荐给你?要么它发生了一些骤变,要么发生了一些大的业务操作。很多时候可能百分之五六十的业务故障,都是发布新功能或者改配置改错导致的。做的比较好的地方,可能能够做到70%以上的推荐准确率。但是也有做的不好的,百分之三四十的准确率。因为阿里业务很复杂,每个环节每个业务都有不一样的方式。但是这个方法,我认为还是一个值得推广和借鉴的大逻辑上的思路,这个就是我们介绍的监控发现问题之后,我们在根因分析层面有哪些探索和思考。五、智能运维在故障治理领域的未来规划最后希望能够和大家一起探讨一下在智能运维领域现在与未来可以做什么事情。运维本质上是解决在线服务运行中的质量、成本和效率三方面,运维不是从上到下的思路,包括我也参与了白皮书的工作,我们也跟其他业界的同事探讨这个问题,不是说有一个顶层规划要怎么做,实际是在这些点所处的具体环节上,很多工程师开始尝试用算法的方式解决问题,逐步汇集成一个数。我们现在在上图左边那条路做了一些探索,已经在业务中用起来了。最早的探索,其实在阿里内部已经稳定运行了接近两年时间,也是效果在不断演化演进。最近我们也在探索右边这条路,就是无人值守相关的东西。出问题的时候很多人问淘宝的故障恢复了没有,支付宝有没有受影响。靠自然语言提出的问题,是不是可以通过机器人回答你,这个也是我们探索的。当然现在还不敢做全自动,还是我们列出来你再确认一下,但已经比你调出系统然后跟很多人沟通半天决策要方便一些。所以其实不仅是在质量领域我们做智能化的监控,智能化的根因分析,其实在节省人效率层面,也可以做一些探索。中间这块跟成本相关,这块在阿里巴巴有很多团队做这样的事情,也可以通过智能化的调度能够做容量预测,优化包括硬件采购的周期,预测你服务器增长怎么样。或者在实施的时候,通过自动化的调度策略,节省服务器的资源。所以其实智能运维这个概念,在今天已经不是个概念,它已经在我们企业实际工作中,有非常多落地的点。希望今天我的分享,能给大家有一些借鉴和参考,我们一起建设智能运维美好的明天。说明:以上内容为阿里高级技术专家王肇刚在 GOPS 2018 · 上海站的分享。本文作者: 王肇刚阅读原文本文来自云栖社区合作伙伴“高效运维”,如需转载请联系原作者。

December 12, 2018 · 1 min · jiezi

跨境物流链路怎么做?菜鸟工程师打造了全球通关“神器”

阿里妹导读:2018天猫双11物流订单量创新高,突破10亿件,这是一次史无前例的物流洪峰。天猫双11十年来,见证了物流业从手写地址、人工分拣,到电子面单、机器人分拣。无论是物流园区、干线运输,还是秒级通关、末端配送,都通过技术高效连接,智能物流骨干网正在加快实现行业数字化、智能化升级。因此,阿里技术推出《菜鸟智慧新物流》专题,邀请菜鸟技术人,为你揭秘物流核心技术。今天第一期,让我们一起走近神秘的“神鲸网络全球通关平台”,全方位了解新技术时代下的跨境智能关务。前言“跨境”,这是在当今行业一个非常 fashion的名词。从2014年起,海关总署陆续颁发多项跨境贸易政策,给跨境进出口业务带来了诸多红利。2014年也被很多业内人士称为跨境进口电商元年。也许你会听到这样一段对话:A:Hey,兄dei,你是做什么的?B:哦,我搞跨境物流的。A:是嘛,跨境这几年很火啊!政府在大力扶持这一块,我看很多公司都在做一块,有前途!B:哪有?道路坎坷,很艰辛的,不过累并快乐着,我也挺看好这块的!在整个跨境物流链路中,会涉及到多个角色:仓、干线、关务、快递等。关务是跨境物流链路最核心的环节,需要协同海关,国检等政府部门完成整个进出口国的通关操作。这块不仅业务复杂,而且存在诸多不确定性。为此,我们搭建了“神鲸网络全球通关平台”。旨在对接海关,协同CP(cainiao partner),从线下到线上,以全球化、数据化、智能化为方向,以快速、轻量、多态为核心目标,为跨境电商客户提供全球一体化的通关解决方案!痛点和挑战如下是整个通关全链路业务流程,包含资质备案、风控、出入区、跨境通关、税汇等核心领域。整个链路交互节点繁多,不同国家,甚至不同监管区在申报模式,交互方式,通关能力上都存在很大差别,另外由于申报链路冗长,任何一个节点出现抖动都有可能导致整个通关发生异常,进而导致申报时效拖长,为保障用户能够正常通关,我们往往需要投入更多的成本去解决申报链路过程发生的种种问题。所以,如何有效使用海关通关能力,给到跨境商户稳定的、高效的、统一的一站式通关解决方案?这是我们需要攻克的核心难题。应对策略通关异常繁多,申报时效冗长,大促成本飙高是大部分跨境通关企业碰到的问题。如何去异常,打时效,降成本,保障通关丝般顺滑?基于此,在神鲸网络通关平台中,我们做了诸多举措,有一体化监控的星宫大盘,阳关道批量申报,政企协同全链路摸高压测以及守护神智能辅助系统等等。今年的双十一大促上,因为有这些强有力的后盾,加上海关通关能力再创新高,大家在喝茶+聊天中度过了一个轻松愉快的双十一。今天,我们重点来交流下星宫大盘、批量申报和智能辅助系统。星宫大盘,一体化监控整个通关链路长,依赖系统多,如果有一个全链路的监控系统进行护卫,不仅可以实时窥视整个链路流转情况,还可以做到异常的实时跟踪处理。为此,我们搭建了关务数据中心,承载关务所有数据,并依托它构建了整个星宫大盘产品,将业务监控,指标监控,系统监控一体化,真正实现360度无死角主动监控。如下图(注:下图中数据非真实数据,仅做示例):数据中心数据中心涵盖了整个关务生态的数据,通过实时+离线两种方式,很好的支撑了实时业务监控和指标监控等核心业务。如下是整个数据中心核心架构,包含消息接入,指标计算,数据存储等核心模块。作为一个数据产品,最基本的的诉求就是能保证数据实时性、准确性,那怎么在大促情况下能够做到99.99%数据准确性?这是数据中心面临的最大的一个挑战。实时性(秒级生效)业务系统通过消息埋点的方式记录各个链路节点数据,通过阿里消息中间件消息异步推送给数据中心。数据中心拥有一个支持水平扩展的庞大的服务器集群,具有强大的消息处理能力,保证消息的实时消费。通过缓存+异步存储的方式提升整体消息处理能力; 存储之前先往缓存存一份,后面热点查询优先从缓存获取数据,提高查询效率,数据插入如果超时或者失败立即创建调度任务进行异步重试插入。准确性(99.99%)由于关务业务特殊性,星宫需要保证监控数据的准确性,传统的方案一般是通过流计算的方式把数据统计出来,这种方案统计和详情数据是分开的,可能会导致数据统计和真实数据存在误差的情况,这对于星宫来说是不可接受的。为此,项目组另辟蹊径采用实时详情数据聚合的方案,这里,我们引入了ES中间件,阿里中间件团队针对ES做了非常多的优化,具有高性能的聚合能力,支持海量级数据的实时聚合。另外我们在数据结构存储上面做了多层优化,比如:热点查询条件用int来逻辑映射,字段存储底层采用列存储。为了加快检索,存储树形结构把目录加载到缓存,犹如数据字典一样。另外为了保证数据消费不丢失,在客户端启动了多层重试机制,保证数据的最终一致性。今年大促上,数据中心表现出色,双11当天QPS达到40000+ 平均耗时11ms,正是这种强大的数据消费能力保证了星宫数据实时性,另外亿级别数据多维度聚合统计基本上都是秒级返回,真正做到了100%可用。批量申报,独木桥变阳关道由于海关各个节点大多采用MQ+FTP的技术架构,文件数的个数会影响整体通道消费能力。另外总署的56号公告要求四单申报进行加签操作,随之带来的将是验签成本的增加。为减轻总署通道压力,并提升验签能力,我们采用了批量申报的策略,简而言之就是将多个订单聚合到一起进行申报,一次加签操作,一次申报动作。如下:批量申报调度模块自研了一个轻量的批量调度框架实现,通过一个任务池汇总所有任务,按照不同业务规则聚合同类型的任务然后进行消费。如下:记得当时该项目刚上线时,还有一个小插曲,压测下来发现整体性能远远达不到要求,这可急坏了整个项目组。任务消费过程大体分为:分页捞取任务-》锁定任务-》消费任务。其中捞取任务和锁定任务过程是通过抢占分布式锁的方式来防止并发,避免同一个任务被多个线程捞取并消费。正式由于这个分布式锁的限制以及单库单表的DB瓶颈,导致整体性能一直上不去。经过讨论,最终我们采用了分布式锁池+DB散列方案。即既然单个分布式锁无法满足要求,那么设计成锁池好了;既然单库单表存在瓶颈,那按照业务关键字进行散列。分布式锁池我们使用的是redis的Set数据结构+spop和sadd命令实现的,应用启动时初始化指定个数的锁放到Set数据结构中,然后通过spop随机获取一个模值捞取任务,任务锁定后再通过sadd返还锁,插入任务时也是通过锁个数进行随机散列到多个库多个表中。通过该机制改造后,整体性能大大提升,数据库压力也降低了好几倍。这次微小的调整,却带来了巨大的性能提升,在今年双十一大促上,批量申报也是大放异彩,整个通关审单时效大大降低,申报能力相比往年也有质的提升。如下是17年和18年双十一某一属地海关的平均审单时效对比,相比17年,今年的平均审单时效非常稳定,基本保持在20分钟以内,海关上行和下行通道毫无压力。如下是某海关30分钟内审单完成率情况,相比往年,今年审单能力有巨大的飞跃,基本上是零堆积,申报速度跟审单速度几乎持平。智能辅助系统,关务守护神今年是关务的智能化元年,在正向申报链路上,我们推出了智能限流与智能hold单产品,自适应保护自身与海关系统。在人工成本降低的同时,保证了海关系统的最大吞吐能力。在异常处理上,我们基于规则引擎上线了异常智能处理系统,通过不断丰富异常处理规则,系统变得越来越聪明,基本上可以自动处理大部分海关异常。同时,作为关务智能大脑,还为关务数据中心提供数据分析服务。智能系统包含产品如下:智能限流整个智能限流的设计不仅支持集群环境下任意接口秒级与分钟级精准限流,还能根据接口的RT与失败率等指标对接口流量进行动态调节。1.技术架构:智能限流分三个主要模块:资源监控(对资源的请求量精准统计)、限流策略(请求量达到阈值后的操作)、智能调控(依据一定的规则与算法调节)。智能限流整体采用了pipeline的设计模式,目前实现了单机限流、集群限流和自适应限流三个阀门,只有全部通过阀门,请求才能被放行,否则就会被拦截。这种设计便于维护以及后期限流策略的扩展,例如在双十一之前紧急增加的集群分钟级限流(开发测试仅半个人日)。单机限流和集群限流都是固定限流,即人为提前设定好接口的限流值,如果请求量超过这个值,便会被流控。人工限流的关键是对请求量的精准统计。动态限流则会依赖一些指标进行实时计算和分析,系统按照一定规则自行判断是否需要限流,这个限流是将接口能力分为档位进行调整,既会下调,也会自动上调恢复接口的能力。2.资源监控资源监控是指统计某个接口的各种指标,包含请求量/失败量/限流量等,这些指标基本上是在单台机器上的统计。但是在限流场景,单机限流仅仅能保护机器本身,对于下游的保护,还是需要集群限流功能,因此还需要对集群环境下的资源访问统计。单机指标统计单机指标主要是基于滑动窗口的原理进行统计,比如QPS(每秒的请求数)的统计是将1秒分为5个时间窗口,每个窗口统计200ms内的请求,最后做累加。单机指标监控主要是做单机限流,单机限流的最大好处是能够保障单台机器不会被上游压垮。而对下游而言,单机限流可用性较低,对集群数据来说准确性不能保障。集群指标统计我们不仅仅要保护自己,还要保护下游系统,因此需要保证集群环境下给到下游的量是精确可控制的。集群指标统计需要借助分布式缓存实现,通过使用incr原子累加功能,实现在分布式环境下对请求量的统计。针对QPS的统计,缓存的key由接口名称+秒级时间戳(yyyyMMddmmSS)组成,例如:xxxx_20181118012012。集群统计的准确性依赖两个点:一个是分布式缓存的性能,另一个是分布式环境下每台机器的时间一致性(NTP网络可以保证)。智能限流的缓存使用的是阿里集团的tair(MDB),单次读写平均在5ms以内,对于并发量不是特别大的业务系统来说误差完全可以接受。3.限流策略通过对资源的准确监控,人工固定限流比较容易实现,只要比较下当前的实际qps值和设定的qps值大小即可,达到设定的限流值该请求就会被终止(目前通过抛出指定类型的异常)。无论是秒级还是分钟级限流,只是监控的粒度不同,即统计的key的时间戳的区别,对于限流的逻辑完全一致。在限流时,我们还会进行主动通知,便于人工干预。异常智能处理异常智能处理主要是在日常和大促后的扫尾阶段发挥重要作用。它以关务知识大脑为核心,协同CP、小二、系统共同高效解决业务异常。处理的异常越多,沉淀的就越多,系统也会越来越智能。关务异常存在繁、杂、多、变等特点,如果靠人工去处理每一个异常订单,需要投入巨大的成本,时效也无法得到保障,在大促期间,异常订单量更是以百倍级别增长。技术是第一生产力,我们需要机器代替人工处理这些异常,系统自动处理也就应运而生。然而,经过不断的实践证明,短期单纯依赖系统自动处理所有的异常是不现实的,有部分还是需要人工介入(比如备案问题),然后再利用系统进行重新申报。因此,异常智能处理系统的目标是:搭建人机交互闭环机制,沉淀底层知识大脑,快速提高异常处理的智能化程度。在底层实现上,我们搭建了一套规则库用于知识沉淀,上层实时监听海关异常回执,实现大部分异常秒级处理;同时,启动定时异常处理任务,每天定点捞取遗漏订单进行处理;最后,为小二和CP推送需要人工介入的异常订单,处理完后再推送到系统,由系统接着处理后续流程。展望未来在全球化的道路上,我们任重而道远,AI智能,大数据协同是未来的方向,基于人工智能方式实现全球通关的丝般顺滑,让全球通关更简单!这是我们的宗旨和目标,我们会一步一个脚印一直走下去!未来的路还很长,我们迫切需要有更多的能人异士加入,一起谱写旷世不灭的传奇。如果你足够优秀,如果你不甘平庸,来吧,让我们一起风骚前行!本文作者:啸鹏阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

December 4, 2018 · 1 min · jiezi

微服务架构可视化平台实践

为什么需要架构可视化随着企业进行微服务架构改造,系统架构复杂度越来越高,架构变化日益频繁,微服务改造后的实际架构模型可能与预期已经产生了巨大差异,架构师或系统运维人员很难准确记忆所有资源实例的构成和交互情况;其次,系统架构在动态演化过程中可能引入了一些不可靠的因素,比如弱依赖变强依赖、局部容量不足、系统耦合过重等,给系统的稳定性带了极大的安全隐患。所以我们每次在面对系统改造、业务大促以及稳定性治理工作之前,都会通过梳理架构图的方式,呈现系统架构中个组件之间的交互方式,架构可视化能够清晰的协助我们识别架构中存在的问题以及建立高可用的系统。架构可视化后,可以给我们带来以下几点但不局限于此的优势:确定系统边界一张好的架构图,应该明确系统所包含的各个组件以及各个组件之间的核心调用关系,这些组件的集合就是系统的处理边界,系统架构的边界在一定程度上也反映了业务域的边界。架构问题识别基于高可用的架构准则,结合可视化的架构图,可以评估架构可能存在的安全风险,比如系统在容灾、隔离以及自愈维度下的健壮性。其次,一些架构链路可视化工具(比如鹰眼)在实际工作中确实大大提高了开发者排查与定位问题的效率。提高系统可用性有了系统架构的上下游依赖关系图,在故障发生时,开发人员可以借助依赖数据快速定位到问题的来源,极大缩短问题修复时间(MTTR)。借助架构图,我们还可以梳理出系统中存在的强弱依赖,在业务高峰期对弱依赖进行降级,或者针对系统依赖的各个组件进行故障模拟,以评测系统整体在面对局部故障的可靠性。常见架构可视化的做法我们熟知的架构图是静态的停留在PPT上的,很多时候我们的架构已经发生了非常大的变化,但是我们还在使用那张看上去很经典却早已过时的架构图。长时间使用与实际架构不符的架构图对线上架构的认知的危害是巨大的,我们需要在脑海中不断更新对系统架构的视图,以保持对系统架构的敏感度。每年的大促或者重大系统改造成为我们梳理系统架构、对架构进行重新认知的机会,此刻我们需要通过各种工具查看系统的各个组件分布以及不同组件的内部与外部的依赖关系,这种梳理架构图的方法是最常用的方式,权且称之为“手工绘制法”。手工经常干的事情,就有追求效率的同学使用计算机系统带来的自动化手段帮助自己做这件事情,比如我们常常看到的基于数据埋点的微服务可视化解决方案,这类架构可视化手段通常在分布式追踪、APM等监控领域使用较多,下图为某APM产品提供的应用维度架构可视化方案:我们称这种可视化方式为“埋点式感知法”,架构组件的识别是依赖关键的核心类检测与埋点,此种方案存在以下弊端:语言相关性:只要是系统埋点,与语言相关的特征基本就拜托不了,需要针对不同语言提供不同的依赖包;不易维护:因为是对核心类的检测,当组件包做了重大变更时,需要同步变更;不易扩展:因为是客户端识别方案,客户端一旦开放出去,新组件的支持只能等待用户更新组件;规模受限:客户端识别的另一个缺点是算法受限,服务端进行识别,可以借助大数据分析等手段更有效准确的识别;还有一种自动化架构感可视化方法,我们称之为“无界架构感知”,是一种语言无关性的架构识别方案,其采用采集用户主机上的进程和容器的元数据、监控数以及网路数据的最最基础的数据,在服务端构建架构图。我们设计架构可视化的理念为了最大限度上降低用户进行架构可视化的成本,我们采用了无界架构感知-应用无侵入的方式微服务进行可视化,通过采集进程数据与网络调用数据,构建进程间的网络调用关系,构建微服务的架构信息。用户只需要安装我们AHAS Agent探针,即可完成架构可视化操作;对于阿里云云原生系统,我们提供了自动化安装方式,而无需登录机器。核心本质软件架构可视化的核心点是寻找在软件体系结构中有意义和有效的元素视图以及这些元素之间的关系。我们认为一款优秀的软件架构可视化产品应该帮助用户排除掉不重要的信息,给用户呈现出对他们有价值的视图,特别是在微服务架构下庞大而复杂的调用关系链场景中。这里面的核心点是__有意义__和__有效__,要做到这两点,首先需要识别什么是有意义和有效的元素和关系,我们在此领域做的事情归纳起来就是“识别”,识别机器上的每个进程是什么,发生的网络调用远端是什么,唯有知晓了这些元素是什么我们才有理由和依据来判断是否对用户有意义以及其在用户架构中的重要程度。在梳理了大量架构图,我们发现用户关心的架构元素主要分为三类:自己的应用服务;应用对外部的资源依赖;服务器本身的信息。 应用对外部资源的依赖通常以其它应用和通用中间件或者存储服务两种形式存在。故我们将需要识别的进程分为:应用服务和常见的组件服务(比如redis、mysql等),这些组件服务又分为用户自建的服务和使用公有云提供的服务,特别是对于Cloud Native应用来说,云服务的识别显得格外重要。目前,我们提供了20种阿里云云服务的识别以及包含mysql、redis、Tomcat等常见的21种三方服务组件,此组件库还在不断扩张中,目的就是最大限度的知晓架构中的元素到底是什么。架构分层我们同样认为架构可视化的有效性跟人的认知层次有关,架构可视化的重点是确定该工具是否更好的支持自顶向下方法、自下而上方法或者两者的结合。开发者更关心应用维度上的架构,架构师或者管理者更关心整体系统架构。所以需要针对不用的使用者提供不同层次的架构可视化视角。理想的架构图需要支持宏观维度以及不断下钻下的微观视角,我们对架构进行了分层设计,目前分为进程层、容器层和主机层,后期我们可能会继续上扩或者下钻支持地域层或者服务层。架构回溯没有哪个系统的架构是一成不变的,系统架构会随着系统的版本迭代不断进行演化。所以对架构可视化操作,还需要具备随着时间的推移可对架构信息进行自动更新已经回溯的能力。在我们提供的架构感知产品中默认架构图会随着时间自动刷新,同时支持对历史的回溯,你可以选择历史中的某一刻查看架构信息,比如,重大版本的变更时,发布前与发布后的系统架构是否发生了违背一些高可用原则的问题,抑或排查是否出现了不该有的依赖问题。可见可得架构可视化解决了可见的问题,但当我们从架构图中发现了问题需要解决时,架构图还应该给我们提供便利的可交互操作入口,让我们可以完成问题发现与解决的闭环。比如通过架构感知监控到了某个应用的流量非常大,我们需要对应用进行限流或者预案,那么通过架构图,我们应该是可以完成我们期望执行的操作。在架构图中融入可以交互的运维操作,让我们从看到到操作,再到问题恢复后体现在图中,这就像计算机发展史上从命令行视图到窗口视图的转变。我们对架构可视化的定位__架构可视化不是目的,只是实现系统高可用性的手段__。借助架构感知采集到的架构数据,在识别了用户使用的组件(我们对mysql、redis、mq等的统称)后,我们借助这些组件以及与组件匹配的故障库,可以给用户自动推荐这些组件可能遇到的故障,配合我们提供的评测服务让用户更方便地对组件进行各种故障的模拟与演练,以提高系统的健壮性。其次,通过架构感知识别Java Application 应用,如果发现其负载较高,配合我们提供的限流降级(阿里巴巴开源的Sentinel商业版)功能,为服务的持续可用性保驾护航。我们对AHAS的定位是一款数据分析型的高可用保障产品,帮助云原生架构系统实现高可用能力的提升。架构可视化是我们给用户提供的高效运维和管控的窗口,我们期望通过丰富的云原生数据体系配合架构图的可视化以及可操作性,建立起以应用为中心的运维一体化平台。在未来,我们会加强与其它云服务的集成,比如监控、容器服务,以丰富架构感知的数据维度;其次,会在数据的深度挖掘和智能化消费上投入更多精力,真正让数据成为企业的核心价值,让数据成为保障业务的稳定性的利器。本文作者:心远阅读原文本文为云栖社区原创内容,未经允许不得转载。

November 30, 2018 · 1 min · jiezi

前端监控实践——FMP的智能获取算法

今天来给大家介绍下前端监控中一个特定指标的获取算法,有人会问,为啥就单单讲一个指标?这是因为,目前大部分的指标,比如白屏时间,dom加载时间等等,都能通过现代浏览器提供的各种api去进行较为精确的获取,而今天讲的这个指标,以往获取他的方式只能是通过逻辑埋点去获取它的值,因此在做一些前端监控时,需要根据业务需要去改变页面对这个值的埋点方式,会比较繁琐,恰巧最近刚刚好在做一些前端监控相关的项目,遇到这个问题时就在想,能不能通过一种无须埋点的方式,将这个值给获取到?倒腾了一段时间,终于把算法弄出来了,今天就来给大家介绍下————FMP(first meaning paint) 指标的智能获取算法什么是FMP解答这个问题之前,我们先来了解下现代前端监控性能的主要指标统计方法,在2013年之后,标准组织推出了 performance timing api ,如下图这个api统计了浏览器从网址开始导航到 window.onload事件触发的时间点,比如请求开始的时间点——requestStart,响应结束的时间点——responseEnd,通过这些时间点我们可以计算出一些对页面加载质量有指导意见的时长,比如以下几个:TTFB : ResponseStart - RequestStart (首包时间,关注网络链路耗时)FPT : ResponseEnd - FetchStart (首次渲染时间 / 白屏时间)TTI : DomInteractive - FetchStart (首次可交付时间)Ready : DomContentLoadEventEnd - FetchStart (加载完成时间)Load : LoadEventStart - FetchStart (页面完全加载时间)通过这些指标我们可以得到很多有用的web端网页加载信息,建立对网页性能概况以上的指标可以对网页进行数值化的衡量,但是其实这种衡量只能体现一个视角的性能观点,比如TTFB很快,就能代表用户能够很快的看到页面的内容嘛?这个不一定是成立的,因此人们有开始从用户的视角去分析网页加载的性能情况,将用户看待加载过程,分成了以下几个阶段:页面是否正在正常加载 (happening)页面加载的内容是否已经足够(useful)页面是否已经可以操作了 (usable)页面是否可以交互,动画是否顺畅(delightful)而我们今天讨论的FMP(first meaningful paint),其实就是回答 is it useful,加载的内容是否已经足够,其实这是一个很难被定义的概念。每个网页都有自己的特点,只有开发者和产品能够比较确定哪个元素加载的时间点属于FMP,今天我们就来讨论一下,如何比较智能的去找出页面那个主要的元素,确定页面的FMP成为FMP元素的条件首先我们可以看看下面的图:我们可以发现在页面中比较useful的内容,都是含有信息量比较丰富的,比如图片,视频,动画,另外就是占可视面积较大的,页面中还存在两种形态的内容可以被视为是useful的,一种是单一的块状元素,另外一种是由多个元素组合而成的大元素,比如视频元素,banner图,这种属于单一的块状元素,而像图片列表,多图像的组合,这种属于元素组合总结一下成为FMP元素的条件:体积占比比较大屏幕内可见占比大资源加载元素占比更高(img, svg , video , object , embed, canvas)主要元素可能是多个组成的算法如何设计前面介绍了FMP的概念还有成为FMP的条件,接下来我们来看看如何设计FMP获取的算法,按照上面的介绍,我们知道算法分为以下两个部分:获取FMP元素计算FMP元素的加载时间如果有了解过浏览器加载原理的同学都知道,浏览器在在获取到html页面之后会逐步的对html文档进行解析,遇到javascript会停止html文档的解析工作,执行javascript,执行完继续解析html,直到整个页面解析完成为止。页面除了html文档中的元素加载,可能在执行javascript的时候,会产生动态的元素片段加载,一般来说,首屏元素会在这期间加载。因此我们只需要监控元素的加载和加载的时间点,然后再进行计算。具体的算法流程如下图相关的代码链接我已经放在最后面了,下面我会逐步的讲解整个算法流程我把整个流程分为两个下面两个部分:监听元素加载,主要是为了确定普通元素加载的时间点确定FMP元素,计算出最终的FMP值下面我们按照步骤来分析初始化监听可以看到首先我们先执行了firstSnapshot方法,用于记录在代码执行之前加载的元素的时间点接下来初始化MutationObserver,开始监听document的加载情况,在发生回调的时候,记录下当前到performance.timing.fetchStart的时间间隔,然后对body的元素进行深度遍历,进行打点,记录是在哪一次回调的时候记录的,如下图监听的最后我们会将在window.onload的时候去触发检查是否停止监听的条件,如下图如果监听的时间超过LIMIT,或者发生回调的时间间隔已经超过1s中,我们认为页面已经稳定,停止dom元素加载的监听,开始进入计算过程完成监听,进行元素得分计算首先前面我们说了,我们的元素对于页面的贡献是不同的,资源加载的元素会对用户视觉感官的影响比较大,比如图片,带背景的元素,视频等等,因此我设计了一套权重系统,如下:可以看到svg,img的权重为2,canvas,object,embed,video的权重为4,其他的元素为1,也就是说,如果一个图片面积为1/2首屏面积,其实他的影响力会和普通元素占满首屏的影响力一样接着我们回到代码,我们首先会对整个页面进行深度优先遍历搜索,然后对每一个元素进行进行分数计算,如下图可以看到我们通过element.getBoundingClientRect获取了元素的位置和大小,然后通过计算"width * height * weight * 元素在viewport的面积占比"的乘积,确定元素的最终得分,然后将改元素的子元素得分之和与其得分进行比较,去较大值,记录得分元素集通过计算确定FMP元素,计算最终FMP时间通过上面的步骤我们获取到了一个集合,这个集合是"可视区域内得分最高的元素的集合",我们会对这个集合的得分取均值,然后过滤出在平均分之上的元素集合,然后进行时间计算可以看到分为两种情况去处理:weight为1的普通元素,那么我们会通过元素上面的标记,去查询之前保存的时间集合,得到这个元素的加载时间点weight不为1的元素,那么其实就存在资源加载情况,元素的加载时间其实是资源加载的时间,我们通过performance.getEntries去获取对应资源的加载时间,获取元素的加载速度最后去所有元素最大的加载时间值,作为页面加载的FMP时间最后以上就是整个算法的比较具体的流程,可能有人会说,这个东西算出来的就是准确的么?这个算法其实是按照特征分析,特定的规则总结出来的算法, 总体来说还是会比较准确,当然web页面的布局如果比较奇特,可能是会存在一些偏差的情况。也希望大家能够一起来丰富这个东西,为FMP这个计算方法提出自己的建议附上代码 链接

November 22, 2018 · 1 min · jiezi

始于阿里,回归社区:阿里8个项目进入CNCF云原生全景图

摘要: 一群技术理想主义者,与太平洋另一边的技术高手们正面PK,在这场躲不开的战役中,一起认真一把。破土而出的生命力,源自理想主义者心底对技术的信念。云原生技术正席卷全球,云原生基金会在去年KubeCon +CloudNativeCon NA的现场宣布:其正在孵化的项目已达14个,入驻的厂家或产品已超过300家,并吸引了2.2万开发者参与项目代码贡献,其明星产品Kubenetes 的GitHub 上Authors 和 Issues 量已排行开源领域的第二名。今年,KubeCon + CloudNativeCon 首次来到中国。在2018 KubeCon + CloudNativeCon的现场,阿里云研究员伯瑜向在场的开发者们宣布,CNCF已将阿里巴巴云原生镜像分发系统Dragonfly接纳为其沙箱项目(Sandbox),并有机会成为国内首个从CNCF毕业的开源项目。目前已经毕业的两个项目,一个是Kubernetes,另一个是Prometheus。据悉,目前阿里巴巴已经有8个项目进入CNCF云原生全景图,分别是分布式服务治理框架Dubbo、分布式消息引擎RocketMQ、流量控制组件Sentinel、企业级富容器技术PouchContainer、服务发现和管理Nacos、分布式消息标准OpenMessaging、云原生镜像分发系统Dragonfly和高可用服务AHAS。时间回到2016年2016年的那届双11,RocketMQ创始人冯嘉和他的团队首次将低延迟存储解决方案应用于双11的支撑,经受住了流量的大考,整个大促期间,99.996%的延迟落在了10ms以内,完成了保障交易稳定的既定目标。对于读写比例几乎均衡的分布式消息引擎来说,这一技术上的突破,即便是放在全球范围内,也绝对是值得称赞的。另一边,在历时3个月的开源重塑后,冯嘉和他的团队启动了RocketMQ向Apache 软件基金会的捐赠之路,但迈出这一步并不容易。“当时国内的开源氛围还没有现在那么活跃,开源之后,很多设计、源码和文档的维护工作还不够理想,但我们就是想证明国内的开源项目和开源社区也可以在世界的开源舞台上发挥价值。”经过近一年的努力,在2017年9月25日,Apache 软件基金会官方宣布,阿里巴巴捐赠给 Apache 社区的开源项目 RocketMQ 从 Apache 社区正式毕业,成为 Apache 顶级项目(TLP),这是国内首个非 Hadoop 生态体系的Apache 社区顶级项目。值得一提的是,根据项目毕业前的统计,RocketMQ有百分八十的新特性与生态集成来自于社区的贡献。2017年,消息领域出现一件里程碑事件分布式消息领域的国际标准OpenMessaging开源项目正式入驻Linux基金会,这是国内首个在全球范围发起的分布式计算领域的国际标准。消息通讯已经成为现代数据驱动架构的关键环节,但在全球范围内,消息领域仍然存在两大问题:一是缺乏供应商中立的行业标准,导致各种消息中间件的高复杂性和不兼容性,相应地造成了公司的产品低效、混乱和供应商锁定等问题。二是目前已有的方案框架并不能很好地适配云架构,即非云原生架构,因此无法有效地对大数据、流计算和物联网等新兴业务需求提供技术支持。这也是冯嘉和他的团队在开源RocketMQ过程中,开发者和合作伙伴经常会提到的问题:“在消息领域,市场上出现了各类不同的开源解决方案,这导致了用户更高的接入和维护成本,为了确保各个消息引擎间能正常通信,还要投入大量的精力去做兼容。”这时候,建立一套供应商中立,和语言无关的消息领域的事实标准,成为各社区成员共同的诉求。此后,在2017年9月,阿里巴巴发起OpenMessaging项目,并邀请了雅虎、滴滴出行、Streamlio共同参与,一年后,参与OpenMessaging开源标准社区的企业达10家之多,包括阿里巴巴、Datapipeline、滴滴出行、浩鲸科技、京东商城、青云QingCloud、Streamlio、微众银行、Yahoo、中国移动苏州研发中心(按首字母排序),此外,还获得了RocketMQ、RabbitMQ和Pulsar 3个顶级消息开源厂商的支持。相比于开源一个分布式消息项目,一套开源标准能被各家厂商所接受,对整个国内开源领域而言,是更具有里程碑意义的事件。2017年9月,Dubbo重启开源Dubbo 是阿里巴巴于2012年开源的分布式服务治理框架,是国内影响力最大、使用最广泛的开源服务框架之一,在2016年、2017年开源中国发起的最受欢迎的中国开源软件评选中,连续两年进入Top10名单。2017年9月7日,在Github将版本更新至2.5.4,重点升级所依赖的JDK及其组件,随后连续发布了11个版本。并于2018年2月捐献给 Apache 软件基金会,希望借助社区的力量来发展 Dubbo,打消大家对于 Dubbo 未来的顾虑。项目重启半年后,Dubbo 项目负责人阿里巴巴高级技术专家北纬在接受媒体采访的时候,从战略、社区、生态和回馈四个方面谈了Dubbo重启开源背后的原因。“集团近几年开始将开源提到了新的战略高度,这次投入资源重启开源,核心是希望让开源发挥更大的社会价值,并和广大开发者一起,建立一个繁荣的Dubbo生态,普惠所有使用 Dubbo 的人和Dubbo本身。”Dubbo项目组成员朱勇在今年上海的技术沙龙上分享Dubbo未来发展的过程中提到,其后续的规划是要解决好两个问题。第一个问题是重点关注技术趋势,例如云原生对Dubbo开源现状的影响。第二个问题是 Dubbo 本身定位的问题,除了保持技术上的领先性,还需要围绕 Dubbo 核心发展生态,和社区成员一起将 Dubbo 发展成一个服务化改造的整体解决方案。2017年11月,阿里自研容器技术PouchContainer开源在开源不到一年的时间里,PouchContainer 1.0 GA 版本发布,达到可生产级别。今年8月,PouchContainer 被纳入开源社区开放容器计划OCI;9月,被收录进高校教材《云计算导论》;11月,Pouch团队携蚂蚁金服容器团队、阿里云ACS团队,与容器生态 Containerd社区 Maintainer进行技术交流,有望发展成 Containerd 社区 Maintainer 席位,代表国内企业在世界容器技术领域发声。PouchContainer发展速度之快,超出了宏亮的想象。宏亮是 Docker Swarm 容器集群项目的核心代码维护者(Maintainer),并于2015年8月出版了《Docker 源码分析》一书,对 Docker 架构和源代码进行了深入的讲解,该书在Docker领域迅速成为畅销书籍。2017年,宏亮承担起阿里自有容器技术的对内支持和对外推广工作,秉承初心,希望在竞争激烈的容器开源领域能抢下属于国内容器技术的一席之地。在他和团队的努力下,阿里集团内部已实现100%的容器化,并已经开始涉及离线业务,实现在、离线业务的混合调度与部署。整个集团能实现100%的容器化,离不开阿里内部自研的P2P分发技术,该项目取名为蜻蜓 Dragonfly,寓意点与点之间的文件分发能如蜻蜓般轻盈和迅速,解决传统文件发布系统中的大规模下载、远距离传输、带宽成本和安全传输的问题。日前,Dragonfly 正式进入 CNCF, 并成为国内第三个被列为沙箱级别(Sandbox Level Project)的开源项目,可见,CNCF 在其云原生的技术版图中正希望借助蜻蜓等优秀的镜像分发技术,以提升企业微服务架构下应用的交付效率。始于阿里,回归社区。今年夏天,国内开源领域,迎来了两位新成员。作为微服务和云原生生态下的两款重要开源框架/组件,Nacos主打云原生应用中的动态服务发现、配置和服务管理,Sentinle则是聚焦在限流和降级两个方面。Nacos和Sentinel均是在阿里近10年的核心业务场景下沉淀所产生的,他们的开源是对微服务和元原生领域开源技术方案的有效补充,同时也非常强调融入开源生态,除了兼容Dubbo和Sentinel,也支持对Spring Cloud 和 Kubenetes等生态,以增强自身的生命力。“阿里巴巴早在 2007 年进行从 IOE 集中式应用架构升级为互联网分布式服务化架构的时候,就意识到在分布式环境中,诸如分布式服务治理,数据源容灾切换、异地多活、预案和限流规则等场景下的配置变更难题,因为在一个大型的分布式系统中,你没有办法把整个分布式系统停下来,去做一个软件、硬件或者系统的升级。”阿里巴巴高级技术专家坤宇在2017 QCon的现场分享到。在配置变更领域,我们从2008年的无 ConfigServer 时代,借用硬件负载设备F5提供的VIP功能,通过域名方式来实现服务提供方和调用方之间的通信,逐步经历了ConfigServer单机版、集群版的多次迭代,不断提高其稳定性。曾写下支付宝钱包服务端第一行代码的阿里高级技术专家慕义,在今年深圳的技术沙龙现场回忆了阿里注册中心自研的10年路:“这期间,集团业务经历了跨越式的发展,每年翻番的服务规模,不断的给ConfigServer的技术架构演进带来更高的要求和挑战,使得我们有更多的机会在生产环境发现和解决一个个问题的过程中,实现架构的一代代升级。Nacos便是在这样的背景下,经过几代技术人的技术攻坚所产生的。”我们希望Nacos可以帮助开发者获得有别于原生或其他第三方服务发现和动态配置管理解决方案所提供的能力,满足开发者们在微服务落地过程当中对工业级注册中心的诉求,缩短想法到实现的路径。巧的是,一边是 Nacos宣布开源,另一边是Spring Cloud生态下的服务注册和发现组件Netflix Eureka宣布闭源,勇敢者的游戏充满了变数,但在坤宇和他的团队看来,这场游戏自己可以走到最后,因为我们并不是一个人在战斗,Nacos只是阿里众多开源项目中的一员,随后还会有更多的开源项目反哺给社区,形成生态,例如轻量级限流降级组件 Sentinel。7月29日,Aliware Open Source•深圳站现场,只能容纳400人的场地,来了700多位开发者。阿里巴巴高级技术专家子矜在现场宣布了轻量级限流降级组件Sentinel的开源。作为阿里巴巴“大中台、小前台”架构中的基础模块,Sentinel经历了10年双11的考验覆盖了阿里的所有核心场景,也因此积累了大量的流量归整场景以及生产实践。Sentinel的出现,离不开阿里历届高可用架构团队的共同努力。“在双11备战中,容量规划是最重要也是最具挑战的环节之一。从第一年开始,双11的0点时刻就代表了我们的历史最高业务访问量,它通常是日常流量的几十倍甚至上百倍。因此,如何让一个技术和业务持续复杂的分布式站点去更平稳支撑好这突如其来的流量冲击,是我们这10年来一直在解的题。”阿里巴巴高可用架构团队资深技术专家游骥在今年的双11结束后分享道。这10年,容量规划经历了人工估算、线下压测、线上压测、全链路压测、全链路压测和隔离环境、弹性伸缩相结合的5个阶段。2013年双11结束后,全链路压测的诞生解决了容量的确定性问题。作为一项划时代的技术,全链路压测的实现,对整个集团而言,都是一件里程碑事件。随后,基于全链路压测为核心,打造了一系列容量规划相关的配套生态,提升能力的同时,降低了整个环节的成本、提升效率。随着容量规划技术的不断演进,2018年起,高可用架构团队希望可以把这些年在生成环境下的实践,贡献给社区,之后便有了Sentinel的开源。一边是作为发起者。将自己生产环境实践下沉淀出来的架构和技术贡献给社区。另一边是作为参与者。基于一些开源项目或云平台,输出可以解决开发者当前工作中存在的痛点的解决方案,例如近期新开源的项目Spring Cloud Alibaba 和 开发者工具 Alibaba Cloud Toolkit。相同的是,技术理想主义者都希望技术可以为让世界变得更好,这才是技术人的兴奋点。“让世界的技术因为阿里巴巴而变得更美好一点点”。这是阿里巴巴毕玄邮件签名中的一句话。他正和一群技术理想主义者,与太平洋另一边的技术高手们正面PK,在这场躲不开的战役中,一起认真一把。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

November 20, 2018 · 1 min · jiezi