Мы находимся в процессе разработки приложения 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 и обеспечивает балансировку нагрузки для всех поддерживаемых протоколов. Наиболее важные из них:
для определения вашего балансира:
<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 тоже.