jvm添加自定義dns實(shí)現(xiàn)過程示例
引言
有一個常見的場景, 我們在開發(fā)過程中,要配置很多的本地host,以實(shí)現(xiàn)測試環(huán)境一些資源的訪問,那么其它人參與進(jìn)來開發(fā)的話,也得在自己電腦上配置,這樣既麻煩,又容易出錯。那么能不能把這些配置,寫到project中去實(shí)現(xiàn)呢, 這樣每個人本地的/etc/hosts文件中會很干凈,可以隨時clone啟動調(diào)試而不需任何配置。答案是肯定的,那么接下來我們就使用java反射的方式來實(shí)現(xiàn)。
操作對象 java.net.InetAddress
我們主要操作的對象就是java.net.InetAddress,可以從源碼中看到, 該類中有兩個核心的變量cache和expirySet。
// mapping from host name to Addresses - either NameServiceAddresses (while // still being looked-up by NameService(s)) or CachedAddresses when cached private static final ConcurrentMap<String, Addresses> cache = new ConcurrentHashMap<>(); // CachedAddresses that have to expire are kept ordered in this NavigableSet // which is scanned on each access private static final NavigableSet<CachedAddresses> expirySet = new ConcurrentSkipListSet<>();
這里會有個疑問, 為啥還有個expirySet,這個問題也可以通過源碼得到解決,即為了刪除失效的條目。
解析
具體含義可以通過閱讀注釋進(jìn)行理解。
// remove expired addresses from cache - expirySet keeps them ordered // by expiry time so we only need to iterate the prefix of the NavigableSet... long now = System.nanoTime(); for (CachedAddresses caddrs : expirySet) { // compare difference of time instants rather than // time instants directly, to avoid possible overflow. // (see System.nanoTime() recommendations...) if ((caddrs.expiryTime - now) < 0L) { // ConcurrentSkipListSet uses weakly consistent iterator, // so removing while iterating is OK... if (expirySet.remove(caddrs)) { // ... remove from cache cache.remove(caddrs.host, caddrs); } } else { // we encountered 1st element that expires in future break; } }
如何實(shí)現(xiàn)反射添加dns條目
接下來就是如何來實(shí)現(xiàn)反射添加dns條目了,本例中基于java17實(shí)現(xiàn),其它版本會有相應(yīng)的變化。
Class<?> cachedAddresses_Class = Class.forName("java.net.InetAddress$CachedAddresses"); Constructor<?> constructor = cachedAddresses_Class.getDeclaredConstructors()[0]; constructor.setAccessible(true); Object o = constructor.newInstance(host, toInetAddressArray(host, ip), Long.MAX_VALUE); Field cacheField = InetAddress.class.getDeclaredField("cache"); cacheField.setAccessible(true); ConcurrentMap<String, Object> cm = (ConcurrentMap<String, Object>) cacheField.get(null); cm.put(host, o); Field expirySetField = InetAddress.class.getDeclaredField("expirySet"); expirySetField.setAccessible(true); ConcurrentSkipListSet<Object> cs = (ConcurrentSkipListSet<Object>) expirySetField.get(null); cs.add(o);
這樣的話, 就可以自己封裝一下,比如dns條目都寫在一個文件中, 編譯打包的時候, 按profile配置決定是否加載。
以上就是jvm添加自定義dns實(shí)現(xiàn)過程示例的詳細(xì)內(nèi)容,更多關(guān)于jvm添加自定義dns的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringIntegration消息路由之Router的條件路由與過濾功能
本文詳細(xì)介紹了Router的基礎(chǔ)概念、條件路由實(shí)現(xiàn)、基于消息頭的路由、動態(tài)路由與路由表、消息過濾與選擇性路由以及錯誤處理與路由等方面的內(nèi)容,提高了系統(tǒng)的可維護(hù)性和可擴(kuò)展性,感興趣的朋友一起看看吧2025-04-04MyBatis實(shí)現(xiàn)樂觀鎖和悲觀鎖的示例代碼
在數(shù)據(jù)庫操作中,樂觀鎖和悲觀鎖是兩種常見的并發(fā)控制策略,本文主要介紹了MyBatis實(shí)現(xiàn)樂觀鎖和悲觀鎖的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-07-07Java中使用輾轉(zhuǎn)相除法求最大公約數(shù)
這篇文章主要介紹了Java中使用輾轉(zhuǎn)相除法求最大公約數(shù),本文直接給出代碼實(shí)例,需要的朋友可以參考下2015-05-05mybatis-parameterType傳入map條件方式
這篇文章主要介紹了mybatis-parameterType傳入map條件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12