Vert.x异步编程

Posted by NotGeek on November 3, 2018

Vert.x 异步编程

本期议题

  • 什么是 Vert.x
  • 为什么要 Vert.x
  • Vert.x 核心概念
  • Vert.x 实战
  • 问答互动

什么是 Vert.x

  • Vert.x是基于 JVM 构建 Reactive 应用的工具箱
    • 基于 Netty 开发
    • 多编程语言支持
    • 多模块支持(数据库、日志或服务发现)

为什么要 Vert.x

  • Reactive 编程模型
    • 函数式
    • 异步
    • 非阻塞
  • Web 技术栈
  • 适合嵌入式或微服务应用

Vert.x 核心概念

  • 线程和编程模型
    • 异步 I/O(asynchronous I/O)
    • 事件循环(Event-loops)
  • 事件总线(Event Bus)

线程和编程模型

1545666837550

事件总线(Event Bus)

1545666860652

Vert.x 实战

  • Verticle
  • EventBus
  • Web 应用

JAVA 重排序,需要仔细的去了解。

​ 我们讲一门技术,重要的是用技术的那个人。其次才是技术的本身,技术本身是发明者和使用者。

​ 作者是怎么去思考的,你需要有自己的思考,否则,你换一个框架,就不会了。

​ Vert.x

什么是 Vert.x

What is Vert.x?

Eclipse Vert.x is a toolkit for building reactive applications on the JVM.

​ — Vert.x website

Vert.x is not a framework but a toolkit: the core library defines the fundamental APIs for writing asynchronous networked applications, and then you can pick the useful modules for your application (e.g., database connection, monitoring, authentication, logging, service discovery, clustering support, etc). Vert.x is based on the Netty project, a high-performance asynchronous networking library for the JVM. Vert.x will let you access the Netty internals if need be, but in general you will better benefit from the higher-level APIs that Vert.x provides while not sacrificing performance compared to raw Netty.

它比较像 Nodejs ,它面面俱到,又像一个非阻塞式的编程。

它是一个工具箱 构建 反应式应用 JVM层面的。

  • 异步
  • 反应

Vert.x 不是一个框架。框架是针对于某一个方面的东西。有很多的实现。

  • Netty
  • 多语言
  • 多模块支持

Netty 是一个很流行的 NIO 的框架,很多 RPC 的框架都会基于 Netty 来开发。Dubbo, WebFlux,WebFlux 两个都会有 一个是 Tomcat、Jetty、Undertow,Undertown Netty。

Java Manual API
JavaScript Manual API
Groovy Manual API
Ruby Manual API
Ceylon Manual API
Kotlin Manual API
Scala Manual API

这些语言都支持。

他不是一个框架,

Web

Web

Vert.x-Web is a tool-kit for writing sophisticated modern web applications and HTTP microservices.

Web Client

Vert.x Web Client is an easy to use advanced HTTP client.

Web API Contract

Web API Contract supports OpenApi 3 specification for a design first approach and provides a validation framework

Web Client 和我们的 HttpClient OkClient 很像,它的健壮性不是特别够,

数据访问

Data access

MongoDB client

JDBC client

SQL common

Redis client

MySQL / PostgreSQL client

Cassandra client Technical Preview

他像一个语言特性,它像 spring 是中间件的那一层。他已经把这种东西实现了。

Reactive

Vert.x provides a couple of components to make your applications more reactive.

Vert.x Rx

Don’t like callback-style APIs? Vert.x provides Rx-ified (using RxJava) versions for most of its APIs so you can use those if you prefer.

RxJava is a great choice when you want to perform complex operations on multiple asynchronous streams of data.

Reactive streams

Vert.x supports reactive streams so your applications can interoperate with other reactive systems such as Akka or Project Reactor.

Vert.x Sync

Vertx-sync allows you to deploy verticles that run using fibers. Fibers are very lightweight threads that can be blocked without blocking a kernel thread. This enables you to write your verticle code in a familiar sequential style.

Kotlin coroutines

Kotlin coroutines for Vert.x, gives you super powers such as async/await or Go-like channels. This enables you to write your verticle code in a familiar sequential style.

RxJava 和 Reactive

Microservices

Vert.x offers various component to build microservice-based applications.

Vert.x Service Discovery

This component lets you publish, lookup and bind to any type of services.

Vert.x Circuit Breaker

This component provides an implementation of the circuit breaker pattern for Vert.x

Vert.x Config

This component provides an extensible way to configure Vert.x applications.

微服务。

  • Service Discovery 服务发现 Circuit Breaker 服务熔断 Config 服务配置

微服务一般会搭配这些东西。

服务发现
  • 服务注册
  • 服务发现

延伸来自于 SOA 的服务治理,还有监控!!

DevOps

微服务不止有 DevOps ,它只是说,我有这样一个理念,我要完成这样一个指标。

分布式的三个要素

都是概念,到最后,需要落地。

MQTT

它是消息服务。

Authentication and Authorisation

Auth common

JDBC auth

JWT auth

Shiro auth

MongoDB auth

OAuth 2

.htdigest Auth

认证和授权

JSON Web Token

Spring Sercrity

  • Servlet 容器
  • Netty

Integration

Mail Client

STOMP Client & Server

Consul Client

RabbitMQ Client

Kafka Client

JCA Adaptor

AMQP Bridge

Event Bus Bridge

TCP Eventbus Bridge

Camel Bridge


Devops

Metrics using Dropwizard

Metrics using Micrometer

Vert.x Health Check

Shell

Docker

Stack Manager


Testing

Vert.x Unit

Vert.x JUnit 5


Clustering

Hazelcast

Infinispan

Apache Ignite

Apache Zookeeper


Services

Service Proxies

SockJS Service Proxies

gRPC

Service Factories

Maven Service Factory

HTTP Service Factory


Cloud

Vert.x OpenShift 3 S2I


Advanced

Codegen

Docgen

Codetrans

Bridge Common

Distro

Web-site

为什么要 Vert.x

  • Reactive 编程模型
    • 函数式
    • 异步
    • 非阻塞
  • Web 技术栈
  • 适合嵌入式或微服务应用

异步和非阻塞是分开的。

  • NIO blocking I/O 是同步的
  • AIO 才是异步的 I/O

异步是我不需要立马知道结果。

同步一般是阻塞的,也有非阻塞的。

  • Web技术栈

Spring Data

  • 关系型数据库
  • 非关系型数据库

Reactor 是同步多工的模式

Reactive 是异步多工的东西

https://projectreactor.io/

Vert.x 核心概念

  • 线程和编程模型
    • 异步 I/O (asynchronous I/O)
    • 事件循环(Event-loops)
  • 事件总线(Event Bus)

他只有编程模型,它的线程模型教给了我们 JAVA 来执行。

1545704998842

JAVA 的 MouseEvent 纵坐标,横坐标

是一个鼠标抽象,

事件驱动早就有了。

技术会出现社会学的东西。

Martin fowler 从软件工程学有贡献,对于软件科学学科,没有一点贡献。

是一个等待,事件的输入。

线程的等待,等待信号输入,事件就来了,

事件不停的空转。

NIO 也是,管道开通的时候,会监听你感兴趣的事件,比如说

  • 连接事件
  • 读事件
  • 写事件

很多技术都是有相关性的。

GC、RMI

AWT 都是由事件来处理的。

事件总线 Event Loop

事件不断地处理。

监听器,事件不断地进如。

  • 一种是点对点
  • 一种是点对多

点对点,点击完了就挂了。

一对多,

比如说,你复制一个链接。

迅雷,QQ 都会弹出来,这就是一个典型的订阅者模式。

Windows 的 NFC 叫 事件消息循环 EventMessagesLoop

一直在等消息。

论文,把概念写的很抽象,但是抽象不好理解!都是有种营销的概念在里边。

Verticle

verticle threading config

部署配置

Event bus

event bus

  • 本地事件
  • 分布式事件
Spring Cloud 有一个 Event Bus

46. Tracing Bus Events

事件和消息的区别是什么?

事件是消息的一种特殊的场景。

消息是无关于场景的。消息对于我的中间件而言。只知道你是一个消息,我只管连个事情,就像邮局一样。消息里边的内容是一个事件,事件带有一个场景。

消息没有场景性!

消息是事件的一种传输模式。

HTTP 无非也就是一个事件,只不过事件是一个同步事件。

Spring Cloud Bus

  • 本地事件

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext();
      appliation.setConfigLocation("META-INF/spring-context.xml");
      application.addApplicationListener(event -> {
          if (event instanceof PayloadApplicationEvent){
              PayloadApplicationEvent payloadApplicationEvent = (PayloadApplicationEvent) event;
              System.err.println(payloadApplicationEvent.getPayload());
          } else {
              System.err.printlv(event);
          }
      });
      // 启动上下文
      application.regresh();
      // Spring 上下文是一个事件发布器,非 ApplicationEvent, 是 PayloadApplicationEvent 
      application.publishEvent("Hello, world");
      application.publishEvent(22323);
      application.publishEvent(appllication);
      
  • 远程事件。

就是非阻塞模型,我们写代码习惯于从上至下,不完全是这样,这个发布事件在下边,而事件的处理却在上边,就像事件的回调的方式。是一个观察者模式。

Demo

当你了解一个技术的时候,你要把一个技术的上下文了解的更加的透彻。越多越好,韩信点兵,多多益善。

只是了解技术怎么去使用,这件事情意义不是特别大。

API 看懂了,怎么做。

  • Reactor
  • RxJava 1 、2
  • Vert.x

都是 Build 模式,换个名字叫 Fluent API

VertxDemo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class VertxDemo {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        // 实现定时器
        vertx.setPeriodic(500, System.out::println);
        vertx.setPeriodic(500, System.out::println);
        vertx.setPeriodic(500, System.out::println);

        // 底层就是类似的实现方式:
        Executors.newScheduledThreadPool(1)
                .schedule(() -> System.out.println("Hello, world"),
                        1000, TimeUnit.MILLISECONDS);
    }
}

io.vertx.core.Verticle

1
2
3
4
5
6
7
8
9
public interface Verticle {
    Vertx getVertx();
    // 创建上下文
    void init(Vertx var1, Context var2);
    // 开始
    void start(Future<Void> var1) throws Exception;
    // 结束
    void stop(Future<Void> var1) throws Exception;
}

就像一个 周期。

现在的 Reactor Reactive_streams Vert.x 都算是一种新的编程模型,并没有太多的新的东西。

不要把技术神话…..

比如说你要搭建一个 blog ,Vert.x 就比 Spring Cloud 简单的多。

面试问你,你不用 Spring cloud 怎么办?

不用 Spring Cloud 不用 tomcat ,用 Vert.x 也可以实现这种东西。

做一个API 的网关也是可以的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    demoVerticle(vertx);
    vertx.close();

}

private static void demoVerticle(Vertx vertx) {
    vertx.deployVerticle(new AbstractVerticle() {
        @Override
        public void start(Future<Void> startFuture) throws Exception {
            // 异步
            System.out.println("start。。。");
            startFuture.complete();
        }

        @Override
        public void stop() throws Exception {
            System.out.println("stop。。。。");
        }
    });
}

执行完以后,关闭。

他就是一种编程方式。

就是一个事件,一个 #start() , 一个 #stop()

Spring 和 Vertx 的 API 都非常的笨重,都在一个里边 叫做 build 模式。

  • Spring 的事件监听,监听不同的事件类型区分。
  • 消息一般通过消费的地址进行区分

处理完怎么做,,,,等

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
/***
 * EventbusDemo
 */
public class VertxEventBusDemo {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        demoEventBus(vertx);
        vertx.close();
    }

    /***
     * 演示 Event Bus Demo
     * @param vertx
     */
    private static void demoEventBus(Vertx vertx) {
        String address = "test-address";
        // 事件订阅者(消费事件)
        vertx.eventBus().consumer(address, message -> {
            // 处理消息(事件)
            Object payload = message.body();
            System.out.println("Address:" + address + " -> message: " + payload);
        }).completionHandler(voidAsyncResult -> {
            System.out.println("消息消费结束");
        });

        // 事件发布者(发布事件)
        vertx.eventBus().publish(address, "hello, world");
        vertx.eventBus().publish(address, 123);
    }
}
1
2
3
消息消费结束
Address:test-address -> message: hello, world
Address:test-address -> message: 123

Spring Cloud 实践同步哦消息中间件传递过去,

通过 RabbitMq 发送过去。通过消息管道发送过去。

分布式并不是直接交互,而是通过中间件,就是 mq 模型。

我用统一的编程模型去区分我是远程的还是本地的。

服务实现者不需要关心我这个具体某个编程实现。

相同的 API 相同的模型,实现不同的功能

RPC 调用 你感觉不到 HTTP 调用。就好像本地调用的意思。

web 应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class VertxWebDemo {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        // 创建 Http Server
        vertx.createHttpServer().requestHandler(request -> {
            // 请求
            String message = request.getParam("message");

            // 响应
            HttpServerResponse response = request.response();
            response.end("Hello: [ message ]:" + message);
        }).listen(8080); // 监听 8080 端口……
    }
}

http://localhost:8080/?message=darain

1545711813527

输入输出

未来 JAVA 可能要掌握所有的编程语言。

路由转发:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class VertxWebDemo {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();

        // 路由
        Router router = Router.router(vertx);


        // 创建 Http Server
        router.get("/echo").handler(context -> {
            // 请求
            HttpServerRequest request = context.request();
            String message = request.getParam("message");

            // 响应
            HttpServerResponse response = request.response();
            response.end("Hello: [ message ]:" + message);
        }); // 监听 8080 端口……

        vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    }
}

http://localhost:8080/echo?message=hello,%20darian

1545712179373

WebFlux 和它更加的想象

官方会夸大一下东西。

函数式编程会把我们的定义式编程 编程 声明式,

会变成 if .... else... 去里边动态的路由。

了解很多的话,理解会越来越透彻。

异步就是回调

你会感受不到回调的编程。

它不完全是异步的。他需要你去声明才行。

1
2
3
4
5
Flux.generator(()-{
    
}).subscribon(Schedulers.elastic());

Schedulers.xxxx

它有回调的方式。观察者模式。

TCP Server

就是桥接到我们

Vue.js 就是抄 JAVA 的模板引擎。一点都不神奇。

Vert.x 和 Node.js 非常非常的像。

Reactive 可能把编程变得更混乱了。

语法糖并不一定看的懂 JAVA

JAVA 可能比较稳定。

他喜欢这样搞。你喜欢这样搞。

用的总比不用好。

  • 阻塞
  • 非阻塞

都差不多。

Vert.x 做微服务,非常的简单,很精巧。

Spring Cloud 可能比较麻烦。

它是一个 Node.js 的 JAVA 版。不是一个框架。

一种语言是不可能统一所有的语言。