У меня есть сервер, реализованный в netty, который обрабатывает запрос пользователя, обращается к промежуточному программному обеспечению и отправляет ответ.Ожидается, что ввод-вывод будет незначительным по сравнению с циклическим переходом к промежуточному программному обеспечению, поэтому для минимизации блокировки у меня есть ExecutionHandler в конвейере поверх OrderedMemoryAwareThreadPoolExecutor.Пока никаких проблем.
Я смотрю, как сервер ведет себя при большой нагрузке.Исходя из прошлого опыта работы с нашим протоколом, мы склонны забиваться случайными атаками DOS - чаще всего пользовательским сценарием, застрявшим в бесконечном цикле или чем-то подобным.В идеале мы могли бы пре-расставить приоритеты их каналов после того, как они преодолеют определенный порог использования, чтобы не повредить обслуживание других пользователей.
Я реализовал простой ThreadPoolExecutor, который использует PriorityBlockingQueue и устанавливает приоритет на основе данныхизвлечено из нашего собственного класса Session (присоединено к контексту в ChannelHandler).Опять же, проблем пока нет.
Сложность возникает при попытке воспользоваться преимуществами упорядочения и осведомленности о памяти встроенных в NetPy ThreadPoolExecutors.В идеале MyThreadPoolExecutor может просто расширить OrderedMemoryAwareThreadPoolExecutor и подключиться к приоритетной очереди.Увы, это невозможно по двум причинам: частное и окончательное.Более подробно:
a) ThreadPoolExecutor.workQueue может быть установлен в его конструкторе, но MemoryAwareThreadPoolExecutor жестко кодирует это как LinkedTransferQueue и не предоставляет его своему дочернему элементу OrderedMemoryAwareThreadPoolExecutor (то есть MyThreadPoolExecutor не имеет доступаустановить его).При необходимости это может быть преодолено с помощью некрасивой настройки приватного поля на основе отражения.
b) Я хотел бы иметь возможность переопределить MyThreadPoolExecutor.doUnorderedExecute (), чтобы я мог вставить обработку приоритетов ипостроить необходимые объекты, но он объявлен окончательным.Код, который вызывает его, менять не нужно.
В результате, чтобы сохранить все полезные функции netty, но использовать очередь с приоритетами, мне пришлось бы скопировать и вставить как OrderedMemoryAwareThreadPoolExecutor, так и MemoryAwareThreadPoolExecutor., подправить пару строк каждого, а затем расширить оттуда.Это не кажется мне хорошей практикой кодирования!Даже если учесть, что это вызывает тревогу.
Теперь несколько вопросов:
1) Решаю ли я не ту проблему?Неужели я лаю совсем не по тому дереву ради того, чего я хочу достичь?
2) Если нет, есть ли лучший способ сделать это, чем обсуждалось выше?
3) Приведенный выше подходЭто может привести к нехватке ресурсов для приоритетных задач, когда общая нагрузка на сервер постоянно находится в пределах емкости.Я готов смириться с этим для «непослушных» пользователей, но как только они вернутся в нормальное состояние, их существующие задачи будут по-прежнему голодать, и для сохранения порядка следует добавить любые новые задачи с более высоким приоритетом.Есть ли у вас какие-либо рекомендации, как лучше всего с этим бороться?(Запрещение пользователей запрещено бизнесом.)
4) Это половина вопроса, половина обратной связи.Документация netty для OrderedMemoryAwareThreadPoolExecutor содержит удобную диаграмму для потока X & Y - возможно, это потоки, объединенные в ThreadPoolExecutor, а не рабочие потоки ввода-вывода?Возможно, стоит сделать это более понятным.Кроме того, когда не используется ExecutionHandler, каждый канал связан с одним рабочим потоком ввода-вывода - так ли это в случае с ExecutionHandler?т. е. порядок добавления задач в ExecutionHandler гарантированно совпадает с порядком их поступления на канал?Если это так, то я не могу видеть, как поток X в документах для MemoryAwareThreadPoolExecutor мог обработать событие 2 до события 1 - я принимаю, что здесь разные потоки могут завершать работу в любом порядке, но я не вижу, как работа может бытьприсваивается той же теме не по порядку (она выскакивает из workQueue).Документы в ExecutionHandler намекают на это, но выиграли бы немного больше деталей.
Большое спасибо за чтение, и любая помощь высоко ценится.