`
edwardpro
  • 浏览: 303696 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

thrift-1-2-3

阅读更多

国庆前后玩了一下thrift,下面是一些入门级的体会和心得:

 

1 在linux 64位下的编译过程,之前已经写过一个文章了:http://edwardpro.iteye.com/blog/1172064

 

 

2 客户端体系结构:

 

thrift在客户端中几个大的部分:

 

TTransport -> TTProtocol -> {生成的业务代码}

 

这三者是一个引用关系,简单说:

TTransport:代表了用什么方式和远端通讯,在thrift官方包中我使用的是TSocket,本质上就是通过socket来进行通讯

TTProtocol:协议层,协议层是指说话的语言,比如可以使用json也可以使用SImpleJson,当然效率最高的我想应该是Bin模式,它在每次发送的头部都有一个版本字段的,这应该是我们通常协议设计的一些基础思想。

业务代码:通过描述生成的,简单说就是调用协议层和远程说话,至于怎么说,是打电话呢还是发短信呢就是有TTransport来指挥的,这样说大家应该基本上能记住这玩意了。

生成代码类中有几个比较重要的static class,大家需要知道的:

1) iface 也就是你描述的方法生成的对应接口

2)Client,也就是你可以用来new的客户端对象

 

3 服务器体系:

 

服务器体系我没有太多研究也就是知道大概用法,首先需要对你服务接口里的iface做implements,实现功能,如这次开发的实现:

 

class TestWebThumbServer implements
		thrift.requestWebThumb.Iface {

	@Override
	public WebThumbResult requestSync(String uri) throws TException {
		System.out.println("called by Sync" + uri);
		return null;
	}

	@Override
	public void requestAsync(String uri) throws TException {
		System.out.println("called by Aync" + uri);
	}

}

 

同样Server也包括这样的流程:

TTransport -> handle(你的业务实现) -> Processor

 

			serverTransport = new TServerSocket(8811);
			com.taobao.wireless.webthumb.thrift.requestWebThumb.Iface handle = new TestWebThumbServer();
			Processor<requestWebThumb.Iface> processor = new requestWebThumb.Processor<webthumb.thrift.requestWebThumb.Iface>(
					handle);
			TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(
					serverTransport).processor(processor));
			server.serve();

 TTransport: 同样担负着协议部分的重要责任

handle:你的实现

Processor:业务处理线程,用来做一个类似Selector的模式(这个问题后面数落的时候会说)

 

4 客户端基本使用过程:

 

1) 根据描述文件生成最初的代码

2) 接下来就是写代码了,其实说起来是很容易的,但是并不是这样的,因为你万事得考虑一个效率和易用性:

 

先说易用性:

 

易用性在我的实现里采用了代理模式,考虑调用代码基本上每个方法调用都是一个模型,因此为了使用方便不重复劳动,因此使用了代理模式,当然了代理模式个人还是很清醒低认识到这玩意对jvm的性能是有伤害的,不过这个实现思路比较简单,当然代码量是不小的,因为我还是用的jdk原生的反射,这些构造函数到方法一步步的处理代码还是很多的,而且有很多异常要判断。

然后在代码里你只需要声明一个虚拟的接口,这个接口生成服务就可以了比如:

public interface WebthumbServiceInternal {
	
	@ClassName(name="requestWebThumb$Client")
	@MethodName(name="requestAsync")
	public void request(String uri);
}

 接下来是性能:

首先我们看到了TSocket这个transport是一个block io设计,所以为了更高效率执行和避免服务器被搞死,我做了一个以服务器为单位的线程池(Executor)来完成这项工作,但在使用时发现一个问题,本来以为连接可以不断开,但实际上在多线程下访问同一个socket,即使你控制了线程还是不行:

会返回一个叫:broken pipe的错误,可以确认线程执行没问题,没有出现污染。经过查阅资料,是说linux下的socket连接会禁止多线程访问,这也就是当你手工连续执行两个方法的时候,是可以的,但是当你用单线程来控制就不行了(因为不同的runnable是属于不同的线程的)

 

因此要解决这个问题就需要使用nio了,我使用的是netty,netty里是通过channel来控制的,channel本质上看起来更像是一个资源会话。所以当我们使用非阻塞的时候发现很多代码要变了:

1) 需要建立一个接收缓冲池

2)channel本身不需要更多的线程管理了,可以通过设置option来解决

3)执行的时候不需要再自己控制所谓的executor了,因为netty帮你做了

 

当然经过了一个晚上的编码,直到天亮,直到看到只有ip4s没有传说中的ip5的时候还是有一个诡异的问题没有解决,当我通过bootstrape连接上去的时候,很奇怪,总是会被服务器踢掉,导致后续的channel就算自己connect也不行了(案例来说应该可以的,但是就是不行),这个问题还没搞定,应该是用netty上有点问题,对netty的pipe也要更多研究下,后面有结果再向大家汇报。

 

接下来我想讲讲自己对thrift的一些感觉:

 

优点:

 

1 发现thrift的通讯是双向的,在Transport中可以制定out和in不同的流,这两者可以分开指定,意味着这玩意已经不再局限在我们所看到的单向rpc模式,而是可以通过自己双手改造成一个双向服务器,而这个对于一些压力非常高的请求就非常必要,比如我们平时在用的tair,就是这样的设计形态(当然它没有oneway是蛮suck的)

 

2 设计层次我前面讲过了,不重复,我觉得在可扩展性上还是不错的,很好用,接口设计都比较清晰,一看源代码就很清楚。

 

 

缺点:

 

 

1 bug太多了,我经过两个晚上已经发现的bug有:

 

Tserver的强壮性很差,特别是我故意发送一些不对的字节流时会出现但是又不是100%,这个看起来应该是processor的问题了,不过因为netty没搞定,心情上没去深入搭理这个问题。

 

Protocol中的Json协议有问题,会引起server端的oom,这个是100%复现的(我使用的是thrift 0.7.0,其他版本为测试不作结论),同样也是因为netty没去查这个thrift的bug。

 

2 自有代码性能不好,这个前面也说了,thrift本身没有实现nio下的持久链接调用这个当今的企业应用环境这个基本上就没有什么实用性了,虽然自己可以写,但是还是希望官方支持下,技术都有小懒的毛病^^

总体来说thrift生成的代码没有太多值得说的地方,包括其生成的接口描述我觉得也是比较混乱,这个也是所有描述型的一个短版,以前soap时代的生成器也大多是这个毛病,不可想象如果生成一个很复杂的服务会是什么情况,所以服务生成真的是有好有坏,如果是内部服务其实效率第一了,这种方案我认为肯定不可取,如果是外部服务在某些情况下是可以考虑的,毕竟这样可以偷懒不少事情,当然这个实际上是根据你的协议设计的,如果协议本身比较复杂的确还是需要的,不然写这个代码姚折腾半天。但是我觉得比较好的方法还是用代理模式,在像java这样的语言里做好框架,然后用代理让客户调用还是很不错的,至少我觉得比生成代码可能要更方便,因为你也得考虑生成代码万一有问题,这个解决起来就费劲了。

 

 

好了关于thrift就说这些,下次解决了netty的问题再来唠叨

 

 

 

分享到:
评论

相关推荐

    thrift-0.9.0.tar.gz

    1. **数据序列化**:Thrift提供了一种高效的二进制编码格式,用于序列化和反序列化数据,这种格式比XML或JSON更紧凑,更适合网络传输。 2. **跨语言支持**:Thrift支持多种编程语言,如C++, Java, Python, PHP, Ruby...

    thrift-编译工具

    1. **IDL(接口定义语言)**:Thrift使用类似C++的语法定义服务接口和数据结构,这些定义存储在.thrift文件中。例如: ```thrift service MyService { string sayHello(1:string name) } ``` 2. **编译器**:Thrift...

    thrift文件生成工具thrift-generator.zip

    thrift-generator 是通过 Java 的接口生成 thrift 文件的工具。例子:public interface... list testCase1(1:map, string&gt; arg0,2:list arg1,3:list arg2,4:i64 arg3,5:string arg4)  } 标签:thrift

    thrift-typescript:从Thrift IDL文件生成TypeScript

    2 : required bool field1, # 3 : required string field, 4 : required i16 field, } 您可以通过命令行生成TypeScript: $ thrift-typescript --target apache --rootDir . --sourceDir thrift --outDir ...

    thrift环境配置方法

    ### 步骤 1:安装 MacPorts MacPorts 是一个用于 macOS 的包管理器,提供了大量的开源软件包,包括 Thrift 的依赖项。安装 MacPorts 后,开发者可以方便地安装 Thrift 所需的依赖项。 ### 步骤 2:安装 Boost ...

    thrift-zookeeper-rpc

    对于Thrift服务化的改造,主要是客户端,可以从如下几个方面进行: 1.服务端的服务注册,客户端自动发现,无需手工修改配置,这里我们使用zookeeper,但由于zookeeper本身提供的客户端使用较为复杂,因此采用curator...

    thrift-0.9.0-dev.tar.gz

    2. **生成代码**:运行Thrift编译器,它会根据.thrift文件生成目标语言的客户端和服务端代码。 3. **实现服务**:在服务端,你需要实现.thrift文件中定义的服务接口。 4. **构建客户端**:在客户端,使用生成的代码...

    thrift安装

    3. **易于使用**:通过Thrift IDL,开发者可以定义数据类型和服务接口,Thrift会自动生成相应的代码,大大简化了开发工作。 4. **服务治理**:Thrift提供了服务注册与发现、负载均衡、容错处理等高级特性,便于构建...

    laravel-thrift-zipkin-project:基于thrift zipkin链路监控

    Zipkin使用安装docker run --name zipkin -d -p...string version(1: string name, 2: zipkin.Options options) throws (1:zipkin.ThriftException ex)}编译服务- Go 使用 thrift -r --gen go:thrift_import=thrift App

    Learning.Apache.Thrift.178588274

    Chapter 3: Running Your First Apache Thrift Service and Client Chapter 4: Understanding How Apache Thrift Works Chapter 5: Generating and Running Code in Different Languages Chapter 6: Handling Errors...

    thrift java build jar

    1. **安装 Thrift** 首先,你需要在本地安装 Thrift 编译器。访问 Thrift 官方网站(https://thrift.apache.org/)获取最新版本,并按照平台指南进行安装。通常,这涉及到下载源码、编译并安装到系统路径中。 2. *...

    编译后的thrift客户端

    编译后的thrift客户端,已经经过公司师父同意分享。 1. cp /Users/dxm/Desktop/thrift /usr/local/bin/ 2. echo $PATH 3. thrift 4. chmod +x /usr/local/bin/thrift 5. thrift 6. thrift -version

    C#通过thrift连接hbase过程

    1. **下载Thrift工具和源码** 首先,你需要下载两个关键文件:thrift-0.9.1.exe(Thrift编译器)和thrift-0.9.1.tar.gz(Thrift源码包)。这些可以从Apache Thrift官方网站获取。下载后,解压源码包。 2. **生成...

    linux下安装和测试thrift

    i32 add(1:i32 num1, 2:i32 num2) } struct IntPair { 1: i32 first, 2: i32 second } ``` 使用Thrift编译器生成Python代码: ```bash thrift --gen py test.thrift ``` 这会在当前目录下生成一个`gen-py`文件夹...

    thrift-service-framework:一个基于facebook thrift rpc框架的服务框架,支持http rpc js客户端调用

    支持以servlet方式嵌入web容器(tomcat/weblogic/jboss之类)运行2、 也可以直接用嵌入式jetty直接从jar包运行###支持javascript调用支持js直接调用,post的json格式为:以下格式无需手动拼写,thrift生成的js客户端会...

    c++开发环境资源包.txt

    boost_1_55_0.tar.bz2 dev_env.sh gperftools.tar.gz libpcap-1.4.0.tar.gz mongo-c-driver-0.8.1 openssl-1.0.2j.tar.gz redis_baic.conf thrift-0.9.0.tar.gz boost_1_55_0.tar.gz dpkt-1.8.tar.gz impacket-...

    workerman-thrift:基于workermanPHP Thrift RPC

    工人 ... 多进程 支持TCP / UDP ...1,下载或git clone https://github.com/walkor/workerman-thrift 2,运行composer install 启动停止 以ubuntu为例 启动php start.php start -d 重启启动php start.php r

    php-thrift-mapper:将PHP数组转换为Apache Thrift结构类型

    struct Bonk{ 1: string message, 2: i32 type}生成如下所示PHP源代码。 class Bonk { static $ _TSPEC ; /** * @var string */ public $ message = null ; /** * @var int */ public $ type = null ; public ...

    通过thrift使用c++访问hbase

    1. **验证HBase和ThriftServer状态**: 确保HBase正常工作,检查thriftserver的9090端口是否在监听,如需启动ThriftServer,可以使用`bin/hbase-daemon.sh start thrift`命令。 2. **编写和编译测试程序**: 创建一个...

Global site tag (gtag.js) - Google Analytics