Apache HttpComponent Á¦´ë·Î »ç¿ëÇϱâ
Java ¾îÇø®ÄÉÀ̼ǿ¡¼ ÀϹÝÀûÀ¸·Î httpÈ£ÃâÀ» ÇÒ¶§ Apache HttpClient¸¦ »ç¿ëÇϸç http client°¡ ¹öÀü¾÷À» ÇÏ¿© Apache HttpComponent·Î º¯°æµÈ°ÍÀº ¾Æ¸¶ ´Ùµé ¾Ë°íÀÖ´Â »çÇ×ÀÏ°ÍÀÔ´Ï´Ù. (¾ÆÁÖ ¿¾³¯¿¡ ¹Ù²¼À¸´Ï±î) ±Ùµ¥ ¹®Á¦´Â ÀÌ HttpComponent°¡ ´Ü¼øÇÑ ¹öÀü¾÷ÀÌ ¾Æ´Ï¶ó ³»ºÎ ¾ÆÅ°ÅØÃÄ°¡ ¾Æ¿¹ º¯°æ µÇ¾úÀ½¿¡µµ ºÒ±¸ÇÏ°í ±âÁ¸¹öÀü°ú ºñ½ÁÇÏ°Ô ¾²°íÀÖ´Â ÄÉÀ̽º°¡ ¸¹Àº°Í°°¾Æ(¹°·Ð ±âÁ¸Ã³·³ ½áµµ µ¹¾Æ´Â °©´Ï´Ù¸¸) ±ÛÀ» Á¤¸®ÇØ º¸°Ú½À´Ï´Ù.
¹«¾ùÀÌ ¹Ù²î¾ú³ª
±âÁ¸ÀÇ °£´ÜÇÑ HttpClient¿Í´Â ´Ù¸£°Ô ¿©·¯ ´õ ¼¼ºÎÀûÀÎ ¿É¼ÇµéÀ» Builder·Î ¼³Á¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÄíÅ°, ±ÇÇÑ, dns, socket, redirect Àü·«µî ¿©·¯ ¼¼ºÎ ¼³Á¤À» ÇÒ ¼ö ÀÖ°Ô º¯°æµÇ¾úÀ¸¸ç À̶§¹®¿¡ ±âÁ¸º¸´Ù Á» »ç¿ëÇÏ´Â Äڵ尡 º¹ÀâÇØÁö±ä ÇßÁö¸¸ ´õ ·Î¿ì·¹º§ÀÇ http È£ÃâÀ» »ý¼ºÇÏ´Â°Ô °¡´É ÇØÁ³½À´Ï´Ù.
¿Ö ComponentÀΰ¡
¿©±â¼ À̸§ÀÌ HttpClient -> HttpComponent·Î º¯°æµÇ¾ú´Ù´Â »ç½ÇÀ» »ý°¢ÇغÁ¾ß ÇÕ´Ï´Ù. ¿Ö ComponentÀϱî¿ä? °£·«ÇÏ°Ô ¼³¸íÇÏÀÚ¸é HttpClient°¡ ±âÁ¸°ú ´Ù¸£°Ô ÀÛÀº ¸ðµâ°ú°°Àº °³³äÀ¸·Î Àç»ç¿ë
°¡´ÉÇÏ°Ô µÇ¾ú´Ù´Â ¶æÀÔ´Ï´Ù.
HttpClient¸¦ »ý¼ºÇÒ¶§ ¾Æ¸¶ ´ÙÀ½Ã³·³ Äڵ带 ÀÛ¼ºÇÒ°ÍÀÔ´Ï´Ù.
HttpClient httpClient = HttpClients.createDefault();
// ÀÌÇÏ»ý·«
±×·¯¸é createDefault
method´Â ³»ºÎ¿¡¼ HttpClientBuilder
¸¦ ÅëÇؼ HttpClient¸¦ »ý¼ºÇÕ´Ï´Ù
/**
* Creates {@link CloseableHttpClient} instance with default
* configuration.
*/
public static CloseableHttpClient createDefault() {
return HttpClientBuilder.create().build();
}
±×·³ ÀÌ build
method¸¦ º¸°ÔµÇ¸é ¾î¸¶¹«½ÃÇÑ Äڵ差À» º¼ ¼ö Àִµ¥¿ä ÄÚµåÀÇ Áß°£¿¡ º¸¸é
@SuppressWarnings("resource")
final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactoryCopy)
.build(),
null,
null,
dnsResolver,
connTimeToLive,
connTimeToLiveTimeUnit != null ? connTimeToLiveTimeUnit : TimeUnit.MILLISECONDS);
³»ºÎ¿¡¼ PoolingHttpClientConnectionManager
¸¦ »ý¼ºÇϴ°ÍÀ» ¾Ë ¼ö Àִµ¥ Áï HttpComponentÀÇ default connection manager´Â Connection Pool·Î ÀÌ·ç¾îÁø°ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.
createDefault
¸»°íµµ ÀÛÀº »çÀÌÁîÀÇ Client¸¦ ¸¸µå´Â createMinimal
method ¼Ò½º¸¦ ºÁµµ Pooling Manager¸¦ »ç¿ëÇϴ°ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.
/**
* Creates {@link CloseableHttpClient} instance that implements
* the most basic HTTP protocol support.
*/
public static CloseableHttpClient createMinimal() {
return new MinimalHttpClient(new PoolingHttpClientConnectionManager());
}
Áï ¿ÜºÎ¿¡¼ argumentÀÎÀÚ·Î ´Ù¸¥ Http Manager¸¦ ¾²Áö ¾Ê°Ô ÇÏÁö ¾Ê´ÂÀÌ»ó HttpComponent´Â ±âº»ÀûÀ¸·Î Connection PoolingÀ¸·Î µ¿ÀÛÇϸç createDefault
¸¦ °è¼Ó È£ÃâÇÏ¸é °è¼Ó »õ·Î¿î Connection PoolÀ» »ý¼ºÇÑ´Ù´Â ÀǹÌÀÔ´Ï´Ù. Áï ÀÌ·¸°Ô »ý¼ºÇÑ HttpClient¸¦ °è¼Ó »ç¿ëÇØ¾ß ÇÑ´Ù´Â ÀǹÌÀÔ´Ï´Ù.
build method¿¡¼ »ý¼ºµÇ´Â InternalHttpClient
¿Í PoolingHttpClientConnectionManager
¸¦ º¸¸é @ThreadSafe
annotationÀÌ ºÙ¾îÀִ°ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. Áï ¿©·¯ thread¿¡¼ ÀÌ °´Ã¼¿¡ Á¢±ÙÇؼ »ç¿ëÇصµ ¾ÈÀüÇÏ´Ù´Â ¶æÀÔ´Ï´Ù.
HttpComponent¿¹Á¦ ¸¦ º¸½Ã¸é »ý¼ºÇÑ ÇϳªÀÇ HttpClient¸¦ ¿©·¯ thread¿¡¼ »ç¿ëÇÒ ¼ö Àִ°ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.
¸¸ÀÏ SpringÀ» ¾´´Ù¸é ÀÌ·¸°Ô ¾µ ¼öµµ ÀÖ°ÚÁÒ.
@Bean
public HttpClient httpClient() {
// http client »ý¼º
return HttpClients.createDefault();
}
// --------------------------
// ´Ù¸¥ class
@Autowired
private HttpClient httpClient;
public void call() {
HttpResponse response = null;
try {
response = hc.execute(new HttpGet("http://¾Æ¹«URL.com"));
String responseText = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
// error handling
} finally {
HttpClientUtils.closeQuietly(response);
}
}
±×·³ httpClient´Â °øÀ¯Çؼ ½áµµ µÇ´Ï HttpGet classµµ °øÀ¯Çؼ ½áµµ µÇ³ª¿ä? ¾ÈµË´Ï´Ù. HttpGetÀº thread safeÇÏÁö ¾Ê½À´Ï´Ù. °°ÀÌ ¾²Áö ¸¶¼¼¿ä.
±×¸®°í ¸ñÀû¿¡ µû¶ó¼ ´Ù¸¥ instance¸¦ ¸¸µé¾î³õ°í ¾²´Â°Íµµ °¡´ÉÇÕ´Ï´Ù.
// method¿¡ 1,2,3 ºÙÀÌ´Â°Ç ±¸¸®Áö¸¸ ±×³É ¿¹Á¦´Ï±ñ
@Bean
public HttpClient httpClient1() {
// ´Ü¼ø ½ÉÇÃÇÑ Á¢¼ÓÀ϶© ¾ê¸¦ ¾²ÀÚ
return HttpClients.createMinimal();
}
@Bean
public HttpClient httpClient2() {
// Ä¿³Ø¼ÇÀ» ¸¹ÀÌ ÇؾßÇϳ×?
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(300);
cm.setDefaultMaxPerRoute(50);
return HttpClients.custom().setConnectionManager(cm).build();
}
@Bean
public HttpClient httpClient3() {
// ¼ÒÄÏ Æ©´×
SocketConfig sc = SocketConfig.custom()
.setSoTimeout(2000)
.setSoKeepAlive(true)
.setTcpNoDelay(true)
.setSoReuseAddress(true)
.build();
return HttpClients.custom().setDefaultSocketConfig(sc).build();
}
¹Ì¸® ¼¼ÆÃÇسõÀº HttpComponentµéÀ» °ñ¶ó ¾²´Â°Ô °¡´ÉÇÏ°ÚÁÒ.
±×¸®°í PoolingHttpClientConnectionManager
ÀÇ »ý¼ººÎºÐ ¼Ò½ºÄڵ带 º¸¸é default poolÀÌ ³·Àº ¼öÄ¡·Î ÀâÇôÀִ°ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.
/**
* @since 4.4
*/
public PoolingHttpClientConnectionManager(
final HttpClientConnectionOperator httpClientConnectionOperator,
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
final long timeToLive, final TimeUnit tunit) {
super();
this.configData = new ConfigData();
this.pool = new CPool(new InternalConnectionFactory(
this.configData, connFactory), 2, 20, timeToLive, tunit);
this.pool.setValidateAfterInactivity(2000);
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "HttpClientConnectionOperator");
this.isShutDown = new AtomicBoolean(false);
}
CPoolÀÇ ÀÎÀÚ¸¦ º¸¸é maxTotalÀº 20, defaultMaxPerRoute°ªÀº 2ÀΰÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ¾Æ¸¶ ¿©·¯ Component¸¦ ¸¸µé°ÍÀ» »ý°¢ÇØ ±âº» ¼öÄ¡°¡ ÀÛÀº°Å °°±äÇѵ¥ middleware°£¿¡ Áö¼ÓÀûÀÎ ¸¹Àº Åë½ÅÀÌ ¸ñÀûÀ̶ó¸é ÀÛÀº ¼öÄ¡¶ó ÀûÀýÈ÷ ´Ã·ÁÁִ°ÍÀ» ±ÇÀåÇÕ´Ï´Ù.
¸¸ÀÏ ÀÌ·± ¼³Á¤À̳ª µ¿ÀÛ¹æ½ÄÀÌ ³Ê¹« ¾î·Á¿ö ´Ù·ç±â Èûµé´Ù¸é ±×³É ¸¶À½ÆíÈ÷ 3.x¹öÀü´ë Apache HttpClient³ª SpringÀÇ RestTemplate¸¦ ¾²´Â°Ô ÁÁÀ» ¼öµµ ÀÖ½À´Ï´Ù. ¸¸ÀÏ HttpComponent¸¦ ÀÌ·± ½ÉÇÃÇÑ ¿¹Á¦¸¸ º¸°í ±×´ë·Î Âß º¹ºÙÀ¸·Î »ç¿ëÇß´Ù¸é ´Ù¸¥ client¸¦ »ç¿ëÇϴ°ͺ¸´Ù ÆÛÆ÷¸Õ½º°¡ ³ª¿ÀÁö ¾ÊÀ»°ÍÀÔ´Ï´Ù.
Á¤¸®
Á¤¸®Çϸé HttpComponent¸¦ ¾µ¶§´Â
- http client °è¼Ó »ý¼ºÇÏÁö ¸»ÀÚ.
- client´Â multi thread¿¡¼ °°ÀÌ ½áµµ ±¦Âú´Ù.
- ¿ÀǼҽº »ç¿ë½Ã¿£ ¹®¼¿Í ¼Ò½ºÄڵ带 Àß »ìÆ캸ÀÚ.