2016-02-12 1 views
1

КонтекстКак/где внедрить коммуникацию сервера в рабочий процесс Flux?

Мы строим поток на основе веб-приложение, где клиент (Flux/React/машинопись) взаимодействует с сервером (C#) через WebSockets (не через HTTP GET).

Когда выполняется действие на стороне клиента, мы отправляем запрос команды серверу через соединение с веб-сокетом.

Сервер всегда реагирует быстро с первым ответом Start (указывая, может ли он выполнить запрошенное действие), а затем отвечает на 1 или более ответов на процесс (может быть несколько сотен ответов, которые содержат информацию о ходе выполнения действие). Когда действие на сервере будет завершено, последний ответ Progress будет иметь долю прогресса 100% и статус ошибки «ОК».

Обратите внимание, что некоторые действия сервера могут занимать всего 100 мс, но другие могут занимать до 10 минут (следовательно, ответы о ходе работы, поэтому клиент может показать что-то о действии для пользователя).

В клиенте, мы имеем:

  • функция sendCommandRequest, которую мы называем отправить запрос команды на сервер через WebSocket
  • функцию обработчика handleCommandResponse (который вызывается в WebSocket OnMessage обратного вызова)

Вопрос, который у нас есть, - это лучший способ вставить серверную связь в приложение на основе Flux? Где мы должны посылать вызовы на websocket и как мы должны перейти от обратного вызова веб-памяти обратно в цепочку Flux?

Предложение

Допустим, мы изменяем параметр визуальных эффектов в графическом интерфейсе клиента (число с плавающей точкой, установите в поле текстовое поле), и это вызывает действие на сервере, который генерирует новое изображение. Это действие занимает 1 секунду для выполнения на сервере.

Теперь, как это происходит, обработчик GUI отправит на диспетчер действие Flux, которое вызывает обратные вызовы зарегистрированных в нем магазинов, а затем хранилища обновляют свои данные на основе полезной нагрузки действия, и запускать различные компоненты посредством обратных вызовов событий изменения, которые используют setState с новыми данными хранилища для запуска повторной обработки.

Мы можем позволить магазинам отправлять командные запросы через websocket на сервер в момент их изменения (например, новое значение параметра). В этот момент у магазина будет новое значение параметра, тогда как изображение остается последним полученным изображением (результат предыдущей команды).

С этого момента сервер начинает отсылать ответы о ходе работы клиенту, которые поступают в обратный вызов websocket onMessage, а окончательный ответ Progress будет содержать новое изображение (через 2 секунды).

В обратном вызове websocket onMessage мы можем отправить второе диспетчерское действие Flux с передачей загруженного нового изображения, и это заставит магазины обновлять свои данные новым изображением, что вызовет прослушивание компоненты для повторной обработки.

Проблема с этим:

  • флюса магазин может частично обновленные данные: пока сервер не посылает назад конечный результат, магазин будет иметь новый параметр, но до сих пор старый image
  • Нам нужно 2 действия с потоком: один используется графическим интерфейсом, чтобы сигнализировать пользователю о внесении изменений, а один используется обратным вызовом веб-сокета, чтобы сообщить, что какой-то результат получен
  • если что-то пошло не так на стороне сервера, новый параметр уже установлен в хранилище Flux, в то время как мы никогда не получим новое изображение, поэтому данные в хранилище будут приходит поврежденным

Есть ли лучшие способы вписаться в связь с сервером в поточном потоке? Любые советы/рекомендации?

ответ

0

если что-то пойдет не так, на стороне сервера, новый параметр уже установлен в Flux магазине, в то время как мы никогда не будем получать новое изображение, поэтому данные в магазине становится коррумпированной

Вот несколько failsafes:

  • Кэширование

У нас есть слой кэширования на каждом из узлов API. Этот метод не только улучшает латентность (до 20%), но и повышает доступность, когда службы зависимостей опускаются. Кроме того, нагрузка на системы зависимостей значительно сокращается (до 70% в нашем случае). Для максимальной гибкости мы помещаем кеш близко к вызовам зависимостей и используем Guava в нашей реализации.

  • защита Dependency

Иногда мы замечаем модели, где служба зависимость будет деградировать, в результате чего потоки в системе API в стойло. Это значительно снижает пропускную способность и может привести к сбою системы из-за истощения потока. Чтобы этого избежать, мы реализовали агрессивные таймауты по зависимостям и автоматизированный механизм устранения вызовов служб зависимостей, когда они не работают. Этот метод значительно улучшает масштабируемость, поскольку потоки теперь могут действовать вместо ожидания таймаута.

  • Спекулятивного Retry

В нашем анализе, некоторая зависимость, как правило, имеет непропорционально большую P99 (ака-девяносто девятой процентиля) задержку, по сравнению сказать P95 латентность. В более общем плане мы видим модели, где наблюдается резкий скачок в латентности. В точке, где происходит скачок латентности, мы вводили параллельный повтор и потребляем первый полученный ответ. Компромисс - это увеличение трафика на наши системы зависимостей в обмен на более низкую задержку и частоту ошибок. В нашем случае этот подход уменьшил задержку до 22%, а коэффициент ошибок - до 81%.

  • Reconnection Алгоритм

Это может случиться так, что сервер XMPP переходит в автономном режиме неожиданно в то время как обслуживания TCP соединения от подключенных клиентов и удаленных серверов. Поскольку число таких соединений может быть довольно большим, алгоритм пересоединения , используемый объектами, которые стремятся подключиться , может оказать существенное влияние на производительность программного обеспечения и сеть заторов. Если предприятие выбирает восстановить соединение, это:

SHOULD set the number of seconds that expire before reconnecting 
    to an unpredictable number between 0 and 60 (this helps to ensure 
    that not all entities attempt to reconnect at exactly the same 
    number of seconds after being disconnected). 

SHOULD back off increasingly on the time between subsequent 
    reconnection attempts (e.g., in accordance with "truncated binary 
    exponential backoff" as described in [ETHERNET]) if the first 
    reconnection attempt does not succeed. 
  • TLS Возобновление

Данной спецификация описывает механизм для распространения зашифрованного состояния сеанса информации клиента в форме билет и механизм , чтобы представить билет обратно на сервер. Билет , созданный сервером TLS и отправленный клиенту TLS. Клиент TLS представляет билет на сервер TLS для возобновления сеанса. Предполагается, что реализации этой спецификации будут поддерживать как механизмы .

Websocket Server

Flux Broker

SOAP

RTMP

RTSP

Media Fragment Resolution

WebSocket Proxy Load Balancing

Flex

WebSocket OAuth

Flux Command Pattern

Flux vs Redux

Традиционно одна из основных различий между веб-приложениями и родные приложения в том, что в отличие от веб-приложений , родные приложения могут быть запущены в автономном режиме. Это изменилось - такие технологии, как Service Workers, позволяют веб-сайту или веб-приложению кэшировать необходимые активы, чтобы он все равно мог работать в автономном режиме. Сюда относятся такие вещи, как файлы JavaScript, CSS и изображения. Сочетание этого метода с интеллектуальным использованием таких вещей, как localStorage, позволит вашей игре продолжать работать, даже если соединение с Интернетом идет вниз. Вам просто нужно синхронизировать все изменения, когда он снова подключится.

Список литературы

+0

Спасибо за содержательный ответ! Я перевариваю это и посмотрю, что применимо к моему прецеденту. –