• grpc与http2的关系


    grpc与http2的关系

    grpc client 发送包到原生的http2 server

    client收到报错:

    panic: rpc error: code = 9 desc = transport: received the unexpected content-type "text/html; charset=UTF-8"
    

    server端输出:

    输出正常,包括了http2的所有信息,默认情况下响应了404。

    [id=1] [  3.994] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
              (niv=1)
              [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    [id=1] [  3.994] recv SETTINGS frame <length=0, flags=0x00, stream_id=0>
              (niv=0)
    [id=1] [  3.994] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
              (window_size_increment=983025)
    [id=1] [  3.995] recv (stream_id=1) :method: POST
    [id=1] [  3.995] recv (stream_id=1) :scheme: http
    [id=1] [  3.995] recv (stream_id=1) :path: /flyrun.FlyRun/Run
    [id=1] [  3.995] recv (stream_id=1) :authority: 127.0.0.1
    [id=1] [  3.995] recv (stream_id=1) content-type: application/grpc
    [id=1] [  3.995] recv (stream_id=1) user-agent: grpc-go/1.0
    [id=1] [  3.995] recv (stream_id=1) te: trailers
    [id=1] [  3.995] recv HEADERS frame <length=62, flags=0x04, stream_id=1>
              ; END_HEADERS
              (padlen=0)
              ; Open new stream
    [id=1] [  3.995] recv DATA frame <length=52, flags=0x01, stream_id=1>
              ; END_STREAM
    [id=1] [  3.995] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [id=1] [  3.995] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [id=1] [  3.995] send HEADERS frame <length=69, flags=0x04, stream_id=1>
              ; END_HEADERS
              (padlen=0)
              ; First response header
              :status: 404
              server: nghttpd nghttp2/1.19.0
              date: Fri, 10 Feb 2017 07:17:14 GMT
              content-type: text/html; charset=UTF-8
              content-length: 147
    [id=1] [  3.995] send DATA frame <length=147, flags=0x01, stream_id=1>
              ; END_STREAM
    [id=1] [  3.995] stream_id=1 closed
    [id=1] [  4.001] closed
    

    总结:

    原生http2协议server端能够完全解析grpc客户端发送的请求,获取任意请求信息。 原生http2协议server默认响应不符合grpc客户端标准。 从grpc客户端的响应来看,应该是content-type不对。

    grpc客户端自定义的固定头信息: content-type: application/grpc user-agent: grpc-go/1.0 method: POST

    也就是说,grpc规定了一些固定的特定的头信息的值,这是与原生http2协议不一样的。

    http2 client 发送包到 grpc server

    grpc server收到的信息:

    2017/02/10 15:46:58 transport: http2Server.HandleStreams found unhandled frame type [FrameHeader PRIORITY stream=3 len=5].
     2017/02/10 15:46:58 transport: http2Server.HandleStreams found unhandled frame type [FrameHeader PRIORITY stream=5 len=5].
     2017/02/10 15:46:58 transport: http2Server.HandleStreams found unhandled frame type [FrameHeader PRIORITY stream=7 len=5].
     2017/02/10 15:46:58 transport: http2Server.HandleStreams found unhandled frame type [FrameHeader PRIORITY stream=9 len=5].
     2017/02/10 15:46:58 transport: http2Server.HandleStreams found unhandled frame type [FrameHeader PRIORITY stream=11 len=5].
    

    原生 http2 发送与接收的信息:

    nghttp -v http://127.0.0.1:5000/abc/efg/hehe                                                 [15/412]
    [  0.000] Connected
    [  0.000] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
              (niv=2)
              [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
              [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
              (dep_stream_id=0, weight=201, exclusive=0)
    [  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
              (dep_stream_id=0, weight=101, exclusive=0)
    [  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
              (dep_stream_id=0, weight=1, exclusive=0)
    [  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
              (dep_stream_id=7, weight=1, exclusive=0)
    [  0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
              (dep_stream_id=3, weight=1, exclusive=0)
    [  0.000] send HEADERS frame <length=49, flags=0x25, stream_id=13>
              ; END_STREAM | END_HEADERS | PRIORITY
              (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
              ; Open new stream
              :method: GET
              :path: /abc/efg/hehe
              :scheme: http
              :authority: 127.0.0.1:5000
              accept: */*
              accept-encoding: gzip, deflate
              user-agent: nghttp2/1.19.0
    [  0.000] recv SETTINGS frame <length=0, flags=0x00, stream_id=0>
              (niv=0)
    [  0.000] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
              (window_size_increment=983025)
    [  0.000] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [  0.000] recv (stream_id=13) :status: 200
    [  0.000] recv (stream_id=13) content-type: application/grpc
    [  0.000] recv (stream_id=13) grpc-status: 12
    [  0.000] recv (stream_id=13) grpc-message: unknown service abc/efg
    [  0.000] recv HEADERS frame <length=56, flags=0x05, stream_id=13>
              ; END_STREAM | END_HEADERS
              (padlen=0)
              ; First response header
    [  0.000] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
              ; ACK
              (niv=0)
    [  0.000] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
              (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
    

    grpc服务端自定义的固定头信息: content-type: application/grpc grpc-status: 12 grpc-message: unknown service abc/efg

    小结:

    所以,默认的原生http2客户端与grpc服务端只能够实现通信,但也不能够实现完整正确的响应解析。

    总结

    grpc与原生http2能够实现协议通信,但在通信包的解释上有更进一步的特殊处理,从而会导致并不能直接与原生http2协议愉快通信。

    比如解释content-type不能识别时,导致的连接异常主断开,无法继续后续的请求与响应。

    nghttp 包 帮助调试

    启动原生http2/h2c server端:

     nghttpd 5003 --no-tls
    

    发送原生http2请求:

     nghttp -v http://127.0.0.1:5000/abc/efg/hehe
    

    如何使用原生http2服务正确地接收并响应grpc请求

    了解这个问题,以便在可能时候实现基于原生http2的grpc反向代理。

  • 相关阅读:
    属性
    继承
    UniApp 环境安装
    Mysql:The user specified as a definer (‘root‘@‘%‘) does not exist 的解决办法
    SpringBoot Consider defining a bean of type 'xxx' in your configuration
    js 取url各部分数据
    uniapp中使用jsencrypt
    centos8.x版本安装宝塔提示Errors during downloading metadata for repository ‘epel’报错的解决方法
    解决 JWT + SSO 报错 :Error creating bean with name 'jwtTokenServices'
    SQL server 清除缓存
  • 原文地址:https://www.cnblogs.com/exmyth/p/14766465.html
Copyright © 2020-2023  润新知