⑴ 如何用thrift精准地表示日期类型
要编写Thrift定义文件,肯定要熟悉Thrift常见的数据类型:
1.基本类型(括号内为对应的java类型):
bool(boolean): 布尔类型(TRUE or FALSE)
byte(byte): 8位带符号整数
i16(short): 16位带符号整数
i32(int): 32位带符号整数
i64(long): 64位带符号整数
double(double): 64位浮点数
string(String): 采用UTF-8编码的字符串
2.特殊类型(括号内为对应的Java类型):
binary(ByteBuffer):未经过编码的字节流
3.Structs(结构):
struct定义了一个很普通的OOP对象,但是没有继承特性。
struct UserProfile {
1: i32 uid,
2: string name,
3: string blurb
}
如果变量有默认值,可以直接写在定义文件里:
struct UserProfile {
1: i32 uid = 1,
2: string name = "User1",
3: string blurb
}
4.容器,除了上面提到的基本数据类型,Thrift还支持以下容器类型:
list(java.util.ArrayList):
set(java.util.HashSet):
map(java.util.HashMap):
用法如下:
struct Node {
1: i32 id,
2: string name,
3: list<i32> subNodeList,
4: map<i32,string> subNodeMap,
5: set<i32> subNodeSet
}
包含定义的其他Object:
struct SubNode {
1: i32 uid,
2: string name,
3: i32 pid
}
struct Node {
1: i32 uid,
2: string name,
3: list<subNode> subNodes
}
5.Services服务,也就是对外展现的接口:
service UserStorage {
void store(1: UserProfile user),
UserProfile retrieve(1: i32 uid)
}
⑵ rpc的实现机制是什么
RPC 的全称是 Remote Procere Call 是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即无论是调用本地接口/服务的还是远程的接口/服务,本质上编写的调用代码基本相同。
比如两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数或者方法,由于不在一个内存空间,不能直接调用,这时候需要通过就可以应用RPC框架的实现来解决。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
二、常见RPC框架
几种比较典型的RPC的实现和调用框架。
(1)RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol)
和java的原生序列化。
(2)Hessian,是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。
(3)THRIFT是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。
二、RPC框架实现原理
在RPC框架中主要有三个角色:Provider、Consumer和Registry。如下图所示:
RPC框架面试总结-RPC原理及实现
节点角色说明:
* Server: 暴露服务的服务提供方。
* Client: 调用远程服务的服务消费方。
* Registry: 服务注册与发现的注册中心。
三、RPC调用流程
RPC基本流程图:
RPC框架面试总结-RPC原理及实现
一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。
四、服务注册&发现
RPC框架面试总结-RPC原理及实现
服务提供者启动后主动向注册中心注册机器ip、port以及提供的服务列表;
服务消费者启动时向注册中心获取服务提供方地址列表,可实现软负载均衡和Failover;
五、使用到的技术
1、动态代理
生成 client stub和server stub需要用到 Java 动态代理技术 ,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。
2、序列化
为了能在网络上传输和接收 Java对象,我们需要对它进行 序列化和反序列化操作。
* 序列化:将Java对象转换成byte[]的过程,也就是编码的过程;
* 反序列化:将byte[]转换成Java对象的过程;
可以使用Java原生的序列化机制,但是效率非常低,推荐使用一些开源的、成熟的序列化技术,例如:protobuf、Thrift、hessian、Kryo、Msgpack
关于序列化工具性能比较可以参考:jvm-serializers
3、NIO
当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、bbo,Hadoop Avro,推荐使用Netty 作为底层通信框架。
4、服务注册中心
可选技术:
* Redis
* Zookeeper
* Consul
* Etcd
⑶ thrift c++ 服务端的异步怎么实现
仰望明天
thrift服务端的c++语言实现
1.thrift 概念1
thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, php, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。
thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
2.生成c++语言的thrift服务端
利用thrift软件框架进行开发要首先进行环境的搭建,安装thrift运行库。
基本流程如下:
1)定义数据类型和服务接口文件:test.thrift;
2)利用代码生成引擎生成服务端框架,thrift --gen cpp test.thrift;
3)在./gen-cpp/test_server.skeleton.cpp文件中添加定制的服务;
4)编写客户端程序向服务端请求服务。
详细过程可以参加注释2给出的链接地址。
thrift定义了自己的数据类型,从而实现了跨语言平台之间的数据交换,关于thrift数据类型的详细说明可以参加注释3给出的链接地址。
3.php客户端
基于c++语言实现的thrift服务端程序经常被用在网站的后台提供实时且高效的服务,通常客户端程序是php语言的实现版本。只要根据数据类型和服务接口文件test.thrift生成php语言的接口文件即可用来调用。方法是thrift --gen php test.thrift,调用该命令后会在工作目录下生成./gen-php目录,里面有php语言的接口文件。
注释:
⑷ 找一下怎么根据thrift文件生成java需要使用的类
提供一种命令行的方式,利用axis——下载一个axis,假设2-1.5版本,解压运行cmd,进入axis的bin目录,执行如下命令:axis2-1.5\bin>wsdl2java.bat-uriD:\wsdl.xml-oD:\output-pcom.bd.zd-uri:wsdl文件-o:Java文件输出路径-p:生成的Java文件包名
⑸ thrift异步客户端怎么结束调用
首先创建thrift文件
namespace Java thriftservice Hello{ string helloString(1:string para)}
执行thrift -gen Java test.thrift会生成一个Hello.java文件
将Hello.java文件拷贝至IDE
server端代码:
[java] view plain
[java] view plain
package com.thrift.test.thrift;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket
⑹ thrift不是一种rpc框架吗,为什么看到有人也用它做序列化
Apache Thrift 跨语言服务框架,本质RPC;我发service需要放候,遇跨语言调用问题,JAVA语言发UserService用提供获取用户信息服务,服务消费端PHP/Python/C++等,我能所语言都适配相应调用式,候我奈使用Http作访问协议;服务消费端能使用HTTP,且更加倾向于 操作本API式 使用服务,我需要Thrift提供支持.
本文UserService例,描述使用thrift式,及其原理..
. service.thrift
struct User{
1:i64 id,
2:string name,
3:i64 timestamp,
4:bool vip
}
service UserService{
User getById(1:i64 id)
}
二. API文件
首先载安装thrift客户端,比windows平台,载thrift.exe,处需要提醒,同thrift客户端版本API能兼容.本例使用thrift-0.9.0.exe;通"--gen"指定API所适配语言.本实例java客户端API.
//windows平台,API文件输service目录(目录需要存)
> thrift.exe --gen java -o service service.thrift
三. UserService实现类
public class UserServiceImpl implements UserService.Iface {
@Override
public User getById(long id){
System.out.println("invoke...id:" + id);
return new User();//for test
}
}
四.原理简析
1. User.java : thriftAPI能力非限,比struct能使用简单数据类型(支持Date,Collection等),我能User看,类实现"Serializable"接口"TBase"接口.
其Serializable接口表明类实例需要序列化网络传输,干扰JAVA本身序列化反序列化机制,重写readObjectwriteObject.thrift本身并没帮助.
TBase接口thrift序列化反序列化使用,两核:readwrite.述thrift文件,struct定义每属性都序号,比:1:id,thrift序列化,根据序号顺序依属性"名称 + 值"写入inputStream,反序列化.(具体参见readwrite实现).
thrift序列化反序列化实例数据,根据"属性序号"进行,保证数据inputstreamoutputstream顺序严格.点要求API发者,更改thrift文件struct定义,需要重新客户端API,否则服务继续使用(能报错,能数据错误).thrift序列化/反序列化程JAVA自带序列化机制同,携带额外class结构,外thrift种序列化机制更加适合网络传输,且性能更加高效.
2. UserService.Client: UserService,Client静态类,类典型代理类,类已经实现UserService所.发者需要使用Client类API与Thrift server端交互,负责与Thrift serverSocket链接,发送请求接收响应.