【问题标题】:How to ping http2 server port for liveness (grpc server)?如何 ping http2 服务器端口以获得活性(grpc 服务器)?
【发布时间】:2018-03-24 00:02:59
【问题描述】:

我正在尝试 ping grpc http2 服务器端口以获得活力。在 Http1.1 中,我们将使用url.openConnection 并检查响应状态码。

http2中的等价物是什么?

下面的代码似乎没有错误,但我不知道如何使用它来检查请求是否成功?

import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.ssl.SslContextFactory;

import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class HeartbeatCheckHttp2 {
    public static void main(String [] args) throws Exception {
        for (int i=0; i<50000; ++i) {
            Thread.sleep(400L);

            HTTP2Client client = new HTTP2Client();
            client.start();

            // Connect to host.
            String host = "localhost";
            int port = 50000;

            FuturePromise<Session> sessionPromise = new FuturePromise<>();
            client.connect(new InetSocketAddress(host, port), new ServerSessionListener.Adapter(), sessionPromise);


            // Obtain the client Session object.
            Session session = sessionPromise.get(5, TimeUnit.SECONDS);

            // Prepare the HTTP request headers.
            HttpFields requestFields = new HttpFields();
            requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);
            requestFields.put("Content-Type", "application/grpc");
            // Prepare the HTTP request object.
            MetaData.Request request = new MetaData.Request("POST", new HttpURI("http://" + host + ":" + port + "/"), HttpVersion.HTTP_2, requestFields);
            // Create the HTTP/2 HEADERS frame representing the HTTP request.
            HeadersFrame headersFrame = new HeadersFrame(request, null, true);

            // Prepare the listener to receive the HTTP response frames.
            Stream.Listener responseListener = new Stream.Listener.Adapter()
            {
                @Override
                public void onData(Stream stream, DataFrame frame, Callback callback)
                {
                    byte[] bytes = new byte[frame.getData().remaining()];
                    frame.getData().get(bytes);
                    callback.succeeded();
                }
            };

            session.newStream(headersFrame, new FuturePromise<>(), responseListener);
            session.newStream(headersFrame, new FuturePromise<>(), responseListener);
            session.newStream(headersFrame, new FuturePromise<>(), responseListener);

            Thread.sleep(TimeUnit.SECONDS.toMillis(20));


            client.stop();
        }
    }
}

我可以使用 SocketAddress 来 ping Tcp 活性,但我想进行实际的 Http2 调用来进行活性检查。

【问题讨论】:

    标签: java grpc http2


    【解决方案1】:

    HTTP/2 协议具有内置的心跳帧,可用于“ping”其他对等方的活跃度。

    HTTP2Client client = new HTTP2Client();
    client.start();
    
    FuturePromise<Session> sessionPromise = new FuturePromise<>();
    client.connect(new InetSocketAddress(host, port), new ServerSessionListener.Adapter() {
        @Override
        public void onPing(Session session, PingFrame frame) {
            // The other peer replies to our pings.
        }
    }, sessionPromise);
    Session session = sessionPromise.get(5, TimeUnit.SECONDS);
    
    session.ping(new PingFrame(System.nanoTime(), false), Callback.NOOP);
    

    说到内置的 ping 功能,如果你想检查一个 HTTP 请求的响应状态,你应该实现onHeaders()

    Stream.Listener responseListener = new Stream.Listener.Adapter() {
        @Override
        public void onHeaders(Stream stream, HeadersFrame frame) {
            MetaData metaData = frame.getMetaData();
            if (metaData.isResponse()) {
                MetaData.Response response = (MetaData.Response)metaData;
                int status = response.getStatus();
                ...
            }
        }
    
        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback) {
            ...
        }
    };
    

    这就是使用通过 HTTP/2 框架使用 HTTP 的服务器的方式。

    使用 gRPC,情况可能会有所不同,因为 gRPC protocol 是通过 HTTP/2 帧传输的,但它不是 HTTP。

    【讨论】:

      猜你喜欢
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2018-06-14
      • 2012-07-07
      • 2011-02-05
      相关资源
      最近更新 更多