22
33import java .net .InetAddress ;
44import java .net .UnknownHostException ;
5+ import java .util .concurrent .Executors ;
6+ import java .util .concurrent .ScheduledExecutorService ;
7+ import java .util .concurrent .ThreadFactory ;
8+ import java .util .concurrent .TimeUnit ;
59
10+ import com .google .common .cache .Cache ;
11+ import com .google .common .cache .CacheBuilder ;
12+ import com .google .common .cache .CacheLoader ;
13+ import com .google .common .cache .RemovalListener ;
14+ import com .google .common .cache .RemovalNotification ;
615import junit .framework .TestCase ;
16+ import org .apache .http .impl .conn .SystemDefaultDnsResolver ;
717import org .junit .Assert ;
18+ import org .slf4j .Logger ;
19+ import org .slf4j .LoggerFactory ;
820
921
1022public class CachedDnsResolverTest extends TestCase {
@@ -30,4 +42,86 @@ public void testResolve() throws InterruptedException, UnknownHostException {
3042 dnsResolver .clear ();
3143 }
3244 }
33- }
45+
46+ public void testAsyncResolve () throws UnknownHostException , InterruptedException {
47+ TestCachedDnsResolver resolver = new TestCachedDnsResolver (
48+ 100 , 20 , 3 );
49+
50+ for (int i = 0 ; i < 10 ; ++i ) {
51+ long start = System .currentTimeMillis ();
52+ InetAddress [] resolve = resolver .resolve ("taobao.com" );
53+ long end = System .currentTimeMillis ();
54+ System .out .println (end - start );
55+
56+ Thread .sleep (2000 );
57+ }
58+ }
59+ }
60+
61+ class BaseResolver extends SystemDefaultDnsResolver {
62+
63+ @ Override
64+ public InetAddress [] resolve (String host ) throws UnknownHostException {
65+ try {
66+ Thread .sleep (5000 );
67+ } catch (InterruptedException e ) {
68+ throw new RuntimeException (e );
69+ }
70+ return super .resolve (host );
71+ }
72+ }
73+
74+ class TestCachedDnsResolver extends BaseResolver {
75+ private final Logger logger = LoggerFactory .getLogger (CachedDnsResolverTest .class );
76+ private final Cache <String , InetAddress []> dnsCache ;
77+
78+ public TestCachedDnsResolver (int maxSize , int expireAfterWriteSec , int refreshAfterWriteSec ) {
79+ RemovalListener <String , InetAddress []> rmListener = new RemovalListener <String , InetAddress []>() {
80+ @ Override
81+ public void onRemoval (RemovalNotification <String , InetAddress []> notify ) {
82+ logger .info ("dns cache remove host key: {}, reason: {}" , notify .getKey (), notify .getCause ().name ());
83+ }
84+ };
85+
86+ ScheduledExecutorService scheduler = Executors .newScheduledThreadPool (2 , new ThreadFactory () {
87+ @ Override
88+ public Thread newThread (Runnable r ) {
89+ Thread thread = new Thread (r );
90+ thread .setName ("refresh-dns-cache-" + thread .getId ());
91+ return thread ;
92+ }
93+ });
94+ dnsCache = CacheBuilder .newBuilder ()
95+ .maximumSize (maxSize )
96+ .weakKeys ()
97+ .expireAfterWrite (expireAfterWriteSec , TimeUnit .SECONDS )
98+ .refreshAfterWrite (refreshAfterWriteSec , TimeUnit .SECONDS )
99+ .removalListener (rmListener )
100+ .build (CacheLoader .asyncReloading (new CacheLoader <String , InetAddress []>() {
101+ @ Override
102+ public InetAddress [] load (String host ) throws Exception {
103+ logger .info ("dns cache load, host: {}" , host );
104+ return TestCachedDnsResolver .super .resolve (host );
105+ }
106+ }, scheduler ));
107+ }
108+
109+
110+ @ Override
111+ public InetAddress [] resolve (String host ) throws UnknownHostException {
112+ InetAddress [] cached = dnsCache .getIfPresent (host );
113+ logger .info ("dns resolve, host: {}, has cached: {}" , host , cached !=null );
114+ if (cached ==null ) {
115+ InetAddress [] realtime = super .resolve (host );
116+ if (realtime !=null ) {
117+ dnsCache .put (host , realtime );
118+ }
119+ return realtime ;
120+ }
121+ return cached ;
122+ }
123+
124+ public void clear () {
125+ dnsCache .cleanUp ();
126+ }
127+ }
0 commit comments