В проекте, подобном сканеру, у нас есть распространенная и широко используемая задача для разрешения / расширения тысяч URL-адресов. Скажем, у нас (очень упрощенный пример):
http://bit.ly/4Agih5
GET 'http://bit.ly/4Agih5' запрос возвращает один из 3xx, мы следуем за перенаправлением права на:
http://stackoverflow.com
GET 'http://stackoverflow.com' возвращает 200. Таким образом, «stackoverflow.com» - это результат, который нам нужен.
Любые URL (не только общеизвестные сокращения, такие как bit.ly) допускаются в качестве входных данных. Некоторые из них перенаправляют один раз, некоторые вообще не перенаправляют (в данном случае результатом является сам URL), некоторые перенаправляют несколько раз. Наша задача - как можно больше следовать всем перенаправлениям, имитирующим поведение браузера. В общем, если у нас есть какой-то URL, A
преобразователь должен вернуть нам URL B
, который должен быть таким же, как если бы A
открывается в каком-то браузере.
До сих пор мы использовали Java, пул потоков и простой URLConnection
для решения этой задачи. Преимущества очевидны:
- simplicity - просто создайте
URLConnection
, установите перенаправления и все (почти);
- хорошая поддержка HTTP - Java предоставляет все необходимое для максимально имитации браузера: автоматическое отслеживание перенаправлений, поддержка файлов cookie.
К сожалению, у такого подхода есть и недостатки:
- производительность - темы не бесплатны,
URLConnection
начинает скачивать документ сразу после getInputStream()
, даже если он нам не нужен;
- объем памяти - точно не уверен, но кажется, что
URL
и URLConnection
- довольно тяжелые объекты, и снова буферизация результата GET сразу после вызова getInputStream()
.
Существуют ли другие решения (или улучшения этого), которые могут значительно увеличить скорость и уменьшить потребление памяти? Предположительно, нам нужно что-то вроде:
- высокопроизводительный облегченный Java HTTP-клиент на основе java.nio;
- C HTTP-клиент, который использует poll () или select ();
- некоторая готовая библиотека, которая разрешает / расширяет URL;