1.3.1、 线程和编程模型
许多网络库和框架依赖于一个简单的线程策略:每个网络客户端在连接时被分配一个线程,并且该线程处理客户端的所有请求,直到它断开连接。使用java.io和java.net包编写的Servlet或网络代码就是这种情况。 虽然这种“同步I/O”线程模型具有简单易懂的优点,但是由于系统线程并不廉价,所以连接时间过长会损害可扩展性,而在负载较重的情况下,操作系统内核在线程调度管理上花费大量时间。 在这种情况下,我们需要转到“异步I/O”,Vert.x提供了坚实的基础。
Vert.x中的部署单位叫做Verticle。一个Verticle通过事件循环处理传入事件,其中事件可以是:接收网络缓冲区、定时事件或其他Verticle发送的消息。 事件循环在异步编程模型中是典型的:
每个事件应在合理的时间内处理,不阻止事件循环。这意味着在事件循环上执行时,不会执行线程阻塞操作,就像图形用户界面中的处理事件(例如通过执行慢速网络请求来冻结Java / Swing接口)一样。 正如我们将在本指南的后面部分中看到的,Vert.x提供了在事件循环之外处理阻塞操作的机制。无论如何,当事件循环处理事件太久时,Vert.x会在日志中发出警告,这也可以配置为匹配应用程序特定的要求(例如,在较慢的IoT ARM板上工作时)。
每个事件循环都附加到一个线程。默认情况下,Vert.x在每个CPU核心线程上附加2个事件循环。直接的后果是常规的Verticle总是在同一个线程上处理事件,因此不需要使用线程协调机制来操纵Verticle的状态(例如Java类字段)。
可以向Verticle传递一些配置(例如,凭证,网络地址, 等等),并且可以部署几个镜像:
来自网络的数据被接收线程接收并处理,然后作为事件传递给相应的Verticle。 当一个Verticle打开一个网络服务器并被部署多个时,事件就以Round-Robin方式分发给这些Verticle实例,在大量并发网络请求的情况下,这可以充分地发挥CPU的效能。最后,Verticle具有简单的起始/停止生命周期,并且一个Verticle可以部署其它Verticle。