RPC远程过程调用,传输层完成通信,TCP Socket进行控制。
常见的RPC框架包括:Thrift、gRPC、Finagle、Dubbo等等。
1 thrift简介
1.1 thrift定义
Thrift是Apache的项目。Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。
1.2 thrift下载
如下图,这里下载最新的window环境下 0.17.0是版本。
下载后修改为thrift.exe文件,方便输入。控制台环境,输入命令:thrift –version
验证版本。
1.3 thrift 类型
thrift基本类型:
- string, 字符串类型,注意是全部小写形式;例如:string aString
- i16, 16位整形类型,例如:i16 aI16Val;
- i32,32位整形类型,对应C/C++/java中的int类型;例如: I32 aIntVal
- i64,64位整形,对应C/C++/java中的long类型;例如:I64 aLongVal
- byte,8位的字符类型,对应C/C++中的char,java中的byte类型;例如:byte aByteVal
- bool, 布尔类型,对应C/C++中的bool,java中的boolean类型; 例如:bool aBoolVal
- double,双精度浮点类型,对应C/C++/java中的double类型;例如:double aDoubleVal
- void,空类型,对应C/C++/java中的void类型;该类型主要用作函数的返回值,例如:void testVoid(),
容器有:
- ]list,链表类型,例如,定义一个list对象:list aList;
- set,集合类型,例如,定义set对象:set aSet;
- map,map类型,例如,定义一个map对象:map<i32, i32> newmap;
支持两种自定义类型:
- enum, 枚举类型,例如,定义一个枚举类型:
enum Kind
{
ONE = 1,
TWO,
THREE,
FIVE = 5,
SIX,
EIGHT = 8
} - struct,自定义结构体类型,在IDL中可以自己定义结构体,对应C中的struct,c++中的struct和class,java中的class。例如:
struct User{
1: i32 begin_in_both,
3: string old_string,
12: i32 end_in_both
}
Exception:是一个继承于本地语言的exception基类
2 Springboot集成thrift
2.1 开发thrift接口
第1步:开发Thrift API接口;这里API接口是IDL文件。当然可以借助idea或其他编辑器的插件会更方便。这里手动编写。
这里定义user.thrift文件如下:
namespace java com.feidao.service
struct User
{
1:i32 userId; #Id
2:string userName; #用户名
3:string passWord; #密码
4:string telephone #手机号
}
exception UserException
{
1:string message
}
service UserService
{
string ping() throws (1:UserException ex);
list<User> getUserList();
}
将user.thrift文件与thrift.exe放在同一目录下,输入命令:
thrift -gen java user.thrift
进入gen-java文件夹,可以看到生成的java文件。
2.2 springboot开发thrift server
第1步:POM文件引入
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.17.0</version>
</dependency>
第2步:工程中引入java接口文件。
第3步:定义UserServiceImpl.java文件实现接口文件。
package org.feidao.chapter71.service;
import com.feidao.service.User;
import com.feidao.service.UserException;
import com.feidao.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class UserServiceImpl implements UserService.Iface {
@Override
public String ping() throws UserException, TException {
return "pong";
}
@Override
public List<User> getUserList() throws TException {
List<User> userList = new ArrayList<>();
User user1 = new User();
user1.setUserName("曹操");
userList.add(user1);
User user2 = new User();
user2.setUserName("刘备");
userList.add(user2);
User user3 = new User();
user3.setUserName("孙权");
userList.add(user3);
return userList;
}
}
第4步:定义 TCP socket server。
package org.feidao.chapter71;
import com.feidao.service.UserService;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.feidao.chapter71.service.UserServiceImpl;
//thrift server service的管理
public class UserServiceManager {
//thrift service端口
public final static int SERVER_USER_PORT = 8888;
public UserServiceManager(){
}
public void server(){
try {
//创建TServer.Args
TProcessor tProcessor = new UserService.Processor<UserService.Iface>(new UserServiceImpl());
TServerSocket tServerSocket = new TServerSocket(SERVER_USER_PORT);
TServer.Args args = new TServer.Args(tServerSocket);
args.processor(tProcessor);
args.protocolFactory(new TBinaryProtocol.Factory());
//单线程服务模型,创建TServer
TServer tServer = new TSimpleServer(args);
//启动server
tServer.serve();
} catch (Exception e) {
e.printStackTrace();
}
}
}
第5步:Application中启动Socket server。
2.3 springboot开发thrift client
第1步:POM文件引入
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.17.0</version>
</dependency>
第2步:工程中引入java接口文件。
第3步:定义client连接和调用服务:
package org.feidao.chapter72;
import com.feidao.service.User;
import com.feidao.service.UserService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import java.util.List;
//thrift client service的管理
public class UserServiceManager {
//thrift service端口
public final static int SERVER_USER_PORT = 8888;
//延时
public final static int SERVER_TIME_DELAY = 30000;
//server host
private String host = "localhost";
private TTransport tTransport = null;
private UserService.Client client;
public UserServiceManager(){
try {
tTransport = new TSocket(host,SERVER_USER_PORT,SERVER_TIME_DELAY);
//定义协议
TProtocol tProtocol = new TBinaryProtocol(tTransport);
//创建client
client = new UserService.Client(tProtocol);
//打开通道
tTransport.open();
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy(){
if(tTransport!=null){
tTransport.close();
}
}
//测试与server端的通信
public void testCommunication(){
System.out.println("send ping....");
try {
String str = client.ping();
if(!str.isEmpty()){
System.out.println("receive:" + str);
}
}catch (Exception e){
e.printStackTrace();
}
}
public void getService(){
try {
List<User> userList = client.getUserList();
if(userList!=null&& userList.size()>0){
for(int i=0;i< userList.size();i++){
User user = userList.get(i);
System.out.println("user:" + user.userName);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
第4步:Application中连接server socket,调用thrift服务。
2.4 测试验证
第1步: 两个springboot项目启动端口分别为8081、8082:thrift服务端口为8888;
第2步:Server启动thrift服务:
第3步:client调用thrift服务:
可以确认thrift服务远程调用成功。