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

    做人第一,做学问第二。
  • 相关阅读:
    Jmeter入门--参数化、集合点
    Jmeter入门--断言(检查点)
    Jmeter入门--性能测试实战
    Jmeter入门--元件作用域和执行顺序
    Jmeter入门--Badboy使用教程(转)
    Jmeter入门--脚本录制
    Jmeter入门--可执行元件
    Jmeter入门--工具组成和线程组
    Jmeter入门--安装教程
    mac设置python及pip环境变量及安装mysqlclient
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8526534.html
Copyright © 2011-2022 走看看