thrift是一个RPC框架,我们使用SpringBoot可以对外暴露http接口,但是系统内部调用如果需要较高的效率,需要使用RPC接口,因此我们会需要使用thrift 再暴露一些内部接口
假设我们有一个service类,里面实现了一个login方法,如果要暴露http的接口,我们需要使用springboot做一个controller,然后在controller里调用这个login,这样完成一个http接口
但如果我们想对外暴露RPC的login接口,这就需要使用thrift
前提:添加依赖
<dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.10.0</version> </dependency>
使用thrift主要分为如下几步
1、生成thrift 接口文件(这个接口文件不是自己写的java类,是需要使用thrift工具生成的)
由于这个接口文件是thrift 工具自动生成的,因此我们需要先用thrift 的描述语言写一下这个接口的定义,然后再用thrift 工具生成
1.1写接口描述文件
接口描述文件是一个后缀名为.thrift的文件,这面这个文件是RPCNetAuthService.thrift,是一个接口描述文件,namespace是最后生成的接口文件的包名
namespace java com.xxx.mbe.thrift.rpcInterface.auth
service RPCNetAuthService{
bool login(1:string userAccount,2:string password)
}
1.2生成接口类
根据RPCNetAuthService.thrift生成接口类有两种方式,一种是下载thrift.exe,使用它的命令生成,另外一种是使用IEDA的thrift插件来生成
1.2.1 使用thrift.exe生成
网上下载thrift.exe,假设放到了D:\thrift\thrift.exe,将RPCNetAuthService.thrift也放到这个目录
打开cmd窗口 执行
cd D:\thrift
thrift --gen java RPCNetAuthService.thrift
这样在这个目录下会生成RpcNetAuthService.java,这个就是生成的接口类
1.2.2使用插件生成
打开File->Settings->Plugins->搜索thrift,安装插件
然后配置插件(我专门建立了一个thrift项目,在这个项目里保存了所有的thrift文件,在ProjectStructure里配置了thrift和输入路径输入语言类型,这样编译后会自动将.thrift文件输出为对应的java文件)
将输出的RpcNetAuthService.java放到一个公共地方(客户端和服务器端都能用到)
2、服务器端实现thrift 接口
下面服务器端要实现这个接口,新建一个类RPCNetAuthServiceImpl
import com.xxx.mbe.auth.service.NetAuthService;
import com.xxx.mbe.auth.service.impl.NetAuthServiceImpl;
import com.xxx.mbe.thrift.rpcInterface.auth.RPCNetAuthService;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
/**
* Created by Test on 2017/7/10.
*/
@Controller
public class RPCNetAuthServiceImpl implements RPCNetAuthService.Iface {
private static final Logger logger = LoggerFactory.getLogger(RPCNetAuthServiceImpl.class);
@Autowired
private NetAuthService netAuthService =new NetAuthServiceImpl();//这里本来想用注入的方法使用,但是service启动的时候是静态类直接new的,所以没法注入,所以这里就new了
@Override
public boolean login(String userAccount, String password) throws TException {
return netAuthService.login(userAccount,password);//这里调用了Service的方法
}
}
3、服务器端启动服务
启动服务代码如下,在main方法中调用下
private static void startRPCServer()
{
try {
// 设置协议工厂为 TBinaryProtocol.Factory
TBinaryProtocol.Factory proFactory = new TBinaryProtocol.Factory();
// 关联处理器与 Hello 服务的实现
TMultiplexedProcessor processor = new TMultiplexedProcessor();
TServerTransport t = new TServerSocket(9090);
TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(t).processor(processor));
processor.registerProcessor(RPCNetAuthService.class.getSimpleName(), new RPCNetAuthService.Processor<RPCNetAuthService.Iface>(new RPCNetAuthServiceImpl()));
// TSimpleServer server = new TSimpleServer(new Args(t).processor(processor));
System.out.println("the serveris started and is listening at 9090...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
这样服务就启动了,下面需要客户端调用
4、客户端调用接口
首先先建立一个client类
import com.xxx.mbe.thrift.rpcInterface.auth.RPCAuthService;
import com.xxx.mbe.thrift.rpcInterface.auth.RPCNetAuthService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TMultiplexedProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
/**
* Created by Test on 2017/7/10.
*/
public class AuthClient {
private RPCNetAuthService.Client rpcNetAuthService;
private TBinaryProtocol protocol;
private TSocket transport ;
public RPCAuthService.Client getRpcAuthService() {
return rpcAuthService;
}
public RPCNetAuthService.Client getRpcNetAuthService() {
return rpcNetAuthService;
}
public void open() throws TTransportException {
transport.open();
}
public void close()
{
transport.close();
}
public AuthClient() throws TTransportException {
transport = new TSocket("localhost",9090);
protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, RPCNetAuthService.class.getSimpleName());
rpcNetAuthService = new RPCNetAuthService.Client(mp2);
}
}
在使用的地方如下调用
AuthClient client = new AuthClient();
client.open();
boolean loginResult = client.getRpcNetAuthService().login(userEntity.getUserName(),userEntity.getPassword());
client.close();
这样就可以调用服务器端的方法了