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

Missian:异步客户端使用指南(转)

 
阅读更多

 

重要:Missian刚刚更新到0.31,新增了Future风格的回调方式。

 

Missian没有绑定spring,但是强烈推荐配合spring一起使用。异步客户端由于需要调用BeanLocator去寻找回调的 Bean,如果配合Spring使用,可以直接使用SpringLocator(BeanLocator的唯一实现),否则需要自己实现。

 

使用异步客户端需要注意一点:由于是异步调用,所以一个远程方法的返回值永远是null(如果不是void的话)或者是原生数据类型的默认值。一段时间后(比如100毫秒)后客户端收到这个返回值,会去找到相应的回调对象进行调用。

 

异步的优势是:在调用的期间我们不需要像同步调用一样有一个线程一直在等着它的返回值,而是调用完即可返回释放线程,当客户端接受到返回值后会进行 回调,业务流程可以继续往下执行。不要小看这个等待的时间,假如A服务调用了一个跨机房的服务或者一个重型的服务B,那么B的响应时间可能是100毫秒甚 至更多,那么可以想象在高并发的情况下,可能A服务的全部线程都耗死在无穷的等待上了。

 

我们还是先看看如何配合Spring来使用Missian异步客户端。

 

步骤一:给Hello.hello(String, int)创建一个回调类

注意和0.2x相比,这里有比较大的不同:

Java代码  收藏代码
  1. public class HelloCallback {  
  2.     public void hello(String returnValue) {  
  3.         System.out.println(returnValue);  
  4.     }  
  5. }  

这个类的方法要和Hello接口的方法一一对应,Hello中所有方法(除了返回值为void的方法)都应该有一个回调方法,回调方法名和Hello接口中对应的方法名一样,而且只接受一个参数,参数类型和对应方法的返回值一致。

 

例如,Hello有一个hello(String, int)方法的返回值是String类型,那么要求HelloCallback必须有一个hello(String)的方法。

 

 

步骤二:修改Hello接口,用注解的方法声明回调Bean

这里和0.21前的版本也有所不同,以前这个注解是用在方法上的,现在直接用在接口上,所以一个接口只需要注解一次了。

Java代码  收藏代码
  1. @CallbackTarget("helloCallback")  
  2. public interface Hello {  
  3.     public String hello(String name, int age);  
  4. }  

 

步骤三:在Spring配置文件中配置这个回调Bean

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  5.     <!-- your callback bean, missian client will invoke its execute() method when received the returned object -->  
  6.     <bean id="helloCallback" class="com.missian.example.bean.HelloCallback">  
  7.     </bean>  
  8. </beans>  

 

步骤四:在Spring中创建AsyncMissianProxyFactory

Xml代码  收藏代码
  1. <bean id="asyncMissianProxyFactory" class="com.missian.client.async.AsyncMissianProxyFactory" init-method="init" destroy-method="destroy">  
  2.     <constructor-arg >  
  3.         <bean class="com.missian.common.beanlocate.SpringLocator"/>  
  4.     </constructor-arg>  
  5. </bean>  

这里我们使用的是AsyncMissianProxyFactory的最简单的构造函数,只接受一个BeanLocator。这时候默认创建一个4 个线程的线程池用来处理回调逻辑,1个线程用来处理IO,需要指定线程数,或者将一个已经存在的线程池传入,可以参考其它几个构造函数:

Java代码  收藏代码
  1. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, ExecutorService threadPool,  int callbackIoProcesses, boolean logBeforeCodec, boolean logAfterCodec, NetworkConfig networkConfig) {}  
  2. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, ExecutorService threadPool,  int callbackIoProcesses, boolean logBeforeCodec, boolean logAfterCodec){}  
  3. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, ExecutorService threadPool) {}  
  4. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, int threadPoolSize, int callbackIoProcesses, boolean logBeforeCodec, boolean logAfterCodec) {}  
  5. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, ExecutorService threadPool, NetworkConfig networkConfig) {}  
  6. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, int threadPoolSize, int callbackIoProcesses, boolean logBeforeCodec, boolean logAfterCodec, NetworkConfig networkConfig) {}  
  7. public AsyncMissianProxyFactory(BeanLocator callbackLoacator, int threadPoolSize){}  

假如在服务器里使用Missian客户端,可以考虑将服务器主线程池传入给AsyncMissianProxyFactory,共享线程池。 

 

步骤五:实现异步调用

 

Java代码  收藏代码
  1. public static void main(String[] args) throws IOException {  
  2.     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/missian/example/client/async/withspring/applicationContext-*.xml");  
  3.     //actually you can inject AsyncMissianProxyFactory into any other beans to use it.  
  4.     //we just show how AsyncMissianProxyFactory works here.  
  5.     AsyncMissianProxyFactory asyncMissianProxyFactory = (AsyncMissianProxyFactory)context.getBean("asyncMissianProxyFactory");  
  6.     Hello hello = (Hello)asyncMissianProxyFactory.create(Hello.class"tcp://localhost:1235/hello");  
  7.     long time = System.currentTimeMillis();  
  8.     for(int i=0; i<10000; i++) {  
  9.         hello.hello("gg"25);    
  10.     }  
  11.     System.out.println(System.currentTimeMillis()-time);  
  12. }  

 你可以清楚地看到,所有的请求都发送出去之后,返回值陆续返回并回掉了HelloCallback。

和同步的客户端一样,可以使用http协议发送数据:

Java代码  收藏代码
  1. Hello hello = (Hello)asyncMissianProxyFactory.create(Hello.class"http://localhost:1235/hello");  

但目前比较遗憾的是,还不能够支持异步调用Hessian服务。  

另外需要说明的是,这个直接从Context里面取出AsyncMissianProxyFactory只是用来演示异步调用的用法;正常的做法应该是将AsyncMissianProxyFactory注入到我们需要使用它的Bean。

 

===============0.31.新增功能分割线===================

 

如何为重载方法都实现回调?

比如以下两个方法都需要回调:

Java代码  收藏代码
  1. public interface Hello {  
  2.     String hello(String name, int age, String country);  
  3.     String hello(String name, int age);  
  4. }  

 按照上面所说的,他们的回调方法都映射到:

Java代码  收藏代码
  1. void hello(String);  

 这样会造成回调错误,因此需要使用一个注解来说明回调方法名:

Java代码  收藏代码
  1. @CallbackTarget("helloCallback")  
  2. public interface Hello {  
  3.     @CallbackTargetMethod("hello0")  
  4.     public String hello(String name, int age, String country);  
  5.   
  6.     @CallbackTargetMethod("hello1")  
  7.     public String hello(String name, int age);  
  8. }  

 对应的,回调类的实现:

Java代码  收藏代码
  1. public class HelloCallback {  
  2.     public void hello0(String returnValue) {  
  3.         System.out.println(returnValue);  
  4.     }  
  5.     public void hello1(String returnValue) {  
  6.         System.out.println("hello1:"+returnValue);  
  7.     }  
  8.       
  9. }  

 注意如果不使用注解,系统寻找默认的方法。注解同样也可以用于非重载的方法。

 

另外一种回调的实现

如果不希望使用注解,那么还有另外一种方式可供选择:

如果服务器端的方法是:

Java代码  收藏代码
  1. String hello(String name, int age);  

 那么客户端的接口可以写成(注意,Missian不要求服务器端和客户端使用同一个接口类,甚至接口名都可以不同,而只要求方法名及参数必须匹配):

Java代码  收藏代码
  1. public interface Hello {  
  2.     public String hello(String name, int age, Callback cb);  
  3. }  

 调用时:

Java代码  收藏代码
  1. Hello hello = (Hello)factory.create(Hello.class"http://localhost:1235/hello");  
  2. Callback cb = ......  
  3. hello.hello("name"80, cb);  

 即可以异步调用成功。

 

Future风格的异步实现

我个人非常喜欢Future这种方法,在Mina中就有大量的使用。同样Missian也提供了这样一个能力。提供了一个AysncFuture,即可以通过get()变成同步,也可以通过addListner()来监听,一旦返回值到达,就会出发监听器。

 

如果服务器端的方法是:

Java代码  收藏代码
  1. String hello(String name, int age);  

 那么客户端的接口可以写成(注意,Missian不要求服务器端和客户端使用同一个接口类,甚至接口名都可以不同,而只要求方法名及参数必须匹配):

Java代码  收藏代码
  1. public interface Hello {  
  2.     public AysncFuture<String> hello(String name, int age, Class<String> returnType);  
  3. }  

 调用时:

Java代码  收藏代码
  1. Hello hello = (Hello)factory.create(Hello.class"http://localhost:1235/hello");  
  2. Async<String> future = hello.hello("name"80, String.class);  

 如果想阻塞直到数据返回,那么:

Java代码  收藏代码
  1. String value = future.get();  
  2. System.out.println(value);  

 如果想通过监听器实现事件驱动:

Java代码  收藏代码
  1. AsyncListener listener = ....  
  2. future.addListener(listener);  
 

 

分享到:
评论

相关推荐

    missian:一个java RPC框架,无模式风格

    1. **克隆源码**:使用Git工具克隆"missian-master"仓库到本地。 2. **构建项目**:通过Maven或Gradle等构建工具编译源代码。 3. **阅读文档**:查看项目文档以了解如何配置和服务调用。 4. **编写客户端和服务端**...

    Spring集成ActiveMQ配置

    6. **Missian ActiveMQ-JMS简单实例**:这可能是一个具体的项目实例,它展示了如何在Spring应用中使用ActiveMQ实现异步RPC(远程过程调用)。在这种模式下,一个服务通过消息将请求发送到队列,另一端的服务监听队列...

    基于WoodandBerry1和非耦合控制WoodandBerry2来实现控制木材和浆果蒸馏柱控制Simulink仿真.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    (源码)基于Spring Boot框架的用户管理系统.zip

    # 基于Spring Boot框架的用户管理系统 ## 项目简介 本项目是一个基于Spring Boot框架的用户管理系统,主要用于实现用户的注册、登录、权限管理等功能。项目使用了Spring Security框架进行身份验证和权限控制,结合JWT(JSON Web Token)实现无状态的会话管理。此外,项目还集成了SQLite数据库,简化了数据库的安装和配置。 ## 项目的主要特性和功能 1. 用户管理 用户注册、登录、登出功能。 用户信息的增删改查操作。 用户密码的修改和重置。 2. 权限管理 使用Spring Security进行权限控制。 通过JWT实现无状态的会话管理。 动态配置权限白名单,允许特定URL无需认证访问。 3. 系统监控 获取服务器的基本信息,如CPU、内存、JVM状态等。 提供服务器重启功能。 4. 邮件服务

    基于springboot企业员工薪酬管理系统源码数据库文档.zip

    基于springboot企业员工薪酬管理系统源码数据库文档.zip

    Linux 操作系统3D显示性能测试工具 Glmark2

    Glmark2是Linux操作系统下广泛使用的3D图形性能测试工具,测试步骤: 1、搭建编译环境,安装必要的依赖项 sudo apt-get install g++ build-essential pkg-config sudo apt-get install libx11-dev libgl1-mesa-dev sudo apt-get install libjpeg-dev libpng-dev 2、执行配置、编译、安装命令: ./waf configure --with-flavors=x11-gl ./waf build -j 8 ##(8表示CPU核数) sudo ./waf install 3、终端中运行:$glmark2 4、等待测试完成(10min左右),结果分数越高,表示性能越好。

    (源码)基于物联网的地震预警系统.zip

    # 基于物联网的地震预警系统 ## 项目简介 随着自然灾害如风暴、地震、热浪和洪水等事件频率的增加,对这些事件的预测和了解的需求也日益凸显。本项目专注于地震预警系统,旨在利用物联网技术提供及时预警,对于保障安全和减少财产损失具有重要意义。 ## 项目目标 主要目标是开发一个能够检测地震早期预警信号的原型系统。该系统旨在通过可靠且高效的预警系统在地震多发区域提高安全性和应急准备。 ## 项目的主要特性和功能 1. 显示机制使用0.96英寸OLED显示屏和Adafruit NeoPixel Stick来展示地震数据。 2. 音频输出集成蜂鸣器以提供可听警告。 3. 电源来源采用Arduino Uno REV3作为电源。 4. 地震检测使用SW420振动传感器。 5. 时间保持引入DS3231实时时钟以准确记录事件。 6. 多级预警根据振动强度,系统能够触发不同级别的视觉和听觉警告。 ## 安装使用步骤 1. 硬件连接

    keil5.26开发编译环境

    keil5.26开发编译环境

    (源码)基于TensorFlow的中文文本分类系统.zip

    # 基于TensorFlow的中文文本分类系统 ## 项目简介 本项目是一个基于TensorFlow的中文文本分类系统,使用卷积神经网络(CNN)和循环神经网络(RNN)进行文本分类。项目涵盖了从数据预处理、模型训练、模型评估到模型预测的全流程,旨在提供一个高效的中文文本分类解决方案。 ## 主要特性和功能 数据预处理包括读取文件数据、构建词汇表、转换分类目录、将文本数据转换为ID序列表示等。 模型构建实现了基于CNN和RNN的文本分类模型,支持LSTM和GRU作为RNN的单元。 模型训练提供了详细的训练配置,包括学习率、批次大小、迭代轮次等参数的设置。 模型评估在验证集上评估模型的性能,输出准确率、损失等信息,并生成混淆矩阵。 模型预测加载训练好的模型,对新的文本消息进行分类预测,并输出预测类别。 ## 安装使用步骤 1. 环境准备 安装Python 23 安装TensorFlow 1.3以上

    基于springboot的智慧医疗采购系统源码数据库文档.zip

    基于springboot的智慧医疗采购系统源码数据库文档.zip

    【重磅,更新!】上市公司绿色专利等绿色发展数据合集(1991-2022年)

    1、资源内容地址:https://blog.csdn.net/abc6838/article/details/143896285 2、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题 3、适用对象:大学生,本科生,研究生小白可用,容易上手!!! 4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理

    基于SpringBoot+Vue的志愿者招募管理系统源码数据库文档.zip

    基于SpringBoot+Vue的志愿者招募管理系统源码数据库文档.zip

    Ruby 学习教程(入门到实践)

    本教程介绍了 Ruby 的基础语法、面向对象特性和高级功能(如代码块、异常处理和元编程),并提供了练习任务及其答案,帮助您快速入门并熟悉 Ruby 的强大功能。通过完成这些任务,您可以轻松掌握 Ruby 编程的核心技能。

    (源码)基于C++的日志数据管理系统.zip

    # 基于C++的日志数据管理系统 ## 项目简介 本项目是一个基于C++的日志数据管理系统(DMS),主要用于在Linux环境下采集、处理和发送日志数据。系统通过读取日志文件、处理登录记录、匹配登录和登出记录,并将处理后的数据发送到服务器。项目结合了多线程技术,确保数据处理的效率和系统的响应性。 ## 项目的主要特性和功能 1. 日志读取与处理 读取日志文件并处理其中的登录记录。 匹配登录和登出记录,保存匹配和未匹配的记录。 处理字节序问题,确保数据准确性。 2. 日志数据发送 向服务器发送处理后的日志数据。 处理发送失败的情况,保存未成功发送的日志记录。 3. 多线程支持 使用多线程技术处理日志读取和发送,提高系统的并发处理能力。 通过线程间通信实现界面更新和数据处理。 4. 用户界面 提供基于Qt的客户端界面,用于显示数据和控制客户端操作。

    376大神asp.net城市出租车状态查询网站毕业课程源码设计

    编号:463 开发软件: Vs2008以上版本 数据库: sqlserver2005以上版本 开发语言和技术: C#结合三层开发模式 系统功能: 出租车管理查询系统开发设计要求能根据出租车的特点,时刻记录着车的实际位置,如经纬度、车速、方向,载客等情况,根据该系统可以方便用户快速的查询到车辆的状态位置等。因此要求系统具有录入、修正、查询、统计、分析等功能。采用asp.net和sqlserver来完成 出租车辆管理 出租车公司 驾驶员管理 模拟真实数据给一个录入模块根据时间查询其当时位置 前台可以查看车辆信息 驾驶员信息 出租公司信息 出租车运行路线查询 可以留言

    基于springboot的招聘求职系统源码数据库文档.zip

    基于springboot的招聘求职系统源码数据库文档.zip

    (源码)基于Arduino的温湿度监测显示系统.zip

    # 基于Arduino的温湿度监测显示系统 ## 项目简介 该项目旨在设计一个基于Arduino的温湿度监测显示系统。通过DHT11温湿度传感器采集数据,并通过LCD显示屏展示温度和湿度信息。此外,项目还包含一个简单的状态图标显示功能。整个系统采用Arduino Uno作为主控板,操作简单,便于用户随时查看当前环境的温湿度情况。 ## 项目的主要特性和功能 1. 温湿度监测使用DHT11温湿度传感器实时监测环境温湿度。 2. LCD显示通过LCD显示屏展示温度和湿度信息,支持两行显示,每行最多显示16个字符。 3. 状态图标根据当前温度展示不同的状态图标,用于快速了解当前环境状况。 4. 简单易懂界面简洁明了,操作方便,适合各种用户群体使用。 ## 安装使用步骤 1. 硬件准备准备Arduino Uno、LCD显示屏、DHT11温湿度传感器、i2c模块等硬件。 2. 连接硬件按照项目中的Pinout图连接各硬件组件。

    基于springboot高校创新创业课程体系源码数据库文档.zip

    基于springboot高校创新创业课程体系源码数据库文档.zip

    NS3中CSMA模型介绍和数据收发流程代码分析

    文档讲述了NS3中CSMA模型介绍(包括信道模型、网络设备、MAC和PHY等),并对CSMAHelper代码中数据收发处理流程、CSMA退避机制和状态机切换进行分析。

    IEEE 14节点标准模型的柴油发电机、光伏模型、电池储能系统、电弧炉等非线性负载复合微电网模型Simulink仿真.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

Global site tag (gtag.js) - Google Analytics