java의 HttpClient를 사용하여 다중 스레드 병렬
5683 단어 javaHttpClient다중 스레드
우리는 자바의 HttpClient를 사용하여 get 요청 웹 페이지를 캡처하는 것이 비교적 실현하기 쉬운 작업이다.
public static String get(String url) {
CloseableHttpResponseresponse = null;
BufferedReader in = null;
String result = "";
try {
CloseableHttpClienthttpclient = HttpClients.createDefault();
HttpGethttpGet = new HttpGet(url);
response = httpclient.execute(httpGet);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffersb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
result = sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != response) response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
get 요청을 다중 스레드로 실행할 때 위의 방법도 사용할 수 있습니다.그러나 이런 다중 스레드 요청은 get 방법을 호출할 때마다 HttpClient를 만드는 실례를 바탕으로 이루어진다.각 HttpClient 인스턴스는 한 번 사용하면 다시 회수됩니다.이것은 분명히 가장 좋은 실현이 아니다.HttpClient는 공식 문서의 Pooling connection 관리자를 볼 수 있는 다중 스레드 요청 방안을 제공합니다.Http클라이언트의 다중 스레드 요청은 내장된 연결 탱크를 바탕으로 이루어진다. 그 중에서 관건적인 클래스는 PoolingHttpClientConnectionManager이다. 이 클래스는 HttpClient 연결 탱크를 관리하는 것을 책임진다.PoolingHttpClientConnectionManager에서 두 가지 관건적인 방법을 제공했습니다: setMaxTotal과 setDefaultMaxPerRoute.setMaxTotal은 연결 풀의 최대 연결 수를 설정하고, setDefaultMaxPerRoute는 모든 루트의 기본 연결 개수를 설정합니다.또한 setMaxPerRoute – 특정 사이트에 대한 최대 연결 개수를 단독으로 설정하는 방법도 있습니다.
HttpHosthost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(host), 50);
문서에 따라 get 요청을 살짝 조정합니다.
package com.zhyea.robin;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class HttpUtil {
private static CloseableHttpClienthttpClient;
static {
PoolingHttpClientConnectionManagercm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
cm.setDefaultMaxPerRoute(50);
httpClient = HttpClients.custom().setConnectionManager(cm).build();
}
public static String get(String url) {
CloseableHttpResponseresponse = null;
BufferedReaderin = null;
String result = "";
try {
HttpGethttpGet = new HttpGet(url);
response = httpClient.execute(httpGet);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffersb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
result = sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != response) response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static void main(String[] args) {
System.out.println(get("https://www.baidu.com/"));
}
}
이렇게 하면 얼마 안 된다.그러나 나 자신에게 있어서 나는 httpclient의fluent 실현을 더욱 좋아한다. 예를 들어 우리가 방금 실현한 httpget 요청은 이렇게 간단하게 실현할 수 있다.
package com.zhyea.robin;
import org.apache.http.client.fluent.Request;
import java.io.IOException;
public class HttpUtil {
public static String get(String url) {
String result = "";
try {
result = Request.Get(url)
.connectTimeout(1000)
.socketTimeout(1000)
.execute().returnContent().asString();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
System.out.println(get("https://www.baidu.com/"));
}
}
우리가 해야 할 일은 이전의 httpclient 의존을 fluent-hc 의존으로 바꾸는 것뿐이다.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.2</version>
</dependency>
그리고 이 fluent가 천연을 실현하는 것은 Pooling Http Client Connection Manager를 이용하여 완성한 것이다.maxTotal과 defaultMaxPerRoute의 값은 각각 200과 100입니다.
CONNMGR = new PoolingHttpClientConnectionManager(sfr);
CONNMGR.setDefaultMaxPerRoute(100);
CONNMGR.setMaxTotal(200);
유일하게 불쾌한 것은 Executor가 이 두 값을 조정할 방법을 제공하지 않았다는 것이다.하지만 이것도 충분합니다. 정말 안 되면 Executor를 다시 쓰는 방법을 고려하고 Executor를 사용하여 get 요청을 실행할 수 있습니다.
Executor.newInstance().execute(Request.Get(url))
.returnContent().asString();
이렇게!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
38. Java의 Leetcode 솔루션텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.