摘要: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示例,并剖析它的内部实现原理来验证是否和本文的猜想一致。

Storm同步调用之DRPC模型探讨的更多相关文章

  1. 循序渐进做项目系列(2):最简单的C/S程序——消息异步调用与消息同步调用

    上篇博客 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法 实现了一个最简单的C/S程序,即让服务器来做加法.当时为了通俗易懂采用了消息异步调用的方式.今天我们要采用消息同步调用的方式 ...

  2. 消息同步调用-- ESFramework 4.0 进阶(07)

    分布式系统的构建一般有两种模式,一是基于消息(如Tcp,http等),一是基于方法调用(如RPC.WebService.Remoting).深入想一想,它们其实是一回事.如果你了解过.NET的Prox ...

  3. 似是而非的JS - 异步调用可以转化为同步调用吗?

    源起 小飞是一名刚入行前端不久的新人,因为进到了某个大公司,俨然成为了学弟学妹眼中'大神',大家遇到js问题都喜欢问他,这不,此时他的qq弹出了这样一条消息 "hi,大神在吗?我有个问题想问 ...

  4. SimpleRpc-客户端与服务端工作模型探讨

    前言 本篇文章讲述客户端与服务端的具体设计细节.有细心的小伙伴发现,客户端和服务端的工作方式不一样:服务端是多线程计算模型,利用工作线程完成数据的读取,而客户端是单线程(利用Reactor线程完成数据 ...

  5. socket 阻塞,同步、I/O模型

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步:       所谓同步,就是在发出一个功能调用时, ...

  6. Winform同步调用异步函数死锁原因分析、为什么要用异步

    1.前言 几年前,一个开发同学遇到同步调用异步函数出现死锁问题,导致UI界面假死.我解释了一堆,关于状态机.线程池.WindowsFormsSynchronizationContext.Post.co ...

  7. Storm集群使用DRPC功能Version1.0.1

    在Storm集群上开启DRPC功能, 基于Storm的1.0.1版本, 并且执行简单的例子测试. 1.DRPC概念 DRPC就是分布式远程过程调用. Storm里面引入DRPC主要是利用storm的实 ...

  8. NIO【同步非阻塞io模型】关于 NIO socket 的详细总结【Java客户端+Java服务端 + 业务层】【可以客户端间发消息】

    1.前言 以前使用 websocket来实现双向通信,如今深入了解了 NIO 同步非阻塞io模型 , 优势是 处理效率很高,吞吐量巨大,能很快处理大文件,不仅可以 做 文件io操作, 还可以做sock ...

  9. Entity Framework 6 Recipes 2nd Edition(11-4)译 -> 在”模型定义”函数里调用另一个”模型定义”函数

    11-4.在”模型定义”函数里调用另一个”模型定义”函数 问题 想要用一个”模型定义”函数去实现另一个”模型定义”函数 解决方案 假设我们已有一个公司合伙人关系连同它们的结构模型,如Figure 11 ...

随机推荐

  1. ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击

    什么是反伪造攻击? 跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可能会影响客户端浏览器和浏览器信任网站之间的交互.这种攻击是完全有可能的 ...

  2. tensorflow安装调试总结(持续更新)

    这段时间需要部署tensorflow到linux上,由于堡垒机不能连外网,所以pip.apt-get.wget.git统统不能用,然后就是各种调试了,下面整理了一些遇到的问题和解决方案,供大家参考(C ...

  3. 第三篇--Jmeter测试数据库Mysql

    Jmeter模拟100用户访问Mysql数据库 1.将Mysql数据库的驱动[mysql-connector-java-5.1.15-bin.jar]放到jmeter的lib目录下,新建线程组100[ ...

  4. keepalive集群工作原理及应用

    author:JevonWei 版权声明:原创作品 集群工作原理 一.集群基础 1.系统的扩展方式 scale up向上扩展:提高单台服务器的性能 scale out向外扩展:多台服务器联合起来满足同 ...

  5. ios 初体验<窗口的创建>

    1. 创建工程,这步很简单,百度下即可,在info.plist 里面 去掉 Main 的 ,便于新手练习ios,创建ios工程后,在AppDelegate.m,里面的方法application 加上几 ...

  6. R0~R16寄存器作用(转)

    R0-R3     用作传入函数参数,传出函数返回值.在子程序调用之间,可以将 r0-r3 用于任何用途. 被调用函数在返回之前不必恢复 r0-r3.如果调用函数需要再次使用 r0-r3 的内容,则它 ...

  7. JavaScript学习日志(五):DOM

    一,基本定义 DOM是针对HTML和XML文档的API,根据W3C的HTML DOM标准,html文档中所以内容(无论是元素还是标签还是注释还是元素属性)都是节点. 二,Node类型:每一个节点都含有 ...

  8. test文件伪装

    该文件属于伪装图片类型.图片另存后把后缀改为rar将看到txt文件. 利用了 cmd cp  /b  命令 命令格式:copy /b 文件1+文件2+......文件N 合并后的文件名<br&g ...

  9. wineshark分析抓取本地回环包

    wineshark分析抓取本地回环包 摘要 由于windows系统没有提供本地回环网络的接口,用Wireshark监控网络的话看不到localhost的流量.想要获取本地的网络数据包,可以通过一款小巧 ...

  10. CentOS7中将home迁移到/下的命令 CentOS7中将home迁移到/下的命令

    # mkdir -p /backup # cp -r /home/* /backup # umount /home #  df -hl # fdisk -l # lvremove /dev/cento ...