thrift-processor

16 篇文章 2 订阅

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 消息头
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

N3verL4nd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值