Есть ли простой способ разрешить DNS-запрос (получить IP по имени хоста) в асинхронном режиме Java, неблокирующим способом (т.е. конечный автомат, а не 1 запрос = 1 поток - я бы хотел запустить десятки тысяч запросов одновременно, но не запускать десятки тысяч потоков)?
Что я нашел до сих пор:
- Стандартная реализация
InetAddress.getByName()
блокируется и выглядит так, как стандартные библиотеки Java не имеют каких-либо неблокирующих реализаций. - Устранение DNS навалом обсуждает аналогичную проблему, но единственным найденным решением является многопоточный подход (т.е. один поток, работающий только с одним запросом за каждый данный момент время), что на самом деле не масштабируется.
- dnsjava библиотека также блокируется.
- древние неблокирующие расширения для dnsjava начиная с 2006 года, поэтому не хватает современных Java concurrency, таких как
Future
использование парадигмы и, увы, очень ограниченная реализация только в очереди. - dnsjnio project также является расширением для dnsjava, но он также работает в потоковой модели (т.е. 1 запрос = 1 поток).
- asyncorg кажется лучшим доступным решением, которое я нашел до сих пор для этой проблемы, но:
- он также с 2007 года и выглядит брошенным
- отсутствует практически любая документация /javadoc
- использует множество нестандартных методов, таких как
Fun
class
Любые другие идеи/реализации, которые я пропустил?
Разъяснение. Я имею довольно большое (несколько TB в день) количество журналов. Каждая строка журнала имеет имя хоста, которое может быть от почти любого места в Интернете, и мне нужен IP-адрес для этого имени хоста для моих дальнейших вычислений статистики. Порядок строк на самом деле не имеет значения, поэтому, в основном, моя идея - запустить 2 потока: сначала перебирать строки:
- Прочитайте строку, проанализируйте ее, получите имя хоста
- Отправить запрос DNS-серверу для разрешения имени хоста, не блокировать ответ
- Сохранение строки и дескриптора дескриптора запроса DNS в некотором буфере в памяти
- Перейдите к следующей строке
И второй поток, который будет:
- Подождите, пока DNS-сервер ответит на любой запрос (используя технику
epoll
/kqueue
) - Прочитайте ответ, найдите, в какой строке он находился в буфере
- Запись строки с разрешенным IP на выход
- Продолжайте ждать следующего ответа
Простая реализация модели в Perl с использованием AnyEvent
показывает мне, что моя идея в целом правильная, и я легко могу добиться таких скоростей, как 15-20K запросов в секунду таким образом (наивная реализация блокировки получается как 2-3 запроса в секунду - просто ради сравнения - так, чтобы как разность в 4 порядка). Теперь мне нужно реализовать то же самое в Java - и я бы хотел пропустить свою собственную реализацию DNS;)