Vishal Sinha
Vishal Sinha

Reputation: 43

Akka behind HAProxy

I have 2 systems: system 1 is running akka and HAProxy, system 2 is running REST components that make a request to akka.

Akka runs on port 4241 on system 1. System 2 is able to connect to System 1 when there is no HAProxy. After I installed HAProxy on system 1, the request from system 2 to system 1 errors out with the logs below:

ERROR[deal-akka.actor.default-dispatcher-18] EndpointWriter - dropping message [class akka.actor.ActorSelectionMessage] for non-local recipient [Actor[akka.tcp://akkaSystemName@Server1IP:42431/]] arriving at [akka.tcp://akkaSystemName@Server1IP:42431] inbound addresses are [akka.tcp://akkaSystemName@Server1IP:4241]

HAProxy runs on 42431.

The HAProxy configuration is the following:

listen akka_tcp :42431
        mode tcp
        option tcplog
        balance leastconn

        server test1 Server1IP:4241 check
        server test2 Server1IP:4241 check

The akka configuration is this:

  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }

  remote {
    netty.tcp {

      hostname = "Server1IP"

      port = 4241

      transport-protocol = tcp

      # Sets the send buffer size of the Sockets,
      # set to 0b for platform default
      send-buffer-size = 52428800b

      # Sets the receive buffer size of the Sockets,
      # set to 0b for platform default
      receive-buffer-size = 52428800b

      maximum-frame-size = 52428800b
    }
  }

Any suggestion would be appreciated.

Upvotes: 1

Views: 564

Answers (1)

Denis Iskhakov
Denis Iskhakov

Reputation: 344

Updated answer:

Probably the Akka Remoting is not supposed to work with a Load Balancer. Look at this part of its documentation:

Akka Remoting is a communication module for connecting actor systems in a peer-to-peer fashion, and it is the foundation for Akka Clustering. The design of remoting is driven by two (related) design decisions:

1.Communication between involved systems is symmetric: if a system A can connect to a system B then system B must also be able to connect to system A independently.

2.The role of the communicating systems are symmetric in regards to connection patterns: there is no system that only accepts connections, and there is no system that only initiates connections.

The consequence of these decisions is that it is not possible to safely create pure client-server setups with predefined roles (violates assumption 2) and using setups involving Network Address Translation or Load Balancers (violates assumption 1).

For client-server setups it is better to use HTTP or Akka I/O.

For your case it seems reasonable to use Akka HTTP or Akka I/O on system 1 to accept and answer requests from system 2.


Old answer:

You have to set the bind-port property in the Akka configuration. Here is the quote from the Akka documentation:

# Use this setting to bind a network interface to a different port
# than remoting protocol expects messages at. This may be used
# when running akka nodes in a separated networks (under NATs or docker containers).
# Use 0 if you want a random available port. Examples:
#
# akka.remote.netty.tcp.port = 2552
# akka.remote.netty.tcp.bind-port = 2553
# Network interface will be bound to the 2553 port, but remoting protocol will
# expect messages sent to port 2552.

For your ports it should be like that:

port = 42431
bind-port = 4241

Upvotes: 1

Related Questions