eclipse-vertx / vert.x

Vert.x is a tool-kit for building reactive applications on the JVM
http://vertx.io
Other
14.31k stars 2.08k forks source link

Load balancing of datagram servers #1789

Closed tsegismont closed 7 years ago

tsegismont commented 7 years ago

As of 3.3.3, you can deploy multiple instances of a verticle, and leverage load balancing for HTTP servers and TCP servers.

However, deploying multiple instances of a verticle creating a datagram listener will result in a java.net.BindException: Address already in use.

You can avoid the exception by enabling address reuse: vertx.createDatagramSocket(new DatagramSocketOptions().setReuseAddress(true))

But only one verticle instance will handle the messages.

tsegismont commented 7 years ago

@normanmaurer @purplefox is this limitation due to some technical constraints? Or was not implemented due to lower priority?

testn commented 7 years ago

Did you try one with setReuseAddress(true)?

alokmenonin commented 7 years ago

Yes , Its still giving , Failed java.net.BindException: Address already in use . Also can refer to below post for more details. https://stackoverflow.com/questions/41952062/vertx-instantiating-multiple-vertical-instances-listening-to-same-socket

testn commented 7 years ago

Sorry... I meant REUSE_PORT. You might need to hack it by using reflection to set the option on the socket descriptor http://marrachem.blogspot.com/2014/09/multi-threaded-udp-server-with-netty-on.html

testn commented 7 years ago

@tsegismont It seems like too much hacking for the feature that Java does not really support out of the box?

vietj commented 7 years ago

agreed, we should do it if there is actual demand for it

testn commented 7 years ago

Epoll implementation of Netty actually supports that though.

vietj commented 7 years ago

good to know @testn we do have an epoll branch in this repo!

tsegismont commented 7 years ago

I thought again about this and the problem is that load balancing datagrams between verticles could be an issue if two datagrams coming from the same source are logically connected.

With TCP it is not a problem since packets of a single connection will go to the same verticle.

vietj commented 7 years ago

good point

tsegismont commented 7 years ago

Closing, implementing this would cause more problems than it would solve.

alokmenonin commented 7 years ago

Then it won't be a limitation in vetx for building a scalable solution which handles datagram packets ? Asynchronous messaging using UDP is so much relevant today especially for IOT applications. I think you guys should give this a shot rather than leaving this item open.

purplefox commented 7 years ago

I thought again about this and the problem is that load balancing datagrams between verticles could be an issue if two datagrams coming from the same source are logically connected.

With TCP it is not a problem since packets of a single connection will go to the same verticle.

Yes that is basically the reason - as there is no concept of connection with datagrams, how would you know which verticle to send the packet too? Random or round robin load balancing probably wouldn't make sense for the user.

It might be possible to create some kind of abstraction which groups packets per source address and balances on that, but that would involve some hacking.

vietj commented 7 years ago

@alokmenonin you can achieve it using the event bus

vietj commented 7 years ago

@purplefox agreed, it means more or less creating a notion of connection for instance the QUIC protocol that has the notion of connection id

pendula95 commented 4 years ago

What about a case where there is no logical connection between packages? This was also a limitation for SE java as there was no way for multiple threads to listen to same address but with introduction of SO_REUSEPORT in java 9 now it is possible. I would rethink this, with current testing I have done with java9 different source addresses are handled by different threads, maybe similar implementation can be made now or even to provide option to chose round robin or random as both would work for the case I want to build with vertx, radius-server, as connection is stateless. I think most of the time in UDP connection is stateless so this feature seems legit.

vietj commented 4 years ago

@pendula95 yes indeed, that being said nobody ever came with this use case for now

vietj commented 4 years ago

I think using event-bus would achieve the same because there is actually one event-loop that process packets, in the case of TCP it is different, one event loop accept sockets (the acceptor) and then load balance each channel to an event loop. In the case of UDP there is only one single channel, so using event-bus to distribute load would achieve exactly the same.