High availability Webitel
Webitel разрабатывается с поддержкой микросервисной архитектуры, которая позволяет обеспечивать надежную и слаженную работу всех приложений. В документе Webitel Architecture вы найдете детальное описание архитектуры Webitel и как сервисы взаимодействуют между собой.
В данном документе мы рассмотрим, как повысить надежность и уменьшить время простоя, спровоцированного возможными сбоями программно-аппаратных ресурсов.
Прежде чем приступать к настройке, необходимо проработать какие компоненты приложения и как будут кластеризоваться.
Выделим основные группы приложений:
Рассмотрим каждую из групп отдельно.
Discover Services
Discover Services решает проблему доступности микросервисов на разных сетевых узлах. Каждое из приложений Webitel во время запуска регистрирует себя с указанием сетевого адреса (IPv4), порта для коммуникации (gRPC) и уникального идентификатора. Без Discover Services невозможна работа приложения.
В качестве Discover Services в Webitel используется consul. В официальной документации consul вы найдете примеры построения отказоустойчивого кластера, а также практики использования.
Каждый из сервисов Webitel содержит обязательную для заполнения строку подключения к кластеру consul:
-consul consul.host:8500
Message Broker
Message Broker обеспечивает возможность гарантированного обмена событиями и сообщениями между приложениями Webitel. Без Message Broker невозможна работа приложений.
В качестве Message Broker в Webitel используется RabbitMQ. В официальной документации rabbitmq вы найдете примеры построения отказоустойчивого кластера, а также практики использования.
Каждый из сервисов Webitel содержит обязательную для заполнения строку подключения к кластеру rabbitmq:
-amqp amqp://user:pass@rabbitmq.host:5672?heartbeat=10
Database
Реляционная база данных хранит настройки приложения, а также данные пользователей. На уровне базы данных реализован механизм работы предиктивного дайлера. Без базы данных невозможна работа приложений.
В качестве базы данных в Webitel используется PostgreSQL (на текущий момент - 15 версия). Для обеспечения целостности данных и уменьшения нагрузки на базу данных, минимально рекомендуемая для использования архитектура с Primary DB и Streaming Replica.
В официальной документации вы сможете найти описание других вариантов кластеризации базы данных:
Сервисы Webitel поддерживают возможность указания несколько строк подключения к базе данных как в режиме "запись\обновление\удаление", так и в режиме "чтение". Пример параметров подключения:
-data_source postgres://user:pass@primary.db.host:5432/webitel?fallback_application_name=engine&sslmode=disable&connect_timeout=10
-sql_data_source_replicas postgres://user:pass@replica.db.host:5432/webitel?fallback_application_name=engine&sslmode=disable&connect_timeout=10&search_path=call_center
Media Services
Media Services - медиа шлюз, который используется в построении голосовых меню (IVR), записей разговоров и других задач телефонии.
В качестве Media Services в Webitel используется FreeSWITCH. Вы можете разместить одно приложение в активном состоянии, а второе поднимать только в том случае, если недоступно основное. Также, вы можете установить несколько приложений FreeSWITCH на разных серверах, которые будут работать в режиме load-balancer (подробней будет описано в разделе SIP Proxies). Для каждого экземпляра FreeSWITCH необходимо будет установить собственный сервис управления маршрутизацией flow_manager (подробней будет описано в разделе Webitel Services).
FreeSWITCH недоступен из внешней сети. Коммуникация между пользователями, а также провайдерами связи происходит с помощью RTP, SIP и Reverse Proxy.
RTP Proxies
Задачи, которые решает RTP Proxies - согласование разных голосовых протоколов (например, между (S)RTP и WebRTC), а также повышение доступности сервиса.
В качестве RTP Proxy в Webitel используется rtpengine. Вы можете установить один или несколько сервисов, которые будут работать в режиме load-balancer (подробней будет описано в разделе SIP Proxies). Либо разделить сервисы для внутренних пользователей и внешних провайдеров связи.
В конфигурационном файле каждого экземпляра rtpengine необходимо указать интерфейс и UDP порт для внешнего управления (по умолчанию, 60000), а также какой сетевой адрес (IPv4) и какой диапазон UDP портов будет использовать приложение. Пример фрагмента конфигурационного файла /etc/rtpengine/rtpengine.conf с описанием данных настроек:
interface = lan/192.168.2.45;wan/81.33.44.55
listen-ng = 192.168.2.45:60000
port-min = 10000
port-max = 59999
SIP Proxy
Для взаимодействия с внешними провайдерами по протоколу SIP 2.0, для подключения SIP-телефонов либо клиентов по WebRTC протоколу, используется OpenSIPS сервер.
В настройках описаны параметры подключения к базе данных:
modparam("db_virtual", "db_urls", "postgres://user:password@primary.db.host:5432/webitel?application_name=opensips")
В таблицах хранится информация о медиа сервисах (Media Services) и RTP Proxies, которые необходимо использовать в режиме load-balancer.
FreeSWITCH (table dispatcher)
id | setid | destination | socket | state | weight | priority | attrs | description
----+-------+--------------------------------+---------------------+-------+--------+----------+------------+-------------
1 | 1 | sip:10.10.10.21:5080 | | 1 | 0 | 0 | | FS1
2 | 1 | sip:10.10.10.22:508 | | 1 | 0 | 0 | | FS2
rtpengine (table rtpengine)
id | socket | set_id
----+------------------------+--------
1 | udp:192.168.2.45:60000 | 1
2 | udp:192.168.2.46:60000 | 1
Для резервирования сервиса OpenSIPS вы можете разместить одно приложение в активном состоянии, а второе поднимать только в том случае, если недоступно основное.
Reverse Proxy
Reverse Proxy используется для доступа из внешней среды к WebSocket серверу, WebRTC и API. В качестве Reverse Proxy выступает nginx. Сервис должен иметь запись в DNS и наличие TLS сертификатов. Может быть совмещен с пунктом Web Server.
В конфигурационном файле описан доступ к сервисам:
REST API
location ~ ^/api(/?)(.*) {
rewrite ^/api(/?)(.*) /$2 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr:$remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://webitel.api.service.local:8080;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
WebRTC
location ~ ^/sip(/?) {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://opensips.service.local:5070;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
}
WebSocket
location ~ ^/ws(/?)(.*) {
rewrite ^/ws(/?)(.*) /$2 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr:$remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://webitel.engine.service.local:10022;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
}
File Storage
location ~ ^/api/storage/(media|recordings|file|tts)/?(.*/)(stream|download|upload|transcript).* {
limit_except GET OPTIONS POST {
deny all;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
proxy_request_buffering off;
rewrite ^/api/storage/(.*) /api/v2/$1 break;
proxy_pass http://webitel.storage.service.local:10023;
}
location ~ ^/any/file(/\d+)?/download(/.*)? {
limit_except GET OPTIONS {
deny all;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
rewrite ^/(any/file(/\d+)?/download)(/.*)? /api/v2/$1 break;
proxy_pass http://webitel.storage.service.local:10023;
}
location ~ ^/any/file/(.*) {
limit_except GET OPTIONS {
deny all;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
rewrite ^/any/file/(.*) /api/v2/any/file/$1 break;
proxy_pass http://webitel.storage.service.local:10023;
}
Микро сервисы Webitel будут описаны ниже.
Web Server
Web Server используется для публикации Web приложений Webitel. Список приложений, которые должны быть установлены на сервере:
webitel-auth-app - авторизация пользователей
webitel-admin-app - интерфейс администратора
webitel-agent-workspace - рабочее место оператора
webitel-supervisor-workspace - рабочее место супервизора
webitel-audit-app - рабочее место аудитора оценки качества
webitel-flow-diagram - графический конструктор маршрутизации
webitel-history - история звонков
webitel-web-widget - библиотеки виджета "кнопка на сайте"
webitel-crm - клиентская база
В качестве Web Server выступает nginx. Сервис должен иметь запись в DNS и наличие TLS сертификатов. Может быть совмещен с пунктом Reverse Proxy.
Files Storage
По умолчанию, Webitel хранит все файлы (записи разговоров, аудио ресурсы для голосовых меню, файлы полученные в чатах) на локальной файловой системе. За работу с файлами отвечает приложение Webitel Storage, которе поддерживает кластеризацию (будет описано в разделе Webitel Services). Самый простой и надежный способ обеспечить доступность файлов внезависимости от текущего расположения сервиса Webitel Storage - подключить хранилище совместимое с протоколом S3. Возможно использование коммерческих сервисов, таких как AWS S3 либо DigitalOcean Spaces, так и размещеных локально, как MinIO. Хранилище может быть подключено как с помощью настроек (смотри Хранилища (Интеграции)), так и на уровне сервиса:
-file_store_type s3
-file_store_props "{\"key_id\": \"KEY1\", \"region\": \"eu-central-1\", \"endpoint\": \"amazonaws.com\", \"access_key\": \"KEY2\", \"bucket_name\": \"bucket.webitel\", \"path_pattern\": \"$DOMAIN/$Y/$M/$D\"}"
Если нет возможности подключить распределенное файловое хранилище S3, тогда необходимо реализовать синхронизацию файлов в директории /opt/storage между всеми виртуальными серверами, на которых будут размещены сервисы Webitel Storage.
Webitel Services
Все микросервисы Webitel поддерживают кластеризацию. Это означает, что вы можете запустить столько экземпляров, сколько вам необходимо на разных виртуальных серверах. Приложения автоматически будут распределять нагрузку, балансировать запросы, а также отключать сервис, если он недоступен.
Для сервисов:
webitel-storage
webitel-engine
webitel-flow-manager
webitel-call-center
webitel-logger
webitel-cases
Необходмо прописать уникальный идентификатор (строка либо целое число) с помощью ключа запуска сервиса. Пример webitel-engine:
ExecStart=/usr/local/bin/engine -id 10
Для сервисов:
webitel-app
webitel-messages
Уникальный идентификатор присваивается автоматически после запуска. Не требуются дополнительные настройки.