[关闭]
@gaoxiaoyunwei2017 2019-12-19T09:51:38.000000Z 字数 9558 阅读 819

京东物流超大规模仓储系统智能监控揭秘

白凡


付正全

大家下午好,咱们在很多运维领域来说,其实包括AIOps现在这个趋势,监控作为AIOps一个基础设施,我觉得这块有必要,咱们对监控这块做一个专项探讨,我们京东物流其实面对有很多不一样的场景,比如说京东物流在全国各地600多个仓库,其实很多机器在各地库房,各省都有。还有国际化,在印尼、泰国都有相应的仓库,都需要监控。

这样面临是一个非常大型的监控问题,这样的问题来说,我们有一些心得,有一些相应的方案分享给大家,我觉得这些东西可能会对大家有一些启发。

今天我从这四个方面,第一个方面说一下京东物流面临的问题和挑战,还有AIOps这个趋势,它对咱们监控体现出哪些要求?咱们怎样向AIOps落地发展?监控这边应该做什么?这边也是我们需要探讨的点。

第二块我们就重点聚焦于咱们的解决方案,就是我们这块到底应该怎样面对问题,给出具体方案;

第三块有一些最佳实践,比如说我们做的一些比较好的实践,一些方案也可以给大家分享,也可以应用在自己实际的使用上。

最后一块我们对AIOps也是有一些自己的规划,这块的规划也会跟大家分享。

image.png-42.1kB

1. 问题及挑战

先看第一块,在我们京东物流仓储,可以说对监控系统说能遇到的复杂问题,我们这里都有。比如说仓促、库房、分布地域广,这个不仅是全国各地还有一些国际化的仓,全球有600多个大型仓库,也超过1500平,每一个仓库都有对应的机房,机房里面都有一些相应仓储系统,这些东西都需要我们监控。

另外一个就是这么多的地域导致这个机器和应用数量特别多,而且机器他们的种类也特别丰富,应用的数量大概是有四五千个,再一个由于我们分布于不同的,全国各地的地域,所以网络环境有差异,这样在我们采集数据的时候有一些问题,这些问题会造成数据的延迟,甚至有一些监控的失误。

还有监控对象种类复杂,我们不光面对不同厂商的软硬件,还有我们自己的应用,我们的中间件都需要我们监控,还有资产变化频繁,我觉得这不光是我们,所有大型互联网公司都会遇到这个问题,特别是资产上云之后。很多地方云上资产变化是非常频繁的,所以咱们要保证资产怎样适应频繁的变化,保证我们资产的准确性,这个问题在我们定位的时候也是非常重要。

还有一块就是部署环境,因为我们这边发布环境各个不同,有一些在IDC是基于京东商城的方案,还有仓储是单独的一些方式,对我们运维来说可能这里面都有很大差异。

image.png-121.3kB

另外一个就是在AIOps这块,咱们智能监控又提出哪些新问题呢?AIOps现在提出已经有几年时间了,为什么现在落地的进展不是特别快呢?我觉得主要有两大方面原因,第一个AIOps其实就是AI加OPS,你需要两个都懂,比如说AI你要懂,运维你要懂,业务场景你要懂。
那么这两块在实际推进过程中,咱们做运维的比较懂业务,但是算法是我们的弱项,像一些研究所,高校他们算法比较强,但是他们脱离业务场景,所以这块导致咱们AIOps发展比较慢。

另一方面原因就是AIOps它这个东西不像其他技术一样,很快形成业界统一的解决方案,咱们AIOps这块目前没有形成这样一个统一的解决方案或者统一的场景落地,因为它与咱们的实际业务场景强相关,每个公司自己的业务场景都不一样,我们要做的AIOps东西也不一样,就导致了整个行业没法一起前进,这也阻碍AIOps进一步发展。

还有一些AIOps的场景化,包括一些算法的工程化,另外还有一些比如说我们要做AIOps可能基于数据化这个层面,要把所有的监控数据应用大数据的处理方式把它们做成一些数据化的东西,但是如果我们数据,比如说采集不全或者是数据不完整,还有一些数据分析做的不到位,那么咱们AIOps也很难去真正落地。还有一些就是AI和算法咱们要做AIOps,可能这两块都懂的人比较少。

image.png-70.7kB

2. 超大规模监控系统解决方案

我们再看下面一个问题,我们这个问题说完了,再讨论一下解决方案,在说解决方案之前我们先应该探讨之下,在座咱们可能都做过监控系统,到底我们对监控系统应该是怎样的认识呢?什么是监控呢?监控有哪些价值呢?等等一系列的问题。

我觉得咱们做监控可能有一些人自己都做过,咱们监控什么样是好的监控?到底什么是监控?监控的价值又是什么?我认为就是三个字,可控性。

咱们一定要达到,让运维人员也好,管理人员也好,能够达到对整个系统,整个IT环境的一个可控,出现任何问题都在我们的控制范围内,比如说我的故障可控,可以通过一些故障的预测,故障的一些扩容,可以避免一些故障,或者出现故障有一些规则可以去给它做一些处理等等,还有一些性能,通过预测都可以做到一个可控。可控的含义就是,我们对整个系统很有信心,了如指掌,所以我觉得这个就是监控最大核心价值。

包括我们AIOps也是这样的,就是为了达到我们对所有东西都是在我们的可控范围内,必须更坏的影响。

image.png-86.3kB

下一个就是运维体系的规划,很多东西如果咱们要做运维体系的话,监控只是其中一部分,我们要做监控可能就脱离整体规划,我觉得运维体系是一个整体,我们在做监控的时候,其实是跟一些资产,IT运维流程,还有运维平台,监控这些东西都是要统一规划,因为有时候如果没有统一规划,我们很容易造成一些重复建设,遇到的一些困难性问题,规划问题等等。
其实在这个规划里面,可以分为几部分,资源层,平台化,就是咱们要把咱们的自动化运维平台建设起来,有了这些平台之后我们可以做一些数据化,就是平台之上咱们可以把监控,监控系统最多就是数据,咱们怎样能把监控这些数据价值挖掘出来,这是我们很重要的点。

image.png-101.6kB

我觉得需要把数据化这块做好,可以通过数据,可视化等等这些方面,有了数据化我们这块做好之后,我们下一步就可以向AIOps努力做一些东西,AIOps也是三个层次,发现问题,比如说AIOps有几个场景,都属于发现问题的范围。

第二个层次就是我们能发现,要能够解决,告警就是最基本的处理问题的一种方式。

第三个层次就是避免问题,我们可以做到故障没有发生之前,预测故障,做相应的处理,比如说扩容,比如说重启,达到避免问题的角度,我觉得这个层次就已经非常好了。

下一个咱们还是谈一下具体监控这块,咱们应该怎么规划?首先准备这块就是一些公共服务,下面监控方案有多种多样,后面具体讲监控方案到底是怎样的方案,咱们有通过被动的,有通过SNP等等方式很多,这个方案也是比较常规的,然后去处理,关键在上面的数据分析,这块就涉及到AIOps的几个点。
其实现在做AIOps,咱们各个企业都是在AIOps几个点上去做,并没有说咱们这些在AIOps这块,并没有说做的非常有完全落地的场景,大家只是在这几个点上去努力。

image.png-96.6kB

下面跟大家聊一下咱们既然要做监控系统,那么咱们首先要有一个目标,咱们要做什么样的监控系统,怎样的监控系统才是比较好的比较优秀的系统呢?我觉得首先要达到这几个指标,及时性,故障在第一时间告警并通知管理员;准确性,不漏报,不误报;精确性,秒级监控、细粒度;兼容性,兼容各服务器,应用、中间件;扩展性,插件式、易扩展、不改代码;可用性,高可用、无单点故障。

右边有一些能力层次度模型,最底层就是仅仅告警而已,再往上以资产为基础,这时候已经引入资产的概念,其实监控、资产和运维他们的关系,资产可以说是监控的基础,作为一个基础数据,有些系统是没有去管理资产,避开了这个问题,但是如果你没有资产的话,其实很多东西做到后面也做不了,必须把整个资产维护准确,这样才能维持我们整个监控数据关系的准确性。

还有就是会分析一些趋势状态,为决策层提供一些依据,自动化的流程,从平台化向流程化这样一个转变。只依靠平台,平台只是一个工具,最终我们要通过这个平台建立完整标准的运维修成,一旦流程建立起来,那么我们很多事情都会变的非常容易,所以我觉得我们监控平台也好,运维平台也好,我觉得重在流程的建立上,通过自己的平台,通过这个工具,能够实现流程的标准化,这样能够提升很大的构成效率。

再往上可能就是我们可以通过数据挖掘方式,挖掘数据价值,再往上就是AIOps这层,预测。当然AIOps从这个图上来看,它不是一蹴而就的,是与底层息息相关的,假如说资产没做好,监控没做好,数据都没有准备好,那AIOps其实肯定也不会做的很好。

image.png-112kB

既然刚才提到CMDB,我这里叫可靠的CMDB,刚才其实我说了CMDB一个最大的问题就是不可靠,现在上云之后它的变化非常频繁,扩容、缩容,当然不光是机器的变化,有些业务关系,业务规则的变化,比如说应用,应用下线,应用负责人,应用成员变化其实都是影响我们整个CMDB结构都会发生变化。
那么应对这种变化通过几种方式也无法完全避免,我觉得通过咱们这五个方式的结合,才能够有效的解决这个问题。
第一个就是自动发现,咱们可以给一个IP段或者给一个协议等等,都可以去做到自动发现。
另外一块就是通过业务接口的方式,像我们京东有太多平台,有很多平台并不是我们自己的平台,通过系统之间的监控去反映资产变化。

还有一个方式就是定时同步,可以做一些定时任务,因为接口有可能有一些历史原因,有些系统也没有接口,有些系统提供的接口可能是不满足我们的,可能也是全量的,需要我们去同步。再有就是流程化,这个其实跟我们京东物流自身业务关系比较大,因为我们在每个仓,开关仓的时候会需要机器的上架,下架,断电等等,这些状态,这里有一个平台,这些管理都在我们的平台全面去管理。

如果跟平台做的动作,流程平台去打通,这样我觉得也是能够确保我们的资产,有任何的变化都能反映出来。最后一个补充方式通过手工的方式,这个也是不可避免的,比如说有些机器坏掉了,有些机器负责人变了,可能知识本身没什么变化,只是负责人变了,那咱们系统也无法探测,这个情况就得通过人工维护了。

image.png-136.9kB

下面其实就开始讲到CMDB有了之后,就介绍一下整体监控架构,其实这个架构来讲也算是比较常规,大家做监控系统流程基本差不多,采集分析决策处理,采集有很多种方式,咱们业绩常用的采集,有一些主动监控,还有一些被动接受,有些调接口的,有些通过标准协议的,方式多种多样,在这块目前都比较成熟。

在分析这块我们说到数据,后面会讲分析的架构,这块要做到监控数据的准确,要求我们这个价格一定要适应场景,因为监控系统和其他业务系统有一个最大的区别,其他业务系统是跟时间,跟业务相关的,他们繁忙程度可能在凌晨业务量少,他们的压力就少,但是监控系统是24小时不停运转,压力一直很大,所以这对我们架构设计会提出一些要求。后面选择和处理,后面我也会涉及到,有一个事件处理引擎。

在监控数据处理这块,这个架构是我们底层数据的架构,其实我觉得这个就从两方面来讲,第一方面就是上层的业务架构,其实业务架构就是对我们整个监控系统,我们的业务数据进行查找,进行可视化,类似于跟前端业务相关的这些东西,但是还有非常重要的一块就是我们底层监控架构。

image.png-68.9kB

这块就是上一页我所讲的监控的分析,咱们这个监控数据在系统底层到底怎样处理的,这块咱们就从底下开始看,我们这边通过agent的方式,它可以把我们的监控指标统一收集。
通常情况下,我们接一个kafka就够了,也可以实现并行的消费,比如说我们可以建多个分区,每个分区去并行消费,提高整个系统通用量。但是基于另外一点,我们考虑还有另外的方式会占更少的资源,因为kafka如果我要建多个consumer的话,那么它就会占多个IO,对我们硬件服务器的要求也会特别高。
我们当时用的一些机器都是用Docker,Docker自己的IO能力是有限的,并不是物理机,我们就通过这个方式加了一层redis queue,并不是做缓存,而是做队列,这样就能够实现一个生产的消费者模式的消费队列,这样我后面可以接多个consumor,这样消费性能就解决了刚才的问题,所以这个方案,kafka这里只需要一个分区就可以了,这样对IO的压力特别小。
再往上又是监控到后台的分析,告警,时间处理等等,这些东西目前来说也比较常规,这个不存在什么大的难点,因为这个是通过MQ,如果我这个机器挂掉了,其实整个机器的状态就没法监控,它的存活状态我们也没法确定,那这怎么办?我们这边会有一个心跳服务器,心跳服务器会定时跟他们同步,如果发现有两个监控周期没有收到数据,就会给他主动一些东西,如果没有响应,我们就可以断定它的状态,是连不上了还是挂掉了。

image.png-122.9kB

刚才我也有提到就是兼容性对咱们监控系统,最开始的规划里面还讲了,监控在整个运维体系的维度,站到那个高度去统一规划,如果一旦规划不好或者规划有问题,考虑不足,就会导致一个公司内部会有很多的监控系统,同时存在。

其实我们做的监控系统,不只在硬件兼容性方面,在一些软件,一些监控的兼容性方面也是做了很多的尝试,把我们目前现有的所有监控还有一些库房等等,这是历史遗留的也好,或者有一些机器不属于运维,但是是我们要用的机器,它们都分布在不同的平台上,我们对这些数据做了统一整合。

image.png-78.3kB

第一个好处咱们能在一个平台,咱们要去看的话研发要登到每个平台都要看一下有没有问题,现在很方便,我们只登陆一个平台就以。

第二个好处就是特别明显,第二个好处我们每一个原来都是独立的,比如说数据库平台,你只能看数据库的状态,我们统一整合了之后,我们对建立应用关系,我们就知道在一个应用维度来说,这一个应用我们能够看到它的全貌,一眼就能看到它到底哪个地方有问题,而且我们还可以基于这些数据,基于应用的所有数据做一个统一分析,我们可以给你定出来到底哪里有问题。统一整合分析会更具有优势一些,也能发挥我们整个所有监控系统的能力。

下一块我们就要再讨论另外一个话题就是异常检测,这块已经涉及到AIOps在异常检测方面,都是AIOps里面比较常规要做的事情。在这一块我给大家分享几个方法,第一个方法就是我们去跟前一个时刻数字相比较,如果波动,绝对值大于某一个数,这样的话就认为他会报警,这样其实缺点非常明显,只考虑相对两个之间值的变化,肯定是不全面的。

image.png-59.9kB

我们再看第二个方法,我们可以根据同比和环比的维度去考虑,同比和环比就是考虑咱们以同一时期或者前一段时刻去比较它的变化幅度,这个误差也是比较大的。

image.png-53.4kB

我们再看第三个方法,是基于基线的,我们做智能监控,有些企业也做过基于基线的阈值,咱们固定阈值已经满足不了咱们的需求了,因为有些事务是随着时间变化的,咱们可以通过建立基线阈值,去给他比较。

image.png-66.2kB

这块其实是能够反映一定问题,但是仍然是有一些限制,咱们这个基线落差也比较大,还有什么方法呢?我觉得第四种就是基于预测,我觉得这个方法是目前我们实践比较好的,我们可以对当前的数据做一个预测,这个预测值和我新收到的值,他们俩之间的差异,他们俩差异如果超过一定幅度,那我可能觉得这个不符合常规。

image.png-77.1kB

其实预测这块是有很多方法,这些办法在整个业界其实在算法界都已经是比较成熟的算法了,比如说这个ISPM,长短期记忆的人工神经网络。我们主要用了这样一个去做持续数据的预测,也取得了非常好的效果,其他也有尝试,但其他可能在效果上可能会稍微差一点。

在流程上我觉得它的过程是这样的,咱们首先会对历史数据做一些预处理,比如说过略掉一些时间点,因为有的数据并不是严格按照时间过来的,还有一些无效的数据,我们会把这个历史数据做成一个周期数据。

为什么做周期数据呢?因为我们所有的预测都是基于实际数据的,所以要把它整理成一个周期性的数据。然后预测,会出来一个预测值,然后跟我们实际收到值去比,如果超过一定的阈值,这时候就可以触发告警,这是一个良好的思路。
除了这个业绩还有稍微高级一点的,我们也可能听过,就是三次预测变化,这个算法是基于一次二次指数平滑,慢慢去优化得来的。一次指数平台其实就是对当前值,预测值做了权重,权重不同,然后进行去平滑计算。
二次指数平滑对一次平滑做了优化,以一次指数平滑结果再次做一次平滑,就会使预测值更精准一些。预测算是一个斜的直线。那么到了三次指数平滑,它其实又增加了一个非常关键的点,就是一个季节性,日期的因素,有三个参数可供我们调整,这个因素就可以考虑到我们季节性,时间,比如说业务可能在白天业务比较繁忙,晚上这种差异,这种算法可以体现出来。
那么它也会有一个预测值,我们会比较这个预测值,这是在异常检测这块,那么下面是讲一下我们对调用链这块做的尝试,其实我们和整体做了一个整合,首先也是非切入性,在金融内部,调用链监控也有好几个,我们至于做这个的初衷,其实在研发介入的时候,可能会方便一些。

image.png-80.2kB

第二就是在调用链这块,的确可以很完整通过我们写一些插件,完整把我们公司内部的中间件,还有一些深层次的调用等等,它这个链比较相信,所以方法站都比较精确。

image.png-85.9kB

另外它有一个问题,它的对应用性能的影响,相对来说比其他的这种调用链的方案会多一些,因为它是基于直接增强。但是我们也做了一些优化,最终这个性能的影响是在3%左右,我们是能够接受的。
比如说做了一些采样,做了一些数据读取的优化,一些数据传输的,协议引入等等,还有一些常量池,可能都能加速我们的调用链的采样。另外一个就是我们将调用链这块数据,都可以通过我们的一些收集,统一的处理,这样就形成相对完整的方案。
在我们这块其实我们是可以检测到一个应用拓扑,我们可以通过报警报出来,后续我们会集成优化。那么下面讲一下我们在事件处理这块,我们很多都是基于一些规则的,我们现在也是基于规则,但是这个规则来源于我们的规则库。

知识库到底解决了哪些问题,咱们怎样用好它?在告警输入孩子是事件或者是工单等等都可以作为输入源,咱们可以从库里面去找到相应的一个执行的模块,我们在执行引擎会去区分,人工处理可能有时候是危险操作,也有可能是不确定,不确定的动作,所以人工来做的。

在这个时候我们不管是人工还是自动,权限和审计都要做好,可以做一些事件回溯,人工处理后面对接到IT,运维流程,流程系统打通。

image.png-61.7kB

刚才我们提到知识库,知识库这块我们也是有一些很多来源,比如说咱们的一些监控数据自动化分析结果,咱们分析的定位结果,也会自动落到知识库里,此人为你可以做一些标记,哪些故障,是哪些原因,都会入到知识库里。知识库也是慢慢迭代,也会直接关联我们的规则引擎。
做好一个智能知识库,对一个AIO来讲,我觉得在智能知识库这块,也是很好的点,很值得我们探索的点。这个东西一旦做好了,咱们还可以向很多方向去发力,比如说咱们智能问答机器人,咱们运维最怕的就是很多研发都来问我们,我们做的都是类似于客服解答问题这样一种工作,我们对AIOps的期望比较远,我们希望基于这个能做出来一个什么呢?比如说智能问答机器人,只要我能学习到都可以给你做出解答,这是我们希望做到的。

image.png-142.1kB

3. 面向AIOPS的智能监控最佳实践

下面跟大家介绍几个最佳实践,第一个我们要说的就是拍照,因为我们经常有一个场景是什么呢?比如说凌晨两点出现故障了等情况,那么这时候咱们即使第一时间通知运维人员,他爬起来登系统里面去看,这个现场也可能已经没有了,比如说CPU升高了,你打开电脑已经降下去了,这时候这个现场就已经丢失了。
那这个我们怎么做呢?如果触发报警,在前面所讲的事件处理里面,就会打一个快照,这个快照文件有一点存在机器上,不会把它发过来,一旦出现问题,那么代表要么是机器有压力,要么它快坏了,总之它有问题,我们会尽量减少传输,不会再对它做一些传输,做一些其他的有压力的一些动作。
所以这个文件是直接存在本地,因为有时候我们打快照,会把站打出来,打一些站内容也比较大,不适合传输。另外这个日志在机器上存储50个文件,多了可以覆盖。

image.png-94.1kB

我最开始提到一个,京东物流全国仓储分布如此广泛,它遇到最大的问题是什么呢?这个网络是非常不稳定的,这个网络有可能某几个省市比较快,某几个省市比较慢。还有现在特别是国际化的一些仓在国外,他们延迟就不控,我们采集数据都采集不到。

我们检测报警的时候,检测联动性连不上了,也会产生很多误报,那这个问题应该怎么解决呢?我们是这样考虑的,我们会构建一个网络检测的拓扑,从咱们这边监控服务端,IDC开始检测,我所有要管理的机器,都会先连一下,看一下这个延时情况,如果延时在可靠范围内,我们目前定的是20毫秒,如果低于20毫秒,它这个数据可以汇报到我们IDC监控端,如果不行就可以从他的节点,他也会找寻下一节节点,也会去聘期他们这个省,这个市,他们一个地域的节点,聘完之后也会找到一些。

也有一些同样的延迟比较低的节点,他们就会直接汇报给他,最终因为每个省对外都有一个统一的出入口,这个和IDC的连接非常快,这时候就可以完成数据的汇报,这样的话在检测一些联动性,其实是这个节点在检测他们的联动性,所以他们的节点联动性就需要他直接检查了,有一些问题报警,他也会直接汇报给他,其实国际化也是这样做的,这样实际上本质就是把一些网络状态连接比较好的机器,然后他们形成一个小的检测网络,他们在向上汇报。

image.png-83.5kB

另外一点,这个不是一成不变的,是实时在变的,假如说发现这里有问题,会触发重新构建一次拓扑,因为咱们资产变化也不可能一直不变。另外一个就是在预测这块,这块刚才已经涉及到了LSTM等等很多算法,我觉得这块咱们要关注的是什么?算法匹配度,比如说我们系统能够自动匹配算法,自动根据选择合适的算法,还有节假日要适配,这块如果考虑了可能就是我们会做的比较好一些。

image.png-85.1kB

在可视化这块,这块不管是哪个公司,都会遇到这块,给大家看一下。

image.png-279.9kB

4. 规划&展望

下面说一下咱们的一个规划,我觉得第一块就是从迭代优化这块,比如说我今天就从三个方面,咱们监控体系,学习构建已经差不多OK了,监控平台也都有了,我们后续这个路怎么走?我觉得首先技术架构这块,AI和算法仍然是我们最核心的一个技术点,在这方面也会投入更多精力。

在产品架构这块目前我们的研发策略是聚焦业务和业务服务,我们其实对于监控产品里面做的很多东西都是直接面向业务面向应用的,我们会发现都是以应用为单位,研发来看咱们的东西也是从应用角度去看,极少数会从IP维度去看。

另外产品这块要注重一些模块化,提高一些产品的复用,还有产品这块我们应该树立,人人都是产品经理这样一个理念,其实我们实际发现团队中有些人写代码写的特别好,但是缺乏一些产品,你让他做什么就做什么,对于这个之外能不能做一些优化,这个东西怎样从用户的角度去做好产品呢?这块做的是不够的。
另外在组织架构这块,主要我认为就是AI这块,AI算法以及运维结合,这块也是我们团队结构后面在努力做的事情。

image.png-71kB

最后一个点我觉得给大家分享一下我们在AIOps这块的规划,其实我觉得还是从顺序来讲,采集分析决策处理,其实这里面我可以归纳为三个方面,第一个就是发现问题,采集和分析。
决策和处理它们是解决问题,我发现了我能解决,但是第三个我能够规避问题,这个达到我们AIOps最高的层次。在采集这块没有什么说的,主要是分析已经涉及了很多,其实我们还是有很多可做的东西。决策这块异常的反馈,工作学习,决策处等等这些东西也有很大的发挥空间。

在处理这块主要以来于我们的直接处理引擎,去做人工,自动的等等,其实最后一个我觉得在规避问题这一块,这块如果真正做好了,咱们运维的使命就算达成了,不出问题,对于整个公司来讲,对于整个领导来讲,咱们不出问题,能够规避到很多问题,提前考虑到,能够预测到,还可以做一些决策的支持,这块体现在哪呢?某一个厂商的机器,统计一下这个故障率最高的是谁,那么可能在决策上,咱们是不是可以减少它的采购量?或者是哪一块硬盘故障率比较高,其实这些东西都是可以做一些预算的建议,决策的支持,这同时也是咱们AIOps,不光是能够节省我们的减少运维故障量,也是管理层带来很多价值。
今天这些就是我今天要分享的内容,谢谢大家。

image.png-78kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注