vertx编程需注意的点
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
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22