简体   繁体   English

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

[英]Danger of instantiating a class in a verticle vert.x

I explain my problem, I have a verticle in which I defined all the routes. 我解释了我的问题,我有一个顶点,其中定义了所有路线。 And I have simple java classes that contain methods that I call in my verticle depending on the route. 而且我有简单的Java类,其中包含我根据路径在顶点中调用的方法。 For example, my downloadFile() method is in the MyFile class like this: 例如,我的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
       }
    }

And I use this class in my verticle like this: 我像这样在我的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);
                });
            }
    }

My colleague tells me that it is not good to instantiate a class in a verticle and when I asked him why, he replied that it becomes stateful and I have doubts about what he says to me because I don't see how. 我的同事告诉我,在一个垂直实例中实例化一个类是不好的,当我问他为什么时,他回答说它变得有状态,并且我对他对我说的内容有所怀疑,因为我不知道怎么做。 And as I declared my MyFile class instance "static final" in my verticle, I want to say that I even gain in performance because I use the same instance for each incoming request instead of creating a new instance . 正如我在自己的Verticle中声明MyFile类实例为“ static final”一样,我想说我什至可以提高性能,因为我对每个传入请求都使用相同的实例,而不是创建一个新实例。

If it's bad to instantiate a class in a verticle, please explain why? 如果在verticle中实例化一个类很不好,请解释为什么?

In addition I would like to know what is the interest of using 2 verticles for a treatment that only one verticle can do? 另外,我想知道使用2个顶点进行仅一个顶点可以执行的处理的兴趣是什么?

For example, I want to build a JsonObject with the data I select in my database, why send this data to another verticle knowing that this verticle does nothing but build the JsonObject and wait for it to answer me for sent the response to the client so that I can build this JsonObject in the verticle where I made my request and immediately sent the response to the client.I put you a pseudo code to see better : 例如,我想用我在数据库中选择的数据构建一个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);
        });
    }
}

I really do not see the point of making 2 verticles since I can use the result of my query in the first verticle without using the second verticle. 我确实看不到制作2个顶点的意义,因为我可以在第一个顶点中使用查询结果而无需使用第二个顶点。

For me, EventBus is important for transmitting information to verticles for parallel processing. 对我而言,EventBus对于将信息传输到顶点以进行并行处理非常重要。

bear in mind... the answers you're looking for are unfortunately very nuanced and will vary depending on a number of conditions (eg the experience of whoever is answering, design idioms in the codebase, tools/libraries at your disposal, etc). 记住...不幸的是,您正在寻找的答案非常细微,并且会因许多条件而异(例如,回答者的经验,代码库中的设计习惯用法,可供您使用的工具/库等) 。 so there aren't an authoritative answers, just whatever suits you (and your co-workers). 因此,没有什么权威性的答案,只是适合您(和您的同事)的任何答案。

My colleague tells me that it is not good to instantiate a class in a verticle and when I asked him why, he replied that it becomes stateful and I have doubts about what he says to me because I see not how. 我的同事告诉我,在一个垂直实例中实例化一个类是不好的,当我问他为什么时,他回答说它变得有状态,并且我怀疑他对我说的话,因为我不知道怎么做。

your colleague is correct in the general sense that you don't want to have individual nodes in a cluster maintaining their own state because that will in fact hinder the ability to scale reliably. 从一般意义上讲,您的同事是正确的,因为您不想让集群中的各个节点保持自己的状态,因为实际上这会阻碍可靠地扩展的能力。 but in this particular case, MyFile appears to be stateless, so introducing it as a member of a Verticle does not automagically make the server stateful. 但是在这种情况下, MyFile似乎是无状态的,因此将其作为Verticle的成员引入并不会自动使服务器变为有状态。

(if anything, i'd take issue with MyFile doing more than file-based operations - it also handles HTTP requests and responses). (如果有的话,除了基于文件的操作之外, MyFile还会带来问题-它也处理HTTP请求和响应)。

And as I declared my MyFile class instance "static final" in my verticle, I want to say that I even gain in performance because I use the same instance for each incoming request instead of creating a new instance . 正如我在自己的Verticle中声明MyFile类实例为“ static final”一样,我想说我什至可以提高性能,因为我对每个传入请求都使用相同的实例,而不是创建一个新实例。

i'd say this goes to design preferences. 我会说这取决于设计偏好。 there isn't any real "harm" done here, per se, but i tend to avoid using static members for anything other than constant literals and prefer instead to use dependency injection to wire up my dependencies. 本身并没有真正的“伤害”,但是我倾向于避免对静态常量以外的任何东西使用静态成员,而宁愿使用依赖注入来连接我的依赖。 but maybe this is a very simple project and introducing a DI framework is beyond the complexity you wish to introduce. 但是也许这是一个非常简单的项目,并且引入DI框架超出了您希望引入的复杂性。 it totally depends on your particular set of circumstances. 这完全取决于您的特定情况。

In addition I would like to know what is the interest of using 2 verticles for a treatment that only one verticle can do? 另外,我想知道使用2个顶点进行仅一个顶点可以执行的处理的兴趣是什么?

again, this depends on your set of circumstances and your "complexity budget". 同样,这取决于您的具体情况和您的“复杂性预算”。 if the processing is simple and your desire is to keep the design equally simple, a single Verticle is fine (and arguably easier to understand/conceptualize and support). 如果处理很简单,并且您希望使设计保持同样简单,则单个Verticle很好(并且可以说更易于理解/概念化和支持)。 in larger applications, i tend to create many Verticles along the lines of the different logical domains in play (eg Verticles for authentication, Verticles for user account functionality, etc), and orchestrate any complex processing through the EventBus . 在较大的应用程序中,我倾向于沿着正在使用的不同逻辑域的方式创建许多Verticles(例如,用于身份验证的Verticles,用于用户帐户功能的Verticles等),并通过EventBus协调任何复杂的处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM