哈啰是一家相对比较年轻的公司,在创业中期,哈啰经历了公司业务量高速增长,同时横向的业务种类也经历了高速扩张的时期。在这样的大背景下,整个前端的一些性能在迭代之后衰减得非常严重,而性能问题又影响到了整体的用户体验,同时排查这些性能问题非常耗时,而且难以定量,于是这些问题阻塞了整个业务的迭代,对公司业务的高速增长造成了非常重大的影响。
在本次分享中,我们将聚焦以下几个问题并加以解决:
性能优化的流程整体上可以分成以下三步,不管怎么做,“万变不离其宗”,它整个的流程抽象起来就是以下这三步:
针对性能优化流程我们可以看出,其实它的出发点和最终归宿,都在于优化性能本身的一些指标。基于这个出发点,我们需要把这些指标都收集过来。而收集过来后就回到了刚刚我们的问题:为什么不能用性能测试的一些工具,而要去做一个性能监控的体系?
这里主要是基于两个原因:第一,它本身性能监控的需求,也就是对于线上稳定性的一个诉求;第二,就在性能数据收集上,如果用性能测试工具去收集数据,可能它在实际的适用面不是特别全,而且并不能如实地反馈线上的情况。基于这些点我们想去做一个性能监控的体系。
整个性能监控平台这个系统,大致上我们可以分成以下三个流程:
这三个流程与上文的性能优化一样,都是一个抽象的流程。也就是说,不管怎么做性能监控的系统,它都脱离不开数据采集、数据清洗和聚合展示这三步。其中的差异点只在于:数据采集从哪采?怎么采?通过什么方式去采?数据清洗怎么清洗?怎样保持数据清洗的持续不出错、高可用?还有就是聚合展示怎么展示?从什么维度展示?只是这些细节有区别,但是它的整个大的流程是一样的。
基于这个整体的流程我们再去细化一下,我们把这三大步的每一步都单独去细化它需要做的一些功能点,基于这些功能点及特点,我们再进一步细化它的整个架构。
第一块我们先来看一下数据采集,数据采集大的的功能点主要包含以下四个模块:
信息获取
信息拼装
缓存模块
上报模块
这里例举的是哈啰当时的一个场景,但在某些不同公司当时的业务场景下,缓存模块甚至是不需要的,上报模块跟缓存模块有时可能会融合在一起,只有一个最终的上报,即时获取即时上报。
拼装这个模块在大部分场景下,当然我还是建议大家都去做数据的拼装,以便于不同平台数据的统一处理。而基于上文列的功能点,我们会得到一张整个数据采集端上的SDK架构。
在做性能监控时,大家在SDK设计上可能会把一些业务监控,或者说业务数据收集的功能也加到SDK当中。
所以它上下会分成几层,中间这一层的数据采集会包含一些常规的业务数据收集,当然其中有些数据可以在业务中被消费、使用,也可以在性能监控中作为整体的参考被收集、消费。
在数据采集之下,就是信息拼装、日志缓存和日志上传,这三块因为涉及到一些特别复杂的逻辑抽象问题,所以我们把它们从分成上作为一整块去处理。
在数据采集横向这一块还有一个无痕埋点,这个无痕埋点主要针对一些异常的收集。这些异常有部分是结合手动的埋点去收集,有部分则需要用AOP的形式去收集。最上层的是初始化数据,会针对不同的端去做一些API和SDK的封装。
1)信息获取
看完了SDK架构之后我们还需要看一下数据采集。分层完之后我们要去采集哪些信息?这边罗列了一些我们需要采集的部分信息:
异常捕获
页面加载时间
页面帧率
网络情况
原生方法调用情况
主要就是收集这五点信息,那么第一、二点信息具体要收集哪些内容呢?
①异常捕获
异常捕获中我们会去监听以下几种异常情况:
一般异常:监听window.onerror
promise未捕获异常:window.addEventListener(‘unhandledrejection’...(在window上加一个监听器、用add Event Listener的方式、监听un handled rejection
Script Error:Access-Control-Allow-Origin + 标签crossorigin(这种情况一般是由于跨域引起的,解决方式也比较多样,我们这边是打了一个允许跨域的标签,通过这种方式让Script Error能正常捕获到)
大家结合实际的异常捕获的情况,可以去做实际的、针对自己场景和所碰到问题的针对性捕获。
②页面加载时间
关于页面加载时间,我们公司将其分成了几种数据活着说几种维度去做加载。分别是白屏时间、首屏时间、页面加载时长以及可操作加载时间四个方面:
白屏时间:重要性得分不为零的页面渲染的时间
首屏时间:首屏是重要性得分最高的页面渲染时间
页面加载时长:页面所有资源加载完成的时间,通过 window.onload判断
可操作加载时间:Dom ready+特定 JS 标记完成时间
这就是页面加载时间所有关注的方面。
注:重要性得分是新增元素得分相加再乘以它的权重
2)信息拼装
数据采集完了之后,接下来就是数据的拼装。拼装的话我们会去做一些数据标准化的数据模型,如图所示:
①通用信息
理论情况下通用信息包含所有的数据采集,因为性能和业务都会有通用信息。一般通用信息包括以下几个内容:
type:type会告诉你这是哪种类型的信息;
时间戳:时间戳主要是为了方便做日志的排序或者日志的后续清洗;
LogId:日志通用,在后续做索引查询时会用到。
②业务信息
在通用信息之后是业务信息。业务信息就是上文提到的性能,像页面加载时间、异常捕获到的异常信息,这些会放到业务信息里面。但它其实也是放在 Detail Properties字段里。业务信息里其实还是有一些相对比较通用的字段,比如说像 Businessid 、PageSessionid、Page Path之类的字段。
但在逻辑上它们更多的是跟当前页面,或者说相对来说可能要非抽象的这种业务关联,所以我们把它也归到业务信息里面。
③用户基础信息
最后一项是用户基础信息。用户基础信息理论上跟通用信息有些类似,所有的日志都会有用户基础信息,里面会记录用户,比如APP的名称、APP版本等。这个APP不一定是狭义上的 APP,我们的前端应用也是一个APP。把这些信息填到日志头中,包括一些操作系统相关的信息。这对于后续做一些比如用户画像、错误归拢时会更方便一些。
3)缓存&上报
在数据拼装完成之后,我们需要去做数据的缓存和上报。这里把它们放在一起去讲,是因为我们在模块设计的时候是把它们放到一起的。
如图所示,SDK在启动时会先去异步读取缓存中的一些内容,如果接收到埋点就会把埋点读出来再发到发送区。
如果没有读取到这些数据,就会先初步组装一些基础类型的数据,比如日志类型、上报类型等,并将它们存放在启动区,等待实际的日志埋点的信息收集进来,再进入到左边的发送区。
放到发送区之后,这里有一个灰度的数据。这其实是我们内部业务的一个逻辑,我们有部分的数据有一个灰度系统,灰度的这部分数据我们会把它单独摘出来,不会放到一起,所以这里是有一个过滤的过程。
完全组装之后,我们把数据全部放到发送区,发送区会等待一个触发上报的策略,去触发器触发,触发完之后才会进行最终的上报。
而这个触发其实也是有好几种策略的,比如时间触发,根据它的日志条数或者日志大小去做触发。那为什么要去做触发而不直接上报呢?
这是基于以下几点考虑:
一个是对于日志上报的服务来说,它的数据本身存在了一定的压力。如果我们每一条业务数据或者说错误数据都做及时上报,那这个服务存在的QPS不会非常高,因为我们所有的C端都接了数据上报。
另外一点是,因为我们是作为一个公司通用的方案,所以有这个策略之后,不同的业务方根据它的业务场景,可以灵活地甄选更适合它业务场景的上报策略,比如说如果有一部分的错误数据或者性能数据,他们相对比较关注,或者业务的优先级特别高,他可以把上报策略调得更频繁,甚至做实时上报。而一些优先级不是特别高的业务,我们就可以把策略调低。
这是为了整体的服务治理以及从整个公司的通用性上考虑。在上报完之后,我们会把已上报的数据从发送区删除。采样跟上报还会有一点区别,采样是在数据上报清洗完之后,或者说清洗过程中,再去做的百分比的筛选。
而上报主要是针对前端的数据,直观地说就是:不是每收集到一部分数据就马上去上报,而是攒一部分数据之后再去做上报。发送成功之后,发送区会删除已经上报的部分数据。
如果发送失败,我们会把已经上报的部分数据删除,并进入下一循环,等待下一次的触发。同时把 Error抛到 SDK外,让业务方去做额外处理。
这就是整个的缓存上报流程。上文提到了一些上报策略,但这些策略并不是绝对的,整个流程,包括上报策略怎么定,可以根据每家公司、每个人碰到场景做额外定制。像目前的场景我们定了几种情况:
每条数据写入Storage缓存后,判断日志数据数是否大于等于logMaxCount,满足则上传
通过初始化时开启的定时为maxTimeLog定时器,定时上传
应用启动后,读取localStorage值到Storage中并触发上报,失败就等待下一次上传时机
由此可见,这几条的优先级、上报方式其实都是可以灵活配置的。
讲完上报策略,我们来看一下数据清洗。前面讲了数据采集的SDK,在SDK上报完性能或错误数据之后,服务端这边,理论上是到了一个HTTP的request去做上报。
这个HTTP服务有一个上报的服务,是一个Service,我们这边是用Node来实现的。这是第一块,它包含日志上报服务,需要去承接接口。
第二块是日志的消息,服务上报了之后,我们会把它放到一个消息队列里面,放进消息队列里面之后,就需要去做日志的清洗,清洗完之后最终还要去做一个日志的存储,所以数据清洗就主要包括日志上报服务、日志消息、日志清洗服务和日志存储这四个模块。整体的清洗流程为:
从下往上看,LogServer提供了一个日志上报的接口给前端调用,前端调用了接口之后会将日志放到Kafka里,也就是上文提到的日志队列。再往上走有一个Flink服务,专门做消息队列的消费和清洗,清洗完之后最早时会将它放到ES里面,后续我们将它迭代放到了Clickhouse上。
在Clickhouse中,我们会提供一些 DSL或者说SQL化的语句,然后让性能平台这边的Node服务去做数据的计算,计算完之后还是由Node服务将这些数据呈现给 PC、web、后台,让运营、技术去看这些具体的性能指标相关的数据。
在图中右上部分有两个半透明框,是用户分析和数据分析,因为我们整个的数据清洗过程是复用的。除了性能平台,一些业务数据也是通过这个流程往上消费,只是它们的主题功能可能会有些不同,所以最终用户分析平台、数据分析平台也会复用这一套流程。
Clickhouse是一个列式存储数据库,它的性能计算或者说横向相同字段的计算的性能是相当高的。但在使用过程中还是碰到了一些问题,比如为什么要用Flink + Clickhouse?原因有以下三个:
速度快,性能类数据,取数计算1S内完成
方案成熟,部署 + 运维简单
关注指标⽀持 SQL描述,方便后续加工呈现
通过实践,上文所讲述的流程架构在后续治理上碰到了一些问题:
脏数据开始增多
部分消息数据丢失
准确性和有效性验证
基于这些问题我们对流程做了一些小改进,这个改进目前在业界用的也是比较多的,如图所示:
在Flink消费时,除了往Clickhouse里写数据之外,还同时往Hive里写数据。为什么这么做呢?因为前面提到的问题绝大部分都是Kafka队列塞得太满,或者Kafka这个队列中间件出现问题,导致 Flink写入时突然卡住,那段时间的数据没有写入。数据没写入会导致后面的消费队列混乱、数据丢失。而且Flink写入 Clickhouse的速度是有限的,这会导致它后续跟不上,相当于恶性循环。
这个时候我们引入了Hive,在Flink写入 Clickhouse的同时,有一个中间件去写入Hive。数据写入Hive之后,如果碰到Kafka故障或者 Flink故障的情况,中间通路不通,我们就会以小时为维度,把Clickhouse这段时间有脏数据的这部分数据全部删除,再从Hive导入这部分数据。如此Hive就能给Flink和Clickhouse做小时级容错,粗暴点讲就是两分备份。但是用Hive也是因为Flink写入Clickhouse的速度并不是太好,所以在这个地方给它做一个补全。
数据清洗基本上讲到这里,接下来是性能监控系统的最后一个流程:聚合展示。聚合展示包含三个模块:展示平台、展示服务、定制处理/清洗。
数据清洗完之后,性能监控的Node服务会用SQL化的语句去做聚合运算,运算完之后它会去做最终展示,这里就需要一个展示平台。
同时这个平台底下还需要一个展示服务。我们这边也是用Node展示服务,去给它做数据的运算、存储,可能还有部分元数据或者业务数据的存储和简单处理,处理完之后才会给到展示平台。
还有一个模块是定制的处理和清洗,前面提到的数据清洗其实是粗的清洗,比如说非序列化的数据,我们根据相应的模型,把消息提取出来,将这些数据清洗成Clickhouse中的数据。
我们在聚合展示中会再去做一些定制化的清洗,举个例子:比如像秒开率、白屏率之类的指标,拿过来元数据后可能会再去做进一步的计算和清洗,有部分数据则去做筛选、拆分,只拿到我们关注的数据,再把它传到我们自己的数据库中。
它整体的业务架构是这样的:
最上层是一个性能平台Web,横向还有用户分析平台和数据分析等。下一层是Node服务,这层服务除了有性能指标服务,也提供了LightHouse服务做动态分析,因为线上监控关注的是上线后,上线前我们在本地测的数据虽然不足以支撑完整的论据,但也还是需要的,所以我们也上线了一个Light House服务。另外还有其他取数的计算,比如上文提到的数据清洗之类的。再下一层的话,我们提供了Node相关的一些组件,这些组件大部分是跟数据存储、数据库调用相关的,技术架构这边会去封装成一个通用软件。
横向的话我们接入了公司的监控告警服务。公司全站层面有一个统一的告警服务,我们只需要给出对应的指标让它去消费就能触发报警,所以没必要单独再搞一套监控告警服务。最底层的话上文提到的Clickhouse是作为数据源,同时我们还接入了PG组件,把一些业务数据和一些消费完、处理完、清洗完的最终数据也放到这个地方。
这是我们内部的监控平台的实际界面,因为是一个纯技术项目,所以没有过多的设计。更多关注的是功能层面的内容,虽然它的界面相对比较简单,但它实际的指标功能相对是比较全的。比如像实时数据、每日的报告以及一些分析工具,像是上文提到的 LightHouse,以及一些性能优化工具都包括在内。
这是平台的一个事例图。在我们这边,针对某些页面,会有一个实时的、清洗完之后生成的一个页面在线上的平均表现图,中间有各种阶段,像DNS、html下载解析、动解析和渲染等。结合这个具体的例子,我们就可以清楚性能优化应该往哪些方向去做。
在做性能优化之前,要根据实际情况去进行分析。比如上文的性能优化分析图中有各种不同阶段,在不同阶段,如果有的部分时间占比特别长,我们就可以有针对性地去做优化。
这里简单讲一下整个系统优化大概的逻辑或者说思路,怎么去分析?怎样去做归集?
如果建连前时间特别长,可以通过DNS预获取的方式,去缩短建连前的时间。当然还能通过别的运营商介入的方式,但这样的话整体成本会非常高,不太适合在创业中期的时候去做。
资源请求可以去上CDN+OSS缩短资源请求的时间。
html文档和资源下载常规上我们会通过Webpack打包优化、离线包这种方案缩短它下载的时间。
解析DOM我们可以通过比如预渲染、SSR、ESR、NSR之类的方式。ESR目前业界虽说比较火,但我们目前并没有用上。而据我了解,真正能用到ESR的公司也不是特别多,因为它对CDN资源浪费还是比较多的。
哈啰这边有两个相对来说用的比较多的,同时像预渲染、离线包之类的做的还不错的整体通用化的性能优化实践方案。
预渲染在概念上跟SSR或ESR有一些相似,但又不太一样。SSR它是把接口请求或者说资源反复来回的时间省略了,同时它吐出的是后端支出。就是后端在全部的接口请求数据返回到服务端之后,服务端全部渲染完,再去吐出给前端。它节省的时间是来回通信的时间,但这会衍生出两个问题:
第一是对后端资源的占用。大家也知道to C的业务像哈啰现在的用户数其实非常高,QPS会很高,如果说这种核心页面全部用SSR来处理的话,对于后端或者说 SSR服务的压力是比较大的,这会影响到公司整体这一块的高可用性和稳定性。
第二的话,因为它需要在所有的页面请求全部返回并渲染完之后才会吐出给前端,它的首屏时间并没有特别短,它真正提升的是整屏渲染完的时间,这个整屏渲染完的时间是非常快的。但它在首屏时间上并没有非常大的优势。
而我们这边有很多的C端活动,包括核心业务的场景等。但在中期,我们并没有精力去做SSR这一块的事情,于是我们想用低成本的方式把首屏缩短。比如说像在这里的一个场景里:
未启动预渲染时,某一个页面首屏时间特别长,白屏时间也特别长。这种场景我们想用低成本的方式将它优化,就借鉴了一下SSR或者说ESR的渲染机制或者说思路。
而我们做的事情比较简单粗暴。在预渲染应用中,我们的页面渲染是提前的,在打包过程中就已经完成了。完成了之后预渲染应用中会存在一个已经渲染完的页面,这个页面html下载完之后就能渲染,而渲染的过程同时会去做这个页面真正的CSS/JS下载、框架初始化和页面渲染。所以它在首屏和白屏上优势会非常大。
大家可以看到中间这个页面渲染的节点,预渲染应用就已经渲染完成了,上面的页面需要把html 、CSS /JS、框架初始化全部走完,所以它在时间上会有很大的优势。它的整体流程如图所示:
在应用编译、部署阶段,我们的打包系统集成了这两个流程,在这一阶段,我们会启动一个无头浏览器去访问页面,访问完页面之后会记录下这个页面的渲染结果,然后生成渲染完的 html文件上传OSS。在不用采用离线包的情况下,相当于上传到OSS的html就是我们最终访问的预渲染产物。这个过程相当于我们在发布系统中也做了整体的集成,这样的话我们访问的速度就能更快。
但这里有一个衍生的问题,大家回头可以看一下,它第一个页面的渲染时间其实是提早了,但它最终实际能交互的页面的渲染时间却反而延后了。因为这中间多了一个html,也就是那个预渲染的页面。
所以在场景上也是有一些选择的。前端性能优化其实很多时候都是一些场景的抉择,就跟 SSR和 CSR一样。
我们整体流程跟发布系统的交互基本是走发布系统,把发布系统的任务放到Jenkins中,Jenkins就会去执行服务中的预渲染,然后拉取OSS上的H5页面,再返回预渲染产物,同时会发布一个离线包。那这个离线包是什么东西呢?
在业界特别是APP场景下,离线包是相对来说比较常见的一个方案。因为前端的资源或者说加载瓶颈主要在于包的来回,SSR只是让请求的来回缩短,但是包的来回并没有减短,该返回多少东西还是返回多少东西,所以引入离线包是去解决这个问题的。这么做的好处有:
流程和系统间的交互简单。就像刚刚提到的SSR,类似这种方案会有比较多的系统间的交互,比如SSR服务就Node服务的请求和后端服务需要去做额外的基建。
可以基于发布系统去做降级和质量治理。当我们把整个的发布流程、离线包生成流程、预渲染服务生成的流程全部整合到一个发布系统中,最终它发布的产物会由发布系统来统一控制,你可以用预渲染服务,也可以不用预渲染服务。
它两个东西其实是一个并存关系,比如说我上线之后,如果我觉得这个场景其他东西预渲染会有问题,我可以在发布系统中把预渲染给去掉,这时线上入口访问进来就会打到发布系统控制的一个入口上,这个入口有对应预渲染的开关,关了之后就不会走预渲染的请求,而是重新回到原来正常的请求里。这样的话整体的线上治理会比较方便,也比较灵活。
而提升效果相对来说SSR可能会更明显。因为我们关注的是白屏和首屏,白屏的话它的效果是非常明显的,几乎没有白屏。
另外就是没有额外的负载压力和系统复杂度成本。不需要关注OI的系统复杂度,业务该怎么开发怎么开发,还是原来CSR那一套。
用了这一套之后首屏的时间缩短了一半多,变成了760ms,白屏没有了,出来就有界面。因为html加载完就是一个可渲染界面。
离线包的话上文其实有提到一个基本流程,它在发布系统中也会包含。在这里离线包其实也有一个单独的开关,但离线包因为涉及到 APP端,所以它的开关是在native端去设置的。当然配置的地方都是在发布系统,但它消费或者说读取的地方会不一样。
在APP中进入一个页面之后,它会去检查是不是H5页面,如果是H5里面它就会去对应的URL请求,然后把离线包资源吐回去,没有资源的话就去远端再次获取,获取之后缓存在本地。
所以说离线包其实是两个流程,一个是本身提前的离线包下载,还有一个是在后续如果没有资源的情况下,它去做一个的离线包的补充。
这就是离线包加上预渲染的一个整体流程。我们在H5的发布系统中发布应用时会做一个整体的H5的编译打包,将H5上传到CDN,再把编译打包的产物拉回预渲染服务中去产出预渲染的产物,同时也会把它拉回到离线包的服务中,产生一个离线包的产物。这两个服务是并存的。最后由一个离线包的构建器把这两个产物合并,这就是最终的离线包的产物。
其实引发性能问题的原因,通常都不是某一单方面的问题,而是各个方面都可能有问题,最终呈现的结果可能是不太达标的。那最终要怎么解决呢?我觉得可以借助一个性能采集监控体系,更好地挖掘性能相关的需求。
如果没有这些东西,大家相当于纯靠自我的想法去做相关优化,这样没有一个很好的切入点,就相当于无头苍蝇。大家都在做优化,那么优化完之后是怎么样?
其实性能优化大部分都逃不开三板斧: 并发、缓存、压缩资源。上文提到的资源相关的问题就是缓存,比如说PAD的压缩缓存。并发的话可能就是更多带宽、更多请求、同时请求。
最后,要善用浏览器和客户端侧提供的各种能力,流程优化有时候强过细节优化。当然到最后可能是要去做细节优化的,但是在初期去做细节优化可能效果会非常差。比如像预渲染,我们在流程优化上做的方案,说实话没有一些特别细节的东西,但是它的实际效果会非常好,它的整体缩短的时间是50%以上的。在秒开或者页面加载要1600多毫秒的时候去做细节优化其实没有任何意义,你优化的部分占它整体的时间的百分比可能非常少。
另外像离线包需要有跟客户端结合的能力,根据场景大家要开阔一下自己的思路,不要光从纯前端调用,还要从善用客户端这一侧提供的一些像本地缓存、JSP相关通知、请求拦截的这些能力,把整个流程给兜起来,做到至少创业前中期的高性能。
今天的分享就到这边,谢谢大家!
Q&A
Q1:如果加入当前端代码还没有发版本,后端代码已经发布,此时,将会存在大量的错误日志上报回来,此时怎样做削峰处理呢?
A1:这里主要讲的是前端的性能监控的体系。大量错误日志的话,主要存在于后端,而重复日志,后端在做数据的初步清洗时,在相同类型、相同业务或者相同用户、单一应用数据短时间超过某一个值之后,会按一个特定的百分比去做削峰。这是在数据的清洗阶段就会去做的削峰和规避。
Q2:数据拼装模型:这个拼装模型和埋点有关系吗,是不是从埋点数据格式里提取消息再做数据处理系统,Hadoop生态组件只采用备份方式吗,HBASE、spark、strom等方式考虑过吗?
A2:是有关系的。在埋点的数据上,包括业务埋点和性能埋点都有一个标准格式,中间像用户信息、基础信息在埋点数据中都有对应的展现。部分数据像Log ID 、Sequence ID之类,这些数据由服务器按顺序生成,但有部分像 Type、用户的APP version、APP OS等。当然核心的业务其实都有业务模型,而这个埋点数据本身也是有固定格式的,它会按固定的格式去做提取。
Hadoop生态组件目前只采用备份方式。因为我们优先考虑的是性能平台,而经过我们的调研,性能平台目前性价比最高、同时性能相对比较好的方案就是现在用的这套方案。Hadoop的话大数据那边可能会有类似的方案,但他们也不是用在性能相关上面,而更多是在业务数据收集上,在前端的话目前还没有用到。
Q3:监控log不做保存和批处理吗,就是实时处理完不做批处理等保存吗?
A3:目前是实时处理完,当然这个点我觉得挺好,之前说到的像脏数据之类的处理,其实还有一种方案,就是我们去做包装批处理,做一个容错,而不是直接全部实时处理。
因为实时处理对于C端这种业务日志处于峰值的时候,风险是比较高的。但目前我们并没有实践,后续可能会整体看一下。
Q4:这套东西有无可能云化、容器化、服务化后,提供Devops API 然后我们的系统可以用呢?
A4:这一套东西能不能云化、容器化、服务化之后提供Devops API?这个可以是肯定是可以的,但目前我们还没有这方面的实践。
所以说可行肯定是可行,因为容器本身跟这个方案本身没有特别大的关联性,只是用容器化的方式去做这一整套方案的部署。但怎么做最佳实践?我觉得可以自己去做一些探索。
Q5:如何使用监控建立一个稳定性保障工程?
A5:用监控建立一个稳定性保障的话,我理解也可以做,比如通过监控线上的一些DSL、请求的error,还有一些加载的错误,把对应的数据上传到我们的技术部,让技术去关注对应的指标,然后做稳定性的保障。
但是前端稳定性保障跟后端不一样,后端是跑在我们自己的一组服务器或者说容器上的。我们可以通过一些手段把这组容器或者说这组服务器上的服务可用性做高,但是用户那边如果碰到问题,并把这个数据反馈到我们这边之后,我们整体的反馈就要去修改代码重新做发布了,所以它维度上会有一些不一样,而且时间间隔上拉的也比较长。
就稳定性或者说 Bug上,我更建议做前置动作,去做自动化测试而不是通过监控。这边我们是做一个兜底,稳定性还是后端依赖监控更多一些,前端更多依赖的是性能相关的治理,需要去做一个指标的设计。当然也可以去设置相对来说小批量的监控做稳定性保障,目前除非是用SSR,这个可能治理的灵活度会比较高,其他的我觉得可能会比较难达到预期目标。
获取本期PPT,请添加群秘微信号:dbachen
↓点这里可回看本期直播
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721