在工作中,我们使用Netflix的Feign Client来帮助处理服务之间的请求。但是,我对其明显缺乏流式传输数据的能力感到困惑,特别是考虑到Netflix众所周知的流媒体视频商业模式。我显然在这里遗漏了一些东西。
要解释一下,请Service A
向假设客户询问Service B
数据流,Service B
在响应中发送流。此时,Feign Client中的execute()
方法被调用:
@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
的行让我感到困惑。
request
对象甚至没有任何类型的流可供阅读,只有byte[] body
。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
,那么您可以进一步提高数据的可用性。
我对这个服务架构领域很陌生。我错过了什么?
答案 0 :(得分:5)
Feign是为控制平面apis设计的,通常不会通过向上流式传输而受益。但是,支持向下流式传输。
我不关心在缓冲如何工作方面更有效率(例如替代字节数组)。请记住,feign的大多数设计都围绕着模板形式(json或xml),并尽可能地重复使用它们(例如,重新传输,缓冲+固定长度很容易且可预测)。
如果它与http客户端相连,我想我会对“流媒体”设计感到高兴。 IOTW,一种以传输中有意义的方式处理流式传输的子类型。例如,常规java的InputStream,OkHttp的OkIo缓冲区,Netty的Netty缓冲区等等。
打开了这个