阅读时间: 4 分钟


什么是Vert.x?
一个典型的Vert.x应用程序由多个顶点组成,这些顶点是可以独立部署和扩展的模块。垂直模块通过在事件总线上发送消息来相互通信。由于Vert.x是一个多语言框架,所以我们可以用不同的编程语言来实现每个顶点。(目前官方支持的语言。Java, JavaScript, Groovy, Ruby, Ceylon, Scala 和 Kotlin)。
Vert.x是无主的,这意味着它不会限制你如何编写你的应用程序。Vert.x的理想用例可能是一个事件驱动的微服务架构。我们也可以用它来构建一个单体应用,或者只是将Vert.x的某些工具纳入Spring应用。例如,它也是非常模块化的,所以你可以准确地定义你所需要的工具,并且只使用这些工具,没有其他的,这就导致了非常轻量级和快速的应用,也可以在小硬件上运行。
只有一件重要的事情,你应该始终牢记。Vert.x是事件驱动的,非阻塞的。所以你通常定义事件处理程序,当某个事件发生时,Vert.x会调用这些处理程序。为了把这些事件传递给处理程序,Vert.x使用了一个叫做 "事件循环 "的线程。我们不应该在你的处理程序中执行任何阻塞代码,因为这也会阻塞事件循环,使整个应用程序变慢。一个典型的阻塞代码将是对数据库的调用并等待结果。幸运的是,Vert.x提供了一些处理这种情况的方法,比如一些流行的数据库的非阻塞客户端,或者将阻塞的代码包装在一个特殊的处理程序中。
优点和缺点
优点
- 编写非阻塞代码的好处是性能的提高。与传统的应用程序相比,应用程序需要使用的线程要少得多,在传统的应用程序中,每个请求都是在一个单独的线程中处理的。更少的线程意味着更少的开销,更好的CPU使用率和在许多并行请求上更好的扩展。
缺点
- 然而,其缺点是,非阻塞代码通常更难读、写和调试。当然也有例外的情况。例如,顶点默认是线程安全的,因为它们只被一个线程访问,这在某些情况下可以降低代码的复杂性。我也相信,在一个由模块化顶点组成的事件驱动系统中严格使用回调,会自动鼓励解耦和编写高度内聚的代码,这非常好。
但是,我们总是要小心,不要意外地包含任何阻塞代码,或者在使用许多嵌套回调时创造一个**"回调地狱"**。正如我已经写过的,如果真的无法避免,有一些方法可以执行阻塞代码。
文档和社区
官方的Vert.x 文档是非常广泛的。这些例子通常都很简单,这很有意义,因为它不会让读者感到不知所措,而是专注于某个工具或用例。然而,如果你是整个反应式编程风格的新手,你可能会错过一些最佳实践,即如何在一个更大更复杂的项目中保持你的代码清洁和良好的结构化。从另一个角度来说,这也为你自己的创造力留下了一些空间。
Vert.x的社区似乎还比较小。例如,在StackOverflow上只有1,523个问题被标记为Vert.x(相比之下,Spring有153,358个问题)。Vert.x的主要社区渠道似乎是一个谷歌小组,目前有8,921个主题。虽然规模不大,但社区似乎非常热情,提供了大量的教程、例子、博客文章和额外的工具和库。
性能测试Vert.x与Spring Boot
出于好奇,我做了一个小测试,比较一个简单的Vert.x应用程序和一个普通的Spring Boot应用程序的性能。这是一个非常基本的网站,只是将一个 "Hello World!"字符串渲染到Thymeleaf模板中。有2个端点,第一个是直接返回结果,第二个是模拟一个典型的案例。当我们必须从一个缓慢的数据库或其他服务中检索结果时。
Spring Boot实例
import java.io.IOException;
import org.apache.catalina.connector.Request;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class WebController {
@RequestMapping(value = "/test1",method = RequestMethod.GET)
public String test1(Model model) throws IOException{
model.addAttribute("welcome", "Hello Knoldus");
return "index";
}
@RequestMapping(value = "/test2",method = RequestMethod.GET)
public String test2(Model model) throws IOException{
String response = Request.Get("http://localhost:8081").execute()
.returnContent().asString();
model.addAttribute("welcome",response);
return "index";
}
}
Vert.x的例子

正如你在第一个测试中所看到的,Vert.x与Spring Boot相比,速度明显要快。 让我们看一下测试期间的CPU和内存使用情况。
正如一个轻量级框架所预期的那样,Vert.x在一段时间内消耗的CPU和内存要少很多。但这只是一个非常简单的测试案例。更有趣的是第二个测试。
结论
没有一个框架是最适合每一个用例的。Vert.x是事件驱动的微服务架构的一个很好的选择,它可以以一种资源效率高的方式处理许多并行请求。
但是,这需要付出更多的实施努力。与Spring Boot相比,它的使用通常更方便(你也可以在我上面的小代码例子中看到)。Spring Boot也提供了一些反应式编程的工具,但它们只是添加到现有的Spring框架中(从第5版开始)。Vert.x完全植根于反应式的概念。这使得我在Vert.x中实现反应式代码时感觉更自然、更有结果。