我已加入其中一个Vertx爱好者,单线程主框架可能无法为我工作,因为在我的服务器中可能会有50个文件下载请求,因为我已经创建了这个类
public abstract T onRun() throws Exception;
public abstract void onSuccess(T result);
public abstract void onException();
private static final int poolSize = Runtime.getRuntime().availableProcessors();
private static final long maxExecuteTime = 120000;
private static WorkerExecutor mExecutor;
private static final String BG_THREAD_TAG = "BG_THREAD";
protected RoutingContext ctx;
private boolean isThreadInBackground(){
return Thread.currentThread().getName() != null && Thread.currentThread().getName().equals(BG_THREAD_TAG);
}
//on success will not be called if exception be thrown
public BackgroundExecutor(RoutingContext ctx){
this.ctx = ctx;
if(mExecutor == null){
mExecutor = MyVertxServer.vertx.createSharedWorkerExecutor("my-worker-pool",poolSize,maxExecuteTime);
}
if(!isThreadInBackground()){
/** we are unlocking the lock before res.succeeded , because it might take long and keeps any thread waiting */
mExecutor.executeBlocking(future -> {
try{
Thread.currentThread().setName(BG_THREAD_TAG);
T result = onRun();
future.complete(result);
}catch (Exception e) {
GUI.display(e);
e.printStackTrace();
onException();
future.fail(e);
}
/** false here means they should not be parallel , and will run without order multiple times on same context*/
},false, res -> {
if(res.succeeded()){
onSuccess((T)res.result());
}
});
}else{
GUI.display("AVOIDED DUPLICATE BACKGROUND THREADING");
System.out.println("AVOIDED DUPLICATE BACKGROUND THREADING");
try{
T result = onRun();
onSuccess((T)result);
}catch (Exception e) {
GUI.display(e);
e.printStackTrace();
onException();
}
}
}
允许处理程序扩展它并像这样使用它
public abstract class DefaultFileHandler implements MyHttpHandler{
public abstract File getFile(String suffix);
@Override
public void Handle(RoutingContext ctx, VertxUtils utils, String suffix) {
new BackgroundExecutor<Void>(ctx) {
@Override
public Void onRun() throws Exception {
File file = getFile(URLDecoder.decode(suffix, "UTF-8"));
if(file == null || !file.exists()){
utils.sendResponseAndEnd(ctx.response(),404);
return null;
}else{
utils.sendFile(ctx, file);
}
return null;
}
@Override
public void onSuccess(Void result) {}
@Override
public void onException() {
utils.sendResponseAndEnd(ctx.response(),404);
}
};
}
以下是我初始化vertx服务器的方法
vertx.deployVerticle(MainDeployment.class.getCanonicalName(),res -> {
if (res.succeeded()) {
GUI.display("Deployed");
} else {
res.cause().printStackTrace();
}
});
server.requestHandler(router::accept).listen(port);
这是我的MainDeployment类
public class MainDeployment extends AbstractVerticle{
@Override
public void start() throws Exception {
// Different ways of deploying verticles
// Deploy a verticle and don't wait for it to start
for(Entry<String, MyHttpHandler> entry : MyVertxServer.map.entrySet()){
MyVertxServer.router.route(entry.getKey()).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext ctx) {
String[] handlerID = ctx.request().uri().split(ctx.currentRoute().getPath());
String suffix = handlerID.length > 1 ? handlerID[1] : null;
entry.getValue().Handle(ctx, new VertxUtils(), suffix);
}
});
}
}
}
这在我需要它的时间和地点工作得很好,但我仍然想知道是否有更好的方法来处理这样的Vertx上的concurencies,如果是这样的例子将非常感激。非常感谢
答案 0 :(得分:1)
我不完全了解您的问题和解决方案的原因。为什么不实现一个Verticle来处理你的http上传并多次部署它?我认为处理50个并发上传应该是vert.x的小菜一碟。
使用Verticle名称部署Verticle时,您可以指定要部署的Verticle实例的数量:
DeploymentOptions options = new DeploymentOptions().setInstances(16); vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
这对于跨多个核心轻松扩展非常有用。例如,您可能要在计算机上部署Web服务器Verticle和多个核心,因此您希望部署多个实例以利用所有核心。
http://vertx.io/docs/vertx-core/java/#_specifying_number_of_verticle_instances
答案 1 :(得分:0)
vertx是一个设计良好的模型,因此不会发生并发问题。 通常,vertx不推荐使用多线程模型。 (因为处理并不容易。)
如果选择多线程模型,则必须考虑共享数据..
简单来说,如果你只想分割EventLoop Area, 首先,确保检查一些CPU核心。 然后设置实例数。
DeploymentOptions options = new DeploymentOptions().setInstances(4);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
但是,如果你有4个CPU的核心,你不会设置超过4个实例。 如果您设置为四个或更多,性能将无法提高。