然而,事件循环只是故事的一半。另一半与Vert.x几乎没有关系。
要连接到数据库,客户端需要连接器驱动程序。在Java领域,Sql最常见的驱动程序是JDBC。问题是,这个驱动程序阻塞了。它在套接字级别阻塞。一个线程总会卡在那里,直到它返回一个响应。
毋庸置疑,驱动程序一直是实现完全无阻塞应用程序的瓶颈。幸运的是,在具有多个活动分叉的异步驱动程序上取得了进展(尽管是非官方的),其中包括:
-
https://github.com/jasync-sql/jasync-sql(适用于Postgres和MySql)
黄金法则
使用Vert.x非常简单,只需几行代码即可启动http服务器。
val vertx = Vertx.vertx()
vertx.createHttpServer().requestHandler(req => {
}).listen(8080)
方法requestHandler是事件循环传递请求事件的地方。由于Vert.x没有意见,处理它是自由的风格。但请记住非阻塞线程的唯一重要规则:不要阻止它。
在使用并发时,我们可以从如今的许多选项中获取,例如Promise,Future,Rx,以及Vert.x自己的惯用方法。但随着应用程序复杂性的增加,单独使用异步功能是不够的。我们还需要轻松协调和链接调用,同时避免回调地狱,以及优雅地传递任何错误。
Scala Future满足上述所有条件,并具有基于函数式编程原理的额外优势。虽然本文不深入探讨Scala Future,但我们可以通过一个简单的应用程序来尝试它。假设该应用程序是一个API服务,用于查找给定其ID的用户:
val vertx = Vertx.vertx()
vertx.createHttpServer().requestHandler(req => {
req.path() match {
case p if p contains(“/user”) =>
val f = for {
f1 <- Future { req.getParam(“id”).get.toInt }
f2 <- if (f1 < 100) Future.unit else Future.failed(CustomException())
f3 <- Future { getUserFromDb(f1) }
} yield f3
f map (r => printout(req, r)) recover {case exception => printout(req, handleException(exception))}
case _ => printout(req, “Default page”)
}
})
.listen(8080)
def printout(req: HttpServerRequest, msg: String) = req.response().end(msg)
def handleException(e: Throwable): String = {
e match {
case t: NoSuchElementException => “Missing parameter”
case t: NumberFormatException => “Parameter not number”
case t: CustomException => “Custom exception”
case t: SQLException => “Database error”
惊喜
最后还准备了一套上面资料对应的面试题(有答案哦)和面试时的高频面试算法题(如果面试准备时间不够,那么集中把这些算法题做完即可,命中率高达85%+)
够,那么集中把这些算法题做完即可,命中率高达85%+)
[外链图片转存中…(img-0x0chELW-1714543648162)]
[外链图片转存中…(img-8RWW4vjB-1714543648162)]