00:00
那么现在就来对它进行一个压力测试,来打开解密特,还是测试我们这个catallo杰S,那么这50个线程,来现在来给它启动起来,那现在来看一下我们新改的加了缓存以后的吞吐量,好来看汇总报告,发现这个吞吐量呢很高,但是这一块异常也很多,几乎有100%的错误把这个停掉,那这块异常的原因是什么?我们来查看结果数,来看这块异常,这有response data,我们返回的数据,返回的数据呢,这是一个接层数据,这会报好多的异常,包括我们现在来看我们的这个服务来刷新,发现我们这个服务已经崩了,那说明我们这个还有问题,那崩了的最大原因在这,他说有一个red异常,说明这个嵌入式的异常叫LIS,它是在这IO使用native在这来操作的时候,出现了一个out of direct。Memory error,这个我们把它叫对外内存溢出,我们看到这是out of memory,那是内存溢出,但是direct我们直接内存,也就是说Nike它是来直接操作我们对外内存的,我们会就会产生一个对外的内存溢出,那这是一个非常严重的问题,而且呢,如果我们项目上线以后长时间运行也一定会出现这个问题,那我们目前出现这个问题的原因什么?这个内存不够,来看一下我们的这一块内存来打开,那么当时在运行的时候呢,只设置了一个100M,但是大家注意,那么这是设置的虚拟机的100M,并不是我们这一块异常指定的什么对外内存,我们来重新压测给大家看一下,比如呢,我设置另外一个,我们把它设置一个300M,我们不设置的很大,我设置成一个300,我们把它点一个保存,我把这一块清掉,我们让它重新启动,我们让它变为300,我们用解微。
01:55
我们连接上,我们来监控一下接微收。走。
02:02
我们连接上我们的商品服务,好来点进来,我们现在来看一下我们这个商品服务能不能提供正常功能,我们刷新一下。啊,现在呢,我们这个数据是出来了,要说我们在这儿自己测试,只要不来进行压力测试的时候没一点问题,但一旦大并发一进来,压力测试一开始我们就出现了内存崩溃原因,但崩溃是不是我们这一块GC的问题呢?我们可以来监控一下,好我们在这儿呢,重新给它进行一个压力测试,我们把这些结果数一定清空掉,好我们来重新运行,走它持续运行期间呢,我们来看这一块,我们发现呢,这个伊甸园区满了,它一清理我们的这个老年袋,它也没有做完全的移除,包括我们这个Meta spacece,我们的圆空间一直也没有占用多少,说明我们这一块是没什么问题的,但我们来看压力测试报告,那压力测试报告呢,我们开始出现异常,开始出现异常,虽然通吐量很大,但是没有什么意义,我们来把它停掉,那这个异常的一出现,我们来刷新,就是我们这个异常就是我们说的。
03:05
堆外内存溢出的异常,我们把这个异常一定给大家记录在这儿,我们后来上线以后,我们要仔细来排查这个异常,好我来写一个凸度,我们现在呢,会产生我们对外内存溢出,那对外内存溢出的原因我们可以提前给大家说一下,原因呢是这样,首先我们这个spring boot整合的这个red场景,我们来给大家看一下,那spring boot呢,我们引入了data read,它里边操作RA用的客户端是这个LIS,好把这个复制过来,我们说spring boot。My spring boot2.02.0以后,我们这个默认呢,是使用默认使用我们这个LIS作为我们操作red的客户端,而这个客户端呢,它最大的特点,我们来点进来看一下这个LIS里边。
04:04
他操作客户端要跟red建立连接,要进行网络通信,他使用的是nit来进行网络通信,然后呢,来说一下,他使用他使用们这个Nike进行我们这个网络通信,这个nit呢,如果大家想学也是非常不错的,我们韩世明老师给大家详细讲解了netty,大家仔细进去学一下,然后就是因为他和nety进行配合使用,他的这一块操作没做好,导致nety的对外内存溢出,所以呢,我们主要的原因就是letters的bug bug导致我们这个对外内存溢处。我们这是导致我们net操作我们的对外内存溢出,包括呢,我们想要看,我们看一下这块报的异常,来提前给大家早早的看一下,他说out of direct memory error,我们出现内存溢出异常,想要分配这么多直接内存,直接内存就是对外内存,也就直接操作我们内内存条的,来看到我这个内存条,即使我剩不下多少内存,那肯定也够我们这个压力测试用了,但是他还报对外内存,问题就在于柚的已经使用这么多,它要释放这么多,而最大只有这么多,也就是说它的对外内存。
05:24
这是按照字节数算的,它是严重不足的,大概只有270兆左右,而我们想我们从来没有设置过这个对外内存,为什么会是这样呢?原因就在这,我们来看一下,我们这来编辑这一块的时候,我们设置了一个最大是300,设置了一个这个最大是300,我们说媒。那么如果没有指定,如果没有指定对外内存,它呢,就默认会使用使用我们这个XMX指定的这个值来作为对外内存,所以导致我们这个并发的时候,由于我们获取的这个数据啊,量非常大,我们高并发一进来,我们数据在转换期间我们都要占内存,我们传输期间要占内存,导致我们整个内存分配不足,对外内存溢出出现了我们这个问题,而且呢,我们也发现,当我们来调大这个内存数的以后,们压力测试不会一下就出现对外内存溢出,会压很久以后才出现,如果我们无限大的调整我们这个内存,我们这个对外内存溢出呢,就会很久以后出现,但是它永远都会出现,出现的原因就是我们没有得到内存的及时释放来,可以看一下它这一块的问题,问题在这说platform这一块。
06:41
他在这儿做了一个判断,说我们新要使用的内存,我们新使用的内存呢,那就是。我们将要占的内存,把以前的内存呢,我们整个做了一个计数发现啊,这是net自己在底层要用多少内存,它在这自己来计数的,它呢,计数一旦超过了我们这个直接内存限制,我们在这儿这个直接内存限制一旦超过了以后。
07:07
我们就会在这抛异常来大家F搜索一下,而且直接内存限制它默认用的值是什么,我们来看这个logo debug,我们就能看到它默认用的值啊,我们是可以通过这个虚拟级运行参数设置的,也是杠D。Must direct memory,也就是说我们可以通过这个设置不设置默认就使用它的这个设置项,我们可以通过可以通过这个进行设置。行,我这一块呢,大概给大家说一下,大家有这么一个概念,也就说我们这个letters加上我们这个net,最终会导致我们这个操作出现对外内存溢出,而我们想要避免这个问题,我们的解决方案。解决方案我们只来调大这个是不行的,不能只去来使用我们这个虚拟机参数来调大这个,不能不能使用这个只去调大对外内存,因为我们刚才测试了,我们虽然调大了一个这个内存,只是延缓了我们出现这个异常,我们在长久的运行期间累积以后们对外内存还会溢出,所以我们真正的解决方案有两个,第一个是升级我们这个letters,升级我们使用的这个letters客户端,我们来指望这个客户端不会给我们操作net出现异常,这是第一个,然后呢,第二个我们也可以直接来切换使用,我们还有一种操作red的括后端,我们叫接edit,我们切换使用它也行。
08:46
那目前呢,Letters客户端还没有一个完美的解决我们对外内存溢出的,他在客户端操作的时候呢,没有及时的释放掉连接,比如我们这个连接出异常以后,把这些资源等等,它可能没有及时释放掉,导致我们这个对外内存溢出。
09:02
那大家可以去来修改源码,如果还想要用它的话,但是呢,我们可以用最简单的方式来直接切换使用简ad,这是一个老版的客户端,它的缺点就是它好久没更新了,而letters的优点就是它使用net作为底层的网络框架,它的吞吐量是极大的,所以呢,我们想要解决这个问题,我们通过刚才的线上定位,我发现我们的这块GC并没有出现什么内存溢出,那所有的内存溢出都是我们在这儿底层来操作net的时候产生的这个问题。所以呢,我们来两种办法,升级客户端,或者切换使用简ad,那我在这呢,我就来切换使用简ad,当然把这个问题留在这儿,我们线上以后呢,我们切换成letters,然后把这个错误呢,我们也可以通过线上日志的方式,我们再来排查一下,好我们来到po文件里边,那如何切换使用我们这个简edit来可以看一下data RA里边,它默认呢会引入letters这个核心包,我们就让它把这个排除来写一个X conclusions,好,我们让他直接先来排除我们这个,这样呢他就不会用到letters来操作我们这个red,但是呢,我们要让他用解edit,所以我们就得继续来写上依赖dependency,我们直接来写一个解A,我们也无需写上版本号。
10:27
所boot呢也都会默认进行控制,而且我们默认来看一下,我们现在是218版本来点进来一定要确认这个dependences里边有我们这个解。我们发现这有这个简ad version,好我们来搜索一下,所以这一块呢,版本都是控制好的,293没问题,来引入这个以后来重新启动一下,把这一块内存呢,我还调成我们原来的方式,比如我来调成100,我来调成100,好来调成100,然后呢我来重新启动。
11:00
走,那重新启动了,我们这一块的连接就有问题了,这一块就断线了,然后呢,我们来确保我们这个首页能被访问,我们来稍等它启动完成。我们来刷新一下我们这个页面,好,我们发现这一块呢,我们获取到数据了,然后我们再来进行压力测试,那压测之前我们来连接上我们这个商品服务,我们来观察一下我们这一块的GC,我们现在分配了100,那么这个老年代里边可用呢,还是有非常多的,好我们现在来看一下们来压力测试,我们把这一块的报告我们来都清空掉,来重新来进行压力测试,走,我们切换了客户端使用以后来看一下汇总报告来我们的吞吐量将近400,我们没有出现任何错误,我们来看一下那这一块的监控们,这个老年袋呢,慢慢的也会变满,满了以后呢,一来回收,回收以后呢,又甚一点发现这个老年代啊,还是内存比较小的,我们可以自己来调整更大的内存,但是我们发现这一块的吞吐量有400多,没有出现任何问题,那这就是我们来通过切换客户端,我们来解决了这个问题,而且吞吐量好,我们把这个复制过来,我们以前的吞吐量压力测试。
12:11
只有100多,但是呢,我们整个给它加入缓存以后来我们把这个三级里边,我们来给下方插入行,我们现在是我们的三级分类,三级分类我们现在使用red作为缓存,使用red作为缓存,我们现在吞吐量呢,就由411,比原来呢提升了四倍左右,包括我们来看一下他们的响应时间们来看聚合报告,90%呢1.53。99%呢,217,好,我们来写一下153 153和217,我们发现我们的响应时间也缩短了很多,所以这就是我们使用缓存的最大好处,但我们遇见的这个坑,我们给大家呢,留在这儿,我们也给大家填了一点,我们发现呢,Net在底层,它是自己在这计数,只要数字呢,出现它的这个默认的容量限制,那它就会在这儿抛出异常,这个异常就是我们刚才看到的对外内存溢出的异常,也就是说net底层只要有操作,他在这来自己来统计内存的使用量,而操作完了呢,他还在这儿会减内存的使用量,那一定是我们的letters客户端在哪一块操作的时候。
13:26
没有及时的调用掉我们这个减内存,导致我们对外内存移除,那除了升级,那就是更换,我们最终呢选择了们最终的更换,而且呢,这个异常我们也留给线上,我们线上呢再来切回letters,我们来监控我们整套日志以及问题,我们来看线上再来如何定位这些错误。好,目前呢,我们就先来这么来解决。这个另外呢,我给大家来补充一点,大家在下边呢,好多同学会有一个疑问,说我们使用的这个red tablelt,我们明明是拿它来操作我们red的,但是呢,我们又说这是底层用letters和这个简edit,它们之间的关系是什么?我们来捋一下,就是我们说的这个,无论是letters也好,还是我们这个解edit也好,这都是操作red的最底层的客户端,这是操作咱们这个red的底层客户端,这个相当于封装了我们这个red的一些操作API。而我们。
14:29
无论是使用letters还是简edits spring,为了简化期间把它们都再次封装,相当于这两个的再次封装,由对他们两个进行了再次封装,封装成了一个我们这个red time,所以我们以后啊,无论底层使用letters还是解我们操作red,直接用red template就行了,而且通过它的自动配置,我们也能看到这个关系,比如CTRLN,我们来找一下们以前的这个red auto configuration,找我们218版本的点进来,我们发现呢,它在这配置的时候,Import导了两个东西,一个是letters的connection configuration和解edit的这个conration configuration,就说无论你是用简edit在底层来连接red也好,还是letters连接我们这个reddi也好,它都是兼容的,那最终呢,无论是谁连接,最终他们呢,我们来点过来看一下,他们都会给容器中放一个这个连接工厂。
15:29
那这个连接工厂呢,最终就是我们这个redt操作要用的就是这个red connection factory。无论我们是使用哪个连接,最终都会得到这个连接工厂。这就是我们spring对这个做了一个底层封装,那他们呢,就是这么一个关系,我们在后来直接使用red table就行了,当然想要使用底层的简历操作也是可以的。这个呢,大家知道一下就行。
我来说两句