Есть приложение, которое принимает сообщение из очереди сообщений, обрабатывает его, и отправляет результат в другую очередь.
Собственно каждая часть (прием, обработка, отправка) выполняется в отдельной горутине, передача данных через каналы.
Приложение принимает из очереди ссылку, обработчик выполняет get запрос, получает статус код и прочую необходимую информацию и отправляет ее в очередь
Делали 3 варианта запуска горутин, далее опишу какие и проблемы в каждом случае, хотелось бы узнать какой из этих способов лучше, и возможные решения проблем.
Вариант 1:
запускаем по одной горутине на прием, обработку и отправку.
Проблема: очень медленная работа, со временем понемногу растет потребление памяти.
Вопрос: из за чего может течь память? (пробовали вызывать после каждой итерации runtime.GC, не помогает)
Вариант 2:
запускаем для каждого сообщения отдельную горутину обработчика.
Плюс: быстрая работа
Проблема: скорость приема сообщений выше скорости обработки, количество горутин растет, тем самым потребляя все больше памяти, временами превышая лимит коннекшенов, и в итоге приложение падает.
Вопрос: как можно контролировать количество горутин в каких то пределах? sync.WaitGroup не то, так как ждет завершения всех, убивая тем самым скорость работы
Вариант 3:
запускаем пул горутин обработчика
Не ясно необходимое количество горутин, при запуске большого количества, часть простаивает (видно по разнице принятых и отправленых сообщений), по всей видимости из за того, что сообщение из канала уходит первому свободному.
Проблема: Как и в первом варианте, но в больших объемах, так же со временем работы скорость работы падает.
Вопрос: как можно управлять пулом горутин, и опять же про память.
Спасибо.