sourcecode

가용성을 위해 HTTP URL에 ping을 실행하는 기본 Java 방법

copyscript 2022. 8. 28. 09:51
반응형

가용성을 위해 HTTP URL에 ping을 실행하는 기본 Java 방법

특정 HTTP URL을 사용할 수 있는지 정기적으로 확인하는 모니터 클래스가 필요합니다.Spring Task Executor 추상화를 사용하여 "정기적인" 부분을 처리할 수 있으므로, 이 내용은 여기서 다루지 않습니다.문제는 다음과 같습니다.Java에서 URL을 ping할 때 권장되는 방법은 무엇입니까?

현재 코드(시작점)는 다음과 같습니다.

try {
    final URLConnection connection = new URL(url).openConnection();
    connection.connect();
    LOG.info("Service " + url + " available, yeah!");
    available = true;
} catch (final MalformedURLException e) {
    throw new IllegalStateException("Bad URL: " + url, e);
} catch (final IOException e) {
    LOG.info("Service " + url + " unavailable, oh no!", e);
    available = false;
}
  1. 이래도 좋을까?
  2. 어떻게든 연결을 끊어야 하나요?
  3. 이건...GET부탁한다.보낼 수 있는 방법이 있나요?HEAD대신?

(내가 하고 싶은 대로 할 수 있을까?)

할 수 있어요.다른 실현 가능한 방법은 를 사용하는 것입니다.

public static boolean pingHost(String host, int port, int timeout) {
    try (Socket socket = new Socket()) {
        socket.connect(new InetSocketAddress(host, port), timeout);
        return true;
    } catch (IOException e) {
        return false; // Either timeout or unreachable or failed DNS lookup.
    }
}

또, 다음과 같은 것이 있습니다.

boolean reachable = InetAddress.getByName(hostname).isReachable();

단, 포트 80은 명시적으로 테스트되지 않습니다.방화벽이 다른 포트를 차단하여 false negative를 얻을 위험이 있습니다.


어떻게든 연결을 끊어야 하나요?

아니요, 당신은 명시적으로 필요하지 않습니다.그건 취급되고 덮개 밑에 고여 있어요.


이것은 GET 요청이라고 생각합니다.대신 HEAD를 보내는 방법이 있나요?

얻은 것을 캐스팅 할 수 있습니다.URLConnection를 사용하여 요청 메서드를 설정합니다.단, GET이 정상적으로 동작하는 동안 일부 불량 웹 애플리케이션 또는 자체 개발한 서버가 HEAD에 대해 HTTP 405 오류를 반환할 수 있습니다(즉, 사용할 수 없음, 구현되지 않음, 허용되지 않음).도메인/호스트가 아닌 링크/리소스를 검증하는 경우는, GET 를 사용하는 것이 신뢰성이 높아집니다.


서버의 가용성을 테스트하는 것만으로는 불충분합니다.URL을 테스트해야 합니다(Webapp이 도입되지 않을 수 있습니다).

실제로 호스트를 연결하면 호스트가 사용 가능한지 여부만 알 수 있으며 컨텐츠가 사용 가능한지 여부는 알 수 없습니다.웹 서버가 문제 없이 시작되었지만 서버 시작 중에 웹 앱이 배포되지 않은 경우에도 마찬가지입니다.다만, 통상은, 서버 전체가 다운하는 일은 없습니다.HTTP 응답 코드가 200인지 여부를 확인하는 것으로 확인할 수 있습니다.

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
    // Not OK.
}

// < 100 is undetermined.
// 1nn is informal (shouldn't happen on a GET/HEAD)
// 2nn is success
// 3nn is redirect
// 4nn is client error
// 5nn is server error

응답 상태 코드의 상세한 것에 대하여는, RFC 2616 섹션 10 을 참조해 주세요.부르기connect()응답 데이터를 결정하는 경우에는 필요하지 않습니다.암묵적으로 연결됩니다.

다음에 참조할 수 있도록 타임아웃을 고려한 유틸리티 메서드의 플레이버에 대한 완전한 예는 다음과 같습니다.

/**
 * Pings a HTTP URL. This effectively sends a HEAD request and returns <code>true</code> if the response code is in 
 * the 200-399 range.
 * @param url The HTTP URL to be pinged.
 * @param timeout The timeout in millis for both the connection timeout and the response read timeout. Note that
 * the total timeout is effectively two times the given timeout.
 * @return <code>true</code> if the given HTTP URL has returned response code 200-399 on a HEAD request within the
 * given timeout, otherwise <code>false</code>.
 */
public static boolean pingURL(String url, int timeout) {
    url = url.replaceFirst("^https", "http"); // Otherwise an exception may be thrown on invalid SSL certificates.

    try {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setConnectTimeout(timeout);
        connection.setReadTimeout(timeout);
        connection.setRequestMethod("HEAD");
        int responseCode = connection.getResponseCode();
        return (200 <= responseCode && responseCode <= 399);
    } catch (IOException exception) {
        return false;
    }
}

URL 대신 Http를 사용합니다.URL 객체 상에서 openConnection()을 호출하여 URL Connection을 실행합니다.

그런 다음 getResponseCode()사용하면 연결에서 읽은 후 HTTP 응답을 얻을 수 있습니다.

다음은 코드입니다.

    HttpURLConnection connection = null;
    try {
        URL u = new URL("http://www.google.com/");
        connection = (HttpURLConnection) u.openConnection();
        connection.setRequestMethod("HEAD");
        int code = connection.getResponseCode();
        System.out.println("" + code);
        // You can determine on HTTP return code received. 200 is success.
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }

URL이 존재하는지 확인하거나 Java를 사용하여 404를 반환하는 방법 같은 질문도 확인하세요.

이게 도움이 됐으면 좋겠다.

를 사용하여 요청 방법을 설정할 수도 있습니다.HEAD예를 들어)를 참조해 주세요.다음은 요청을 보내고 응답을 읽고 연결을 끊는 방법을 보여 주는 입니다.

는 음다음음음음음음 a a a a a a를 합니다.HEAD웹사이트 이용 가능 여부를 확인해 달라고 요청한다.

public static boolean isReachable(String targetUrl) throws IOException
{
    HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(
            targetUrl).openConnection();
    httpUrlConnection.setRequestMethod("HEAD");

    try
    {
        int responseCode = httpUrlConnection.getResponseCode();

        return responseCode == HttpURLConnection.HTTP_OK;
    } catch (UnknownHostException noInternetConnection)
    {
        return false;
    }
}
public boolean isOnline() {
    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    } catch (IOException | InterruptedException e) { e.printStackTrace(); }
    return false;
}

가능한 질문

  • 이게 정말 충분히 빠른가요?네, 아주 빨라요!
  • 어쨌든 요청하고 싶은 제 페이지를 ping 하면 안 될까요?물론입니다. "인터넷 연결 사용 가능"과 도달 가능한 서버를 구별하고 싶은 경우 둘 다 체크할 수 있습니다.DNS가 다운되면 어떻게 해야 합니까?Google DNS(예: 8.8.8.8)는 세계에서 가장 큰 공용 DNS 서비스입니다.2013년 기준으로 하루에 1,300억 건의 요청을 처리합니다.예를 들어, 당신의 앱이 응답하지 않는 것은 아마도 오늘의 화제가 되지 않을 것입니다.

링크를 읽습니다.아주 좋은 것 같다

EDIT: 사용 기간 중에는 이 방법만큼 빠르지 않습니다.

public boolean isOnline() {
    NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

그것들은 조금 다르지만 인터넷 접속을 확인하는 기능에서는 첫 번째 방법은 접속 변수 때문에 느려질 수 있습니다.

레슬렛 프레임워크의 사용을 검토해 주십시오.레슬렛 프레임워크는 이러한 종류의 의미에 매우 적합합니다.파워풀하고 유연합니다.

코드는 다음과 같이 단순할 수 있습니다.

Client client = new Client(Protocol.HTTP);
Response response = client.get(url);
if (response.getStatus().isError()) {
    // uh oh!
}

언급URL : https://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-an-http-url-for-availability

반응형