【每日鲜蘑】一时Vert.x一时爽

20,130 阅读4分钟

Vert.x 异步框架

开源的 Vert.x 其实不是一个框架,而是一个以“异步非阻塞”编程模型为核心思想的工具集。而“异步非阻塞”编程模型在IO密集的应用中提供了更好的性能。

Vert.x和我

第一次接触Vert.x是在2016年,觉得全异步编程是一件很有意思的事情。那时,努力的去消除等待造就了互联网的繁荣。

  • 滴滴正在消除打车等待的时间;
  • 美团饿了么正在消除用餐等待的时间;
  • 人像识别智能推荐等新型技术也在消除各类各样的等待时间;
  • 医院可以在线挂号了;
  • 银行可以在线排号了;
  • 看电影都可以在线选座了;
  • 在线支付消除了人们付款的时间;

消除等待的的思维正在影响这个社会,也影响着人们的生活方式。而在编程技术圈,全异步也越来越被接受。前端技术的发展流向会影响到后端技术的发展,那时候前端异步已经完全成熟,而后端也有一大批新的异步框架产生。从那时起,我开始学习Vert.x.

刚开始使用Vert.x是用来做第三方调用测试的。当时由于第三方提供的服务不太稳定,而且有字端变更时也有时不会通知我们,所以就写了个服务脚本,用来探查第三方服务的可用性和是否有变动等等,当时使用的感觉还不错。

PS: 个人对RSocket充满了期待...

Spring Boot的比较

与SpringBoot的性能对比

有一天,另一个公司的朋友打电话问我:“Spring Boot查询Redis中的数据,QPS是1600正常吗?”,详细的服务器配置如下:

压测描述:调用SpringBoot的Http接口,从Redis中取得Key=aa对应的Value,Value值也是aa。
服务器:2核4G
框架:Spring Boot
数据源:Redis
数据源驱动:Lettuce

压测结果描述
压测QPS:1600
CPU:60%

具体的压测指标并没有仔细询问,但是第一反应还是觉得不太正常。毕竟正常的Redis提供数万QPS还是很轻松的。

之后,我使用Vert.x在现有服务上编写了一个简单的接口进行测试,QPS基本可以达到27000左右,而CPU占用20%左右,远远没有达到压测的极限。

服务代码(简单)

private void queryRedis(RoutingContext routingContext) {
    @Nullable String key = routingContext.request().getParam("key");
    // @TODO 处理key为空...
    RedisFactory.api().get(key, ar -> {
        if (ar.failed()) {
            routingContext.fail(ar.cause());
            return;
        }
        routingContext.response().end(ar.result().toBuffer());
    });
}

启动参数

java -XX:MetaspaceSize=32m -XX:MaxMetaspaceSize=128m -Xmx256m -Xms256m -XX:NewSize=1 -Xss256k -XX:-UseBiasedLocking  -XX:AutoBoxCacheMax=20000 -XX:+AlwaysPreTouch -XX:-UseCounterDecay -XX:-TieredCompilation -jar luckin-resource-1.0-SNAPSHOT-fat.jar run com.jiaomatech.luckin.MainVerticle

wrk压测命令

wrk -t8 -c128 -d90s  http://127.0.0.1:8081/app/redis\?key\=aa --latency -- / 16

首次压测(纯属娱乐)

首次压测

首次压测

首次压测JVM监控

首次压测JVM监控

第二次压测(纯属娱乐)

第二次压测

第二次压测

第二次压测JVM监控

第二次压测JVM监控

总结(纯属娱乐)

Running 2m test @ http://127.0.0.1:8081/app/redis?key=aa
  8 threads and 128 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.70ms    1.56ms  35.83ms   75.38%
    Req/Sec     3.44k   421.98     4.53k    69.32%
  Latency Distribution
     50%    4.43ms
     75%    5.43ms
     90%    6.61ms
     99%    9.94ms
  2462183 requests in 1.50m, 93.92MB read
Requests/sec:  27341.00
Transfer/sec:      1.04MB

没有对比就没有伤害,Vert.x256M的内存下跑起来很轻松。Spring Boot想要在小内存下启动会困难的多,而且CPU的消耗也会比较大。

Vert.x 常见应用场景

并非说Vert.x只适合这些应用场景,但个人认为我们在这些应用场景中,可以获得更好的收益。

资源服务

这是一类IO密集型的服务,数据可能来源于MysqlRedis等等,相比于Spring Boot服务,Vert.x在同等硬件条件下可以提供更好的性能。

简单服务

Vert.x编写一个Http服务或者WebSocket服务是十分快速的,特别在短期项目开发中,这将是个不错的选择。比如在已有的服务上增加一个双11模块来专门应对关于双十一的活动。

快速编写&快速消亡

很多服务其实生命周期是很短暂的,而Vert.x基于Verticle部署服务的方式,十分适合短命的服务,我们只需要在合适的时候将Verticle部署上,在不需要的时候将Verticle销毁。

为APP提供服务

2019年底,我将Vert.x引入了公司里的技术体系,在第一个项目的使用场景就是为APP提供服务(一个类似于Luckin Coffee的食品快销APP),包含支付、订单、券、活动等等模块,效果还不错。而PC端由于大多是一些增删查改的操作,使用人员数量也相对较少,就直接使用Spring boot做简单的编码。

其他

在了解Vert.x之后,总能在应用中找到其体现价值的地方。