zoukankan      html  css  js  c++  java
  • ubuntu下Thrift快速入门

    一、thrift简介

    二、thrift安装

    (1)安装一些必要库

    sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev

    对于其他系统,如centos、mac、windows,安装要求见下面官网教程:

    http://thrift.apache.org/docs/install/

    (2)下载

    http://thrift.apache.org/download 我下载的版本是0.9.1

    (3)解压安装

    解压后,进入根目录,输入:

    ./configure && make

    如果最后输出一个ERROR,说 "libcrypto required",可能是需要安装

    libssl - dev的包

    sudo apt-get install libssl-dev

    如果输入thrift   -version,提示说thrift-compiler没有安装,怎安装上。

    sudo apt-get install thrift-compiler

    安装完compiler后,就可以开始编写thrift文件了。

    三、thrift基本语法和架构

    1、Thrift基础架构

    Thrift 是一个服务端和客户端的架构体系,从我个人的感官上来看 Thrift 是一个类似XML-RPC+Java-to- IDL+Serialization Tools=Thrift 的东东,Thrift 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports),通过 IDL 脚本对传输数据的数据结构(struct) 和传输数据的业务逻辑(service)根据不同的运行环境快速的构建相应的代码,并且通过自己内部的序列化机制对传输的数据进行简化和压缩提高高并发、 大型系统中数据交互的成本,下图描绘了 Thrift 的整体架构,分为 6 个部分:

    (1).你的业务逻辑实现(You Code)

    (2).客户端和服务端对应的 Service

    (3).执行读写操作的计算结果

    (4).TProtocol

    (6).底层 I/O 通信

    图 中前面 3 个部分是 1.你通过 Thrift 脚本文件生成的代码,2.图中的褐色框部分是你

    根据生成代码构建的客户端和处理器的代码,3.图中红色的部分是 2 端产生的计算结

    果。从 TProtocol 下面 3 个部分是 Thrift 的传输体系和传输协议以及底层 I/O 通信,

    Thrift 并且提供 堵塞、非阻塞,单线程、多线程的模式运行在服务器上,还可以配合

    服务器/容器一起运行,可以和现有 JEE 服务器/Web 容器无缝的结合。

    2、数据类型

    A、Base Type :基本类型

    (1)bool:布尔类型(true或false)

    (2)byte:8位有符号整数

    (3)i16:16位有符号整数

    (4)i32:32位有符号整数

    (5)i64:64位有符号整数

    (6)double:64位浮点数

    (7)string:文本字符串,使用UTF-8编码

    B、Container:容器:如list、set、map

    C、Struct:结构体类型

    如下面的一个例子:

    struct People {

    1:string name;

    }

    struct和C里面的结构体很类似。

    D、Exception:异常类型

    E、Service:定义对象的接口和一系列方法

    如下面一个例子:

    service  DemoService {

    string getUserName(1:i32 id);

    i32 add(1:i32 num1, 2:i32 num2);

    }

    一个service对应一个类,里面是一些方法。

    如getUserName方法就是根据一个id返回一个字符串,add方法是对num1和num2进行求和。

    3、协议

    Thrift可以在kehudaun和服务端之间传输选择通信协议,协议总体上分为文本(text)和二进制(binary)传输协议。

    * TBinaryProtocol – 二进制编码格式进行数据传输。

    * TCompactProtocol – 这种协议非常有效的,使用 Variable-Length Quantity(VLQ) 编码对数据进行压缩。

    * TJSONProtocol – 使用 JSON 的数据编码协议进行数据传输。

    * TSimpleJSONProtocol – 这种节约只提供 JSON 只写的协议,适用于通过脚本语言解析

    * TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。

    4、传输层

    * TSocket- 使用堵塞式 I/O 进行传输,也是最常见的模式。

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

    * TFileTransport- 顾名思义按照文件的方式进程传输,虽然这种方式不提供 Java 的实现,但是实现起来非常简单。

    * TMemoryTransport- 使用内存 I/O,就好比 Java 中的 ByteArrayOutputStream实现。

    * TZlibTransport- 使用执行 zlib 压缩,不提供 Java 的实现。

    5、服务端类型

    * TSimpleServer - 单线程服务器端使用标准的堵塞式 I/O。

    * TThreadPoolServer - 多线程服务器端使用标准的堵塞式 I/O。

    * TNonblockingServer – 多线程服务器端使用非堵塞式 I/O,并且实现了 Java 中的NIO 通道。

    四、thrift简单例子

    1、创建thrift文件

    vim   demo.thrift
    namespace java com.demo
    
    service DemoService{
    
    //根据id获取用户名
    string getNameById(1:i32 id)
    
    }

    namespace在java里面就是对应package,这里 namespace   java  com.demo,第二个关键字表示使用的语言

    一个service会对应生成一个类文件

    2、编译创建代码

    thrift  -r   --gen  java  demo.thrift

    接着生成了一个gen-java文件夹,通过tree gen-java查看文件夹的结构:

    3、创建eclipse工程

    (1)创建一个java project,然后添加之前编译thrift生成的必要jar包,这里,由于我们使用的是java语言,就到

    /thrift-0.9.1/lib/java/build/lib和/thrift-0.9.1/lib/java/build/下添加jar包。

    (2)将前面生成的DemoService.java复制到工程里

    (3)创建服务端

    创建server的实现类:ServerImpl.java

    package com.server;
    
    import org.apache.thrift.TException;
    
    import com.demo.*;
    
    public class ServerImpl implements DemoService.Iface {
    
    
      @Override
      public String getNameById(int id) throws TException {
        
        System.out.println("Your username is wgc");
        return "wgc";
      }
    
    }

    创建Server启动类:Server.java

    package com.server;
    
    import org.apache.thrift.TProcessor;
    import org.apache.thrift.protocol.TBinaryProtocol;
    import org.apache.thrift.server.TServer;
    import org.apache.thrift.server.TSimpleServer;
    import org.apache.thrift.transport.TServerSocket;
    import org.apache.thrift.transport.TTransportException;
    
    import com.demo.DemoService;
     
    
    public class Server {
      
       public static final int SERVER_PORT = 8090;
    
       public void startServer() throws TTransportException{
            System.out.println("Server start ....");
          TProcessor tprocessor = new DemoService.Processor<DemoService.Iface>(new ServerImpl());
          TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
           TServer.Args tArgs = new TServer.Args(serverTransport);
               tArgs.processor(tprocessor);
               tArgs.protocolFactory(new TBinaryProtocol.Factory());
               TServer server = new TSimpleServer(tArgs);
               server.serve();
    
        }
       
      public static void main(String[] args) throws TTransportException {
        Server server = new Server();
        server.startServer();
    
      }
    
    }

    (4)创建客户端

    创建Client.java:

    package com.client;
    
    import org.apache.thrift.TException;
    import org.apache.thrift.protocol.TBinaryProtocol;
    import org.apache.thrift.protocol.TProtocol;
    import org.apache.thrift.transport.TSocket;
    import org.apache.thrift.transport.TTransport;
    
    import com.demo.DemoService;
     
    
    public class Client {
      
      public static final String SERVER_IP = "localhost";
       public static final int SERVER_PORT = 8090;
       public static final int TIMEOUT = 30000;
    
       public void startClient( ) throws TException {
         TTransport transport = null;
         
         transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
          // 协议要和服务端一致
          TProtocol protocol = new TBinaryProtocol(transport);
          // TProtocol protocol = new TCompactProtocol(transport);
          // TProtocol protocol = new TJSONProtocol(transport);
          DemoService.Client client = new DemoService.Client(protocol);
          transport.open();
          String result = client.getNameById(1);
     
     
        
      }
       
      public static void main(String[] args) throws TException {
        Client client = new Client();
        client.startClient();
    
      }
    
    }

    (5)测试程序

    先启动Server,再启动客户端,它会在终端输出:

    Server start ....

    Your username is wgc

    到这里,一个简单的客户端、服务端程序就实现了。

    (6)工程目录结构

    参考文献:

    (1) http://roclinux.cn/?p=3316

    (2) http://www.dataguru.cn/forum.php?mod=viewthread&tid=219377

    (3) http://wenku.baidu.com/link?url=x8Q7r1UtaFAu45HbP06pigiM_SmFTZbpQdAfk7fvp4--s70fWHBFQgte5pIgNpNJGlKOl3l2BvDthvBTCHsE3G3jfEQk5q3FT7bASItwrle




  • 相关阅读:
    How to: Display a List of Non-Persistent Objects in a Popup Dialog 如何:在弹出对话框中显示非持久化对象列表
    How to: Use XPO Upcasting in XAF 如何:在 XAF 中使用 XPO 强制转换
    How to: Use the Entity Framework Data Model Located in an External Assembly 如何:使用位于外部程序集中的EF数据模型
    How to: Use the Entity Framework Code First in XAF 如何:在 XAF 中使用EF CodeFirst
    How to: Supply Initial Data for the Entity Framework Data Model 如何:为EF数据模型提供初始数据
    How to: Calculate a Property Value Based on Values from a Detail Collection 如何:基于详细信息集合中的值计算属性值
    How to: Use the Entity Framework Model First in XAF 如何:在 XAF 中使用EF ModelFirst
    How to: Change the Format Used for the FullAddress and FullName Properties 如何:更改用于FullAddress和FullName属性的格式
    How to: Create a Business Model in the XPO Data Model Designer 如何:在 XPO 数据模型设计器中创建业务模型
    How to: Initialize Business Objects with Default Property Values in Entity Framework 如何:在EF中用默认属性值初始化业务对象
  • 原文地址:https://www.cnblogs.com/wxmarr/p/4597712.html
Copyright © 2011-2022 走看看