thrift-client异步+server非阻塞

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()

  1. while(true){
  2. Thread.sleep(1);
  3. }

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

另外如果加入访问超时时间,需要调用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,也就是说判断是否断开,是否服务可用,需要调用一次远程函数才能获得(当然可以定时调用某函数实现之)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值