avoiding too many file open on create a lot of vertx httpclient

839 views
Skip to first unread message

Kocsis Tibor

unread,
Oct 19, 2016, 5:18:55 AM10/19/16
to vert.x
Hi,

I have the following very basic code, it creates 1000 httpclient in a loop and make a http request call:

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClient;

public class HttpRequest extends AbstractVerticle {
   
   
@Override
   
public void start() throws Exception {
       
super.start();
       
       
for (int i = 0; i < 1000; i++) {
           
HttpClient httpClient = vertx.createHttpClient();
            httpClient
.getNow(80, "localhost", "", response -> {
           
});
       
}
   
}
   
   
public static void main(String[] args) {
       
Vertx vtx = Vertx.vertx();
        vtx
.deployVerticle(new HttpRequest());
   
}
}


On my computer it can't run, the error is too many file open. I think it creates a lot of sockets, and these sockets reach the unix file limit for my user. I can increase this limit, but then I put 50000 for the end of the loop and the problem is there again. So what is the correct way in vertx to generate thousands of http call in a loop?

(Btw I got the same problem on server side with httpserver)

Regards,
Tibor

Clement Escoffier

unread,
Oct 19, 2016, 6:11:09 AM10/19/16
to ve...@googlegroups.com
Hi,

You need to close the clients when you don’t need them anymore:
client.close();

Clement


--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/068db03e-ff9a-49c0-bf20-da6f0332cc3d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kocsis Tibor

unread,
Oct 19, 2016, 6:19:39 AM10/19/16
to vert.x
Hi Clement,

I called the client.close() inside the response handler but the error is the same as previous.

httpClient.getNow(80, "localhost", "", response -> {

    httpClient
.close();
});


Exception in thread "globalEventExecutor-1-1" java.lang.InternalError: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.102-1.b14.el7_2.x86_64/jre/lib/ext/cldrdata.jar (Too many open files)
    at sun
.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:1003)
    at sun
.misc.URLClassPath.getResource(URLClassPath.java:212)
    at java
.net.URLClassLoader$1.run(URLClassLoader.java:365)
    at java
.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java
.security.AccessController.doPrivileged(Native Method)
    at java
.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java
.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java
.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun
.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java
.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java
.util.ResourceBundle$RBClassLoader.loadClass(ResourceBundle.java:503)
    at java
.util.ResourceBundle$Control.newBundle(ResourceBundle.java:2640)
    at java
.util.ResourceBundle.loadBundle(ResourceBundle.java:1501)
    at java
.util.ResourceBundle.findBundle(ResourceBundle.java:1465)
    at java
.util.ResourceBundle.findBundle(ResourceBundle.java:1419)
    at java
.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1361)
    at java
.util.ResourceBundle.getBundle(ResourceBundle.java:845)
    at java
.util.logging.Level.computeLocalizedLevelName(Level.java:265)
    at java
.util.logging.Level.getLocalizedLevelName(Level.java:324)
    at java
.util.logging.SimpleFormatter.format(SimpleFormatter.java:165)
    at java
.util.logging.StreamHandler.publish(StreamHandler.java:211)
    at java
.util.logging.ConsoleHandler.publish(ConsoleHandler.java:116)
    at java
.util.logging.Logger.log(Logger.java:738)
    at io
.netty.util.internal.logging.JdkLogger.log(JdkLogger.java:606)
    at io
.netty.util.internal.logging.JdkLogger.warn(JdkLogger.java:482)
    at io
.netty.util.concurrent.GlobalEventExecutor$TaskRunner.run(GlobalEventExecutor.java:235)
    at io
.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java
.lang.Thread.run(Thread.java:745)

Alexander Lehmann

unread,
Oct 19, 2016, 6:56:25 AM10/19/16
to vert.x
If you start 5000 http client requests, it will create 5000 sockets requiring n*5000 file descriptors (not sure if the http client uses more than one) since all requests are executed concurrently.

While it may be necessary to open many http connections, you have to put some limit on that since the file descriptors will run out at some point anyway.

If you create the httpClient outside your loop, it will use the connection pool limit so that only a certain number of requests are executed concurrently and the others will wait for previous requests to finish and then start (I think the default size is 10, you can change that with an options property).

Another possibility would be to start each new request in the response handler of the previous one (essentially serializing the requests) or you can start some requests concurrently and then start new ones in the response handler of each request. For a load test that makes sense since you can control the number of requests that are concurrently running, for a regular operation of a programm, using the connection pool is probably simpler.

Jochen Mader

unread,
Oct 19, 2016, 7:31:39 AM10/19/16
to ve...@googlegroups.com
On the machine you are running use "ulimit -n" to figure out what the max number of open file handles is.
This is most likely a number well below 5000.
This problem is actually a pretty common one, especially with NIO-based interactions because they allow you to open way more concurrent connections than ever before.
Increase that limit to  a more fitting value.

To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Jochen Mader | Lead IT Consultant

codecentric AG | Elsenheimerstr. 55a | 80687 München | Deutschland
tel: +49 89 215486633 | fax: +49 89 215486699 | mobil: +49 152 51862390
www.codecentric.de | blog.codecentric.de | www.meettheexperts.de | www.more4fi.de

Sitz der Gesellschaft: Düsseldorf | HRB 63043 | Amtsgericht Düsseldorf
Vorstand: Michael Hochgürtel . Mirko Novakovic . Rainer Vehns
Aufsichtsrat: Patric Fedlmeier (Vorsitzender) . Klaus Jäger . Jürgen Schütz

Kocsis Tibor

unread,
Oct 19, 2016, 7:49:42 AM10/19/16
to vert.x
Can you give some more hint to use the built in connection pool in this case? I tried the following code but still execute all the request concurrently and "too many open files" come:

    @Override
   
public void start() throws Exception {
       
super.start();

       
       
HttpClient httpClient = vertx.createHttpClient();

        httpClient
.getNow(80, "localhost", "", response -> {

            httpClient
.close();

       
});
   
}
   
   
public static void main(String[] args) {

       
Vertx vtx = Vertx.vertx(new VertxOptions());
       
for (int i = 0; i < 10000; i++) {
            vtx
.deployVerticle(HttpRequest.class.getName());
       
}
   
}


Kocsis Tibor

unread,
Oct 19, 2016, 7:51:44 AM10/19/16
to vert.x
Thank you for your answer but as i mentioned above, i try to solve the problem inside the application or in better case with vertx.

Mumuney Abdlquadri

unread,
Oct 19, 2016, 8:26:32 AM10/19/16
to ve...@googlegroups.com
Hi Tibor,

Can you try this:

public class HttpRequest extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
        HttpClient httpClient = vertx.createHttpClient();


for (int i = 0; i < 1000; i++) {

            httpClient.getNow(80, "localhost", "", response -> {
                System.out.println(response.statusMessage()+response.statusCode());


});
}
}

public static void main(String[] args) {
Vertx vtx = Vertx.vertx();
vtx.deployVerticle(new HttpRequest());
}
}

In your last example your still deploying the verticle which creates a fresh HTTPClient 5000 times...

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.

Mumuney Abdlquadri

unread,
Oct 19, 2016, 8:27:20 AM10/19/16
to ve...@googlegroups.com
sorry maybe I got the number wrong. but let me know if it works.

Kocsis Tibor

unread,
Oct 19, 2016, 8:48:47 AM10/19/16
to vert.x
It works! Thank you very much!

Now I understand the mechanism, the httpClient creates an async worker for every end() call, and the instance manages the connection pool (default 40).

Regards,
Tibor
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages