Назад | Перейти на главную страницу

Балансировщик нагрузки Apache для mod_proxy_wstunnel?

Мы находимся в процессе разработки приложения JavaEE 7 для развертывания на JBoss / Wildfly, которое будет широко использовать веб-сокеты. Мы используем mod_proxy_wstunnel для поддержки веб-сокетов, и нам удалось настроить и запустить прокси-конфигурацию с помощью mod_cluster на Apache 2.4:

Интернет -> Apache HTTPD -> Wildfly

Теперь мы столкнулись с проблемой кластеризации этого приложения. У нас будет как минимум 4 запущенных узла как для масштабируемости, так и для обеспечения высокой доступности. Я пробовал создать <Proxy /> элемент с 2-мя рядовыми серверами для достижения этой цели. Выглядело это примерно так:

<VirtualHost *:80>
   ...

   <Proxy balancer://myBalancer>
     BalancerMember ws://localhost:9080
     BalancerMember ws://localhost:19080
   </Proxy>

   <Location /ws>
     ...

     ProxyPass balancer://myBalancer/MyContextPath/myWebSocketEndpoint
     ProxyPassReverse balancer://myBalancer/MyContextPath/myWebSocketEndpoint
   </Location>
</VirtualHost>

Однако это не работает. Я всегда получаю ошибки подключения в JavaScript при попытке открыть веб-сокет по пути http://localhost/ws. Я бегло просмотрел документацию по mod_proxy_balancer и заметил, что он заявляет о поддержке протоколов HTTP, FTP и AJP13. Есть ли способ сбалансировать нагрузку на веб-сокеты и протокол WS? Или это полностью неподдерживаемая конфигурация? Какие еще альтернативы я могу использовать для этого? Очевидно, что использование единственного сервера веб-сокетов в качестве нашей производственной конечной точки неприемлемо, поскольку представляет собой единственную точку отказа. Буду ОЧЕНЬ благодарен за любой совет, который вы дадите!

Согласно официальной документации Apache: https://httpd.apache.org/docs/2.4/en/mod/mod_proxy_balancer.html

mod_proxy_balancer требует службы mod_proxy и обеспечивает балансировку нагрузки для всех поддерживаемых протоколов. Наиболее важные из них:

  • HTTP, используя mod_proxy_http
  • FTP, используя mod_proxy_ftp
  • AJP13, используя mod_proxy_ajp
  • WebSocket, используя mod_proxy_wstunnel

для определения вашего балансира:

<Proxy balancer://wsBalancer>
    BalancerMember ws://host1:9080 route=jvm1
    BalancerMember ws://host2:9080 route=jvm2
    ProxySet lbmethod=byrequests stickysession=JSESSIONID
</Proxy>

затем сделайте вызовы ws, чтобы добраться до этого балансировщика:

<LocationMatch "^/cometd/.*">
    ProxyPass "balancer://wsBalancer/" stickysession=JSESSIONID
</LocationMatch>   

Где здесь / cometd / - это WS-контекст вашего приложения.

Начиная с версии 2.4.5 существует модуль mod_proxy_wstunnel, который обеспечивает поддержку протокола WebSocket (ws: //) и безопасного протокола WebSocket (wss: //) для mod_proxy. Однако wss можно использовать только с 2.4.10+ из-за ошибки в более ранних версиях (PR55320).

Хотя это явно не упоминается в документации, вы можете использовать протокол ws (s) с mod_proxy (и mod_proxy_balancer), как и любые другие поддерживаемые протоколы. Просто убедитесь, что mod_proxy_wstunnel действительно загружен.

Из описания неясно, есть ли какие-либо полезные ошибки в журналах Apache. Вы уверены, что ваше веб-приложение обращается только к /ws? Возможно несоответствие пути, /ws/anything закончится как /MyContextPath/myWebSocketEndpoint/anything на вашем сервере WebSocket, что, вероятно, не то, что вам нужно.

В этом случае вам понадобятся:

<Proxy balancer://myBalancer>
    BalancerMember ws://localhost:9080
    BalancerMember ws://localhost:19080
</Proxy>

RewriteEngine On
RewriteRule /ws(/.*)? balancer://myBalancer/MyContextPath/myWebSocketEndpoint [P,L]

Я не уверен, можно ли это сделать с помощью Apache + mod_proxy.

Что касается альтернатив Apache, существуют другие коммерческие решения, которые обеспечивают балансировку нагрузки и поддержку Websocket. АЦП Ishlangu Load Balancer от Shaka Technologies поддерживает прозрачные (нулевые) веб-сокеты. Я считаю F5 BIG-IP тоже.