5

在工作中,我们使用 Netflix 的Feign Client来帮助处理服务之间的请求。然而,我对它明显缺乏流数据的能力感到困惑,特别是考虑到 Netflix 众所周知的流视频商业模式。我显然在这里遗漏了一些东西。

解释一下,sayService A向 Feign Client 请求Service B一个数据Service B流并在响应中发送该流。此时,execute()Feign Client 中的方法被调用:

@Override public Response execute(Request request, Options options) throws IOException {
  HttpURLConnection connection = convertAndSend(request, options);
  return convertResponse(connection);
}

HttpURLConnection convertAndSend(Request request, Options options) throws IOException {
  final HttpURLConnection connection = (HttpURLConnection) new URL(request.url()).openConnection();

  /** SNIP **/

  if (request.body() != null) {
    if (contentLength != null) {
      connection.setFixedLengthStreamingMode(contentLength);
    } else {
      connection.setChunkedStreamingMode(8196);
    }
    connection.setDoOutput(true);
    OutputStream out = connection.getOutputStream();
    if (gzipEncodedRequest) {
      out = new GZIPOutputStream(out);
    }
    try {
      out.write(request.body()); // PROBLEM
    } finally {
      try {
        out.close();
      } catch (IOException suppressed) {
      }
    }
  }
  return connection;
}

标记的行PROBLEM让我感到困惑。

  1. request对象甚至没有任何类型的流可以读取,只是一个byte[] body.
  2. 在传出端,整个正文立即写入OutputStream。它不应该将数据分块吗?

例如

// pseudocode
try {
  location = 0
  bufferSize = 2048
  buffer = request.body().read(location, bufferSize)
  while(out.readyToRead() && buffer.length > 0) {
    out.write(buffer)
    location += bufferSize
    buffer = request.body().read(location, bufferSize)
  }
}

如果请求有一个流而不是一个流byte[] body,您可以进一步改进它以在数据可用时发送数据。

我对这个服务架构领域很陌生。我错过了什么?

4

1 回答 1

6

Feign 是为控制平面 API 设计的,这些 API 通常不会从向上流中受益。不过,支持向下流式传输。

关于缓冲的工作方式(例如替代字节数组),我不关心提高效率。请记住,feign 的大部分设计都围绕模板形式(json 或 xml)并尽可能地重用它们(例如,在重传时,缓冲 + 固定长度很容易且可预测)。

如果将“流”设计与 http 客户端耦合,我想我会非常高兴。IOTW,一种以在传输中有意义的方式处理流的子类型。例如,普通 java 的 InputStream,OkHttp 的 OkIo 缓冲区,Netty 的 Netty Buffer 等。

斯宾塞打开这个进行调查https://github.com/Netflix/feign/issues/220

于 2015-04-13T15:07:37.563 回答