170 похожих чатов

Ребята, есть такой вопрос. У меня приложение интегрировано с веб-соккетами сторонних

систем. Точнее, с биржами криптовалют, откуда получают поток данных по сделкам, биржевым стаканам, тикам и т.п.
Я использую для интеграции опенсорс пакетики, в которых уже реализованы готовые обёртки, что экономит время интеграции.

В общем, каналы на которых льётся очень много данных регулярно отваливались и не переподключались средствами пакетов, хотя там есть Keep Alive настройки и т.п.
Я решил реализовать некий Visor, который следит за прекращением получания данных отттуда и переподключает соккеты с помоom. методов пакетов Stop()/Listen(). Это стало работать, но в некоторых случаях соккеты падают всё-таки намертво.
Я уже попробовал даже полностью убивать структуру этих пакетов и заново как с нуля создавать инстанс и подключаться. Это ещё решило часть зависаний, но всё равно случается, что коннект зависает и вообще никак не рестартует.
Судя пологам, случаются ошибки вроде “Broken Pipe”. Т.к. поток данных огромный, а зависания случаются раз с периодом от 1 часа до 3 суток, вообще не понятно что происходит.
Спасает только перегрузка приложения, сразу всё начинает работать без проблем. Т.е. речь о бане со стороны биржи не идёт.

Пакеты разные, и зависают одинаково. Я посмотрел, что все они используют стандартный пакет websocket.
И там происходит некоторое кэширование Dialer. Сохраняется DefaultDialer при первом обращении и далее через него. Видимо, поэтому если пересоздать даже новую структуру пакета работы с биржей, то websocket.go отдаёт закэшированный диаллер и проблема не решается.
Кстати, заметил что соккеты могут восстановится после очень долгого простоя сами, может срабатывается какой-то таймаут или ещё что-то.
Пока не вникал в детали, но ощущение, что происходит какой-то сбой пакетов в стандартном клиенте websocket.go и далее уже происходят постоянные ошибки, которые лечатся только полной перегрузкой приложения.

Причём я заметил, что это характерно именно для каналов, где проходит очень большой поток информации, Каждые 10-20 миллисекунд что-то летит. Словно происходит какая-то рассинхронизация потока данных на уровне протокола и всё перестаёт работать, хотя подключение к бирже проходит успешно.
Каналы где сообщения приходят реже 500мс такой проблемы почти нет.

Был ли у кого опыт с нестабильными соккетами и как это лечить?

9 ответов

23 просмотра

> не переподключались средствами пакетов, хотя там есть Keep Alive настройки и т.п. Вот этот момент не понял, как это так " не переподключались средствами пакетов"? Broken Pipe обычно значит какие то сетевые проблемы, может провайдер у вас начинает резать трафик? В общем и целом без исследования это будет гадание на кофейной гуще Какой у вас хостинг? Домашний?

Andrew-Popov Автор вопроса
Andrew ᛉ
> не переподключались средствами пакетов, хотя там...

Hetzner. Но это происходит где угодно, в том числе дома. И в ДЦ.

Andrew Popov
Hetzner. Но это происходит где угодно, в том числе...

А сами настройки websocket ковыряли? Их там много. Помониторить-бы, что происходит. От сети, до памяти.

Andrew-Popov Автор вопроса
Andrew ᛉ
> не переподключались средствами пакетов, хотя там...

У пакетов есть методы Stop() и Listen(). Вроде того. Т.е. даже если остановить и заново запустить, то подключение не выдаёт ошибки, но данные не приходят, вроде как продолжаются сетевые ошибки. И даже если вообще создать заново новую структуру. tc.doneC, tc.stopC, err = binance.WsBookTickerServe( tc.symbol.ExternalCode, tc.responseHandler(), errHandler, ) То и это не помогает. Ошибки нет, но валятся сетевые ошибки и реальные данные из соккетов нельзя получить. Пока не перегрузишь всё приложение. Сразу всё ОК. К чему я пришёл, что в этом случае всё работает также, как и если бы я перегрузил приложение. Я уже всё что можно с нуля инстанцирую. Кроме закэшированных каких-то диалеров внутри самого клиента websocket.go Кода там много внутри, но много мест подобных этому: if d == nil { d = &nilDialer }

а какие пакеты вы пробовали? и пробовали ли пробрасывать свой диалер?

Andrew-Popov Автор вопроса
🎄 Doe
А сами настройки websocket ковыряли? Их там много....

Пока нет. Я не очень опытный в сетевых приложениях. Вот сейчас как раз погружаюсь и решил спросить совета...

Andrew-Popov Автор вопроса
c
а какие пакеты вы пробовали? и пробовали ли пробра...

github.com/adshao/go-binance/v2 github.com/huobirdcenter/huobi_golang Я не увидел у них возможнеости инъецировать свой диалер. Видимо, если проблема в нём, то придётся форкать и рефакторить. Но я пока не уверен, что проблема именно там где я думаю.

Andrew Popov
У пакетов есть методы Stop() и Listen(). Вроде тог...

Блин, кроме измерений и профилирования хз даже что посоветовать

много кто мониторит живость вебсокет подключений вот например https://github.com/slack-go/slack/blob/master/websocket_managed_conn.go#L33

Похожие вопросы

Обсуждают сегодня

Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
> Копаем глубже > Следующий момент был, когда я спросил его, знает ли он JavaScript. Он ответил, что его учили работать с C#. Я тоже в университете писал на C#, но даже там мн...
Oleg Volkov
4
И никого не интересует какие пакеты кто использует. ((% Заходишь на сайт симфони и видишь поддержку Украины - по законам РФ это ж экстремизм. Только никто не отказывается от с...
Am Ambrion
11
лучше скажите, причём тут паскаль?
Alexey Kulakov
36
Чтобы перехватить все нажимания буков на форме, надо хук ставить? Пробовал на форме ОнКейДаун, оно ловит клаву если фокус не на компоненте с вводом текста
Serjone
15
Но, может, есть уже проверенная? Наши требования такие: 1. Сообщения должны приходить из Инста в CRM оду 2. Должна быть возможность подключить несколько экаунтов Инстаграм. Р...
Alexander Sharoiko MSE / Александр Шаройко
7
Народ! Впервые клиенту пришло письмо от РКН, у вас, дескать, есть яндекс метрика, а нигде не написано, что вы ее юзаете. Никто не сталкивался?
Sasha Beep
14
Всем привет! вывожу на общей стр дочерние ресурсыв каждом ресурсе галерея, и первая фотка должна выводиться на общей [!DocLister? &prepare=photo !]
Alekso
12
А можно вопрос? Мне сегодня сказали что у меня функция (которая просто заполняет массив значениями) не правильная void Full(double * arr, int n) { for (int i = 0; i < n; i...
† C E †
7
Добрый вечер. Хочу чтобы у меня в классе поле было функцией, которая возвращает строку. Делаю так: interface ... TGetOutPath = function : String of object; ... protec...
Kirill Filippenok
12
Карта сайта