• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

vertx编程需注意的点

武飞扬头像
forwardMyLife
帮助1

vertx是基于netty的网络编程开发工具,若想用vertx开发出高性能的程序就必须对netty的底层原理有一定的了解,netty是基于事件驱动的网络开发框架,底层是基于JDK的Nio的socketChannle和Selector,io多路复用,服务端有在专门监听连接的EventLoop线程,连接建立后创建对应的SocketChannel,并io事件注册到work线程池中的某个EventLoop线程绑定的Selector上,每个socketChannel都有对应的channelPileline。channelPipeline对应多个channelHandler和ChannelContext,以责任链的形式来处理读写事件。

1.verticle

Vert.x 通过开箱即用的方式提供了一个简单便捷的、可扩展的、类似 Actor Model 的部署和并发模型机制。您可以用此模型机制来保管您自己的代码组件。

这个模型是可选的,也可以直接基于vertxCore创建您的应用程序。

verticle有3类,

类型 解释
Stardand Verticle 这是最常用的一类 Verticle —— 它们永远运行在 Event Loop 线程上,单个verticle绑定一个eventLoop线程,一个应用程序可以绑定多个vertcile实例
Worker Verticle 这类 Verticle 会运行在 Worker Pool 中的线程上。一个实例绝对不会被多个线程同时执行
Multi-Threaded Worker Verticle 这类 Verticle 也会运行在 Worker Pool 中的线程上。一个实例可以由多个线程同时执行
学新通  

上图来自vertx in action一书

2.vertx的异步回调编程

vertx 大部分的情况下运行在eventLoop线程上,所以应用程序一定不要有阻塞的代码,vertx的世界是完全异步的,这是vertx的黄金法则
对于http请求或者其他中间件交互的情况,尽可能的使用vertx实现的api,
如在vertx应用发起http请求,尽量使用vertx提供的客户端,使用future或promise获取异步结果,在回调中,处理结果。

package com.ly;

import com.ly.entity.Good;
import com.ly.session.SessionEntity;
import io.vertx.core.*;
import io.vertx.core.http.*;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.Session;
import io.vertx.ext.web.handler.SessionHandler;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisOptions;
import io.vertx.redis.client.impl.RedisClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class VertxServer implements ApplicationListener<ContextRefreshedEvent> {


    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext().getParent() == null) {
            VertxOptions vertxOptions = new VertxOptions();
            vertxOptions.setMaxEventLoopExecuteTime(10000 * 60);
            vertxOptions.setMaxEventLoopExecuteTimeUnit(TimeUnit.MILLISECONDS);
            Vertx vertx = Vertx.vertx(vertxOptions);
            HttpServerOptions options = new HttpServerOptions();
            options.setIdleTimeout(3600);
            options.setTcpKeepAlive(true);
            HttpServer server = vertx.createHttpServer(options);
            Router router = Router.router(vertx);
            SessionStore sessionStore = SessionStore.create(vertx);
            router.routeWithRegex("/static.*").handler(StaticHandler.create());
            router.routeWithRegex(".*service.*")
                    .handler(SessionHandler.create(sessionStore)).handler(ctx -> {
                if (ctx.request().path().contains("initSession")) {
                    ctx.request().response().setStatusCode(401)
                            .putHeader("Content-Type", "application/json").end((new JsonObject().put("msg", "illegal request").encode()));
                } else {
                    ctx.next();
                }
            }).handler(ctx -> {
                preCheck((result) -> {
                    if (result.succeeded()) {
                        doNext(ctx);
                    } else {

                    }
                }, vertx);
            }).failureHandler((ctx) -> {
                System.out.println(ctx.failure());
            });
            server.requestHandler(router).listen(8081);
            System.err.println("vertxServer start success");
        }
    }

    public void preCheck(Handler<AsyncResult<Boolean>> asyncResultHandler, Vertx vertx) {
        HttpClientOptions clientOptions = new HttpClientOptions();
        HttpClient client = vertx.createHttpClient(clientOptions);
        client.request(HttpMethod.POST, 8088, "localhost", "/hello1?name=ly").onSuccess(httpClientRequest -> {
            httpClientRequest.headers().set("Content-Type", "application/json;charset=utf-8");
            httpClientRequest.headers().set("Accept", "application/json;charset=utf-8");
            httpClientRequest.end();
            httpClientRequest.response().onSuccess(response -> {
                response.bodyHandler(buffer -> {
                    String s = new String(buffer.getBytes(), StandardCharsets.UTF_8);
                    System.out.println("result:"   s);
                    asyncResultHandler.handle(Future.succeededFuture(Boolean.TRUE));
                });
                System.out.println(response.statusCode() response.statusMessage());

            });
        });
    }

    private void doNext(RoutingContext ctx) {
        HttpServerResponse response = ctx.response();
        Session session = ctx.session();
        if (session.get("wow") == null) {
            session.put("wow", "wow");
            System.err.println((String) session.get("wow"));
            ctx.request().remoteAddress();
            List<Good> goodList = new ArrayList<>();
            goodList.add(Good.builder().id(1).stockNumber(100).build());
            session.put("goods", goodList);
        } else {
            System.out.println("goods:"   session.get("goods"));
        }
        SessionEntity sessionEntity = new SessionEntity();
        sessionEntity.setId("28947208947");
        session.put("typeTest", sessionEntity);
        String path = ctx.request().path();
        if (ctx.request().path().contains("service/removeCookie")) {


            Cookie cookie = Cookie.cookie("vertx-web.session", new Date().getTime()   "");

            cookie.setPath("/");
            cookie.setSameSite(CookieSameSite.NONE);
            ctx.addCookie(cookie);
            ctx.request().response().addCookie(cookie);

        } else if (path.contains("clearSession")) {
            ctx.session().destroy();
        }


        response.putHeader("content-type", "text/plain");
        response.end("hello word!");
    }
}

学新通

学新通
学新通
待响应回调后,再决定是否执行对应的结果。

如果一定要运行阻塞式代码可以考虑
1.context.runContext
2.对于http应用来说,使用blockHandler该handler会有work pool执行。

官方文档:
https://vertxchina.github.io/vertx-translation-chinese/core/Core.html
https://vertx.io/

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiacgah
系列文章
更多 icon
同类精品
更多 icon
继续加载