`

关于“异步”,从Amazon的工作流框架中获得的思考

阅读更多

紧接着上篇文章云平台的工作流框架AWS Flow Framework给我带来的另一个有所感触的话题是“异步”:

 

 

这个框架把异步的行为划分为Workflow端执行的部分和Activity端执行的部分,Workflow控制工作流程,Activity执行具体的工作流task,二者都以poll的模式不断从中心SWF去获取任务。对于开发者来说,用类似这样简单的代码,就完成了整个工作流任务的部署,框架为开发人员隐藏了大部分实现细节:

 

@Workflow
public interface CalculateWorkflow
{
    @Execute
    public void calculate();
}

public class CalculateWorkflowImpl implements CalculateWorkflow
{
    ……
    public void calculate()
    {
        Promise<String> val1 = activity1.calc();
        Promise<String> val2 = activity2.calc();
        
        printResult(val1, val2);
    }

    @Asynchronous
    public void printResult(Promise<String> val1, Promise<String> val2)
    {
        System.out.println("Result: " + val1 + " and " + val2);
    }
}

 

对于这样一段代码(再配合Activity的代码),做了两点处理:

1、activity调用的逻辑,返回值通过Promise包装:

 

Promise<String> val1 = activity1.calc();
Promise<String> val2 = activity2.calc();

 

2、@Asynchronous所修饰的方法会被处理成本地执行的异步方法,其中的参数使用Promise包装:

 

public void printResult(Promise<String> val1, Promise<String> val2)

 

这样一来,这里面包含了三个异步任务:

a、Activity1端执行的 activity1.calc(),

b、Activity2端执行的 activity2.calc(),

c、等待上述两个任务执行完毕后再在Workflow端执行的printResult。

 

其中,使用Promise包装的参数,它的作用就在此,在上述两个异步的Activity方法执行返回后,才会触发printResult方法的执行(printResult方法依赖于两个Activity方法执行结果的返回 ),可是,这和一般等待执行的异步流程merge操作不同的是,在等待过程中它不会block住线程(反例可以参考Future类,它的get方法是会block住线程的) ,最大限度地减少了资源的占用。

 

这只是其中利用异步的设计,给我印象很深刻的一个场景。对于减少资源占用,我们还经常接触到许多其它类似的场景,比如NIO Server,这是多路复用技术的一种。

传统服务器接收到请求以后,从request到response,整个过程占住一个线程不放,但是这种服务器可以在收到请求之后,将需要完成的工作用一个或若干个Command包装好,交给线程池中的工作线程去完成,对于收到请求和返回响应这样的过程,使用1~2个独立的线程去完成,在事件发生时,系统线程才通知这1~2个线程去完成和客户端的一次交互(或者用监控线程去轮询当前挂在Server上所有的连接,寻找需要响应的连接来完成交互)。

当在线用户数量大大超出服务器的线程数时,使用NIO模式可以保证在收到请求和返回响应的用户接口层不成为瓶颈

另外还有一个特别值得一提的场景,由于互联网的BS模式下,从Server实时或准实时地向Client推送一些东西是比较麻烦的(有同学说用pushlet来解决,但这个办法有很大的局限性),有一种解决这个问题的办法是客户端使用ajax去定期获取数据(比如现在的很多SNS网站都用了这种办法),在这种情况下服务端对请求处理的压力就陡然增大了。

 

Nginx是一款高性能的代理服务器,性能高的其中一个重要原因是,它基于epoll模型设计的。与之相对的是select模型,select采用的是轮询的办法,每次读写状态检测都检查FD_SET中所有的句柄,当句柄数量增大时,这个过程消耗的时间应该是线性增长的。另外,FD_SIZE也设定了整个可开启的句柄数,这造成了另一种局限。

epoll模型就没有这两个问题,它给每个活跃FD挂接一个异步回调函数,不需要第三方去遍历和调用这些句柄,而它的句柄限制是操作系统的限制

 

关于Continuation Server。这种模式下Client和Server会调过来,Continuation Server发送页面给客户端,作为function call,然后等待客户端返回执行结果(SendPageAndWait),因此,在服务端收到响应的时候,要恢复之前方法调用的上下文环境,继续执行收到响应后的下一行语句

这个过程就需要服务器端能够在发送页面前将上下文环境保存下来,在获得响应之后动态获取调用栈恢复上下文环境,这些工作都是异步事件驱动的。

 

不能不说一说Node.js,这是JavaScript在2011年最火爆的词语之一,其实服务端js不是什么新东西,只不过因为Node.js,人们高呼,JavaScript居然也可以这样快!大概V8引擎做的编译优化太好了,许多前端工程师第一次发现自己的价值其实远不止在页面上 。Node.js把复杂的事件处理框架隐藏起来,开发人员只需要关注业务接口的调用。

Node.js所有的事件触发的调用都是异步和非阻塞的,它对高并发的访问有很好的承受能力(Node宣称他们的服务器每一台都可以承受几万连接并发)。如果服务端面对一场subscribe的灾难,虽然有足够大的队列来承受瞬间的高并发访问,但是瓶颈在请求接收和响应上,那么Node.js应该能成为一个有价值的解决方案。

 

最后,对于Jscex,还有Barrier模式, 这篇文章 已经介绍过了,故不赘述。

 

异步调用给传统软件编码的思维带来了新的挑战,无论是对现场的快照、异常的处理还是分支跳转的控制,但是带来了许多不可替代的优势,资源占用更少,效率更高,可扩展性更强。

 

文章系本人原创,转载请注明出处和作者

1
0
分享到:
评论

相关推荐

    aws for java

    **AWS Flow Framework for Java** 是一个专为Java开发者设计的框架,旨在简化基于Amazon Web Services (AWS) 的工作流应用程序的开发过程。此框架提供了丰富的功能集合,帮助开发者构建可靠且可扩展的应用程序。 ##...

    AWS-SAA考试认证-学习资料中文

    1. Amazon Simple Workflow Service (SWF):这是一个工作流服务,用于协调分布式和容错的同步和异步任务。它帮助开发者构建复杂的后台应用,这些应用能够处理大量的并行活动和任务协调。 2. Amazon Relational ...

    ASP.NET中小企业OA系统的设计与实现(源代码+论文).rar

    5. **工作流引擎**:OA的核心是工作流程,可以使用Windows Workflow Foundation (WF) 或自定义的工作流实现审批流程的自动化,如请假申请、报销审批等。 6. **文件管理**:OA系统通常需要集成文件存储和共享功能,...

    Python库 | mypy-boto3-swf-1.12.8.0.tar.gz

    Amazon Simple Workflow Service (SWF) 是一个完全托管的服务,它为构建分布式应用提供了工作流管理框架。通过SWF,开发者可以协调多个异步任务和活动,处理复杂的工作流程逻辑,而不用担心底层的调度和通信问题。...

    Python库 | django-elastic-transcoder-0.9.2.tar.gz

    2. 工作流管理:该库提供了工作流管理机制,可以跟踪视频处理的状态,包括待处理、正在处理和已完成,便于进行错误处理和进度监控。 3. 集成Amazon S3:Django-Elastic-Transcoder利用Amazon S3作为存储媒介,方便...

    PyPI 官网下载 | aws-cdk.aws-lambda-destinations-1.66.0.tar.gz

    这个库提供了方便的方法来配置和管理Lambda函数的这些目的地,使得开发者能够更轻松地实现异步工作流和错误处理。 描述中提到的“资源全名:aws-cdk.aws-lambda-destinations-1.66.0.tar.gz”表明这是CDK `aws-...

    亚马逊

    同时,他们也可能采用现代化的开发工具和工作流,例如Git版本控制、Jenkins持续集成/持续部署(CI/CD),以及代码审查和质量保证实践。 了解这些JavaScript相关的知识点,对于在亚马逊或其他类似公司从事Web开发...

    java开源包1

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包11

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包2

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包3

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包6

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包5

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包10

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包4

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包8

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包7

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包9

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

Global site tag (gtag.js) - Google Analytics