How to disable TCP-port sharing in vert.x 2.0.0?

421 views
Skip to first unread message

Nikolay Artamonov

unread,
Aug 18, 2013, 2:40:39 AM8/18/13
to ve...@googlegroups.com
I run two instances of my application (inside diffirent JVMs) with embedded vert.x. Each instance tries to create HttpServer and bind to some port and host:

Vertx vertx = VertxFactory.newVertx();
HttpServer server = vertx.createHttpServer().requestHandler(handler);
server.listen(port, host);

When I used vert.x 1.2.3 last call (HttpServer#listen) was throwing exception with cause java.net.BindException if `port` was already used by other instance of application. After upgrade to vert.x 2.0.0 it doesn't happen anymore. I suppose it's because of how scaling works in new version of vert.x.

How can I determine that some port is already used by other instance of application?

Thanks!

Tim Fox

unread,
Aug 18, 2013, 4:43:55 AM8/18/13
to ve...@googlegroups.com
On 18/08/13 07:40, Nikolay Artamonov wrote:
> I run two instances of my application (inside diffirent JVMs) with embedded
> vert.x. Each instance tries to create HttpServer and bind to some port and
> host:
>
> Vertx vertx = VertxFactory.newVertx();
> HttpServer server = vertx.createHttpServer().requestHandler(handler);
> server.listen(port, host);
>
> When I used vert.x 1.2.3 last call (HttpServer#listen) was throwing
> exception with cause java.net.BindException if `port` was already used by
> other instance of application. After upgrade to vert.x 2.0.0 it doesn't
> happen anymore.

In 2.0, any bind exception will be provided to you in the
Handler<AsyncResult> that you provide to the listen method.

Nikolay Artamonov

unread,
Aug 18, 2013, 7:27:13 AM8/18/13
to ve...@googlegroups.com
Yes, I tried it. Unfortunately, AsyncResult is always succeeded, even if port was already binded by some other application instance. So I get no bind exception when run two instances (inside different JVM) of application with following source code (Scala). 

import org.vertx.java.core.{AsyncResult, VertxFactory, Handler, Vertx}
import org.vertx.java.core.http.{HttpServer, HttpServerResponse, HttpServerRequest}

object Main extends App {
  val server = VertxFactory.newVertx().createHttpServer().requestHandler(handler)
  server.listen(88, "localhost", new Handler[AsyncResult[HttpServer]] {
    def handle(res: AsyncResult[HttpServer]) {
      res.succeeded() match {
        case true  => println("Server was binded to port 88.")
        case false => res.cause().printStackTrace()
      }
    }
  })

  System.in.read()

  def handler = new Handler[HttpServerRequest] {
    def handle(req: HttpServerRequest) {
      println("REQ %s: %s (server ID=%s)".format(req.method(), req.uri(), this.##))
      req.response().setStatusCode(200)
      req.response().end()
    }
  }
}

Tim Fox

unread,
Aug 18, 2013, 7:34:53 AM8/18/13
to ve...@googlegroups.com
It's impossible to bind two server sockets to the same host:port- this
is not a Java limitation, or a Vert.x limitation, it's just how TCP
sockets work.

Vert.x doesn't do any port sharing between different Vert.x instances.

Nikolay Artamonov

unread,
Aug 19, 2013, 2:54:16 PM8/19/13
to ve...@googlegroups.com
I know it. I don't claim that vert.x can actually share TCP port that is not possible. What I claim that two adjacent calls to HttpServer#listen() with same port and host does not throw bound exception (or any other exception), synchronously or asynchronously. Is it correct contract for method HttpServer#listen()?

воскресенье, 18 августа 2013 г., 15:34:53 UTC+4 пользователь Tim Fox написал:

Tim Fox

unread,
Aug 20, 2013, 2:31:45 AM8/20/13
to ve...@googlegroups.com
On 19/08/13 19:54, Nikolay Artamonov wrote:
> I know it. I don't claim that vert.x can actually share TCP port that is
> not possible. What I claim that two adjacent calls to HttpServer#listen()
> with same port and host does not throw bound exception (or any other
> exception), synchronously or asynchronously. Is it correct contract for
> method HttpServer#listen()?

The second one to listen should fail.

Can you provide a runnable test case that demonstrates the issue (not in
Scala please)?
>
> О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, 18 О©╫О©╫О©╫О©╫О©╫О©╫О©╫ 2013 О©╫., 15:34:53 UTC+4 О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ Tim Fox
> О©╫О©╫О©╫О©╫О©╫О©╫О©╫:

Nikolay Artamonov

unread,
Aug 23, 2013, 11:01:28 AM8/23/13
to ve...@googlegroups.com

Can you provide a runnable test case that demonstrates the issue (not in
Scala please)?

Tim Fox

unread,
Aug 23, 2013, 1:46:46 PM8/23/13
to ve...@googlegroups.com
Vert.x allows you to bind multiple servers in the same Vert.x instance
to the same host/port - under the bonnet only one server is created and
requests are round robin'd between them. This is explained in the API
manual.

So I would your test to fail.

Tim Fox

unread,
Aug 23, 2013, 1:51:44 PM8/23/13
to ve...@googlegroups.com
On 23/08/13 18:46, Tim Fox wrote:
Vert.x allows you to bind multiple servers in the same Vert.x instance to the same host/port - under the bonnet only one server is created and requests are round robin'd between them. This is explained in the API manual.

http://vertx.io/core_manual_java.html#scaling-tcp-servers

The link is for TCP but the same applies for HTTP servers

Nikolay Artamonov

unread,
Aug 23, 2013, 2:50:12 PM8/23/13
to ve...@googlegroups.com
Thanks, Tim! If I understand you correctly, you said that multiple HttpServers in the same vertx instance can be bound to the same port/host. But in my test I actually create two different non-clustered vert.x instances (according to javadocs) with this call:

VertxFactory.newVertx()

Am I missing something or don't understand? Is it correct that that two HttpServers in different vertx instances can be bound to the same port/host? If so, how can I disable such load balancing behaviour?



2013/8/23 Tim Fox <timv...@gmail.com>

--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/I6qdw8GXVoQ/unsubscribe.
To unsubscribe from this group and all of its topics, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
С уважением,
Артамонов Николай
mailto:narta...@gmail.com

javajosh

unread,
Aug 24, 2013, 2:28:31 AM8/24/13
to ve...@googlegroups.com


On Friday, August 23, 2013 11:50:12 AM UTC-7, Nikolay Artamonov wrote:
Thanks, Tim! If I understand you correctly, you said that multiple HttpServers in the same vertx instance can be bound to the same port/host. But in my test I actually create two different non-clustered vert.x instances (according to javadocs) with this call:

VertxFactory.newVertx()

Am I missing something or don't understand? Is it correct that that two HttpServers in different vertx instances can be bound to the same port/host? If so, how can I disable such load balancing behaviour?

Your test is creating two verticles in one vertx instance. Therefore they are sharing ports.

A proper test would require the use of two processes. E.g. something like this:

===test.sh===
echo 'vertx.createHttpServer().requestHandler {req ->"got a request!"}.listen(8080) ; println "listening on 8080"' > foo.groovy
vertx run foo.groovy &
vertx run foo.groovy 

This will yield:
ERROR: transport error 202: bind failed: Address already in use

Tim Fox

unread,
Aug 24, 2013, 3:25:37 AM8/24/13
to ve...@googlegroups.com
Nikolay - can you add an issue in Bugzilla?

Thanks

On 23/08/13 19:50, Nikolay Artamonov wrote:
> Thanks, Tim! If I understand you correctly, you said that multiple
> HttpServers *in the same vertx instance* can be bound to the same
> port/host. But in my test I actually create *two different non-clustered
> vert.x instances* (according to
> javadocs<http://vertx.io/api/java/org/vertx/java/core/VertxFactory.html#newVertx()>)
> with this call:
>
> VertxFactory.newVertx()
>
> Am I missing something or don't understand? Is it correct that that two
> HttpServers in *different* vertx instances can be bound to the same
Reply all
Reply to author
Forward
0 new messages