TProcessor 是服务调用组件。
负责从 TProtocol 输入流读取消息,写入到 TProtocol 输出流。
TProcessor
public interface TProcessor {
public boolean process(TProtocol in, TProtocol out)
throws TException;
}
TBaseProcessor
TBaseProcessor 提供了 TProcessor 的默认实现。
public abstract class TBaseProcessor<I> implements TProcessor {
private final I iface;
// 方法名到 ProcessFunction 的映射
private final Map<String,ProcessFunction<I, ? extends TBase>> processMap;
protected TBaseProcessor(I iface, Map<String, ProcessFunction<I, ? extends TBase>> processFunctionMap) {
this.iface = iface;
this.processMap = processFunctionMap;
}
public Map<String,ProcessFunction<I, ? extends TBase>> getProcessMapView() {
return Collections.unmodifiableMap(processMap);
}
@Override
public boolean process(TProtocol in, TProtocol out) throws TException {
TMessage msg = in.readMessageBegin();
ProcessFunction fn = processMap.get(msg.name);
if (fn == null) {
TProtocolUtil.skip(in, TType.STRUCT);
in.readMessageEnd();
TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'");
out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
x.write(out);
out.writeMessageEnd();
out.getTransport().flush();
return true;
}
fn.process(msg.seqid, in, out, iface);
return true;
}
}
Processor
由 thrift 自动生成,实现自 TProcessor。
public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
public Processor(I iface) {
super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
}
protected Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
super(iface, getProcessMap(processMap));
}
private static <I extends Iface> Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
processMap.put("sayHello", new sayHello());
return processMap;
}
public static class sayHello<I extends Iface> extends org.apache.thrift.ProcessFunction<I, sayHello_args> {
public sayHello() {
super("sayHello");
}
public sayHello_args getEmptyArgsInstance() {
return new sayHello_args();
}
protected boolean isOneway() {
return false;
}
public sayHello_result getResult(I iface, sayHello_args args) throws org.apache.thrift.TException {
sayHello_result result = new sayHello_result();
// public com.meituan.model.Response success;
// public com.meituan.model.Request req;
// 执行真正的调用逻辑
result.success = iface.sayHello(args.req);
return result;
}
}
}
ProcessFunction
ProcessFunction 对象是实际方法的抽象
public abstract class ProcessFunction<I, T extends TBase> {
// thrift 方法调用没有利用到反射,故 methodName 在方法调用中没有太大的作用
private final String methodName;
private static final Logger LOGGER = LoggerFactory.getLogger(ProcessFunction.class.getName());
public ProcessFunction(String methodName) {
this.methodName = methodName;
}
public final void process(int seqid, TProtocol iprot, TProtocol oprot, I iface) throws TException {
T args = getEmptyArgsInstance();
try {
// 读取请求参数
// 对消息的编解码操作由相应的 Tbase 类实现
args.read(iprot);
} catch (TProtocolException e) {
iprot.readMessageEnd();
TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());
oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid));
x.write(oprot);
oprot.writeMessageEnd();
oprot.getTransport().flush();
return;
}
// org.apache.thrift.TBaseProcessor#process 执行了 readMessageBegin 方法
iprot.readMessageEnd();
TBase result = null;
try {
result = getResult(iface, args);
} catch(TException tex) {
LOGGER.error("Internal error processing " + getMethodName(), tex);
TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing " + getMethodName());
oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid));
x.write(oprot);
oprot.writeMessageEnd();
oprot.getTransport().flush();
return;
}
// 不是单向调用
// 单向调用没有返回值
if(!isOneway()) {
// seqid 和请求保持一致
// 对消息的编解码也是依赖相应的 Tbase
oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.REPLY, seqid));
result.write(oprot);
oprot.writeMessageEnd();
// 刷新缓存池
oprot.getTransport().flush();
}
}
// 是否是单向RPC,只调用不要求返回
protected abstract boolean isOneway();
// 获得返回值的抽象方法,实现由 thrift 自动生成
public abstract TBase getResult(I iface, T args) throws TException;
// 获得空的参数
public abstract T getEmptyArgsInstance();
// 获得方法名
public String getMethodName() {
return methodName;
}
}
TMultiplexedProcessor
允许单个 TServer 提供多种服务
public class TMultiplexedProcessor implements TProcessor {
private final Map<String,TProcessor> SERVICE_PROCESSOR_MAP
= new HashMap<String,TProcessor>();
public void registerProcessor(String serviceName, TProcessor processor) {
SERVICE_PROCESSOR_MAP.put(serviceName, processor);
}
public boolean process(TProtocol iprot, TProtocol oprot) throws TException {
TMessage message = iprot.readMessageBegin();
if (message.type != TMessageType.CALL && message.type != TMessageType.ONEWAY) {
throw new TException("This should not have happened!?");
}
int index = message.name.indexOf(TMultiplexedProtocol.SEPARATOR);
if (index < 0) {
throw new TException("Service name not found in message name: " + message.name + ". Did you " +
"forget to use a TMultiplexProtocol in your client?");
}
String serviceName = message.name.substring(0, index);
TProcessor actualProcessor = SERVICE_PROCESSOR_MAP.get(serviceName);
if (actualProcessor == null) {
throw new TException("Service name not found: " + serviceName + ". Did you forget " +
"to call registerProcessor()?");
}
TMessage standardMessage = new TMessage(
message.name.substring(serviceName.length()+TMultiplexedProtocol.SEPARATOR.length()),
message.type,
message.seqid
);
return actualProcessor.process(new StoredMessageProtocol(iprot, standardMessage), oprot);
}
private static class StoredMessageProtocol extends TProtocolDecorator {
TMessage messageBegin;
public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin) {
super(protocol);
this.messageBegin = messageBegin;
}
@Override
public TMessage readMessageBegin() throws TException {
return messageBegin;
}
}
}
使用
public class MultiServer {
public static void main(String[] args) throws TTransportException {
TMultiplexedProcessor processor = new TMultiplexedProcessor();
processor.registerProcessor( "helloService1", new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl()));
processor.registerProcessor( "helloService2", new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl()));
TServerSocket serverTransport = new TServerSocket(8888);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(processor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
}
}
public class TestClient {
public static void main(String[] args) throws TException {
TSocket transport = new TSocket("localhost", 8888);
transport.open();
TBinaryProtocol protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "helloService1");
HelloService.Client service = new HelloService.Client(mp);
Request request = new Request();
request.setName("lgh");
request.setAge(27);
System.out.println(service.sayHello(request));
}
}
TMultiplexedProcessor 通过读取消息头区分调用的哪一个服务
serviceName:helloService1
标准的 thrift 消息头