thrift-client异步+server非阻塞

来源:互联网 发布:淘宝卖家怎么快速升心 编辑:程序博客网 时间:2024/06/18 12:36

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

0 0
原创粉丝点击