Storm同步调用之DRPC模型探讨

摘要:Storm的编程模型是一个有向无环图,决定了storm的spout接收到外部系统的请求后,spout并不能得到bolt的处理结果并将结果返回给外部请求。所以也就决定了storm无法提供对外部系统的同步调用功能。

  最近新的黑名单项目需要在storm实时计算平台上提供对外部系统请求调用的同步响应(也就是让storm支持同步调用而不是回调),而Storm的编程模型是一个有向无环图,也就决定了storm的spout接收到外部系统的请求后,将请求数据分发给下游的bolt进行处理后,spout并不能得到bolt的处理结果并将结果返回给外部请求。

  在传统也就是业界大部分应用场景storm对外部系统的调用都是采用回调的方式。本人之前参与的某4000万用户,日均1000万交易量的信用卡中心也是采用回调的方式。

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/7602242.html

storm常见回调设计方案

  首先jetty,tomcat等启动服务,接收外部系统的请求,将请求得到的数据发往kafka,activeMQ等消息队列中,就立马响应给外部系统。

  然后storm实时平台去消息队列中拉取数据并进行分布式并行处理,然后将运算完的结果存入第三方存储介质(外部系统直接通过读取该介质获取结果)或者调用外部系统的接口将处理的结果推送出去(以回调的方式实现伪同步请求)。

   目前的需求

现在的项目是一个产品,要接入各大银行的系统中,所以通过要求对方提供一个回调接口来实现同步是不可能的。必须依靠自己去实现同步请求响应,外部系统将消息发往storm实时平台,然后外部系统会阻塞,等待storm实时平台处理完后将结果返回给外部系统。

   这个时候当然就是去storm的官网去看看有没有对应的高级接口,果不其然看到了DRPC,熟悉RPC的就知道就是远程过程调用,就是向远程系统发送socket请求并得到远程系统处理的结果,那么DPRC也就是分布式远程过程调用而已,那么他就一定提供了同步请求响应的功能。

   关于DRPC在文章末尾会简单演示一下,这里重点说下我对storm的DRPC的原理理解。上面我也说了storm的编程模型是一个有向无环图,从模型的角度来说是不可能支持同步请求的功能的。

   自己如何基于storm实现同步调用

   我也自己思考下,如果是我自己会如何在现有的storm的编程模型下如何实现同步调用。

方案一:大家最容易想到的方案就是,在storm的拓扑的spout节点中new ServerSocket(8080),来接收外部系统的请求,然后将请求的数据分发给下游的bolt处理,处理完后将结果返回给外部系统。 

问题一:storm的计算模型的拓扑结构是一个有向无环图,处理的结果并不会返回给spout节点。

  我可以让bolt将处理的结果存入redis,然后spout不断轮询去redis读取对应的结果并返回!

  貌似可以,但是查看spout的调用源代码会发现,如果这样会导致spout的吞吐量下降,因为spout只有从redis轮询到当次请求的处理结果后才会在循环调用nextTuple()方法,当然在spout实现类中开启多线程后,貌似可以解决nextTuple方法阻塞(具体没有去想,因为本身这个方案不可行了,就没必须去掉头发了)storm的任务中再去开多线程是无效率的,还不如不选择storm技术。

问题二:spout节点启动的机器是不固定的,ip是会变化的,则对外部系统调用时ip的维护带来了麻烦,所以这种方案不可取。

public void nextTuple() {
        获取请求的数据
        collector.emit();
        while(true)
        {
            去redis中读取该次请求的结果,读到则结束循环
        }    
 }

方案二:抛开storm实时平台,单独开发一套中转程序,负责接收外部系统的请求,将外部请求的参数存入一个先进先出的队列中,阻塞等待storm处理的结果。storm拓扑的spout中创建socket去连接中转程序,中转程序从队列中拿出请求参数返回给spout。spout获取到请求参数后,将参数传给下游的bolt去计算,下游的最后一层bolt计算完也创建socke去连接中转程序并将结果发送给中转程序。中转程序获得bolt返回结果,存入某个地方,然后中转程序中阻塞的地方轮询得到结果后,就结束轮询响应给外部系统了。

  当然这只是一个简单的方案设计,具体还有很多细节设计以及考虑在我们的Server端,因为它要同时协调三个不同的程序的请求,并且能够根据以每一个请求自动聚合外部系统请求,spout请求,bolt请求为一组。

  Storm的DRPC概述

  storm的DRPC其实就实现外部系统同步调用storm实时平台的功能组件了。应该不需要我去从零开发了。接下来就看看storm的DPRC功能是否和我当初的想法是否一致!

官方话语:

分布式RPC(DRPC)背后的思想是将真正强大功能的计算与storm的计算并行化。Storm拓扑以一个函数参数的流作为输入,它向每个函数调用发出一个输出流的结果。

  分布式RPC(DRPC)的真正目的是使用storm实时并行计算极端功能。Storm拓扑需要一个输入流作为函数参数,以一个输出流的形式发射每个函数调用的结果。。从一个客户端的角度来看,一个分布式RPC调用就像是一个常规的RPC调用。

分布式RPC工作流程如下图所示:

  客户端程序会向启动的DRPC服务器发送要执行的函数名称和该函数的参数。具备DRPC功能的拓扑会使用一个DRPCSpout接收来自DRPC服务器传来的函数调用流。每个函数调用都用一个惟一的id标记在DRPC服务器上。拓扑计算好结果后会由一个名为ReturnResults的bolt去连接DRPC服务器给出对应函数调用id的结果,然后DRPC服务器根据ID找到等待中的客户端,为等待中的客户端消除阻塞,并发送结果给客户端。

  从一个客户端的角度来看,一个分布式RPC调用就像是一个常规的RPC调用。

public class Client {
    public static void main(String[] args) throws TException,
            DRPCExecutionException {
        DRPCClient client = new DRPCClient("192.168.19.131", 3772);
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
             String result = client.execute("method_name","param is intsmaze--"+i+"---");
            System.out.println(result);
        }
        client.close();
    }
}

下一篇将会重点讲解如何运行storm的drpc示例,并剖析它的内部实现原理来验证是否和本文的猜想一致。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏挖掘大数据

如何高效地合并Spark社区PR到自己维护的分支

最近刚刚忙完Spark 2.2.0的性能测试及Bug修复,社区又要发布2.1.2了,国庆期间刚好有空,过了一遍2.1.2的相关JIRA,发现有不少重要修复2.2...

3758
来自专栏漫漫前端路

写个 vue-loading-template 组件

源码(star ? start : start):github.com/jkchao/vue-…

4002
来自专栏老九学堂

Java开发常用工具

Java开发常用工具 小贴士 Java是目前最流行的软件开发语言,其IDE环境也备受开发者关注,IDE可以极大的提高开发速 一 UltraEdit ? Ultr...

3315
来自专栏lulianqi

超高性能管线式HTTP请求(实践·原理·实现)

这里的高性能指的就是网卡有多快请求发送就能有多快,基本上一般的服务器在一台客户端的压力下就会出现明显延时。

1501
来自专栏小灰灰

QuickTask动态脚本支持框架整体介绍篇

一个简单的动态脚本调度框架,支持运行时,实时增加,删除和修改动态脚本,可用于后端的进行接口验证、数据订正,执行定时任务或校验脚本

1212
来自专栏H2Cloud

C++执行内存memcpy的效率测试

在进行memcpy操作时,虽然是内存操作,但是仍然是耗一点点CPU的,今天测试了一下单线程中执行memcpy的效率,这个结果对于配置TCP epoll中的wor...

4424
来自专栏java架构师

Hadoop学习5--配置本地开发环境(Windows+Eclipse)

一、导入hadoop插件到eclipse 插件名称:hadoop-eclipse-plugin-2.7.0.jar 我是从网上下载的,还可以自己编译。 放到ec...

3088
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用wrk对HTTP延迟进行基准测试

本文重点介绍称为开源HTTP基准测试工具WRK,它可以在高负荷下测量HTTP服务的延迟。

4310
来自专栏coding

oh-my-zsh,让你的终端从未这么爽过

7.5K5
来自专栏社区的朋友们

TAF 必修课(六):容错

上一节简单提到了客户端在选取 Invoker 节点时,会对 Invoker 列表执行死活检查,屏蔽掉一定时间内异常的节点,从而达到容灾的目的。下面对 TAF 容...

3610

扫码关注云+社区

领取腾讯云代金券