文档章节

Vert.x3异步实战

任梁荣
 任梁荣
发布于 2016/09/01 19:11
字数 2114
阅读 115
收藏 1

作者:思想苇草
链接:https://zhuanlan.zhihu.com/p/20485640
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

从今天开始我们逐步翻译整理Vertx官网技术文档,并做最佳实践,Vertx技术初学者们可以参考这些文档,大牛们请忽略。

由于英语水平有限,翻译不足之处,烦请各位看官斧正。

代码

源代码 cescoffier/my-vertx-first-app · GitHub

环境

  1. JDK 8

  2. Maven

开始

  1. 在你喜欢的地方,创建一个目录,vertxStart

  2. 创建 src/main/java 目录

  3. 创建 src/test/java 目录

  4. pom.xml 文件

整个项目结构如下:

    .
    |---pom.xml
    |---src
    |   |
    |   |---main
    |   |   |___ java
    |   |
    |   |___test
    |       |___ java

创建 pom.xml 文件

<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                  http://maven.apache.org/xsd/maven-4.0.0.xsd">
                  <modelVersion>4.0.0</modelVersion>
                  <groupId>io.vertx.blog</groupId>
                  <artifactId>my-first-app</artifactId>
                  <version>1.0-SNAPSHOT</version>

                  <dependencies>
                    <dependency>
                        <groupId>io.vertx</groupId>
                        <artifactId>vertx-core</artifactId>
                        <version>3.0.0</version>
                    </dependency>
                  </dependencies>

                  <build>
                    <plugins>
                        <plugin>
                            <artifactId>maven-compiler-plugin</artifactId>
                            <version>3.3</version>
                            <configuration>
                                <source>1.8</source>
                                <target>1.8</target>
                            </configuration>
                        </plugin>
                    </plugins>
                   </build>
</project>

这个 pom.xml 文件很清晰,包含了下面两点内容

  • 声明了 vertx-core 依赖

  • 配置maven-compiler-plugin 使用Java 8

 

开始编写代码

创建 src/main/java/io/vertx/blog/first/MyFirstVerticle.java文件。

操作如下图

 

内容如下:

package io.vertx.blog.first;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;

public class MyFirstVerticle extends AbstractVerticle {

    @Override
    public void start(Future<Void> fut) {
        vertx
            .createHttpServer()
            .requestHandler( r -> {
                r.response().end("<h1>Hello from my first Vert.x 3 application</h1>");
            })
            .listen(8080, result -> {
                if (result.succeeded()) {
                    fut.complete();
                } else {
                    fut.fail(fut.cause());
                }
            });
    }
}

这个程序很简单,这个类继承了AbstractVerticle。在Vert.x里,一个verticle就是一个组件。通过继承AbstractVerticle,我们的类就能够获取vertx对象并使用了。

当要部署verticle的时候,start方法就会被调用。当然,我们也可以实现一个stop方法,但是在这个例子中,并没有实现这个方法,将由Vert.x来替我们进行垃圾回收。这个start方法接受一个Future对象,当我们start方法完成了或者报告一个错误的时候,它会通知Vert.x。Vert.x一个特性就是异步/无阻塞,当我们部署verticle的时候,它并不会等到这个start方法完成才完成部署。因此,这个Future参数对于通知Vert.x,start方法完成是非常重要的。(小编注:这边有点绕,因为start方法内含有异步回调,这些代码不会马上执行,而Vertx不会等待这些代码的执行,它会一直往下走直到结束)

这个start方法创建了一个HTTP服务器、接受一个请求并处理它。这个处理request请求的是一个lambda表达式,传入一个requestHandler方法,任何时刻,当这个服务器接受一个请求就会调用。这里,我们会返回一个“hello...”的字符串。最后,这个服务器绑定了8080端口。这可能会失败,因为8080端口可能被占用了。我们传入了另外一个lambda表达式,来检查这个链接是否成功了。就像前面提到的,当成功的时候,它会调用fut.complete,失败了就调用ful.fail返回一个错误。

编译

mvn clean compile

编译结果如下图所示:

测试

完成了应用的开发工作是很好的,但是我们可能并没有那么细心,所以需要对它进行测试。这个测试,使用了junit和vertx-unit。vertx-unit是vert.x的一个组件,用来测试vert.x的应用程序将会更加的得心应手。

打开pom.xml文件,然后加上下面两个依赖。

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-unit</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

接下来,创建测试类,src/test/java/io/vertx/blog/first/MyFirstVerticleTest.java,内容如下:

package io.vertx.blog.first;

import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(VertxUnitRunner.class)
public class MyFirstVerticleTest {

    private Vertx vertx;

    @Before
    public void setUp(TestContext context) {
        vertx = Vertx.vertx();
        vertx.deployVerticle(MyFirstVerticle.class.getName(),
        context.asyncAssertSuccess());
    }

    @After
    public void tearDown(TestContext context) {
        vertx.close(context.asyncAssertSuccess());
    }

    @Test
    public void testMyApplication(TestContext context) {
        final Async async = context.async();

        vertx.createHttpClient().getNow(8080, "localhost", "/",
        response -> {
            response.handler(body -> {
            context.assertTrue(body.toString().contains("Hello"));
            async.complete();
            });
        });
    }
}

这是用来测试我们verticle的Junit测试,它使用了vertx-unit,vert.x-unit会让我们的异步测试变的更加容易,同时也是vert.x的基本组件之一。

在setUp方法里,我们创建了一个Vertx的实例并且部署了verticle。你可能会注意到,@Before方法与我们传统的测试方法不一样,它接收一个TestContext参数。这个对象让我们控制测试程序的异步部分。举例来说,当我们部署verticle的时候,它启动是异步的。在它正确启动之前我们并不能检查什么。因此,deployVerticle方法的第二个参数,我们传入一个结果的处理者:context.asyncAssertSuccess()。如果verticle没有正确启动,这个测试就失败了。此外,它会等待直到vertical完成。记住,在我们的verticle中,我们调用fut.complete()。因此,它会等待直到这个方法被调用,而在调用失败的情况下,测试也会失败。

这个tearDown方法就简单了,仅仅是结束我们创建的这个vertx实例。

现在让我们来看看测试程序的这个testMyApplication方法。这个方法向我们的应用程序发出一个请求并且检查结果。发出请求和接收回复是异步。所以,我们需要一个能够控制异步的方式。就像,setUp和tearDown方法,这个测方法接收一个TestContext参数。在这个对象中,我们创建了一个异步处理对象async,当测试完成的时候,使用async.complete()帮我们通知测试框架。

所以,一旦async handle被创建了,我们就创建了一个HTTP的客户端并且提交了一个HTTP请求,由我们的应用程序通过调用getNow()(getNow是get(...).end()的缩写)方法来处理。这个Response是通过lambda表达式来处理的。在lambda表达式中,我们通过传入另一个lambda表达式到handler方法来取得响应。body参数就是响应(作为一个buffer对象)。我们检查这个响应体包含了字符串"Hello"然后声明测试已经完成了。

现在让我们再来看一下这个assertions。不像传统的junit测试,它使用context.assert...。实际上,当assertion失败,将会立刻打断这个测试。所以,使用这些assertion方法对测试Vert.x异步应用程序是非常重要的。

我们的测试可以在IED中运行,也可以使用maven:

mvn clean test

编写test类后,开始测试。如图:

 

打包

现在让我们来总结一下。我们有一个应用程序和一个测试程序。现在我们需要来打包这个应用程序。在这篇文章中,我们将应用程序打包到一个fat.jar里。fat.jar是一个单独的可执行的Jar文件,包含了所有运行这个程序的依赖。把Vert.x应用程序打包成一个文件是很方便的,同时也容易执行。

为了创建这个fat.jar,我们需要编辑pom.xml文件,添加下面这个片段到</plugins>之前。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
        <phase>package</phase>
        <goals>
            <goal>shade</goal>
        </goals>
        <configuration>
            <transformers>
                <transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <manifestEntries>
                    <Main-Class>io.vertx.core.Starter</Main-Class>
                    <Main-Verticle>io.vertx.blog.first.MyFirstVerticle</Main-Verticle>
                </manifestEntries>
                </transformer>
            </transformers>
            <artifactSet/>
            <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
            </configuration>
        </execution>
    </executions>
</plugin>

这里使用maven-shade-plugin插件来创建fat jar。在manifestEntries里写明了verticle的名字。你可能会奇怪Starter类是怎么来的。它实际上是vert.x的一个类,由它创建vertx实例和部署我们的verticle。

配置好插件,然我们开始运行:

mvn clean package

之后,将会创建target/my-first-app-1.0-SNAPSHOT-fat.jar将所有的依赖都嵌入到了我们的程序之中(包括vert.x本身)。

执行我们的应用程序

现在,我们有了fat jar,但是我们想要看的我们的程序运行起来。前面说了,由于打包fat jar,运行一个vert.x将会很容易:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

执行成功后如下图所示:

 

然后,打开浏览器访问http://localhost:8080

参考结果如下图所示:


按Ctrl + c停止。

 

总结

这个Vert.x 3速成教程,向你展现了怎么使用Vert.x 3部署一个简单的应用程序,还有如何测试、打包和运行。现在你已经知道了使用Vert.x 3构建一个非常棒的程序需要的所有基本步骤。

© 著作权归作者所有

共有 人打赏支持
任梁荣
粉丝 7
博文 39
码字总数 39723
作品 0
上海
后端工程师
私信 提问
java 8实现的一个最简单的mysql代理服务器

可以用java8基于vert.x3 快速实现一个最简单的mysql代理服务器。 什么是mysql 代理? mysql代理是介于client端和mysql服务端中间层服务,如下图所示: 为什么要使用代理? 大部人都知道使用代...

孟飞阳
2016/08/07
90
0
服务器后端开发系列——《实战Memcached内存缓存系统》

1、实战Memcached缓存系统(1)Memcached基础及示例程序 内容:建筑Memcached背景知识和入门示例程序。 2、实战Memcached缓存系统(2)Memcached Java API基础之MemcachedClient 内容:以Mem...

晨曦之光
2012/04/24
98
0
SpringBoot整合RabbitMQ之典型应用场景实战一

实战前言 RabbitMQ 作为目前应用相当广泛的消息中间件,在企业级应用、微服务应用中充当着重要的角色。特别是在一些典型的应用场景以及业务模块中具有重要的作用,比如业务服务模块解耦、异步...

liwei2000
2018/11/15
0
0
【视频分享】尚硅谷Java视频教程_RBAC权限实战视频教程

        本视频讲授RBAC权限模型的设计、以及在项目中的应用 。 1. 使用Maven进行项目构建 。 2. 页面设计采用响应式前端框架BootStrap 。 3. 采用多种方式展现用户数据:树形结构(z...

后端编程嘟
2018/05/24
0
0
2018年swoole实战4-异步io读写

继上篇 2018年swoole实战3-异步非阻塞投递任务 io读写很耗时,经常会成为一个项目的瓶颈,swoole针对此提供了 异步文件系统io,不必再被io所阻塞 异步读文件 新建 test.txt 新建 read.php 执...

章鱼喵_
2018/07/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Windows同步对象Event和Linux的条件变量

最近在看一些同步对象模拟的东东,特别对在Windows下如何模拟条件变量折腾了很久。 1 Windows同步对象Event 微软有一个很有意思的同步对象,某种程度上和Linux的条件变量很相似。但秉承微软一...

shzwork
28分钟前
1
0
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

//第一种做法 public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList <Integer> li=new ArrayList<Integer>(); ArrayList <TreeN......

南桥北木
38分钟前
1
0
linux 服务管理 Crontba、Ntpdate、Logrotate、Supervisor

crond linux 系统则是由 cron (crond) 这个系统服务来控制的。Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的。 另外, 由于使用者自己也可以设置计划任务,所以,...

狼王黄师傅
今天
3
0
Sobel算子和Scharr滤波器

Sobel算子在数学上的本质是微分,对离散信号,是求邻域内的增量。 基本原理:在图像上,对图像信号在某点进行微分,表示图像的某个特征(如,强度、色调或者饱和度)在该点的变换程度。以强度...

yepanl
今天
2
0
Jenkins API 使用

Jenkins 是一款流行的开源持续集成工具,可以用来做一些软件开发的自动化工作,如打包,测试,自动部署等。 Jenkins 中有 view 和 job 的概念, view 相当于组, job 则是具体的任务。 view...

YanWen
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部