zoukankan      html  css  js  c++  java
  • Netty学习——Thrift的入门使用

    Netty学习——Thrift的入门使用

    希望你能够,了解并使用它。因为它是一个效率很高的框架

    官网地址:http://thrift.apache.org/


    1.Thrift数据类型

     一门技术如果需要支持多门语言,那么这门技术的字符类型肯定会很少,因为数据类型需要是多门语言的交集。Thrift 不支持无符号类型,因为很多编程语言不存在无符号类型,如java

    • byte:有符号字节
    • i16:16位有符号整数
    • i32:32位有符号整数
    • i64:64位有符号整数
    • doubule: 64位的浮点数
    • string:字符串

     2.thrift 容器类型 结构体(Struts)特别知名的一个RPC框架。

    Thrift应该是一个首选两个系统之间的调用
    集合中的元素可以出了service之外的任何类型,包括exception
    Thrift容器类型

    • list:一系列由T类型的数据组成的有序列表,元素可以重复
    • set:一系列由T类型的元素组成的无需集合,元素不可重复
    • map:一个字典结构,key为K类型,value为V类型,相当于java中的HashMap

    3.Thrift工作原理

    如何实现多语言之间的通信?
    数据传输使用socket(多语言支持),数据再以特定的格式(如string)发送,接收方语言进行解码
    定义thrift的文件,由thrift文件(IDL)生成双方语言的接口,model,在生成的model以及接口中会有解码编码的代码
    Thrift IDL文件 demo (struct相当于protobuf的message)

    4.thrift类型

    • 结构体(Struct)
    • 枚举(enum)
    • 异常(exception)
    • 服务(service):若干个方法的集合,相当于java中创建的interface一样
    • 常量(const)
    • 类型定义:Thrift支持C++一样的typedef定义:
      • typedef i32 int
      • typedef i64 long
    • 命名空间格式:namespace 语言名字 路径
    • 文件包含: include “global.thrift” 相当于C的include和java中的import
    • 注释: #3 // /**/
    • 可选和必选: required , optional (和PB一样,尽量都使用optional)

     使用整体流程步骤:1.写thrift文件,生成java代码     2.程序中进行调用

    1.写thrift文件,生成java代码

      thrift , idea中也有编写插件,有代码提示和语法高亮,但是我这里revert了,没有语法提示。尴尬

    namespace java thrift.generated
    
    typedef i16 short
    typedef i32 int
    typedef i64 long
    typedef string String
    typedef bool boolean
    
    struct Person{
        1:optional String username,
        2:optional int age,
        3:optional boolean marrid
    }
    
    exception DataException{
        1:optional String message,
        2:optional String callStack,
        3:optional String date
    }
    
    service PersonService{
        Person getPersonByUsername(1:required String username) throws(1:DataException dataException),
    
        void savePerson(1:reuqired Person person) throws(1:DataException dataException)
    }

    生成代码: thrift --gen java data.thrift  (前提,已经安装好thrift,如果没安装,请查看我的文章 - thrift安装教程) 

     如果没有提示,代表执行完成,查看你的目录,会多一个 gen-java目录

     我是将这些文件移动到我的java文件目录下了。

    但是看起来有很多错,没关系,这是因为我们还没有引用相关的jar包

    在 search.maven.org 找到需要的jar包:"org.apache.thrift:libthrift-as3:0.13.0"

    dependencies {
        compile(
                "io.netty:netty-all:4.1.43.Final",
                "com.google.protobuf:protobuf-java-util:3.11.0",
                "com.google.protobuf:protobuf-java:3.11.0",
                "org.apache.thrift:libthrift-as3:0.13.0"
        )
    }

    报错就消失了

    2.程序中进行调用

    实现类:继承上面自动生成的接口  (这个实现类,客户端和服务器端都能用)

    package com.dawa.thrift;
    
    import org.apache.thrift.TException;
    import thrift.generated.DataException;
    import thrift.generated.PersionService;
    import thrift.generated.Person;
    
    /**
     * @Title: PersonServiceImpl
     * @Author: 大娃
     * @Date: 2019/12/4 15:29
     * @Description:
     */
    public class PersonServiceImpl implements PersionService.Iface {
        @Override
        public Person getPersonByUsername(String username) throws DataException, TException {
            System.out.println("GET Client Param"+username);
    
            Person person = new Person();
            person.setUsername("大娃");
            person.setAge(20);
            person.setMarried(false);
            return person;
        }
    
        @Override
        public void savePerson(Person person) throws DataException, TException {
            System.out.println("Got Client Param:");
            System.out.println(person.getUsername());
            System.out.println(person.getAge());
            System.out.println(person.isMarried());
        }
    }

    服务器端代码

    package com.dawa.thrift;
    
    import org.apache.thrift.TProcessorFactory;
    import org.apache.thrift.protocol.TCompactProtocol;
    import org.apache.thrift.server.THsHaServer;
    import org.apache.thrift.server.TServer;
    import org.apache.thrift.transport.TFramedTransport;
    import org.apache.thrift.transport.TNonblockingServerSocket;
    import thrift.generated.PersionService;
    
    /**
     * @Title: ThriftServer
     * @Author: 大娃
     * @Date: 2019/12/4 15:32
     * @Description:
     */
    public class ThriftServer {
        public static void main(String[] args) throws Exception {
            TNonblockingServerSocket socket = new TNonblockingServerSocket(8899);
           //arg 构建时需要的一系列信息
            THsHaServer.Args arg = new THsHaServer.Args(socket).minWorkerThreads(2).maxWorkerThreads(4);
            PersionService.Processor<PersonServiceImpl> processor = new PersionService.Processor<>(new PersonServiceImpl());
            arg.protocolFactory(new TCompactProtocol.Factory());
            arg.transportFactory(new TFramedTransport.Factory());
            arg.processorFactory(new TProcessorFactory(processor));
    
            //启动Server
            TServer server = new THsHaServer(arg);
            System.out.println("Thrift Server Started!");
            server.serve();
    
        }
    }

    客户端代码

    package com.dawa.thrift;
    
    import com.sun.security.ntlm.Server;
    import org.apache.thrift.protocol.TCompactProtocol;
    import org.apache.thrift.protocol.TProtocol;
    import org.apache.thrift.transport.TFramedTransport;
    import org.apache.thrift.transport.TSocket;
    import org.apache.thrift.transport.TTransport;
    import thrift.generated.PersionService;
    import thrift.generated.Person;
    
    /**
     * @Title: ThriftClient
     * @Author: 大娃
     * @Date: 2019/12/4 15:38
     * @Description:
     */
    public class ThriftClient {
        public static void main(String[] args) {
            TTransport tTransport = new TFramedTransport(new TSocket("localhost",8899),600);
            TProtocol protocol = new TCompactProtocol(tTransport);
            PersionService.Client client = new PersionService.Client(protocol);
    
            try {
                //打开socket
                tTransport.open();
                //调用方法
                Person person = client.getPersonByUsername("大娃");
                System.out.println(person.getUsername());
                System.out.println(person.getAge());
                System.out.println(person.isMarried());
    
                System.out.println("-----------------");
                Person person1 = new Person();
                person1.setUsername("二娃");
                person1.setAge(29);
                person1.setMarried(false);
                //调用保存方法
                client.savePerson(person1);
    
    
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }finally {
                tTransport.close();
            }
        }
    }

    运行客户端,再运行服务器端,运行成功,连接成功。数据传输成功,方法也能够前后端都调用
    success:看似是本地调用,实际是通过socket,RPC的方式实现的远程调用。

     

  • 相关阅读:
    SRM 551 div2
    HDU_4390 Number Sequence (容斥原理)
    HDU 多校联合第五场
    HDU 多校联合第六场
    POJ 2057 The Lost House (经典树形dp)
    Lucas定理
    HDU 4385 Moving Bricks (状态dp+贪心)
    HDU 多校联合第三场
    当最短路变成二维 _!
    POJ 1848 (一道不错的树形dp)
  • 原文地址:https://www.cnblogs.com/bigbaby/p/11983548.html
Copyright © 2011-2022 走看看