Тайм-аут запроса Tomcat
В моем веб-приложении есть несколько запросов, которые длятся дольше 20 секунд. Но в некоторых ситуациях код может привести к бесконечному циклу или чему-то подобному, что замедляет работу сервера.
Я хочу поставить тайм-аут запроса на 60 секунд на стороне сервера. Это реализовано в Tomcat?
Спасибо, Горатью
6 ответов
С Tomcat 7 вы можете добавить StuckThreadDetectionValve, который позволит вам идентифицировать "застрявшие" потоки. Вы можете настроить клапан в элементе контекста приложений, в которых вы хотите обнаружить:
<Context ...>
...
<Valve
className="org.apache.catalina.valves.StuckThreadDetectionValve"
threshold="60" />
...
</Context>
Это будет записывать запись WARN в журнал tomcat для любого потока, который занимает более 60 секунд, что позволит вам идентифицировать приложения и запретить их, потому что они неисправны.
Основываясь на исходном коде, вы можете написать свой собственный клапан, который пытается остановить поток, однако это может повлиять на пул потоков, и в Java нет надежного способа остановить поток без сотрудничества с этим потоком....
Если вы пытаетесь помешать выполнению запроса слишком долго, то установка таймаута в Tomcat вам не поможет. Как говорит Крис, вы можете установить значение глобального таймаута для Tomcat. Но, из Apache Tomcat Connector - общие тайм-ауты HowTo, см. Раздел "Тайм-аут ответа":
JK также может использовать тайм-аут при ответах на запросы. Этот тайм-аут не измеряет полное время обработки ответа. Вместо этого он контролирует, сколько времени между последовательными ответными пакетами разрешено.
В большинстве случаев это то, что на самом деле нужно. Рассмотрим, например, длительные загрузки. Вы не сможете установить эффективный глобальный тайм-аут ответа, поскольку загрузка может длиться много минут. Большинство приложений, тем не менее, имеют ограниченное время обработки, прежде чем возвращать ответ. Для этих приложений вы можете установить явное время ожидания ответа. Приложения, которые не согласуются с тайм-аутами ответа, являются приложениями пакетного типа, хранилищем данных и приложениями для составления отчетов, которые, как ожидается, будут наблюдать длительное время обработки.
Если JK прерывает ожидание ответа из-за истечения времени ожидания ответа, невозможно остановить обработку на бэкэнде. Несмотря на то, что вы освобождаете ресурсы обработки на своем веб-сервере, запрос будет продолжать выполняться на бэкэнде - без возможности отправить результат после истечения времени ожидания ответа.
Таким образом, Tomcat обнаружит, что сервлет не ответил в течение времени ожидания, и отправит ответ пользователю, но не остановит работу потока. Я не думаю, что вы можете достичь того, что вы хотите сделать.
Вы можете установить время по умолчанию в server.xml
<Connector URIEncoding="UTF-8"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
enableLookups="false"
maxHttpHeaderSize="8192"
maxSpareThreads="75"
maxThreads="150"
minSpareThreads="25"
port="7777"
redirectPort="8443"/>
В этой статье рассказывается об установке тайм-аутов на уровне сервера. http://www.coderanch.com/t/364207/Servlets/java/Servlet-Timeout-two-ways
Что заставляет приложение идти в бесконечный цикл? Если вы открываете соединения с другими ресурсами, возможно, вы захотите установить таймауты для этих соединений и отправить соответствующий ответ, когда наступит тот тайм-аут.
Для тех, кому не нравится ни одно из решений, опубликованных выше, таких как я, вы можете просто реализовать таймер самостоятельно и остановить выполнение запроса, выдав исключение времени выполнения. Что-то вроде ниже:
try
{
timer.schedule(new TimerTask() {
@Override
public void run() {
timer.cancel();
}
}, /* specify time of the requst */ 1000);
}
catch(Exception e)
{
throw new RuntimeException("the request is taking longer than usual");
}
или предпочтительно использовать Java TimeLimiter Гуава здесь
Добавить кота в Eclipse
В Eclipse, в качестве сервера Tomcat, дважды щелкните "Сервер Tomcat v7.0 на локальном хосте". Измените свойства, как показано в настройках тайм-аута 45, на любое значение, которое вам нравится.