Thrift-简介
-
thrift是facebook开发的一套rpc服务框架
-
定义了一种与具体编程语言无关的IDL(交互式数据语言)来描述服务的接口以及数据的格式
-
为IDL提供了一个编译器
3.1 译器根据IDL文件,生成多种语言的代码
3.2 丰富的语言支持支持C++,Java,Python,PHP,Ruby等等
thrift可以做什么?
-
可以视为一套轻量级的高性能网络服务框架
1. 服务开发者不用关注网络IO
2. 服务开发者不用关注打包,解包
3. 服务开发者面对的是直接的函数接口,简单、明了的参数 -
节省服务调用者的开发量
1. 提供多个语言的客户端代码
2. 调用者不关注网络IO
3. 调用者不关注打包、解包请求远程的server就像调用本地的函数一样 -
简单、可扩展的多语言间数据交换
thrift为IDL中定义的每个数据结构都提供read,write方法,用来序列化和反序列化。 -
thrift支持的数据类型
bool,byte,i16,i32,i64,double,string,binary,map,list,set,struct结构体 -
thrift数据交换
- 数据交换被抽象成两层
传输层:通过内存,裸socket,文件http等
协议层:二进制,json等
协议层位于传输层之上 - 序列化
使用write来进行序列化的操作 - 反序列化
使用read来进行反序列化的操作
- 数据交换被抽象成两层
-
thrift定义服务
thrift文件(rcho.thrift)
namespace cpp echo
server Echo{
string echo(1:string str),
void echo1(1:string str),
oneway void echo2(1:string str),
}
void与oneway void的区别?
1. void在应用层有确认,即serber会向client发响应包,响应包中包含rpc名,
sequence id(鸳鸯返回server收到的RPC头部的seqid),响应类型(正常情况下T_REPLY,产生异常为T_EXCEPTION)。
即在void类型下,server可以通过抛出异常来想client传递信息,包括异常类型以及字符串信息
2. oneway void只是在tcp协议层确认请求是否成功,即只要client成功将RPC请求发送出去,就认为成功并返回。
thrift-生成文件
使用thrift -r --gen cpp echo.thrift编译生成cpp文件 -
thrift-分层模型
handler 具体的请求处理类
processor 根据transport层的数据,调用handler
transport 传输层
protocol: 协议层
server: 服务层 -
Thrift-TNonblockingServer结构
- 接入线程监听新连接上的读事件
- 接入线程收完一个请求包之后,将请求放入任务队列,并取消监听当前连接上的读事件和写事件
- 处理线程处理完毕之后,通过管道通知接入线程已经处理完毕
- 接入线程收到通知之后,监听连接上的写事件,往外发送响应
- 响应发送完毕之后,重新监听连接上的读事件
-
Thrift-server端抛出异常
-
Thrift生成的代码中有一个Process函数,里面根据RPC名字调用相应的处理函数
-
处理函数在调用的时候,都被包在一个try-catch中
-
处理函数抛出异常被上层thrift生成代码捕获
-
Server给client返回异常信息
正常情况返回类型为T_REPLY
异常情况下为T_EXCEPTION
thrift的API使用
所有的写请求都通过thrift router中转,读请求直连keylist服务。
- void keylist_create(1:string name,2:KeyListType type, 3:bool with_mark_remove,4:i32 recored_limit,5:bool notify_update);
创建一个ketlist,name:keylist的名字,type:32中类型之一,with_mark_remove:是否需要标记删除功能,为true的情况下,系统内部实际存在两个keylist,一个保存全量数据,一个不包含标记删除的数据,recored_limit:默认的当个key的最大记录数限制,notify_update:当key对应的记录数发生变化的时候,是否想thrift router发送通知 - voivoid keylist_set_record_limit(1:string name,2:i64 key,3:i32 limit);设置名字为name的keylist中key的最多记录数限制为limit
- void keylist_insert(1:string name,2:i64 key,3:i64 val_key,4:i64 sort_key,5:i64 val);
- insert:不存在就插入,否则直接返回
- Replace:不存在就插入,否则就更新
- Update:存在就更新,否则直接返回 - void keylist_update(1:string name,2:i64 key,3:i64 val_key, 4:i64 sort_key, 5:i64 val)
- void keylist_update_val(1:string name,2:i64 key,3:i64 val_key,4:i64 val)
- void keylist_replace(1:string name, 2:i64 key,3:i64 val_key,4:i64 sort_key,5:i64 val)
- void keylist_remove(1:string name,2:i64 key,3:i64 val_key)
- void keylist_remove_by_val_key_range(1:string name,2:i64 key,3:i64 start_val_key,4:i64 end_val_key)
删除val_key位于[start_val_key,end_val_key)区间的所有数据,注意不包含end_val_key
key to [sort] list存储服务接口
- void keylist_clear(1:string name, 2:i64 key);
清除key的所有数据 - void keylist_mark_remove(1:string name, 2:i64 key, 3:i64 val_key);
如果table有标记删除功能的话,是从非全量list中删除数据 - FindResult keylist_find(1:string name, 2:i64 key, 3:i64 val_key, 4:bool in_full_list);
从key对应list数据中查找val_key,in_full_list只在有标记功能是有效,否则忽略 - GetRangeResult keylist_get_range(1:string name, 2:i64 key, 3:i32 start, 4:i32 limit, 5:bool in_full_list);
获取key对应的list中从第start条数据开始的limit条数据。返回的数据是有序的。 - map<i64, GetRangeResult> keylist_get_range_multi(1:string name, 2:list keys, 3:i32 start, 4:i32 limit, 5:bool in_full_list);
- GetRangeResult keylist_get_range_by_val_key(1:string name, 2:i64 key, 3:i64 val_key, 4:i32 start, 5:i32 limit, 6:bool in_full_list);
对于key-list, 对val_key在key的列表中所处位置为参照点(offset为0),取第start条数据开始的limit条数据,如果val_key不存在,以其下一个位置为参照点。
对于key-sortlist,要求val_key必须存在。依照val_key找到对应的sort_key,然后以这条数据为参照点。 - GetRangeResult keylist_get_range_by_sort_key(1:string name, 2:i64 key, 3:i64 sort_key, 4:i32 start, 5:i32 limit, 6:bool in_full_list);
只对key to sort list有效。以sort key为参照点,如果不存在的话,以下一个位置为参照点。(key对应的list是有序的,优先按照sort key排序 - GetRangeResult keylist_get_by_val_key_range(1:string name, 2:i64 key, 3:i64 start_val_key, 4:i64 end_val_key, 5:bool in_full_list);
获取key对应的列表中,val_key位于[start_val_key, end_val_key)区间的所的数据。
取到的数据是按照val_key有序的。
对key to list和key to sort list都有效。 - GetRangeResult keylist_get_by_sort_key_range(1:string name, 2:i64 key, 3:i64 start_sort_key, 4:i64 start_val_key, 5:i64 end_sort_key, 6:i64 end_val_key, 7:bool in_full_list);
只有key to sort list有效。获取key对应列表中,<sort_key, val_key>位于[<start_sort_key, start_val_key>, <end_sort_key, end_val_key>)区间上的所有数据。
key对应的list是有序的,优先按照sort key排序,sort key相等时按val_key排序。 - void keylist_insert_multi(1:string name, 2:list items);
- void keylist_replace_multi(1:string name, 2:list items);
- void keylist_update_multi(1:string name, 2:list items);
- void keylist_remove_multi(1:string name, 2:list items);
- void keylist_clear_multi(1:string name, 2:list keys);
- void keylist_mark_remove_multi(1:string name, 2:list items);
- void keylist_resize(1:string name, 2:i64 key, 3:i32 size);
如果key对应的list长度超过size,那么只保留最前面的size条数据。 - void keylist_resize_multi(1:string name, 2:list keys, 3:list sizes);
- list keylist_find_multi(1:string name, 2:list items);