在顶点vert.x中实例化类的危险

时间:2018-08-14 17:06:45

标签: java performance vert.x

我解释了我的问题,我有一个顶点,其中定义了所有路线。而且我有简单的Java类,其中包含我根据路径在顶点中调用的方法。例如,我的downloadFile()方法位于MyFile类中,如下所示:

    public class MyFile {

        public final void downloadFile(RoutingContext rc, Vertx vertx) {
            final HttpServerResponse response = rc.response();
            response.putHeader("Content-Type", "text/html");
            response.setChunked(true);

            rc.fileUploads().forEach(file -> {

                final String fileNameWithoutExtension = file.uploadedFileName();

                final JsonObject jsonObjectWithFileName = new JsonObject();
                 response.setStatusCode(200); 
                 response.end(jsonObjectWithFileName.put("fileName", fileNameWithoutExtension).encodePrettily());
            });
        }

       public final void saveFile(RoutingContext rc, Vertx vertx) {
                 //TODO
       }
    }

我像这样在我的Verticle中使用此类:

    public class MyVerticle extends AbstractVerticle{

            private static final MyFile myFile = new MyFile();

            @Override
            public void start(Future<Void> startFuture) {
                final Router router = Router.router(vertx);
                final EventBus eventBus = vertx.eventBus();

                router.route("/getFile").handler(routingContext -> {
                    myFile.downloadFile(routingContext, vertx);
                });

        router.route("/saveFile").handler(routingContext -> {
                    myFile.saveFile(routingContext, vertx);
                });
            }
    }

我的同事告诉我,在一个垂直实例中实例化一个类是不好的,当我问他为什么时,他回答说它变得有状态,并且我怀疑他对我说的话,因为我不知道怎么做。当我在自己的Verticle中声明MyFile类实例为“ static final”时,我想说我什至可以提高性能,因为我为每个传入请求使用相同的实例,而不是创建一个新实例。

如果在verticle中实例化一个类很不好,请解释为什么?

此外,我想知道使用2个垂直线进行仅一个垂直线可以做的治疗的兴趣是什么?

例如,我想用我在数据库中选择的数据构建一个JsonObject,为什么将这个数据发送到另一个verticle,却知道该Verticle除了构建JsonObject之外什么都不做,并等待它回答我,将响应发送给客户端,这样我就可以在发出请求的Verticle中构建此JsonObject,并立即将响应发送给客户端。我给您添加了一个伪代码,以使效果更好:

public class MyVerticle1 extends AbstractVerticle{

    public void start(Future<Void> startFuture) {

        connection.query("select * from file", result -> {

            if (result.succeeded()) {
                List<JsonArray> rowsSelected = result.result().getResults();
                eventBus.send("adress", rowsSelected, res -> {
                    if (res.succeded()) {
                        routinContext.response().end(res.result().encodePrettily());
                    }
                });
            } else {
                LOGGER.error(result.cause().toString());
            }

        });

    }

}

public class MyVerticle2 extends AbstractVerticle{

    public void start(Future<Void> startFuture) {
        JsonArray resultOfSelect = new JsonArray();

        eventBus.consumer("adress", message -> {
            List<JsonArray> rowsSelected = (List<JsonArray>) message.body();
            rowsSelected.forEach(jsa -> {
                JsonObject row = new JsonObject();
                row.put("id", jsa.getInteger(0));
                row.put("name", jsa.getString(1));
                resultOfSelect.add(row);
            });

            message.reply(resultOfSelect);
        });
    }
}

我真的看不到制作2个顶点的意义,因为我可以在第一个顶点中使用查询结果而无需使用第二个顶点。

对于我来说,Eve​​ntBus对于将信息传输到顶点以进行并行处理非常重要。

1 个答案:

答案 0 :(得分:1)

请记住-不幸的是,您正在寻找的答案非常细微,并且会因许多条件而异(例如,回答者的经验,代码库中的设计习惯用法,可供您使用的工具/库等)。所以没有权威的答案,无论什么适合您(和您的同事)。

  

我的同事告诉我,在一个实例中实例化一个类是不好的   verticle,当我问他为什么时,他回答说它变成有状态的   而且我怀疑他对我说了什么,因为我不知道如何。

从一般意义上讲,您的同事是正确的,因为您不想让集群中的各个节点保持其自身状态,因为实际上这会阻碍可靠地扩展的能力。但是在这种情况下,MyFile似乎是无状态的,因此将其引入Verticle的成员并不会自动使服务器变为有状态。

((如果有的话,我会{@ {1}}会做比基于文件的操作更多的问题-它还会处理HTTP请求和响应)。

  

当我在我的MyFile类实例中声明“ static final”时   verticle,我想说我甚至因为使用而获得了性能   每个传入请求的实例相同,而不是创建一个新实例   实例。

我会说这取决于设计偏好。本身并没有真正的“伤害”,但是我倾向于避免对静态常量以外的任何东西使用静态成员,而宁愿使用依赖注入来连接我的依赖。但是也许这是一个非常简单的项目,并且引入DI框架超出了您希望引入的复杂性。这完全取决于您的特定情况。

  

此外,我想知道使用2有什么好处   只能治疗一个顶点吗?

同样,这取决于您的具体情况和您的“复杂性预算”。如果处理很简单,并且您希望使设计保持同样简单,则单个Verticle很好(并且可以说更易于理解/概念化和支持)。在较大的应用程序中,我倾向于沿着正在使用的不同逻辑域的路线创建许多Verticles(例如,用于身份验证的Verticles,用于用户帐户功能的Verticles等),并通过MyFile协调任何复杂的处理。