什么是Thrift
Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
那什么是RPC?
参考博客《如何给老婆解释什么是RPC》,写得诙谐幽默,易于理解
安装
上官网下载thrift生成代码的安装包 http://thrift.apache.org/download ,最新的0.12.0在调用时会报一个错但是不影响传输,不喜欢报错的选择之前的版本。
编写thrift文件生成接口代码
1、下载thrift-0.11.0.exe后,创建一个thrift文件service.thrift
namespace java com.thrift.contract
// 定义服务
service DataService{
// 类型 方法 参数
InvokeResult DataCore(1:string value)
}
// 结构体
struct InvokeResult {
1: required bool result;
2: optional string message;
3: optional string data
}
这是一个较为通用的写法,传入的参数可以自定义解析规则,返回的数据中包含:是否成功,提示信息,返回结果集数据
2、把thrift-0.11.0.exe和service.thrift 放在一个目录下,cmd进入当前目录,执行thrift -r -gen java service.thrift
,提示thrift不是命令则执行thrift-0.11.0.exe -r -gen java service.thrift
在当前目录下多了一个gen-java的目录,里面有生成的Java文件,全粘贴进项目中,其中某个文件的@Override会报错,直接删掉报错语句就好了
更多的thrift语法参考博客:https://www.cnblogs.com/yuananyun/p/5186430.html
SpringBoot中使用
服务端
引入依赖
<!-- thrift -->
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
服务端需要实现我们定义的服务,然后启动服务给客户端调用
首先就是实现接口
import com.thrift.contract.DataService;
import com.thrift.contract.InvokeResult;
@Component
public class DataCoreService implements DataService.Iface {
@Override
public InvokeResult DataCore(String value) {
long start = System.currentTimeMillis();
InvokeResult result = new InvokeResult();
//尽情发挥
//尽情发挥
//尽情发挥
return result;
}
接着是启动
@Component
public class ThriftServerService implements Runnable {
@Autowired
private DataCoreService dataCoreService;
@Override
public void run() {
try {
//thrift服务端口号
TServerTransport serverTransport = new TServerSocket(8888);
//提供的服务实现
TProcessor processor = new DataService.Processor<DataService.Iface>(dataCoreService);
//协议
TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
TTransportFactory transportFactory = new TTransportFactory();
TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(serverTransport);
tArgs.processor(processor);
tArgs.protocolFactory(protocolFactory);
tArgs.transportFactory(transportFactory);
TServer server = new TThreadPoolServer(tArgs);
System.out.println("Starting the simple server...");
server.serve();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
由于我们的代码中使用到了@Autowired注解,所以肯定不能在Spring的启动类中直接new一个,因为这样是不会自动注入的,所以我们使用ApplicationContext的getBean方法来获取Spring容器中已初始化的bean
private static ThriftServerService thriftServerService;
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DatacenterCoreserviceApplication.class, args);
try {
thriftServerService = context.getBean(ThriftServerService.class);
new Thread(thriftServerService).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
客户端
/**
* 请求thrift服务端
* @param host 服务端地址
* @param port 端口
* @param value 传值
* @param socketTimeout 传输超时
* @param connectTimeout 连接超时
*/
public InvokeResult getResult(String host, int port, String value, int socketTimeout, int connectTimeout) throws Exception {
InvokeResult res;
TTransport transport = null;
try {
transport = new TSocket(host, port, socketTimeout, connectTimeout);
TProtocol protocol = new TBinaryProtocol(transport);
DataService.Client client = new DataService.Client(protocol);
transport.open();
res = client.DataCore(value);
} catch (Exception ex) {
throw ex;
} finally {
if (transport != null) {
transport.close();
}
}
return res;
}
参考博客:https://www.cnblogs.com/fingerboy/p/6424248.html