ProtoBuffer是Google开发的一款RPC框架,也是HBase中client与server通信所使用的框架。下面以HBase的scan为例,来说明下其RPC框架是如何工作的。scan命令到达server之后,首先执行RpcServer的call方法,在call中调用service的callBlockingMethod方法:service.callBlockingMethod(md, controller, param)。而service来自于RSRpcService的rpcServer = new RpcServer(rs, name, getServices())。
protected List<BlockingServiceAndInterface> getServices() {
List<BlockingServiceAndInterface> bssi = new ArrayList<BlockingServiceAndInterface>(2);
bssi.add(new BlockingServiceAndInterface(
ClientService.newReflectiveBlockingService(this),
ClientService.BlockingInterface.class));
bssi.add(new BlockingServiceAndInterface(
AdminService.newReflectiveBlockingService(this),
AdminService.BlockingInterface.class));
return bssi;
}
继续跟踪newReflectiveBlockingService方法
public static com.google.protobuf.BlockingService
newReflectiveBlockingService(final BlockingInterface impl) {
return new com.google.protobuf.BlockingService() {
public final com.google.protobuf.Descriptors.ServiceDescriptor
getDescriptorForType() {
return getDescriptor();
}
public final com.google.protobuf.Message callBlockingMethod(
com.google.protobuf.Descriptors.MethodDescriptor method,
com.google.protobuf.RpcController controller,
com.google.protobuf.Message request)
throws com.google.protobuf.ServiceException {
if (method.getService() != getDescriptor()) {
throw new java.lang.IllegalArgumentException(
"Service.callBlockingMethod() given method descriptor for " +
"wrong service type.");
}
switch(method.getIndex()) {
case 0:
return impl.get(controller, (org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest)request);
case 1:
return impl.mutate(controller, (org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest)request);
可以看到此处是一个回调,将RSRpcService的this对象注册到ClientService得到一个Service对象,当在RpcServer中调用该Service对象的service.callBlockingMethod(scan, controller, param)时会执行当时注册到ClientService的RSRpcService的scan方法。