您的位置:首页 > 其它

thrift-client异步+server非阻塞

2016-07-14 10:27 302 查看
1.thrift 下载安装:

官网:http://thrift.apache.org/ 上面会最新版的安装下载

java mavendependency:

<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.1</version>
</dependency>


libthrift 的<span style="font-family: Arial; background-color: rgb(255, 255, 255);">源码下载:</span><span style="font-family: Arial; background-color: rgb(255, 255, 255);">git://anonscm.debian.org/users/eevans/libthrift-java.git  (这个也是找了好久,特此记录一下)</span>


2.简单使用:

参见:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/index.html

简单来讲,就是先定义thrift文件,然后用工具生成响应语言的代码(如java代码),编写并开启服务端(需要使用生成的代码),编写客户端并连接上服务端(也需要使用生成的代码)

3.多线程异步调用使用心得:

搭建方式参见:http://blog.csdn.net/larrylgq/article/details/7497342

a) 异步thrift搭建后会阻塞线程,所以如果thrift服务只是你服务中的一部分,请另起一个线程使用

new Thread(new Runnable() {
@Override
public void run() {
try{
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(new InetSocketAddress(IP,PORT));
TBinaryProtocol.Factory proFactory = new TBinaryProtocol.Factory();
TProcessor tprocessor = new Gs2Ls.Processor<Gs2Ls.Iface>(new Gs2LsImpl());
TNonblockingServer.Args configArgs = new TNonblockingServer.Args(serverTransport);
configArgs.processor(tprocessor);
configArgs.protocolFactory(proFactory);
TServer server = new TNonblockingServer(configArgs);
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();

在添加的Gs2LsImpl 类中需要实现对应的Gs2Ls.Iface接口

b) 在客户端搭建中注意使用和 server相同的protocol协议和传输层transport

如上例,则异步客户端使用TAsyncClientManager ,AsyncClient ,TNonblockingTransport,TBinaryProtocol.Factory()
while(true){
Thread.sleep(1);
}

客户端需要等待回调,所以不能直接完成退出,所以测试时需要加上上述代码。

另外如果加入访问超时时间,需要调用asyncClient.setTimeout(TIMEOUT); 方法

c) 在客户端的回调类中需要实现AsyncMethodCallback接口,服务端的回复会回调onComplete方法,可以做相关逻辑处理;服务端的任何异常会回调onError方法,客户端可以根据异常类型及异常内容做相关处理

@Override
public void onError(Exception exception) {
if(exception instanceof java.util.concurrent.TimeoutException && exception.getMessage().contains("timed out")){
// TODO timeout
}else if(exception.getMessage().equals("Connection refused: no further information")){
// TODO reconnection
new ReconnectThriftTask(1000);
}
}

如上例,可以根据返回超时和服务端断开链接错误做相关处理

d)Thrift Client线程不安全(就因为这点,我在做的系统不考虑用thrift了),多线程下使用可能导致崩溃。查看源码得知,该client线程不安全有多种:第一在TAsyncClient中有一个___currentMethod 

变量,每次调用某个接口时会new一个method_call并赋值,然后在回调成功时设置为null,当不为空时会直接抛出IllegalStateException异常,也就是说一个client不能真正完成并发操作。第二,client的每次调用远程方法有多次Socket写操作,如果多个线程混用同一个client,可能会导致传输的字节顺序混乱。

e) java中AsyncClient只有在调用远程方法时,才会真正跟server进行链接,而且错误是会调用至客户端的callback,也就是说判断是否断开,是否服务可用,需要调用一次远程函数才能获得(当然可以定时调用某函数实现之)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: