RPC远程过程调用,传输层完成通信,TCP Socket进行控制。
常见的RPC框架包括:Thrift、gRPC、Finagle、Dubbo等等。
1 thrift简介
1.1 thrift定义
Thrift是Apache的项目。Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。
1.2 thrift下载
官网下载:https://thrift.apache.org/download
如下图,这里下载最新的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服务远程调用成功。
具体参考代码:https://gitee.com/linghufeixia/springboot-simple
chapter7-1:thrift server
chapter7-1: thrift client
教程列表:
springboot simple(0) springboot简介
springboot simple(1) springboot Helloworld
springboot simple(2) springboot Starter
springboot simple(3 )springboot Web开发
springboot simple(4)springboot 数据持久化
springboot simple (5) springboot Nosql
springboot simple (6) springboot mqtt
springboot simple (7) springboot thrift
springboot simple (8) springboot kafka
springboot simple (9) springboot jpa(Hibernate)
springboot simple (10) springboot protobuf
springboot simple (11) springboot protostuff
springboot simple (12) springboot RabbitMQ