Как перехватывать и обрабатывать ошибку org.apache.http.conn.HttpHostConnectException . Connection timed out: connect?
Java приложение отправляет запросы в интернет и получает ответы. Использую Apache HTTP Client. Работа идет через свои HTTP Proxy (3proxy на VPS). Иногда возникает ошибка:
сен 24, 2016 5:40:51 PM main_pkg.cycle$JThread1 run SEVERE: null org.apache.http.conn.HttpHostConnectException: Connect to *PROXY_IP*:*PROXY_PORT* [/PROXY_IP*:*PROXY_PORT*] failed: Connection timed out: connect at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:158) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:388) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at main_pkg.network.delete_task(network.java:859) at main_pkg.task.task_subscribe(task.java:629) at main_pkg.task.choise_task_type(task.java:506) at main_pkg.cycle$JThread1.run(cycle.java:781) Caused by: java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:74) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141) . 11 more
Сам код запроса выглядит так, таймаут задан 61 секунда:
try < httpget = new HttpGet("http://myurl.ru/"); httpget.setConfig(config); response = httpclient.execute(httpget, localContext); >catch (ConnectTimeoutException e) < >EntityUtils.consume(response.getEntity());
Ошибка возникает как я понимаю тогда, когда прокси сервер не отвечает. Ошибка возникает на строке = httpclient.execute(httpget, localContext); Проблема не в сервере, т.к. это бывает достаточно редко, и любой следующий запрос проходит корректно сразу. Как ее обрабатывать, что бы при ее возникновении этот же запрос отправлялся заново, и в результате получать корректный ответ? Нужно использовать try-catch , но как именно? То что написано сейчас не работает.
Connection
Заголовок Connection определяет, остаётся ли сетевое соединение активным после завершения текущей транзакции (запроса). Если в запросе отправлено значение keep-alive , то соединение остаётся и не завершается, позволяя выполнять последующие запросы на тот же сервер.
Предупреждение: Заголовки, связанные с соединением, такие как Connection и Keep-Alive (en-US) , запрещены в HTTP/2. Chrome и Firefox просто игнорируют эти заголовки в HTTP/2 ответах, однако Safari, следуя требованиям HTTP/2, вообще не будет загружать какие-либо ответы, которые содержат данные заголовки.
За исключением стандартных заголовков «hop-by-hop» ( Keep-Alive (en-US) , Transfer-Encoding (en-US) , TE (en-US) , Connection , Trailer (en-US) , Upgrade (en-US) , Proxy-Authorization (en-US) и Proxy-Authenticate (en-US) ), любые «hop-by-hop» заголовки, используемые в сообщении, должны быть перечислены в заголовке Connection так, чтобы первый прокси знал, как их использовать, и не передавал дальше. Также могут быть перечислены стандартные «hop-by-hop» заголовки (часто это относится к Keep-Alive (en-US) , но это необязательно).
| Тип заголовка | Общий заголовок |
|---|---|
| Запрещённое имя заголовка | да |
Синтаксис
Connection: keep-alive Connection: close
Указания
Указывает, что клиент или сервер хотели бы закрыть соединение. Это значение по умолчанию для запросов HTTP/1.0.
Указывает, что клиент хотел бы сохранить соединение активным. Постоянное соединение используется по умолчанию для запросов HTTP/1.1. Список заголовков — это имена заголовка, которые удаляются первым непрозрачным прокси-сервером или промежуточным кешем: эти заголовки определяют соединение между источником и первым объектом, а не целевым узлом.
Совместимость с браузерами
BCD tables only load in the browser
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 6 янв. 2024 г. by MDN contributors.
Your blueprint for a better internet.
CONNECT
HTTP CONNECT method запускает двустороннюю связь с запрошенным ресурсом. Метод можно использовать для открытия туннеля.
К примеру, метод CONNECT может использоваться для доступа к сайту, который использует SSL (en-US) (HTTPS). Клиент запрашивает HTTP-прокси-сервер для туннелирования TCP-соединения с желаемым назначением. Затем сервер переходит к подключению от имени клиента. После того, как соединение установлено сервером, прокси-сервер продолжает проксировать поток TCP к клиенту и от него.
CONNECT is a hop-by-hop method.
| Запрос имеет тело | Нет |
|---|---|
| Успешный ответ имеет тело | Да |
| Безопасный | Нет |
| Идемпотентный | Нет |
| Кешируемый | Нет |
| Допускается в HTML формах | Нет |
Синтаксис
CONNECT www.example.com:443 HTTP/1.1
Пример
Некоторые прокси сервера могут запросить авторизацию для создания туннеля. Смотрите также Proxy-Authorization (en-US) .
Host: server.example.com:80 Proxy-Authorization: basic aGVsbG86d29ybGQ=
Спецификация
| Specification |
|---|
| HTTP Semantics # CONNECT |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 6 янв. 2024 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.
Database Connection Pool
Добрый день, хабралюди!
2 недели назад я начал работать juior java разработчиком, и, соответственно, получать много нового для себя опыта. Сегодня я решил совместить приятное с полезным и начать этот опыт оформлять в письменные мысли — в виде статей о тех технологиях, принципах и приёмах, с которыми я столкнулся на своём джуниорском пути. Нижеследующая статья — первая среди подобных, и выкладывая её здесь, я хочу, во-первых, понять, нужны ли хабрасообществу подобные вещи — рассказы не умудрённых опытом и сотнями проектов старожилов, а небольшие попытки поделится опытом от джуниора джуниору, — а во-вторых, как обычно, услышать замечания, исправления и критику.
Спасибо за внимание.
Подавляющее большинство современных веб-приложений использует базы данных для хранения информации. Приложение может обмениваться информацией с БД, используя соединение (database connection). Если создавать при каждом обращении к БД, получается проигрыш во времени: выполнение транзакции может занять несколько милисекунд, в то время как на создание соединения может уйти до нескольких секунд. С другой стороны, можно создать одно-единственное соединение (например, используя шаблон «Singleton») и обращаться к базе данных только через него. Но это решение чревато проблемами, в случае высокой нагрузки: если одновременно сто пользователей попытается получить доступ к базе данных используя одно соединение, образуется очередь, что также пагубно сказывается на производительности приложения.
Database Connection Pool (dbcp) — это способ решения изложенной выше проблемы. Он подразумевает, что в нашем распоряжении имеется некоторый набор («пул») соединений к базе данных. Когда новый пользователь запрашивает доступ к БД, ему выдаётся уже открытое соединение из этого пула. Если все открытые соединения уже заняты, создаётся новое. Как только пользователь освобождает одно из уже существующих соединений, оно становится доступно для других пользователей. Если соединение долго не используется, оно закрывается.
Пример реализации простейшего пула соединений можно найти на официальном сайте java.sun.com: Connection Pooling
Поскольку подобный подход наиболее полезен в случае enterprise- и web-приложений, вполне логично, что такой популярный контейнер сервлетов, как Apache Tomcat предоставляет собственное решение для создания dbcp. Решение это основанно на библиотеке apache-commons-dbcp. Чтобы реализовать поддержку пула соединений с своём приложении, нужно пройти через несколько этапов.
Во-первых, нужно объявить новый ресурс в контексте приложения. Ресурс (в нашем случае — БД) описывается следующим кодом:
type=»javax.sql.DataSource» maxActive=»100″
maxIdle=»30″ maxWait=»10000″
username=»username»
password=»password»
driverClassName=»jdbc.driver.name»
url=»jdbc:protocol://hostname:port/dbname»/>
Думаю, пояснения не нужны.
Контекст приложения описывается XML-файлом. Я считаю правильным хранить его в %document_root%/META-INF/context.xml, однако это не единственный вариант. Подробней про контекст можно почитать на сайте Tomcat’a: The Context Container.
Теперь нужно добавить ссылку на этот ресурс в web.xml:
Теперь мы можем использовать этот ресурс в нашем приложении. Для того чтобы получить объект Connection для выполнения sql-кода, исопльзуется следующий код:
InitialContext initContext= new InitialContext();
DataSource ds = (DataSource) initContext.lookup(«java:comp/env/jdbc/dbconnect»);
Connection conn = ds.getConnection();
Для получения источника данных (data source) используется механизм JNDI (подробнее про него можно почитать здесь)
Всё! Теперь вы можете выполнить conn.createStatement() и реализовать логику работы с БД. В конце, как обычно, следует закрыть соединение (conn.close()), однако в отличии от обычного соединения через драйвер JDBC, это соединение на самом деле не закроется: оно будет помечено в пуле как свободное, и его можно будет переиспользовать позже. Перед возвратом соединения в пул все Statement’ы и ResultSet’ы, полученные с помощью этого соединения, автоматически закрываются в соответствии с API (спасибо Colwin за замечание).