zoukankan      html  css  js  c++  java
  • thrift概述

    Apache Thrift 是FaceBook实现的一种跨平台的远程服务调用(RPC)的框架。它采用接口描述语言(IDL)定义并创建服务,传输数据采用二进制格式,相对于XML和Json等常用数据传输方式体积更小。

    首先一个完整的RPC模块主要分三部分:

    1.服务层(service):RPC接口的定义与实现

    2.协议层(protocol):RPC报文格式和数据编码格式

    3.传输层(transport):实现底层的通信(如socket)以及系统相关的功能(如事件循环、多线程)

    图 1. 架构图

    如上图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据Thrift定义的服务接口描述文件生成的客户端和服务端代码框架,红色部分是根据Thrift文件生成代码实现数据的读写操作。红色部分以下是Thrift的传输体系、协议以及底层的I/O通信。

    一个thrift简单实例过程:

    1.写Thrift定义文件(.thrift)

    复制代码
    1 namespace java com.eviac.blog.samples.thrift.server  // defines the namespace   
    2    
    3 typedef i32 int  //typedefs to get convenient names for your types  
    4    
    5 service AdditionService {  // defines the service to add two numbers  
    6         int add(1:int n1, 2:int n2), //defines a method  
    7 }
    复制代码

    2.编译Thrift定义文件

    thrift --gen <language> <Thrift filename>

    对于java语言来说就是:

    thrift --gen java add.thrift

    执行完之后,在gen-java目录下你会发现构建RPC服务器和客户端有用的源代码,在本例中将生成一个AddtionService.java的文件。

    现将生成的代码贴上:

    复制代码
      1 /**
      2  * Autogenerated by Thrift Compiler (0.8.0-xsb)
      3  *
      4  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
      5  *  @generated
      6  */
      7 
      8 
      9 import org.apache.thrift.scheme.IScheme;
     10 import org.apache.thrift.scheme.SchemeFactory;
     11 import org.apache.thrift.scheme.StandardScheme;
     12 
     13 import org.apache.thrift.scheme.TupleScheme;
     14 import org.apache.thrift.protocol.TTupleProtocol;
     15 import java.util.List;
     16 import java.util.ArrayList;
     17 import java.util.Map;
     18 import java.util.HashMap;
     19 import java.util.EnumMap;
     20 import java.util.Set;
     21 import java.util.HashSet;
     22 import java.util.EnumSet;
     23 import java.util.Collections;
     24 import java.util.BitSet;
     25 import java.nio.ByteBuffer;
     26 import java.util.Arrays;
     27 import org.slf4j.Logger;
     28 import org.slf4j.LoggerFactory;
     29 
     30 public class AdditionService {
     31 
     32   public interface Iface {
     33 
     34     public int add(int n1, int n2) throws org.apache.thrift.TException;
     35 
     36   }
     37 
     38   public interface AsyncIface {
     39 
     40     public void add(int n1, int n2, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.add_call> resultHandler) throws org.apache.thrift.TException;
     41 
     42   }
     43 
     44   public static class Client extends org.apache.thrift.TServiceClient implements Iface {
     45     public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
     46       public Factory() {}
     47       public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
     48         return new Client(prot);
     49       }
     50       public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
     51         return new Client(iprot, oprot);
     52       }
     53     }
     54 
     55     public Client(org.apache.thrift.protocol.TProtocol prot)
     56     {
     57       super(prot, prot);
     58     }
     59 
     60     public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
     61       super(iprot, oprot);
     62     }
     63 
     64     public int add(int n1, int n2) throws org.apache.thrift.TException
     65     {
     66       send_add(n1, n2);
     67       return recv_add();
     68     }
     69 
     70     public void send_add(int n1, int n2) throws org.apache.thrift.TException
     71     {
     72       add_args args = new add_args();
     73       args.setN1(n1);
     74       args.setN2(n2);
     75       sendBase("add", args);
     76     }
     77 
     78     public int recv_add() throws org.apache.thrift.TException
     79     {
     80       add_result result = new add_result();
     81       receiveBase(result, "add");
     82       if (result.isSetSuccess()) {
     83         return result.success;
     84       }
     85       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "add failed: unknown result");
     86     }
     87 
     88   }
     89   public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
     90     public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
     91       private org.apache.thrift.async.TAsyncClientManager clientManager;
     92       private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
     93       public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
     94         this.clientManager = clientManager;
     95         this.protocolFactory = protocolFactory;
     96       }
     97       public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
     98         return new AsyncClient(protocolFactory, clientManager, transport);
     99       }
    100     }
    101 
    102     public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
    103       super(protocolFactory, clientManager, transport);
    104     }
    105 
    106     public void add(int n1, int n2, org.apache.thrift.async.AsyncMethodCallback<add_call> resultHandler) throws org.apache.thrift.TException {
    107       checkReady();
    108       add_call method_call = new add_call(n1, n2, resultHandler, this, ___protocolFactory, ___transport);
    109       this.___currentMethod = method_call;
    110       ___manager.call(method_call);
    111     }
    112 
    113     public static class add_call extends org.apache.thrift.async.TAsyncMethodCall {
    114       private int n1;
    115       private int n2;
    116       public add_call(int n1, int n2, org.apache.thrift.async.AsyncMethodCallback<add_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
    117         super(client, protocolFactory, transport, resultHandler, false);
    118         this.n1 = n1;
    119         this.n2 = n2;
    120       }
    121 
    122       public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
    123         prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("add", org.apache.thrift.protocol.TMessageType.CALL, 0));
    124         add_args args = new add_args();
    125         args.setN1(n1);
    126         args.setN2(n2);
    127         args.write(prot);
    128         prot.writeMessageEnd();
    129       }
    130 
    131       public int getResult() throws org.apache.thrift.TException {
    132         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
    133           throw new IllegalStateException("Method call not finished!");
    134         }
    135         org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
    136         org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
    137         return (new Client(prot)).recv_add();
    138       }
    139     }
    140 
    141   }
    142 
    143   public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
    144     private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
    145     public Processor(I iface) {
    146       super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
    147     }
    148 
    149     protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
    150       super(iface, getProcessMap(processMap));
    151     }
    152 
    153     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) {
    154       processMap.put("add", new add());
    155       return processMap;
    156     }
    157 
    158     private static class add<I extends Iface> extends org.apache.thrift.ProcessFunction<I, add_args> {
    159       public add() {
    160         super("add");
    161       }
    162 
    163       protected add_args getEmptyArgsInstance() {
    164         return new add_args();
    165       }
    166 
    167       protected boolean isOneway() {
    168        return false;
    169       }
    170 
    171       protected add_result getResult(I iface, add_args args) throws org.apache.thrift.TException {
    172         add_result result = new add_result();
    173         result.success = iface.add(args.n1, args.n2);
    174         result.setSuccessIsSet(true);
    175         return result;
    176       }
    177     }
    178 
    179   }
    180 
    181   public static class add_args implements org.apache.thrift.TBase<add_args, add_args._Fields>, java.io.Serializable, Cloneable   {
    182     private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("add_args");
    183 
    184     private static final org.apache.thrift.protocol.TField N1_FIELD_DESC = new org.apache.thrift.protocol.TField("n1", org.apache.thrift.protocol.TType.I32, (short)1);
    185     private static final org.apache.thrift.protocol.TField N2_FIELD_DESC = new org.apache.thrift.protocol.TField("n2", org.apache.thrift.protocol.TType.I32, (short)2);
    186 
    187     private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    188     static {
    189       schemes.put(StandardScheme.class, new add_argsStandardSchemeFactory());
    190       schemes.put(TupleScheme.class, new add_argsTupleSchemeFactory());
    191     }
    192 
    193     public int n1; // required
    194     public int n2; // required
    195 
    196     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    197     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    198       N1((short)1, "n1"),
    199       N2((short)2, "n2");
    200 
    201       private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
    202 
    203       static {
    204         for (_Fields field : EnumSet.allOf(_Fields.class)) {
    205           byName.put(field.getFieldName(), field);
    206         }
    207       }
    208 
    209       /**
    210        * Find the _Fields constant that matches fieldId, or null if its not found.
    211        */
    212       public static _Fields findByThriftId(int fieldId) {
    213         switch(fieldId) {
    214           case 1: // N1
    215             return N1;
    216           case 2: // N2
    217             return N2;
    218           default:
    219             return null;
    220         }
    221       }
    222 
    223       /**
    224        * Find the _Fields constant that matches fieldId, throwing an exception
    225        * if it is not found.
    226        */
    227       public static _Fields findByThriftIdOrThrow(int fieldId) {
    228         _Fields fields = findByThriftId(fieldId);
    229         if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
    230         return fields;
    231       }
    232 
    233       /**
    234        * Find the _Fields constant that matches name, or null if its not found.
    235        */
    236       public static _Fields findByName(String name) {
    237         return byName.get(name);
    238       }
    239 
    240       private final short _thriftId;
    241       private final String _fieldName;
    242 
    243       _Fields(short thriftId, String fieldName) {
    244         _thriftId = thriftId;
    245         _fieldName = fieldName;
    246       }
    247 
    248       public short getThriftFieldId() {
    249         return _thriftId;
    250       }
    251 
    252       public String getFieldName() {
    253         return _fieldName;
    254       }
    255     }
    256 
    257     // isset id assignments
    258     private static final int __N1_ISSET_ID = 0;
    259     private static final int __N2_ISSET_ID = 1;
    260     private BitSet __isset_bit_vector = new BitSet(2);
    261     public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    262     static {
    263       Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    264       tmpMap.put(_Fields.N1, new org.apache.thrift.meta_data.FieldMetaData("n1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
    265           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "int")));
    266       tmpMap.put(_Fields.N2, new org.apache.thrift.meta_data.FieldMetaData("n2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
    267           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "int")));
    268       metaDataMap = Collections.unmodifiableMap(tmpMap);
    269       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(add_args.class, metaDataMap);
    270     }
    271 
    272     public add_args() {
    273     }
    274 
    275     public add_args(
    276       int n1,
    277       int n2)
    278     {
    279       this();
    280       this.n1 = n1;
    281       setN1IsSet(true);
    282       this.n2 = n2;
    283       setN2IsSet(true);
    284     }
    285 
    286     /**
    287      * Performs a deep copy on <i>other</i>.
    288      */
    289     public add_args(add_args other) {
    290       __isset_bit_vector.clear();
    291       __isset_bit_vector.or(other.__isset_bit_vector);
    292       this.n1 = other.n1;
    293       this.n2 = other.n2;
    294     }
    295 
    296     public add_args deepCopy() {
    297       return new add_args(this);
    298     }
    299 
    300     @Override
    301     public void clear() {
    302       setN1IsSet(false);
    303       this.n1 = 0;
    304       setN2IsSet(false);
    305       this.n2 = 0;
    306     }
    307 
    308     public int getN1() {
    309       return this.n1;
    310     }
    311 
    312     public add_args setN1(int n1) {
    313       this.n1 = n1;
    314       setN1IsSet(true);
    315       return this;
    316     }
    317 
    318     public void unsetN1() {
    319       __isset_bit_vector.clear(__N1_ISSET_ID);
    320     }
    321 
    322     /** Returns true if field n1 is set (has been assigned a value) and false otherwise */
    323     public boolean isSetN1() {
    324       return __isset_bit_vector.get(__N1_ISSET_ID);
    325     }
    326 
    327     public void setN1IsSet(boolean value) {
    328       __isset_bit_vector.set(__N1_ISSET_ID, value);
    329     }
    330 
    331     public int getN2() {
    332       return this.n2;
    333     }
    334 
    335     public add_args setN2(int n2) {
    336       this.n2 = n2;
    337       setN2IsSet(true);
    338       return this;
    339     }
    340 
    341     public void unsetN2() {
    342       __isset_bit_vector.clear(__N2_ISSET_ID);
    343     }
    344 
    345     /** Returns true if field n2 is set (has been assigned a value) and false otherwise */
    346     public boolean isSetN2() {
    347       return __isset_bit_vector.get(__N2_ISSET_ID);
    348     }
    349 
    350     public void setN2IsSet(boolean value) {
    351       __isset_bit_vector.set(__N2_ISSET_ID, value);
    352     }
    353 
    354     public void setFieldValue(_Fields field, Object value) {
    355       switch (field) {
    356       case N1:
    357         if (value == null) {
    358           unsetN1();
    359         } else {
    360           setN1((Integer)value);
    361         }
    362         break;
    363 
    364       case N2:
    365         if (value == null) {
    366           unsetN2();
    367         } else {
    368           setN2((Integer)value);
    369         }
    370         break;
    371 
    372       }
    373     }
    374 
    375     public Object getFieldValue(_Fields field) {
    376       switch (field) {
    377       case N1:
    378         return Integer.valueOf(getN1());
    379 
    380       case N2:
    381         return Integer.valueOf(getN2());
    382 
    383       }
    384       throw new IllegalStateException();
    385     }
    386 
    387     /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    388     public boolean isSet(_Fields field) {
    389       if (field == null) {
    390         throw new IllegalArgumentException();
    391       }
    392 
    393       switch (field) {
    394       case N1:
    395         return isSetN1();
    396       case N2:
    397         return isSetN2();
    398       }
    399       throw new IllegalStateException();
    400     }
    401 
    402     @Override
    403     public boolean equals(Object that) {
    404       if (that == null)
    405         return false;
    406       if (that instanceof add_args)
    407         return this.equals((add_args)that);
    408       return false;
    409     }
    410 
    411     public boolean equals(add_args that) {
    412       if (that == null)
    413         return false;
    414 
    415       boolean this_present_n1 = true;
    416       boolean that_present_n1 = true;
    417       if (this_present_n1 || that_present_n1) {
    418         if (!(this_present_n1 && that_present_n1))
    419           return false;
    420         if (this.n1 != that.n1)
    421           return false;
    422       }
    423 
    424       boolean this_present_n2 = true;
    425       boolean that_present_n2 = true;
    426       if (this_present_n2 || that_present_n2) {
    427         if (!(this_present_n2 && that_present_n2))
    428           return false;
    429         if (this.n2 != that.n2)
    430           return false;
    431       }
    432 
    433       return true;
    434     }
    435 
    436     @Override
    437     public int hashCode() {
    438       return 0;
    439     }
    440 
    441     public int compareTo(add_args other) {
    442       if (!getClass().equals(other.getClass())) {
    443         return getClass().getName().compareTo(other.getClass().getName());
    444       }
    445 
    446       int lastComparison = 0;
    447       add_args typedOther = (add_args)other;
    448 
    449       lastComparison = Boolean.valueOf(isSetN1()).compareTo(typedOther.isSetN1());
    450       if (lastComparison != 0) {
    451         return lastComparison;
    452       }
    453       if (isSetN1()) {
    454         lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.n1, typedOther.n1);
    455         if (lastComparison != 0) {
    456           return lastComparison;
    457         }
    458       }
    459       lastComparison = Boolean.valueOf(isSetN2()).compareTo(typedOther.isSetN2());
    460       if (lastComparison != 0) {
    461         return lastComparison;
    462       }
    463       if (isSetN2()) {
    464         lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.n2, typedOther.n2);
    465         if (lastComparison != 0) {
    466           return lastComparison;
    467         }
    468       }
    469       return 0;
    470     }
    471 
    472     public _Fields fieldForId(int fieldId) {
    473       return _Fields.findByThriftId(fieldId);
    474     }
    475 
    476     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    477       schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    478     }
    479 
    480     public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    481       schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    482     }
    483 
    484     @Override
    485     public String toString() {
    486       StringBuilder sb = new StringBuilder("add_args(");
    487       boolean first = true;
    488 
    489       sb.append("n1:");
    490       sb.append(this.n1);
    491       first = false;
    492       if (!first) sb.append(", ");
    493       sb.append("n2:");
    494       sb.append(this.n2);
    495       first = false;
    496       sb.append(")");
    497       return sb.toString();
    498     }
    499 
    500     public void validate() throws org.apache.thrift.TException {
    501       // check for required fields
    502     }
    503 
    504     private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    505       try {
    506         write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    507       } catch (org.apache.thrift.TException te) {
    508         throw new java.io.IOException(te);
    509       }
    510     }
    511 
    512     private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    513       try {
    514         // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
    515         __isset_bit_vector = new BitSet(1);
    516         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    517       } catch (org.apache.thrift.TException te) {
    518         throw new java.io.IOException(te);
    519       }
    520     }
    521 
    522     private static class add_argsStandardSchemeFactory implements SchemeFactory {
    523       public add_argsStandardScheme getScheme() {
    524         return new add_argsStandardScheme();
    525       }
    526     }
    527 
    528     private static class add_argsStandardScheme extends StandardScheme<add_args> {
    529 
    530       public void read(org.apache.thrift.protocol.TProtocol iprot, add_args struct) throws org.apache.thrift.TException {
    531         org.apache.thrift.protocol.TField schemeField;
    532         iprot.readStructBegin();
    533         while (true)
    534         {
    535           schemeField = iprot.readFieldBegin();
    536           if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
    537             break;
    538           }
    539           switch (schemeField.id) {
    540             case 1: // N1
    541               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
    542                 struct.n1 = iprot.readI32();
    543                 struct.setN1IsSet(true);
    544               } else { 
    545                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    546               }
    547               break;
    548             case 2: // N2
    549               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
    550                 struct.n2 = iprot.readI32();
    551                 struct.setN2IsSet(true);
    552               } else { 
    553                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    554               }
    555               break;
    556             default:
    557               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    558           }
    559           iprot.readFieldEnd();
    560         }
    561         iprot.readStructEnd();
    562 
    563         // check for required fields of primitive type, which can't be checked in the validate method
    564         struct.validate();
    565       }
    566 
    567       public void write(org.apache.thrift.protocol.TProtocol oprot, add_args struct) throws org.apache.thrift.TException {
    568         struct.validate();
    569 
    570         oprot.writeStructBegin(STRUCT_DESC);
    571         oprot.writeFieldBegin(N1_FIELD_DESC);
    572         oprot.writeI32(struct.n1);
    573         oprot.writeFieldEnd();
    574         oprot.writeFieldBegin(N2_FIELD_DESC);
    575         oprot.writeI32(struct.n2);
    576         oprot.writeFieldEnd();
    577         oprot.writeFieldStop();
    578         oprot.writeStructEnd();
    579       }
    580 
    581     }
    582 
    583     private static class add_argsTupleSchemeFactory implements SchemeFactory {
    584       public add_argsTupleScheme getScheme() {
    585         return new add_argsTupleScheme();
    586       }
    587     }
    588 
    589     private static class add_argsTupleScheme extends TupleScheme<add_args> {
    590 
    591       @Override
    592       public void write(org.apache.thrift.protocol.TProtocol prot, add_args struct) throws org.apache.thrift.TException {
    593         TTupleProtocol oprot = (TTupleProtocol) prot;
    594         BitSet optionals = new BitSet();
    595         if (struct.isSetN1()) {
    596           optionals.set(0);
    597         }
    598         if (struct.isSetN2()) {
    599           optionals.set(1);
    600         }
    601         oprot.writeBitSet(optionals, 2);
    602         if (struct.isSetN1()) {
    603           oprot.writeI32(struct.n1);
    604         }
    605         if (struct.isSetN2()) {
    606           oprot.writeI32(struct.n2);
    607         }
    608       }
    609 
    610       @Override
    611       public void read(org.apache.thrift.protocol.TProtocol prot, add_args struct) throws org.apache.thrift.TException {
    612         TTupleProtocol iprot = (TTupleProtocol) prot;
    613         BitSet incoming = iprot.readBitSet(2);
    614         if (incoming.get(0)) {
    615           struct.n1 = iprot.readI32();
    616           struct.setN1IsSet(true);
    617         }
    618         if (incoming.get(1)) {
    619           struct.n2 = iprot.readI32();
    620           struct.setN2IsSet(true);
    621         }
    622       }
    623     }
    624 
    625   }
    626 
    627   public static class add_result implements org.apache.thrift.TBase<add_result, add_result._Fields>, java.io.Serializable, Cloneable   {
    628     private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("add_result");
    629 
    630     private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
    631 
    632     private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    633     static {
    634       schemes.put(StandardScheme.class, new add_resultStandardSchemeFactory());
    635       schemes.put(TupleScheme.class, new add_resultTupleSchemeFactory());
    636     }
    637 
    638     public int success; // required
    639 
    640     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    641     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    642       SUCCESS((short)0, "success");
    643 
    644       private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
    645 
    646       static {
    647         for (_Fields field : EnumSet.allOf(_Fields.class)) {
    648           byName.put(field.getFieldName(), field);
    649         }
    650       }
    651 
    652       /**
    653        * Find the _Fields constant that matches fieldId, or null if its not found.
    654        */
    655       public static _Fields findByThriftId(int fieldId) {
    656         switch(fieldId) {
    657           case 0: // SUCCESS
    658             return SUCCESS;
    659           default:
    660             return null;
    661         }
    662       }
    663 
    664       /**
    665        * Find the _Fields constant that matches fieldId, throwing an exception
    666        * if it is not found.
    667        */
    668       public static _Fields findByThriftIdOrThrow(int fieldId) {
    669         _Fields fields = findByThriftId(fieldId);
    670         if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
    671         return fields;
    672       }
    673 
    674       /**
    675        * Find the _Fields constant that matches name, or null if its not found.
    676        */
    677       public static _Fields findByName(String name) {
    678         return byName.get(name);
    679       }
    680 
    681       private final short _thriftId;
    682       private final String _fieldName;
    683 
    684       _Fields(short thriftId, String fieldName) {
    685         _thriftId = thriftId;
    686         _fieldName = fieldName;
    687       }
    688 
    689       public short getThriftFieldId() {
    690         return _thriftId;
    691       }
    692 
    693       public String getFieldName() {
    694         return _fieldName;
    695       }
    696     }
    697 
    698     // isset id assignments
    699     private static final int __SUCCESS_ISSET_ID = 0;
    700     private BitSet __isset_bit_vector = new BitSet(1);
    701     public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    702     static {
    703       Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    704       tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
    705           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "int")));
    706       metaDataMap = Collections.unmodifiableMap(tmpMap);
    707       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(add_result.class, metaDataMap);
    708     }
    709 
    710     public add_result() {
    711     }
    712 
    713     public add_result(
    714       int success)
    715     {
    716       this();
    717       this.success = success;
    718       setSuccessIsSet(true);
    719     }
    720 
    721     /**
    722      * Performs a deep copy on <i>other</i>.
    723      */
    724     public add_result(add_result other) {
    725       __isset_bit_vector.clear();
    726       __isset_bit_vector.or(other.__isset_bit_vector);
    727       this.success = other.success;
    728     }
    729 
    730     public add_result deepCopy() {
    731       return new add_result(this);
    732     }
    733 
    734     @Override
    735     public void clear() {
    736       setSuccessIsSet(false);
    737       this.success = 0;
    738     }
    739 
    740     public int getSuccess() {
    741       return this.success;
    742     }
    743 
    744     public add_result setSuccess(int success) {
    745       this.success = success;
    746       setSuccessIsSet(true);
    747       return this;
    748     }
    749 
    750     public void unsetSuccess() {
    751       __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
    752     }
    753 
    754     /** Returns true if field success is set (has been assigned a value) and false otherwise */
    755     public boolean isSetSuccess() {
    756       return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
    757     }
    758 
    759     public void setSuccessIsSet(boolean value) {
    760       __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
    761     }
    762 
    763     public void setFieldValue(_Fields field, Object value) {
    764       switch (field) {
    765       case SUCCESS:
    766         if (value == null) {
    767           unsetSuccess();
    768         } else {
    769           setSuccess((Integer)value);
    770         }
    771         break;
    772 
    773       }
    774     }
    775 
    776     public Object getFieldValue(_Fields field) {
    777       switch (field) {
    778       case SUCCESS:
    779         return Integer.valueOf(getSuccess());
    780 
    781       }
    782       throw new IllegalStateException();
    783     }
    784 
    785     /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    786     public boolean isSet(_Fields field) {
    787       if (field == null) {
    788         throw new IllegalArgumentException();
    789       }
    790 
    791       switch (field) {
    792       case SUCCESS:
    793         return isSetSuccess();
    794       }
    795       throw new IllegalStateException();
    796     }
    797 
    798     @Override
    799     public boolean equals(Object that) {
    800       if (that == null)
    801         return false;
    802       if (that instanceof add_result)
    803         return this.equals((add_result)that);
    804       return false;
    805     }
    806 
    807     public boolean equals(add_result that) {
    808       if (that == null)
    809         return false;
    810 
    811       boolean this_present_success = true;
    812       boolean that_present_success = true;
    813       if (this_present_success || that_present_success) {
    814         if (!(this_present_success && that_present_success))
    815           return false;
    816         if (this.success != that.success)
    817           return false;
    818       }
    819 
    820       return true;
    821     }
    822 
    823     @Override
    824     public int hashCode() {
    825       return 0;
    826     }
    827 
    828     public int compareTo(add_result other) {
    829       if (!getClass().equals(other.getClass())) {
    830         return getClass().getName().compareTo(other.getClass().getName());
    831       }
    832 
    833       int lastComparison = 0;
    834       add_result typedOther = (add_result)other;
    835 
    836       lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
    837       if (lastComparison != 0) {
    838         return lastComparison;
    839       }
    840       if (isSetSuccess()) {
    841         lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
    842         if (lastComparison != 0) {
    843           return lastComparison;
    844         }
    845       }
    846       return 0;
    847     }
    848 
    849     public _Fields fieldForId(int fieldId) {
    850       return _Fields.findByThriftId(fieldId);
    851     }
    852 
    853     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    854       schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    855     }
    856 
    857     public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    858       schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    859       }
    860 
    861     @Override
    862     public String toString() {
    863       StringBuilder sb = new StringBuilder("add_result(");
    864       boolean first = true;
    865 
    866       sb.append("success:");
    867       sb.append(this.success);
    868       first = false;
    869       sb.append(")");
    870       return sb.toString();
    871     }
    872 
    873     public void validate() throws org.apache.thrift.TException {
    874       // check for required fields
    875     }
    876 
    877     private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    878       try {
    879         write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    880       } catch (org.apache.thrift.TException te) {
    881         throw new java.io.IOException(te);
    882       }
    883     }
    884 
    885     private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    886       try {
    887         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    888       } catch (org.apache.thrift.TException te) {
    889         throw new java.io.IOException(te);
    890       }
    891     }
    892 
    893     private static class add_resultStandardSchemeFactory implements SchemeFactory {
    894       public add_resultStandardScheme getScheme() {
    895         return new add_resultStandardScheme();
    896       }
    897     }
    898 
    899     private static class add_resultStandardScheme extends StandardScheme<add_result> {
    900 
    901       public void read(org.apache.thrift.protocol.TProtocol iprot, add_result struct) throws org.apache.thrift.TException {
    902         org.apache.thrift.protocol.TField schemeField;
    903         iprot.readStructBegin();
    904         while (true)
    905         {
    906           schemeField = iprot.readFieldBegin();
    907           if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
    908             break;
    909           }
    910           switch (schemeField.id) {
    911             case 0: // SUCCESS
    912               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
    913                 struct.success = iprot.readI32();
    914                 struct.setSuccessIsSet(true);
    915               } else { 
    916                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    917               }
    918               break;
    919             default:
    920               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    921           }
    922           iprot.readFieldEnd();
    923         }
    924         iprot.readStructEnd();
    925 
    926         // check for required fields of primitive type, which can't be checked in the validate method
    927         struct.validate();
    928       }
    929 
    930       public void write(org.apache.thrift.protocol.TProtocol oprot, add_result struct) throws org.apache.thrift.TException {
    931         struct.validate();
    932 
    933         oprot.writeStructBegin(STRUCT_DESC);
    934         oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
    935         oprot.writeI32(struct.success);
    936         oprot.writeFieldEnd();
    937         oprot.writeFieldStop();
    938         oprot.writeStructEnd();
    939       }
    940 
    941     }
    942 
    943     private static class add_resultTupleSchemeFactory implements SchemeFactory {
    944       public add_resultTupleScheme getScheme() {
    945         return new add_resultTupleScheme();
    946       }
    947     }
    948 
    949     private static class add_resultTupleScheme extends TupleScheme<add_result> {
    950 
    951       @Override
    952       public void write(org.apache.thrift.protocol.TProtocol prot, add_result struct) throws org.apache.thrift.TException {
    953         TTupleProtocol oprot = (TTupleProtocol) prot;
    954         BitSet optionals = new BitSet();
    955         if (struct.isSetSuccess()) {
    956           optionals.set(0);
    957         }
    958         oprot.writeBitSet(optionals, 1);
    959         if (struct.isSetSuccess()) {
    960           oprot.writeI32(struct.success);
    961         }
    962       }
    963 
    964       @Override
    965       public void read(org.apache.thrift.protocol.TProtocol prot, add_result struct) throws org.apache.thrift.TException {
    966         TTupleProtocol iprot = (TTupleProtocol) prot;
    967         BitSet incoming = iprot.readBitSet(1);
    968         if (incoming.get(0)) {
    969           struct.success = iprot.readI32();
    970           struct.setSuccessIsSet(true);
    971         }
    972       }
    973     }
    974 
    975   }
    976 
    977 }
    复制代码

    3.写一个service handler(也可以叫serviceImpl)

    Service handler 类必须实现 AdditionService.Iface接口。AdditionServiceHandler.java代码如下:

    复制代码
     1 import org.apache.thrift.TException;
     2 
     3 
     4 public class AdditionServiceHandler implements AdditionService.Iface{
     5 
     6     @Override
     7     public int add(int n1, int n2) throws TException {
     8         // TODO Auto-generated method stub
     9         return n1 + n2;
    10     }
    11     
    12 
    13 }
    复制代码

    4.写一个简单的服务器

    下面的示例代码是一个简单的Thrift服务器。可以看到下面的代码中有一段是注释了的,可以去掉注释来启用多线程服务器。
    示例服务器(MyServer.java)

    复制代码
     1 import org.apache.thrift.transport.TServerSocket;  
     2 import org.apache.thrift.transport.TServerTransport;  
     3 import org.apache.thrift.server.TServer;  
     4 import org.apache.thrift.server.TServer.Args;  
     5 import org.apache.thrift.server.TSimpleServer;  
     6    
     7 public class MyServer {  
     8    
     9  public static void StartsimpleServer(AdditionService.Processor<AdditionServiceHandler> processor) {  
    10   try {  
    11    TServerTransport serverTransport = new TServerSocket(9090);  
    12    TServer server = new TSimpleServer(  
    13      new Args(serverTransport).processor(processor));  
    14    
    15    // Use this for a multithreaded server  
    16    // TServer server = new TThreadPoolServer(new  
    17    // TThreadPoolServer.Args(serverTransport).processor(processor));  
    18    
    19    System.out.println("Starting the simple server...");  
    20    server.serve();  
    21   } catch (Exception e) {  
    22    e.printStackTrace();  
    23   }  
    24  }  
    25     
    26  public static void main(String[] args) {  
    27   StartsimpleServer(new AdditionService.Processor<AdditionServiceHandler>(new AdditionServiceHandler()));  
    28  }  
    29    
    30 }
    复制代码

    5.写一个简单的客户端

    下面的例子是一个使用Java写的客户端短使用AdditionService的服务。

    复制代码
     1 import org.apache.thrift.TException;  
     2 import org.apache.thrift.protocol.TBinaryProtocol;  
     3 import org.apache.thrift.protocol.TProtocol;  
     4 import org.apache.thrift.transport.TSocket;  
     5 import org.apache.thrift.transport.TTransport;  
     6 import org.apache.thrift.transport.TTransportException;  
     7    
     8 public class AdditionClient {  
     9    
    10  public static void main(String[] args) {  
    11    
    12   try {  
    13    TTransport transport;  
    14    
    15    transport = new TSocket("localhost", 9090);  
    16    transport.open();  
    17    
    18    TProtocol protocol = new TBinaryProtocol(transport);  
    19    AdditionService.Client client = new AdditionService.Client(protocol);  
    20    
    21    System.out.println(client.add(100, 200));  
    22    
    23    transport.close();  
    24   } catch (TTransportException e) {  
    25    e.printStackTrace();  
    26   } catch (TException x) {  
    27    x.printStackTrace();  
    28   }  
    29  }  
    30    
    31 }
    复制代码

    运行服务端代码(MyServer.java)将会看到下面的输出。

    Starting the simple server...

    然后运行客户端代码(AdditionClient.java),将会看到如下输出。

    300

    Thrift主要由五个部分组成:

    系统类型以及IDL编译器:负责由用户给定的IDL文件生成相应语言的接口代码。

    Tprotocol:实现RPC的协议层,可以选择多种不同的对象串行化方式,如JSON,Binary.

    Transport:实现RPC的传输层,同样可以选择不同的传输层实现,如socket,非阻塞的socket等。

    Tprocessor:作为协议层和用户提供的服务实现之间的纽带,负责调用服务实现的接口。

    Tserver:聚合TProtocol,TTransport和TProcessor几个对象。

    上述的这5个部件都是在 Thrift 的源代码中通过为不同语言提供库来实现的,这些库的代码在 Thrift 源码目录的 lib 目录下面,在使用 Thrift 之前需要先熟悉与自己的语言对应的库提供的接口。

    数据类型

    Thrift 脚本可定义的数据类型包括以下几种类型:

    • 基本类型:
    • bool:布尔值,true 或 false,对应 Java 的 boolean
    • byte:8 位有符号整数,对应 Java 的 byte
    • i16:16 位有符号整数,对应 Java 的 short
    • i32:32 位有符号整数,对应 Java 的 int
    • i64:64 位有符号整数,对应 Java 的 long
    • double:64 位浮点数,对应 Java 的 double
    • string:未知编码文本或二进制字符串,对应 Java 的 String
    • 结构体类型:
      • struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
    • 容器类型:
      • list:对应 Java 的 ArrayList
      • set:对应 Java 的 HashSet
      • map:对应 Java 的 HashMap
    • 异常类型:
      • exception:对应 Java 的 Exception
    • 服务类型:
      • service:对应服务的类

    协议

    Thrift 可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本 (text) 和二进制 (binary) 传输协议,为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目 / 产品中的实际需求。常用协议有以下几种:

    TBinaryProtocol —— 二进制编码格式进行数据传输

    TCompactProtocol —— 高效率的、密集的二进制编码格式进行数据传输

    TJSONProtocol —— 使用 JSON 的数据编码协议进行数据传输

    TSimpleJSONProtocol —— 只提供 JSON 只写的协议,适用于通过脚本语言解析

    传输层

    常用的传输层有以下几种:

    1.TSocket —— 使用阻塞式 I/O 进行传输,是最常见的模式

    2.TFramedTransport —— 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO

    若使用 TFramedTransport 传输层,其服务器必须修改为非阻塞的服务类型,TNonblockingServerTransport 类是构建非阻塞 socket 的抽象类,TNonblockingServerSocket 类继承 TNonblockingServerTransport

    3.TNonblockingTransport —— 使用非阻塞方式,用于构建异步客户端

    服务端类型

    常见的服务端类型有以下几种:

    1.TSimpleServer —— 单线程服务器端使用标准的阻塞式 I/O

    2.TThreadPoolServer —— 多线程服务器端使用标准的阻塞式 I/O

    3.TNonblockingServer —— 多线程服务器端使用非阻塞式 I/O

    本文参考以及引用:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/

                             http://my.oschina.net/jack230230/blog/66041

    做人第一,做学问第二。
  • 相关阅读:
    hdu 5723 Abandoned country 最小生成树 期望
    OpenJ_POJ C16G Challenge Your Template 迪杰斯特拉
    OpenJ_POJ C16D Extracurricular Sports 打表找规律
    OpenJ_POJ C16B Robot Game 打表找规律
    CCCC 成都信息工程大学游记
    UVALive 6893 The Big Painting hash
    UVALive 6889 City Park 并查集
    UVALive 6888 Ricochet Robots bfs
    UVALive 6886 Golf Bot FFT
    UVALive 6885 Flowery Trails 最短路
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8526534.html
Copyright © 2011-2022 走看看