Во-первых, комментарий @ skaffman точный. Вы не должны ловить и игнорировать исключения, как сейчас делает ваш код. В общем, это ужасная практика. В этом случае вы вполне могли бы выбросить улики, которые бы указывали на реальную проблему.
Во-вторых, я думаю, что вы, возможно, страдаете от неправильного понимания того, на что способен сервер. Независимо от того, как вы это реализуете, сервер может обрабатывать только определенное количество запросов в секунду. Если вы добавите к нему больше запросов, некоторые из них будут отброшены.
Что я подозреваю, так это то, что вы отправляете слишком много запросов за короткий промежуток времени и переполняете буфер запросов операционной системы.
Когда ваш код привязывается к сокету сервера, операционная система устанавливает очередь запросов для хранения входящих запросов на привязанном IP-адресе / порте. Эта очередь имеет конечный размер, и, если очередь заполнена при поступлении нового запроса, операционная система отбросит запросы. Это означает, что если ваше приложение не может accept
запросов достаточно быстро, некоторые из них будут отброшены.
Что вы можете с этим поделать?
- Существует перегрузка
ServerSocket.bind(...)
, позволяющая указать backlog
запросов, которые будут удерживаться в очереди уровня ОС. Вы можете использовать это ... или использовать большее отставание.
- Вы можете изменить свой основной цикл, чтобы быстрее получать запросы из очереди. Одна проблема с вашим текущим кодом заключается в том, что вы создаете новую тему для каждого запроса. Создание потоков стоит дорого, и вы можете уменьшить стоимость, используя пул потоков для переработки потоков, использованных для предыдущих запросов.
ПРЕДОСТЕРЕЖЕНИЯ
Вы должны быть немного осторожны. Весьма вероятно, что вы можете изменить свое приложение, чтобы принимать (не отбрасывать) больше запросов в краткосрочной перспективе. Но в долгосрочной перспективе вы должны принимать запросы только настолько быстро, насколько это возможно. Если он принимает их быстрее, чем вы можете их обработать, может произойти ряд плохих вещей:
- Вы будете использовать много памяти всеми потоками, пытающимися обрабатывать запросы. Это увеличит нагрузку на процессор различными способами.
- Вы можете повысить конкуренцию за внутренние структуры данных Java, базы данных и т. Д., Стремясь снизить пропускную способность.
- Вы увеличите время, необходимое для обработки и ответа на отдельные запросы GET. Если задержка слишком велика, клиент может приостановить запрос ... и отправить его снова. Если это произойдет, работа, выполненная сервером, будет потрачена впустую.
Чтобы защититься от этого, на самом деле лучше НЕ принимать столько запросов, сколько сможете. Вместо этого используйте ограниченный пул потоков и настройте размер пула (и т. Д.) Для оптимизации пропускной способности, сохраняя время для обработки отдельных запросов в разумных пределах.