本文正在参与「金石方案」

小伙伴们好呀,拖拖拉拉的我,总算把 秒杀项目 布置到云端上去了!

秒杀系统上云,从 1342ms 提升到 138ms

这次过程也比较顺利,建立下 RabbitMQ 就好了。

helm install rabbitmq bitnami/rabbitmq --namespace prod -f config.yaml

不过我发现,每次都得研究下这个配置文件,真的是头大,而且后边假如要装插件,开启插件这些好像也挺麻烦的,像 Redis 的 布隆过滤器,RabbitMQ 的推迟插件 等等。

而且捣鼓到最后,还得打包成自己的镜像才干好好保存下来

越操作越不耐烦,还是写代码省心

这个算是我布置在云端的第一个有意义的 k8s 应用,有点小激动,狠狠地测验下

代码根本没啥改动,简单地调整下这些 host 。

秒杀系统上云,从 1342ms 提升到 138ms

顺手将 redisson 改成了主从,代码中 lettuce 还没修正。

秒杀系统上云,从 1342ms 提升到 138ms

写个 Dockerfile 布置下。

FROM adoptopenjdk:11-jre-hotspot as builder
MAINTAINER Jav4ye
WORKDIR application
ARG JAR_FILE=/target/seckill-demo.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM adoptopenjdk:11-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENV TZ="Asia/Shanghai"
ENV JVM_OPTS="-Xmx512m -Xms512m"
ENTRYPOINT ["sh","-c","java ${JVM_OPTS} org.springframework.boot.loader.JarLauncher"]

秒杀系统上云,从 1342ms 提升到 138ms

单机

秒杀系统上云,从 1342ms 提升到 138ms

下面是 十次 测验成果数据,能够跳到阅读 小结 内容

第一次 均匀呼应 是 1711 ms , 50 % 的恳求是 1808ms,99% 是 2552 ms ,最小是 708 ms,最大是 2961 ms ,吞吐量是 224.1/s 。

秒杀系统上云,从 1342ms 提升到 138ms

第2次 均匀呼应 是 400 ms , 50 % 的恳求是 394 ms,99% 是 1002 ms ,最小是 21 ms,最大是 1198 ms ,吞吐量是 503.3 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第三次 均匀呼应 是 337 ms , 50 % 的恳求是 311 ms,99% 是 791 ms ,最小是 11 ms,最大是 847 ms ,吞吐量是 557.4 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第四次 均匀呼应 是 97 ms , 50 % 的恳求是 85 ms,99% 是 236 ms ,最小是 17 ms,最大是 365 ms ,吞吐量是 745.2 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第五次 均匀呼应 是 124 ms , 50 % 的恳求是 109 ms,99% 是 332 ms ,最小是 11 ms,最大是 3033 ms ,吞吐量是 248 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第六次 均匀呼应 是 84 ms , 50 % 的恳求是 83 ms,99% 是 156 ms ,最小是 14 ms,最大是 217 ms ,吞吐量是 805 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第七次 均匀呼应 是 224 ms , 50 % 的恳求是 224 ms,99% 是 486 ms ,最小是 18 ms,最大是 565 ms ,吞吐量是 657.5 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第八次 均匀呼应 是 92 ms , 50 % 的恳求是 81 ms,99% 是 326 ms ,最小是 9 ms,最大是 3024 ms ,吞吐量是 250.5 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第九次 均匀呼应 是 80 ms , 50 % 的恳求是 72 ms,99% 是 173 ms ,最小是 14 ms,最大是 396 ms ,吞吐量是 789.9 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第十次 均匀呼应 是 72 ms , 50 % 的恳求是 63 ms,99% 是 138 ms ,最小是 12 ms,最大是 347 ms ,吞吐量是 792.4 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

小结

第一次这么仔细的测验,可是这种测验还不严谨,看网上说要 命令行的方法去运行 jmeter 测验,可是我还是偷个懒,这样和上文测验出来的成果也好有个比较。

在上文 《写个简易版秒杀体系练练手》 中,有下面这份陈述

秒杀系统上云,从 1342ms 提升到 138ms

当然,上文的这个陈述是 取最好 的那一次,也便是 预热 JVM 后的成果。

这次,测验了 十次 ,也是 500 并发。

能够看到 第一次 恳求的数据效果十分差!99% 的恳求要 2552 ms,这可能便是没 预热JVM 的状况。

第2次,第三次,效果也很差,可是到 第四次 开始,效果就好起来了 99% 的恳求在 350 ms以下。

最好的一次,是第十次, 99% 的恳求在 138 ms

比照上文的成果,从 1342ms 提升到 138ms ,硬生生提升了 10倍效率,这要是放在生产环境下,那不得把牛吹坏了

次数 均匀呼应 50% 99% min max 吞吐量
1 1711 ms 1808 ms 2552 ms 708 ms 2961 ms 224.1/s
2 400 ms 394 ms 1002 ms 21 ms 1198 ms 503.3 /s
3 337 ms 311 ms 791 ms 11 ms 847 ms 557.4 /s
4 97 ms 85 ms 236 ms 17 ms 365 ms 745.2 /s
5 124 ms 109 ms 332 ms 11 ms 3033 ms 248 /s
6 84 ms 83 ms 156 ms 14 ms 217 ms 805 /s
7 224 ms 224 ms 486 ms 18 ms 565 ms 657.5 /s
8 92 ms 81 ms 326 ms 9 ms 3024 ms 250.5 /s
9 80 ms 72 ms 173 ms 14 ms 396 ms 789.9 /s
10 72 ms 63 ms 138 ms 12 ms 347 ms 792.4 /s

当然,从表中还能够发现,这 网络颤动 还有点大,不知道怎的,这个 max 忽然就卡到 3024 ms 去,严重降低了这个 吞吐量

上文也提到过,最大的问题应该是 网络开支,毕竟还是用了 MQ 异步下单内存标记,**Redis 预扣库存 ** 等手法去优化。

现在都布置到 k8s 上,RabbitMQ,Redis,MySQL 都在上面,就不会有这么大的网路开支了。

接下来怎样优化呢?

现在只有零散的思路,比方吞吐量的话,我可能会测验下这个 reactive 的方法,或许将 Springboot 内嵌的 Tomcat 换成 jettyundertow 试试。

代码的话,试试将 lettuce 也更换成主从模式的看看,再看看 API 有哪些能够优化的。

最主要的,还是这个 JVM ,下次用 VisualVM 连上去看看 JVM 在这期间的改变,看看 CPU,内存,等的改变。

秒杀系统上云,从 1342ms 提升到 138ms

集群(3个)

尽管一向吐槽布置变得麻烦,可是这个点一点就扩容,一下子就变成集群真的太赞了!

所以我在上文提到直接用 分布式锁 就好了,毕竟很难忍住不试下。

一下子变成多个消费者,可是好在用了这个分布式锁,避免了 重复消费订单 的问题。

这也很契合我理想中的代码,业务代码就归业务代码好了,微服务那一套能别离的就尽量别离出来,现在靠这个 k8s 就能完成 负载均衡 了,确实好便利,当然,不便利的就落到 k8s 运维人员身上去了,比方负载均衡策略的调整啥的。

秒杀系统上云,从 1342ms 提升到 138ms

第一次 均匀呼应 是 1705 ms , 50 % 的恳求是 1795 ms,99% 是 3838 ms ,最小是 16 ms,最大是 4155ms ,吞吐量是 157.1 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

第2次 均匀呼应 是 587 ms , 50 % 的恳求是 529 ms,99% 是 2162 ms,最小是 20 ms,最大是 2265 ms ,吞吐量是 388.7 /s 。

秒杀系统上云,从 1342ms 提升到 138ms

这我就有点纳闷了,怎样还这么慢的!

按理说,我这集群是来提高吞吐量的啊!难道是因为我这是 假的集群(都在 minikube 节点上)

秒杀系统上云,从 1342ms 提升到 138ms

成果查看容器日志时,发现居然有错

秒杀系统上云,从 1342ms 提升到 138ms

把日志下载到本地发现,原来是这个 ID 重复了……

之前偷个懒,直接用 hutool 工具生成了,现在变成集群也不好修正呀。

秒杀系统上云,从 1342ms 提升到 138ms

那好吧,先暂时作罢,看来还得把这个 分布式ID 生成器建立下。

那咱们下文见,下文就来看看单机下 JVM 的改变先吧,over!