HAProxy 背后的 Akka

Akka behind HAProxy

我有 2 个系统:系统 1 是 运行 akka 和 HAProxy,系统 2 是 运行 向 akka 发出请求的 REST 组件。

Akka 在系统 1 的端口 4241 上运行。当没有 HAProxy 时,系统 2 能够连接到系统 1。我在系统 1 上安装 HAProxy 后,从系统 2 到系统 1 的请求出错,日志如下:

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 在 42431 上运行。

HAProxy 配置如下:

listen akka_tcp :42431
        mode tcp
        option tcplog
        balance leastconn

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

akka配置是这样的:

  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
    }
  }

如有任何建议,我们将不胜感激。

更新的答案:

Akka Remoting 可能不适用于负载均衡器。看看它的这部分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.

对于您的情况,在系统 1 上使用 Akka HTTP 或 Akka I/O 来接受和回答来自系统 2 的请求似乎是合理的。


旧答案:

您必须在 Akka 配置中设置 bind-port 属性。这是引自 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.

对于您的端口,它应该是这样的:

port = 42431
bind-port = 4241