Java中使用Thrift

Java中使用Thrift

Thrift建立(server端)

定义一个thrift接口:

java 复制代码
service ThriftService {
    void myFunc();
}

通过 thrift compiler 生成 java 代码

java 复制代码
thrift --gen java ThriftService.thrift

生成了Thrift的接口类:

java 复制代码
public class ThriftService {
	// 同步和异步调用接口
    public interface Iface {...}
    public interface AsyncIface {...}
    
    // 接口的实现类(同步和异步)
    public static class Client {...}
    public static class AsyncClient {...}   
}

实现server端:

java 复制代码
public class Server {
    public static class ThriftServiceImpl implements ThriftService.Iface{
 
        @Override
        public String myFunc(String name) throws TException {
            return "My Thrift Function";
        }
    }
 
    public static void main(String[] args) throws TTransportException {
        // 获取实现
        ThriftServiceImpl impl= new ThriftServiceImpl();
        // 接口与实现类的绑定关系在这里完成
        HelloWorldService.Processor<ThriftServiceImpl> processor = new ThriftService.Processor<ThriftServiceImpl>(impl);
        // 构建服务器
        TServerTransport serverTransport = new TServerSocket(9090);
        TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
        server.serve();
    }
}

Thrift调用(client端)

client端可以直接调用接口,二不用关心具体的实现类。

1 直接建立thrift通信

java 复制代码
public class Client {
    public static void main(String[] args) throws TException {
        TTransport transport = new TSocket("localhost", 9090);
        transport.open();
        TProtocol protocol = new TBinaryProtocol(transport);
        ThriftService.Client client = new ThriftService.Client(protocol);
		client.myFunc();
        transport.close();
    }
}

或者:

java 复制代码
	TFastFramedTransport transport = new TFastFramedTransport(new TSocket(host, port));
	TBinaryProtocol protocol = new TBinaryProtocol(transport);
	SimpleSerice.Client client = new SimpleService.Client(protocol);
	try {
	    transport.open();
	    client.myFunc();
	} finally {
	    transport.close();
	}

通信层协议,使用TTransport接口来描述,Thrift 提供了几种 transport 类供使用:

  • TSocket:BIO
  • TFramedTransport:NIO
  • TMemoryTransport:内存I/O

需要注意的是,transport 客户端要和服务端对应,比如如果要对 NIO 模型的服务端进行调研,transport 就必须使用 TFramedTransport或TFastFramedTransport。

传输层协议,引用 transport 并提供 thrift 的序列化协议,Thrift 也提供了几种常用的传输协议:

  • TBinaryProtocol:二进制协议
  • TCompactProtocol:压缩格式
  • TJSONProtocol:JSON 协议

2 使用JDK动态代理

首先创建代理类,这里只需要引用 thrift 接口中的 Service 类,并通过引用发现内部 Client 类:

java 复制代码
public class ThriftClientProxy implements InvocationHandler {

    private Class clazz;
    private Class clientClazz;
    private String host;
    private int port;

    public Object newInstance(Class clazz, String host, int port) {
        this.clazz = clazz;
        this.host = host;
        this.port = port;
        this.clientClazz = Class.forName(classs.getName() + "$Client");

        return Proxy.newProxyInstance(
            getClass().getClassLoader(),
            clientClazz.getInterfaces(),
            this
        );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        TFastFramedTransport transport = new TFastFramedTransport(new TSocket(host, port));
        TBinaryProtocol protocol = new TBinaryProtocol(transport);
        Class[] classes = {TProtocol.class};
        try {
            transport.open();
            return method.invoke(clientClazz.getConstructor(classes).newInstance(protocol), args);
        }
        finally {
            transport.close();
        }
    }
}

之后将相应的 Iface 注册到 IOC 容器中即可。

java 复制代码
@Configuration
public class ThriftClientConfiguration {

    @Value("${simple.service.host}")
    private String host;

    @Value("${simple.service.port}")
    private int port;

    @Bean
    public SimpleService.Iface thriftClient() {
        return (SimpleService.Iface) new ThriftClientProxy().newInstance(SimpleService.class, host, port);
    }
}

业务代码中只需要注入 SimpleService.Iface,并直接调用接口方法,而完全不需要关注内部逻辑实现。

相关推荐
生万千欢喜心几秒前
Linux 安装金蝶天燕中间件 AAS-V9.0.zip
java·linux
耿雨飞3 分钟前
Python 后端开发技术博客专栏 | 第 03 篇 面向对象编程进阶 -- 从 SOLID 原则到 Python 特色 OOP
开发语言·python·面向对象·oop
charlie1145141914 分钟前
嵌入式现代C++工程实践——第14篇:第二次重构 —— 模板登场,编译时绑定端口和引脚
开发语言·c++·stm32·安全·重构
源码站~6 分钟前
基于python的校园代跑(跑腿)系统
开发语言·python
BugShare7 分钟前
一个用 Rust 编写的、速度极快的 Python 包和项目管理器
开发语言·python·rust
耿雨飞12 分钟前
Python 后端开发技术博客专栏 | 第 04 篇 Python 内存管理与垃圾回收 -- 从引用计数到分代回收
开发语言·python·垃圾回收
雾岛听蓝14 分钟前
Qt 输入与多元素控件详解
开发语言·经验分享·笔记·qt
海兰15 分钟前
【第2篇-续】从零开始helloworld使用openAI通用模型的完整实现示例附源代码
java·人工智能·spring boot·alibaba·spring ai
ooseabiscuit16 分钟前
记录 idea 启动 tomcat 控制台输出乱码问题解决
java·tomcat·intellij-idea
执笔画流年呀17 分钟前
多线程及其特性
java·服务器·开发语言