java thrift rpc框架_【Java】分布式RPC通信框架Apache Thrift 使用总结

命令行参数 -r 代表递归生成里面引用的其他文件, --gen 后面跟生成的目标语言,最后跟上thrift文件。

生成的Java文件里会有一个接口HelloService.Iface,这就是一个普通的Java Interface,服务端要提供该接口的实现,实现之前需要引用libthrift的jar包,比如我们这么实现:

package com.yuanwhy.service;

import org.apache.thrift.TException;

public class HelloServiceImpl implements HelloService.Iface {

@Override

public String sayHello(String name) throws TException {

return "Hello, " + name + "!";

}

}

这样,服务端就实现了服务的逻辑部分,但是要让别人在网络上真正可用,我们还得把这个服务发布出去,发布的方式就是借助Socket编程,监听一个对外服务的端口,这也是网络通讯的基本套路。利用Thrift提供的API,在HelloServiceProvider类中启动Thrift服务:

package com.yuanwhy.demo;

import com.yuanwhy.service.HelloService;

import com.yuanwhy.service.HelloServiceImpl;

import org.apache.thrift.TProcessor;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TSimpleServer;

import org.apache.thrift.transport.TServerSocket;

import org.apache.thrift.transport.TTransportException;

public class HelloServiceProvider {

/**

* 启动 Thrift 服务器

*

* @param args

*/

public static void main(String[] args) {

try {

// 设置服务端口为 7911

TServerSocket serverTransport = new TServerSocket(7911);

TProcessor processor = new HelloService.Processor(new HelloServiceImpl());

TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor));

System.out.println("Start server on port 7911...");

server.serve();

} catch (TTransportException e) {

e.printStackTrace();

}

}

}

运行main函数之后,服务端就会监听7911端口,开始对外提供sayHello的服务了。

客户端(Client)

客户端想要使用服务端通过thrift发布的服务,只需要遵循面向接口编程的基本思想,引用Java接口,用thrift的API连接服务端即可,比如HelloServiceConsumer类中这么使用sayHello服务:

package com.yuanwhy.demo;

import com.yuanwhy.service.HelloService;

import org.apache.thrift.TApplicationException;

import org.apache.thrift.TEnum;

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;

/**

* Created by zeze on 2018/03/23.

*/

public class HelloServiceConsumer {

public static void main(String[] args) {

TTransport transport = new TSocket("0.0.0.0", 7911);

try {

transport.open();

TProtocol protocol = new TBinaryProtocol(transport);

HelloService.Client client = new HelloService.Client(protocol);

System.out.println(client.sayHello("yuanwhy"));

transport.close();

} catch (TApplicationException e) {

if (e.getType() == TApplicationException.MISSING_RESULT) {

System.out.println("null");

}

} catch (TException e){

}

}

}

客户端运行结果会打印Hello, yuanwhy!,表明服务调用成功。仔细观察一下客户端的代码会发现,基本和普通的Socket编程没有太大的区别,只是又被thrift做了一层的封装,让我们可以按照约定的接口直接像client.sayHello("yuanwhy")这样调用远程服务。

注意:客户端如果是在不同的Java项目中调用服务,只需要服务端把thrift文件或者生成的Java接口文件以API的方式提供出来即可,客户端绝对不需要引用HelloServiceImpl实现类,因为目的就是让逻辑在服务端实现,对客户端透明。

另外,当服务端返回null时,客户端会抛一个Type为TApplicationException.MISSING_RESULT的异常出来,如果不处理就会影响客户端正常的流程。这一点可以在Thrift的生成代码中看出来:

public String recv_sayHello() throws org.apache.thrift.TException

{

sayHello_result result = new sayHello_result();

receiveBase(result, "sayHello");

if (result.isSetSuccess()) {

return result.success;

}

throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "sayHello failed: unknown result");

}

总结

以上对Thrift的使用只做了个简单的介绍,真正在项目中使用Thrift还会涉及很多,比如各种Thrift数据结构的使用,在对Thrift接口进行升级过程中struct的字段最好保留原有字段顺序以达到兼容目的,还比如客户端应该建立连接池机制,而不是每次调用服务时都去新建一次TCP连接等等。

理解Thrift基本的运行模式,对后续更深入研究RPC实现机制会有更好的帮助, 更多Thrift数据结构及其使用方法,可以直接访问官网https://thrift.apache.org 来学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值