0

我们目前为我们的 RPC 使用节俭服务器。我们希望支持的调用之一是将读取文件的结果返回到直接的 ByteBuffer 中。THRIFT-883 说这不受支持(因为不支持 ByteBuffer.array()),所以想知道如果我们切换到 finagle 是否可以支持直接 ByteBuffers?

finagle 是否克服了这个限制,还是它也面临这个限制?

示例代码:

节约

struct BlockRequest {
  1: i64 blockId,
  2: i64 offset,
  3: i64 len
}

struct BlockResponse {
  1: i64 blockId
  2: i64 offset
  3: i64 len
  4: binary data
}

service DataService {
  BlockResponse requestBlock(1: BlockRequest request)
    throws (1: BlockInfoException bie, 2: FileDoesNotExistException fdne)
}

爪哇

  @Override
  public BlockResponse requestBlock(BlockRequest request) throws BlockInfoException,
      FileDoesNotExistException, TException {

    final long blockId = request.blockId;
    final long offset = request.offset;
    final long len = request.len;
...

    final RandomAccessFile file = new RandomAccessFile(filePath, "r");
    long fileLength = file.length();
    final long readLen;
    if (len == -1) {
      readLen = fileLength - offset;
    } else {
      readLen = len;
    }

    FileChannel channel = file.getChannel();
    final MappedByteBuffer data = channel.map(FileChannel.MapMode.READ_ONLY, offset, readLen);

    final BlockResponse response = new BlockResponse();
    response.setBlockId(blockId);
    response.setOffset(offset);
    response.setLen(readLen);
    response.setData(data);

    return response
...
4

1 回答 1

0

不能使用 thrift 这个,因为文件可能很大。

真正的问题是:通过网络将一个可能很大的文件完全放在一个块中是否是个好主意?您的服务已经定义了以块的形式交付文件的能力,而这正是我的建议。当然,有时您必须将文件复制到内存中,但即使您只使用原始套接字也是如此:有时数据需要在内存中。

为了防止大块,限制允许的最大长度。无论您是为超大请求抛出异常还是仅以BlockResponse某种方式指示服务器端限制(以允许客户端清楚地区分 EOF 和限制)都是一个品味问题。我可能会使用后一种方法来防止不必要的额外往返。

于 2014-08-02T11:08:34.327 回答