关于Vert.x结合SpringBoot结合使用的一些想法

Vert.x是最近才开始玩的新玩具,仓库地址Github。然而截止到目前(2018/3/6),vertx已经发布到3.5.1版本了。SpringBoot我是在1.3.x年代开始接触的,现在2.0.0.RELEASE版本都已经发布了。
这两个都是很牛逼的项目,不用多说,目前的项目里我都有实际在使用,都帮助我解决了很多问题,提升了效率。于是很自然的想法,如果把它们放到一起使用,会是怎样一种体验?做肯定是能做的,但是效果如何?会不会抹杀vertx灵活高效的操作模式?这样结合的好处在哪里?是弊大于利?还是搞个四不象出来了,不伦不类的?
思考了一段时间,我决定把我的想法写出来,希望有人能跟我一起探讨下这中间的操作空间在哪里。

1.用代码说话

我再github上放了一个demo,附上地址:Ivan97/iooo-vertx-bundle

一共三个分支,有兴趣的可以跑跑看,master分支与springboot-vertx同步,这是springboot结合vertx搞出来的,pure-vertx分支是单纯的vertx组件搞的。
项目基于jdk1.8,构建工具用maven,项目目录下执行mvn命令就能跑起来。

我就主要说说springboot-vertx分支的代码吧。

整个工程很简单,是在pure-vertx分支上面改出来的,加了springboot的依赖。常规的启动方式:mvn spring-boot:run,效果如下:

看代码去分析的话,就是用springboot去管理verticle的生命周期,管理依赖和配置,之后可以加入更多东西。

用spring管理一个Vertx实例。

1
2
3
4
5
6
7
8
@Configuration
public class VertxConfiguration {
@Bean
public Vertx vertx() {
return Vertx.vertx();
}
}

初始化BoosterVerticle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@SpringBootApplication
public class SpringBootVertxApplication implements CommandLineRunner {
@Autowired
private Vertx vertx;
@Autowired
private ApplicationProperties applicationProperties;
public static void main(String[] args) {
SpringApplication.run(SpringBootVertxApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
vertx.deployVerticle(() -> new BoosterVerticle(vertx, applicationProperties),
new DeploymentOptions());
}
}

BoosterVerticle中定义了两个deploy方法,各自的签名如下

1
2
private Future<Void> deploy(Class<? extends Verticle> clazz, Object... params)
private Future<Void> deploy(Class<? extends Verticle> clazz)

这两个方法都有使用:

1
2
3
//deploy verticles
Future<Void> ioooVerticleFuture = deploy(IoooVerticle.class, new AtomicLong(0));
Future<Void> cocoVerticleFuture = deploy(CocoVerticle.class);

2.假装分析一波

总体上看来,并没有觉得很突兀吧,标准的verticle代码,标准的springboot代码,但是在使用上更便捷吧,配置管理,依赖注入,也可以很方便地实现,当然,vertx本身也可以做到同样的效果,代码在pure-vertx分支上可以看到。但是借助于springboot强大的工程性,可以更快速更方便的表达,我个人认为是完全可行的,是有1+1>2的效果的,代码就这样搞,剩下的就是jvm调优的事了。

附上一个启动脚本吧,写到这里想起来的,没有放到工程里。

用法:放到打包之后的jar包的目录下执行(保证该目录下只有一个*.jar文件)

application.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env bash
# springboot的jar放同级目录下即可,只能有一个jar文件
CURRENT_PATH=$(cd "$(dirname "$0")"; pwd)
JAR=$(find . -maxdepth 1 -name "*.jar")
JAR="$CURRENT_PATH/${JAR:2}"
PID=$(ps -ef | grep $JAR | grep -v grep | awk '{ print $2 }')
#参数说明:
# -XX:MetaspaceSize=128m (元空间默认大小)
#-XX:MaxMetaspaceSize=128m (元空间最大大小)
#-Xms1024m (堆最大大小)
#-Xmx1024m (堆默认大小)
#-Xmn256m (新生代大小)
#-Xss256k (棧最大深度大小)
#-XX:SurvivorRatio=8 (新生代分区比例 8:2)
#-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
#
#知识点:JDK8之后把-XX:PermSize 和 -XX:MaxPermGen移除了,取而代之的是
#-XX:MetaspaceSize=128m (元空间默认大小)
#-XX:MaxMetaspaceSize=128m (元空间最大大小)
JAVA_OPTIONS="-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC"
case "$1" in
start)
if [ ! -z "$PID" ]; then
echo "$JAR 已经启动,进程号: $PID"
else
echo -n -e "启动 $JAR ... \n"
nohup java ${JAVA_OPTIONS} -jar $JAR >/dev/null 2>&1 &
if [ "$?"="0" ]; then
echo "启动完成,请查看日志确保成功"
else
echo "启动失败"
fi
fi
;;
stop)
if [ -z "$PID" ]; then
echo "$JAR 没有在运行,无需关闭"
else
echo "关闭 $JAR ..."
kill -9 $PID
if [ "$?"="0" ]; then
echo "服务已关闭"
else
echo "服务关闭失败"
fi
fi
;;
restart)
${0} stop
${0} start
;;
status)
if [ ! -z "$PID" ]; then
echo "$JAR 正在运行"
else
echo "$JAR 未在运行"
fi
;;
*)
echo "Usage: ./application.sh {start|stop|restart|status}" >&2
exit 1
esac

=========================================

更新一下这篇文章:

关于vertx与springboot结合的的实践,我写了一个新的demo,托管在github。
这种形式的结合应该比之前的好很多。

Ivan97/iooo-vertx-boot-booster

其中使用了ioootech/iooo-spring-boot-vertx-starter来帮助管理vertx组件及deploy verticles

如果你喜欢我的blog,请鼓励我一杯咖啡☕️
0%