`
lsy
  • 浏览: 123002 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

正确认识分布式异构环境下的异步服务和应用场景设计

 
阅读更多

基础知识

首先,“异步服务”完整的解释应该是客户端以异步通信的方式调用Web服务;而非服务端必需要实现一个异步处理机制的服务端Web服务;

其次,应用架构设计中是否应用“异步服务”完全取决于客户端应用场景所需,服务端应用无需刻意进行任何设计和实现;

因此,基于以上理解,切勿走近实现异步业务场景,必须由服务端配合实现的误区。

异步通信的应用场景

谈为何需要应用异步通信时,首先,需要搞清楚异步通信相对同步而言所产生的价值及收益,其次,要明白什么应用场景需要使用异步通信,是否必须一定要异步通信。异步通信顾名思义就是以多线程的方式对发送请求和接受响应进行分离,从而实现在请求发出后,不需要线程等待,可以充分利用时间、资源处理其他任务,待请求处理完成响应返回时,再次接管线程实现后续业务逻辑处理。一切听起来都很美妙,那么是否所有请求调用都应该作为异步请求调用,并且适用于所有场景呢?其实不然,下一小节分析异步通信的弊端,这里描述一下应用场景,根据多年分布式异构系统ESB总线平台构建的实施经验,归纳为以下三个:

1、  服务端所提供服务相对独立,接口运行稳定,且变更(主动回调)成本代价非常高

2、  服务端所提供服务业务逻辑复杂,处理耗时较长

3、  服务端与客户端部署于同一网络组网,并且相互之间防火墙网络策略透明,网络通信稳定

抛离上述三个场景,均不建议大规模使用异步通信,否则很有可能产生灾难性的故障。因此,从其他方面考虑如何实现异步的场景,正如本文后续章节所建议的方案。

异步通信并非万能

设想考虑一个场景,目前需求需要构建一个机票代购平台的二级代售平台。因此,需要通过各大航空公司获取航班信息和机票信息,但是获取这些信息的服务水平协议(SLA)和服务质量(Qos)完全依赖于航班公司提供的外部服务,由于提交请求的时间、参数不同,很有可能得到操作响应的时间不同,若在节假日高峰期(假设耗时很长、逻辑处理相当复杂)出现等待超时则将严重影响客户满意度,从而流失客户资源。那么异步通信可以多线程进行任务处理,目前的需求场景是否就应该使用异步通信呢?其实答案是否定的,其原因如下:

1、  航班信息接口服务相对稳定,并且为多个代理终端服务,不会因为某一个代理商变更,实现接受请求,进行业务处理,主动回写代理终端接口

2、  航班信息接口服务网络环境与代理终端均在公网,通信都基于TCP/IP,因此如果服务端宕机或网络故障,将导致代理终端出现网络堵塞,同样会出现网络等待超时的异常。

 

所以,该场景并不适合使用异步通信。而实际上,航班数据接口,代理终端也是通过同步的方式进行实时通信在线查询,并且设置每次会话最大时长和最大错误重试的次数限制。

因此,在未充分考虑应用场景和各系统软硬件背景的情况下,不建议大规模使用异步服务,异步场景在请求发出后,客户端都要维护一个等待回写的进程,服务端完成业务逻辑进行响应时,客户端要关联正确的远程会话,从而执行准确无误的读取。而这样的方式分布式异构平台下,且每个系统均为多机多实例的集群架构时,客户端维护等待进程并关联正确会话信息并不容易,这不仅要考虑网络、各系统可靠性和可用性,还要考虑客户端系统内本身硬件服务器上下文、资源连接、应用会话等,一旦大规模纯粹的异步服务应用场景存在,很有可能失控,导致服务端挂起的进程堵塞,客户端多次尝试回写失败,各方问题排查受阻,反而影响业务正常运转。

所以,建议纯粹的异步通信服务仅仅在时效性要求特别高的少数应用场景使用,并且必须经过各系统模拟真实生产环境中多机多实例集群架构测试,衡量异步回写成功率,从而决定该异步服务是否满足Qos指标,再慎重评估能否接入使用。

JAX-WS异步实现

JAX-WS编程模型相对于JAX-RPC编程模型而言,其中一个优势就是对异步通信调用服务支持。因此,当决定以异步通信的方式调用一个Web服务时,最常用的方式就是按照JAX-WS编程模型开发服务客户端程序。下面介绍一下几个重要环节:

1、  服务客户端支持JDK 5.0

2、  JAX-WS启用JAXB的数据映射,并且配置异步映射,如下代码:

true

3、  一切从WSDL开始,养成良好的习惯。通过服务生产客户端程序的异步调用代码,如下所示:

   

    @WebMethod(operationName = "process")

    public Response<com.zte.soa.ucloudapp.helloworld.helloworldbpelprocess.ResponseParameters> processAsync(

        @WebParam(partName = "payload", name = "requestParameters", targetNamespace = "http://soa.zte.com/ucloudApp/HelloWorld/HelloWorldBPELProcess")

        RequestParameters payload

    );

 

    @WebMethod(operationName = "process")

    public Future<?> processAsync(

        @WebParam(partName = "payload", name = "requestParameters", targetNamespace = "http://soa.zte.com/ucloudApp/HelloWorld/HelloWorldBPELProcess")

        RequestParameters payload,

        @WebParam(name = "asyncHandler", targetNamespace = "")

        AsyncHandler<com.zte.soa.ucloudapp.helloworld.helloworldbpelprocess.ResponseParameters> asyncHandler

    );

 

    @WebResult(name = "responseParameters", targetNamespace = "http://soa.zte.com/ucloudApp/HelloWorld/HelloWorldBPELProcess", partName = "payload")

    @WebMethod(action = "process")

    public ResponseParameters process(

        @WebParam(partName = "payload", name = "requestParameters", targetNamespace = "http://soa.zte.com/ucloudApp/HelloWorld/HelloWorldBPELProcess")

        RequestParameters payload

    );

SayHiEp ss = new SayHiEp(wsdlURL, SERVICE_NAME);

HelloWorldBPELProcess port = ss.getHelloWorldBPELProcessPt();

  RequestParameters _payload = new RequestParameters();

  _payload.setInput("lishuyi");

        {

                 System.out.println("同步调用 process... ");

                 ResponseParameters response = port.process(_payload);

                 System.out.println("process.result=" + response.getOutput());

        }       

        {

                 System.out.println("异步回调 process...");

                 ProcessCallBackAsync _asyncHandler =  new ProcessCallBackAsync();

                 Future<?> response = port.processAsync(_payload, _asyncHandler);

                 while (!response.isDone()) {

                     Thread.sleep(1000);

                 } 

                 ResponseParameters output = _asyncHandler.getOutput();

                 System.out.println("process.result=" + output.getOutput());

        }      

       

        {

                 System.out.println("异步无阻塞轮询 process...");             

            Response<ResponseParameters> response = port.processAsync(_payload);

            while (!response.isDone()) {

                Thread.sleep(1000);

            }

            ResponseParameters output = response.get();

            System.out.println("process.result=" + output.getOutput());

        }

       

        {

                 System.out.println("异步阻塞轮询 process...");

                 Response<ResponseParameters> response = port.processAsync(_payload);

                 ResponseParameters output = response.get(120000, TimeUnit.SECONDS);  //wait 2 minutes

            System.out.println("process.result=" + output.getOutput());

        }

上述代码,分别演示了对一个外部Web服务的四种调用方式:

1)  传统的同步调用

2)  异步回调,需要实现一个自定义的AsyncHandler,并且返回在返回java.util.concurrent.Future的方法中实现响应回写

3)  异步无阻塞轮询,在返回javax.xml.ws.Response的方法中获取响应

4)  异步阻塞轮询,设置最大等待时间

上述代码可以清楚的看到:

a)       是否异步通信的方式调用完全取决于客户端

b)       异步回调与异步轮询都需要设置线程等待

c)       异步回调与异步轮询均基于java.util.concurrent实现

非异步通信方式实现异步场景

既然客户端使用异步通信的方式调用Web服务存在诸多隐患,那么如何解决切实需要异步应用场景呢?这里建议以下两个方案:

1、JMS消息队列

最为有效,并且可以实现服务端与客户端的高可用性和完全解耦,即便某方系统发生故障后,再完成故障恢复或失效转移后,通信数据依旧可以重建,详细方案介绍参考:http://t.cn/zWT9Bap

2、两次同步调用

如果条件允许,尤其是企业内ESB总线上的两个系统通信,那么可以在服务请求客户端再额外实现一个响应接受服务端接口;而在服务请求服务端再额外实现一个响应接受发送客户端程序。那么数据交互模式可以由一个异步的场景,变成两个同步的场景,即客户端在提交完成请求后,服务端马上给予接收到请求的答复反馈;之后服务端可以在闲时进行后台的业务处理,但业务处理完成后再将结果以请求的方式发给调用的客户端,客户端给予服务端收到响应的答复反馈。

BPEL中的异步处理

BPEL(Business Process Execution Language)是JAX-RPC和JAX-WS以外的实现Web Service的另外一套标准规范和实现,并且已纳入OASIS标准。在BPEL规范制定之初,就已经注意到了客户端使用异步通信调用服务的弊端,因此BPEL在实现Web Service的时候,刻意将BPEL划分为Synchronous BPEL Process 和 Asynchronous BPEL Process。其目的就是要客户端程序将同步调用和异步调用严谨的区分开来。对于Synchronous BPEL Process的客户端,BPEL 提供了two-way operation 的调用方式,即一个同步BPEL服务的调用,客户端既有输入也有输出;而对于Asynchronous BPEL Process的客户端,BPEL提供了两个one-way operation 的调用方式,即一个异步的BPEL服务的调用,客户端有一个提交请求的调用,并且还有一个提交获取响应的调用。通过这样的方式,避免同步的BPEL服务设计客户端使用异步通信的方式调用,提前识别出了风险,并且进行的不同方式架构设计。

BPEL原生的API实现方式,对于BPEL服务的two-way operation和one-way operation 方式调用,都可以通过以下三个类进行客户端代码的编写实现:

com.oracle.bpel.client.Locator ----连接BPEL Process Manager

com.oracle.bpel.client.dispatch.IDeliveryService ----定位BPEL服务

com.oracle.bpel.client.NormalizedMessage ---- 提交调用请求,two-way operation 方式对应request方法;one-way operation 方式对应post方法。详细可参考官网介绍:http://docs.oracle.com/cd/B14099_19/integrate.1012/b14448/invoke.htm#BABJJJCC

在我们实际项目中,由于构建企业总线平台,与诸多系统打交道,因此不可能要求所有系统都采用BPEL原生的API实现客户端,强迫各业务系统对BPEL产生依赖,因此我们实际的架构设计采用上述方案提到的“两次同步调用”的方式。即BPEL服务接受到请求后,在其后台进行逻辑处理,待完成后主动将结果回写到客户端提供的接受响应结果的Web Service接口中,代码片段设计如下:



总结

最后用一句广告词形容客户端以异步通信的方式调用Web服务:“异步虽好,可不要贪恋哦!”

分享到:
评论

相关推荐

    基于J2EE的Web Service分布式应用研究.pdf

    基于J2EE的Web Service分布式应用研究涉及的技术领域非常广泛,从文档中提取的知识点包含了J2EE技术、Web Service技术、分布式系统设计、服务架构、以及异步与同步服务模式等多个方面。 1. J2EE技术:J2EE(Java 2 ...

    JMS和XML的分布式应用研究.pdf

    JMS与XML的结合在很多场景下都有应用,如企业服务总线(ESB)、事务处理、事件驱动架构(EDA)等。一个具体的例子可能是在电子商务系统中,订单信息以XML格式创建并发送到JMS消息队列,然后由后台服务异步处理,如...

    对几种典型分布式计算技术的比较.pdf

    中间件技术是一种位于操作系统和应用软件之间的基础性软件,属于可复用软件的范畴。中间件起着一个桥梁的作用,它在操作系统、网络和数据库之上,应用软件之下,其主要功能是为上层的应用软件提供各种通用的服务。...

    异步场景下的全栈溯源.pdf

    ### 异步场景下的全栈溯源 #### 异步模式的典型场景 在现代软件架构设计中,异步处理已成为解决复杂系统问题的关键技术之一。它不仅能够提高系统的响应速度和吞吐量,还能增强系统的可扩展性和健壮性。在异步模式...

    分布式数据库DragonBase架构设计与实践.pdf

    综上所述,DragonBase分布式数据库不仅体现了数据库技术的演进历程,还展示了云原生环境下的分布式数据库设计原则和关键技术,旨在提供高可用、高性能、强一致性的数据库服务,以满足金融级和其他对数据要求极高的...

    分布式算法导论原书第2版

    《分布式算法导论原书第2版》这本书主要围绕分布式计算环境下的算法设计与分析进行展开。分布式算法是计算领域中一个非常重要的分支,它涉及如何在多个机器之间分割计算任务,以及如何协调这些机器完成任务。分布式...

    Go在分布式数据库中的应用

    在分布式数据库的开发中,需要考虑的关键特性包括但不限于水平扩展、一致性、分布式事务处理、数据一致性和可用性的权衡、异构数据库之间的数据迁移和交互等。 Go语言在分布式数据库中的应用实例主要表现为以下几点...

    一种基于JSON的分布式系统架构.pdf

    根据给定文件内容,知识点可从多个方面详细展开: 一、分布式系统架构概述 分布式系统架构是一种计算方法,它将...随着技术的不断进步和应用场景的扩展,这些知识点在未来的技术发展中仍然具有重要的指导和应用价值。

    分布式数据库的研究新趋势.pdf

    在异构分布式数据库中,各数据库在保证各自独立性和安全性的前提下,实现透明信息共享和数据访问,从而将这些异构数据库统一管理为一个分布式数据库。这样的设计可以有效节省信息存储空间并提高信息访问量。 异构...

    共享经验分布式Q-学习模型在RoboCup中的应用.pdf

    RoboCup仿真比赛提供了一个完全分布式控制、实时异步的多智能体环境,使得它成为多智能体智能控制和人工智能理论研究的理想实验平台。在这个环境中,每个队伍由一个教练服务器和五个全自治的队员组成,所有队员共享...

    基于分布式计算框架的通信对抗系统研究.pdf

    为了实现有效的通信体系架构,采用的是客户端/服务器应用体系结构,该结构由注册服务器、消息服务器和应用程序接口组成。其中,注册服务器管理应用程序的注册信息,如名称、IP地址和端口号;消息服务器负责处理消息...

    6种分布式事务最终一致性解决方案,一次性说清.docx

    在设计分布式事务时,我们需要关注系统的高可用性、数据的最终一致性、服务的独立演化和部署能力,以及对异构数据存储的支持。同时,低侵入性和对同步/异步流程的支持也是重要的考虑因素。在实际应用中,架构师需要...

    基于SOA技术架构的多并发异构业务系统中台技术设计.pdf

    5. **数据一致性**:在分布式环境下,保持数据的一致性是挑战,可以借助CAP理论和分布式事务解决方案,如2PC、TCC、Saga等。 6. **监控与日志**:实时监控服务性能,记录日志,以便于问题排查和优化。 总结来说,...

    藏经阁-FLASH_大规模分布式图计算引擎及应用.pdf

    该引擎的设计目标是解决在分布式环境中如何高效地进行图计算的问题,以应对日益增长的数据量和复杂的数据关系。FLASH的全称可能意味着“Fast Large-scale Graph Computing”,强调其在处理大规模图数据时的速度和...

    论文研究-在CORBA中实现异步调用.pdf

    CORBA提供了一种机制,使得在分布式异构计算环境中实现对象间的互操作成为可能。 接下来,我们深入探讨四种异步激发方式: 1. 多线程方式:在多线程方式中,客户端应用程序创建一个或多个线程来处理从服务器对象...

    强一致、高可用、高性能分布式Log存储系统的设计与实现_简怀兵@YY Research Lab.pdf

    7. **应用场景**:分布式Log存储系统可以作为其他分布式系统的"积木",如分布式Cache、分布式K/V、分布式消息队列和分布式数据库等的底层支撑,提供通用的功能模块。 8. **架构设计**:系统采用分布式Log存储架构,...

    网络与分布式计算复习提纲05710.doc

    中间件是介于操作系统和应用软件之间的一层软件,它提供服务以便于应用之间的资源共享和通信。功能包括命名服务、作业调度、高级通信、资源管理等。中间件在分布式系统中起到桥梁作用,隐藏底层平台的异构性,提供...

    基于Spark的分布式大数据分析算法研究.pdf

    分布式开发强调在多节点环境中编程和管理任务的能力,使得开发人员可以在分布式系统上构建、部署和管理应用。 2. Apache Spark框架 Apache Spark是一个开源的分布式大数据处理框架,提供了一个快速、通用且高级的...

Global site tag (gtag.js) - Google Analytics