簡體   English   中英

Java中的非阻塞(異步)DNS解析

[英]Non-blocking (async) DNS resolving in Java

有沒有一種干凈的方法可以在 Java 中以非阻塞方式異步解析 DNS 查詢(通過主機名獲取 IP)(即狀態機,而不是 1 個查詢 = 1 個線程 - 我想同時運行數萬個查詢,但是不運行數萬個線程)?

到目前為止我發現了什么:

  • 標准InetAddress.getByName()實現是阻塞的,看起來標准 Java 庫缺少任何非阻塞實現。
  • Resolving DNS in bulk question討論了類似的問題,但找到的唯一解決方案是多線程方法(即一個線程在每個給定時刻只處理 1 個查詢),這不是真正可擴展的。
  • dnsjava庫也只是阻塞。
  • dnsjava有一些古老的非阻塞擴展可以追溯到 2006 年,因此缺乏任何現代 Java 並發性的東西,例如Future范式用法,以及非常有限的僅隊列實現。
  • dnsjnio項目也是 dnsjava 的擴展,但它也適用於線程模型(即 1 個查詢 = 1 個線程)。
  • asyncorg似乎是迄今為止我發現的針對此問題的最佳可用解決方案,但是:
    • 它也是 2007 年的,看起來被遺棄了
    • 幾乎沒有任何文檔/javadoc
    • 使用了許多非標准技術,例如Fun

我錯過的任何其他想法/實現?

澄清 我有相當大(每天幾 TB)的日志量。 每個日志行都有一個主機名,它可以來自互聯網上的幾乎任何地方,我需要該主機名的 IP 地址以進行進一步的統計計算。 行的順序並不重要,所以,基本上,我的想法是啟動 2 個線程:首先遍歷行:

  • 讀一行,解析它,得到主機名
  • 向 DNS 服務器發送查詢以解析給定的主機名,不要阻止回答
  • 將線路和 DNS 查詢套接字句柄存儲在內存中的某個緩沖區中
  • 轉到下一行

第二個線程將:

  • 等待 DNS 服務器回答任何查詢(使用epoll / kqueue類的技術)
  • 閱讀答案,找到它在緩沖區中的哪一行
  • 將具有解析 IP 的行寫入輸出
  • 繼續等待下一個答案

Perl 中使用AnyEvent一個簡單模型實現向我表明,我的想法通常是正確的,我可以通過這種方式輕松實現每秒 15-20K 查詢的速度(朴素的阻塞實現類似於每秒 2-3 個查詢 - 只是為了比較 -所以這就像 4 個數量級的差異)。 現在我需要在 Java 中實現相同的 - 我想跳過推出我自己的 DNS 實現;)

您可能正在尋找基於 MINA的 DNSApache 目錄服務實現 JavaDocs 和其他有用的指南位於該頁面的左側邊欄中。

在 netty 中有一些關於非阻塞 DNS 的工作,但它仍在進行中,可能只會在 5.0 中發布

我認為,您必須在使用基本套接字支持的原始 UDP 之上或使用 NIO 通道在 TCP 之上自己實現 DNS 客戶端協議。

我沒有你的問題的答案(我不知道是否有一個 DNS 庫可以在你想要的異步模式下運行),而且評論太長了。

但是,您應該能夠快速生成一個異步的,而不必自己編寫完整的 DNS 處理程序。 警告,我還沒有這樣做,所以我可能是錯的。

從 dnsjava 代碼開始,您應該能夠實現自己的解析器,該解析器將為您提供發送方和接收方方法。 查看SimpleResolver並查看send方法。 您應該能夠將此方法分解為兩種方法,一種是將您的請求發送到調用 TCPClient 或 UDPClient 之前(如您所描述的,此時您將處理在線發送的實際情況,與您的第一個線程),以及一個接收,它將被您的第二個線程調用作為對套接字讀取的響應,並處理解析響應。 您可能必須從 SimpleResolver 中復制所有代碼(您需要許多私有方法並且許可允許這樣做),或者您可以創建自己的版本並在類路徑中的 jared 之前簡單地加載它,或者,您可以將您的方式反映到相關方法並將它們設置為可訪問

您可以使用nettymina快速構建網絡客戶端。 對於文檔,我更喜歡 netty。

如果你確實沿着這條路走下去並且可以/想要開源它,如果你遇到麻煩,我可以留出一些時間來幫助你。

Linux 有異步 DNS 查找功能: http : //www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html

如果你在 Linux 上,你只需要將它封裝在一些 JNI 中。

你有多種選擇

選項 1:Java 5 Executors

  1. 固定線程池:Executors.newFixedThreadPool(int)
  2. Future : Future 表示異步計算的結果。 提供了檢查計算是否完成、等待計算完成以及檢索計算結果的方法。

選項 2:帶有 MessageListener 的 JMS

  1. 需要依賴 JMS Provider 等。

選項 2:基於 Actor 的框架

你可以用 this 很好地擴展這個。看看Akka

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM