参考up:孙哥
孙哥主页
Thrift的引言
Thrift特点
1. Thrift是一个RPC框架:解决远端功能调用
2. 可以进行异构系统的RPC调用
* 什么是异构系统? 服务的提供者 和 服务的调用者 不同语言开发系统
3. 为什么在当前系统开发中 会存在异构系统的RPC?
* 存在异构系统的调用 Python ---->Hbase(Java)
* 遗留系统的整合
4. 设计一个异构系统的RPC,解决的核心问题是什么?
* 两个进程之间的通信-----网络完成 ip:port 建立网络连接,进行通信即可。
* 存在挑战:
* 得需要精通不同编程语言的网络 IO 线程 等相关技术内容
* 数据传输的格式 1. 字符串json传输慢 2.二进制的格式(语言的二进制格式可能不一样,做适配)
ThriftRPC 框架
- 基本概念:
是apache组织开源的一个顶级异构系统RPC框架,用于完成异构系统的RPC通信 支持多种语言:Java ,C++,PHP,Python ,Ruby.......
-
特点:
- 跨语言支持(同种语言的效率没有非异构框架块)
- 开发快速
- 学习简单 IDL语言
- 稳定
-
Thrift的设计思想
- 针对不同的编程语言提供了一个库(jar)
- 作用:网络通信的代码 协议(序列化) 相关内容 java libthrift
- IDL 语言 中立语言 用于服务发表
- Thrift命令 把IDL 语言 自动转换成 需要的编程语言
ThriftRPC安装
:::info
- 安装--把IDL转换成具体语言的命令
::: 2.Thrift安装 3.针对不同的编程语言,引入相应的库
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.19.0</version>
</dependency>
IDL 语法
:::info
安装IDL 语法插件
:::
- 注释
# 单行注释
// 单行注释
/*
* 多行注释
* */
- namespace
namespace java com.suns
namespace py com.suns
指定生成好的代码 包
- 数据类型
- 基本类型
i8 有符号的8位整数 byte
i16 有符号的16位整数 short
i32 int
i64 long
double double
bool boolean
string String " " ' ' utf-8
- 集合类型
list<T>
set<T>
map<K,V>
map<i32,string> sex={1:"female",2:"male"}
list<i32> ages=[1,2,3,4]
- 结构体 struct 自定义对象 等价于java中的类-->实体类
struct User{
1:string name,
2:i32 age,
3:list<i32>ages=[1,2,3,4]
}
struct 不能继承
成员与成员的分割 可以用, ;
结构体里面的每一个字段 都要进行编号 1,2,3....
变量类型 变量名
optional 可选的 默认为每一个成员加入的关键字
代表这个字段在序列化过程中可选的。如果这个字段没有默认值,就不序列化,有就序列化
required 必选 ,无论是否有值都序列化
- 枚举(enum)
enum SEASON{
SPRING=1,
SUMMERT=2
...
}
不支持枪套,i32
- 异常(Exception)
exception MyExeption{
1:i32 errorCode
2:string message
}
- 服务 service
service UserService{
bool login(1:string name,2:string password)
void register(1:User user)//User IDL语言中的结构体
}
注意:
1. 异常的处理
service UserService{
bool login(1:string name,2:string password) throws(1:MyException e,2:XXXException e)
void register(1:User user)//User IDL语言中的结构体
}
2,oneway 表示客户端发起请求后不等待响应返回,只能和void这种方法配合
service UserService{
bool login(1:string name,2:string password) throws(1:MyException e,2:XXXException e)
oneway void register(1:User user)//User IDL语言中的结构体
}
3.继承
service BaseService{
void m1(1:string name)
}
service UserService extends BaseService{
}
- include :::info 作用:进行IDL模块化编程 suns.thrift struct User{ 1:string name }
suns2.thrift include "suns.thrift" service UserSerivice{ void register(1:test.User user) } :::
- Thrift 将IDL生成对应代码的命令
thrift --gen java xxx.thrift -r递归创建,引用的文件 thrift -r --gen java xxx.thrift
Thrift RPC的开发
- 环境搭建
安装Thrift 引入依赖
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.19.0</version>
</dependency>
-
项目结构的定义 :::info client 客户端 server 服务端 common rpc编程共有的内容 1,实体内容2.服务的接口 :::
-
Thrift核心对象 :::info
- TTransport
作用:封装网络通信 TSocket 阻塞IO通信 TNonblockdingTransport 非阻塞网路通信 TFramedTransport 加入了封帧的操作 (半包 粘包
- TProtocol
处理的协议(序列化的方式) TBinayProtocol 二进制序列化 TJSONProtocol JSON进行序列化 TCompactProtocol 压缩方式 处理二进制
- TProcessor
整合 网络通信和 业务功能
- TServer 服务端
:::
Thrift-common
//这是一个thrift文件
namespace java com.suns
struct User{
1:string name,
2:string password
}
service UserService{
User queryUserByNameAndPassword(1:string name,2:string password)
void save(1:User user)
}
Thrift-service
public class UserServiceImpl implements UserService.Iface {
@Override
public User queryUserByNameAndPassword(String name, String password) throws TException {
System.out.println("queryUserByNameAndPassword"+name+password);
return new User("xiaojianr","123");
}
@Override
public void save(User user) throws TException {
System.out.println("save user is"+user.getName()+user.getPassword());
}
}
Thrift 服务器
public class TestServer {
public static void main(String[] args) throws TTransportException {
//TTransport
TServerTransport tServerTransport=new TServerSocket(9000);
//TBinaryProtocol
TBinaryProtocol.Factory factory=new TBinaryProtocol.Factory();
//TProcessor 发布对应的功能
UserService.Processor processor=new UserService.Processor(new UserServiceImpl());
TSimpleServer.Args arg=new TSimpleServer.Args(tServerTransport);
arg.protocolFactory(factory);
arg.processor(processor);
TServer tServer=new TSimpleServer(arg);
tServer.serve();
}
}
Thrift-Client
public class TestClient {
public static void main(String[] args) throws TException {
TTransport transport=new TSocket("localhost",9000);
transport.open();
TProtocol tProtocol=new TBinaryProtocol(transport);
UserService.Client userService=new UserService.Client(tProtocol);
User user=userService.queryUserByNameAndPassword("xiaoji","123");
System.out.println(user);
}
}
启动服务端,和客户端
注意事项
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version> <!-- 请使用你需要的版本 -->
</dependency>
实战开发中的思考
在实战开发中,往往服务端的功能 其实以及开发完成了
1. 现有本地的功能,服务端的功能以及写好了
2. 根据系统的功能,才可能决定,这个服务发布成RPC
所以在发布RPC业务实现 IFace接口,主页通过原有的Service方法的调用,进行实现,这样维护性更好,实战中使用的就是这种方法
TServer 服务的相关内容
TServer类型
1. 带表的是Thrift开发中的服务器
2. 功能:服务的开启server() 服务的关闭 stop()
3. 阻塞 非阻塞 有没有线程池 Reactor模式
TsimpleServer: 阻塞 单线程的服务器
TThreadPoolServer: 阻塞 线程池的服务器
TNonBlockingServer: 非阻塞 单线程的服务器
TThreadSeletorServer: 实现了主从版的Reactor (类似Netty)