SugarCRM使用EDA替代SOA

Replacing SOA API calls by EDA request/replies usi谈论在EAI企业应用整合如何使用EDA替代原来的SOA API。

EDA事件驱动架构和SOA面向服务架构的主要区别是: EDA是异步,SOA是同步,如下图:

下图显示在EAI中服务和客户之间的调用关系:

首先,我们要停止思考关于传统的API调用方式:请求/响应,我们要使用事件这个概念替代,事件代表你的应用中发生的事情,而且这个事情可能引起其他应用的兴趣。

当一个用户资料需要在你网站被创建,一般是调用API然后等待响应OK。或者重新按照 “fire and forget”方式重新编写应用,万一发生错误单独处理。

但是如果应用被调用时,需要有一个问题被回答时怎么办呢?解决办法是使用Request/Reply企业整合模式(EIP). 大多数企业消息系统(EMS)都提供企业服务总线(ESB), 其中消息格式都有统一规定,但是数据格式是自由的,是由用户自己定义的。

以SugarCRM 为案例,下面是SugarCRM/Requests队列的消息:


Timestamp: 1382055093876 ms
MessageId: 345781632423
ReplyQueue: SugarCRM/Replies
Data: {"method":"GET","url":"/Accounts/f1eeca5f-c0eb-891e-db92-52323b958a87"}

上面消息(事件)是一个请求查询某个用户资料,从Data中可以看出,将REST调用变成Command。

SugarCRM有一个引擎不断监视“SugarCRM/Requests”队列,它接受到上面消息,然后转变为一个API调用请求再执行,API返回结果后再将结果转为消息,放入“SugarCRM/Replies” 队列:


Timestamp: 1382055096943 ms
MessageId: 345781632567
ReplyTo: 345781632423
Data: {"id":"f1eeca5f-c0eb-891e-db92-52323b958a87","name":"RR. Talker Co","date_entered":"2013-09-12T18:09:00-04:00","date_modified":"2013-09-12T18:09:00-04:00","modified_user_id":"1","modified_by_name":"Administrator","created_by":"1","created_by_name":"Administrator","description":"","deleted":false,"assigned_user_id":"seed_jim_id","assigned_user_name":"Jim Brennan","team_count":"","team_name":[{"id":"East","name":"East","name_2":"","primary":true}],"linkedin":"","facebook":"","twitter":"","googleplus":"","account_type":"Customer","industry":"Electronics","annual_revenue":"","phone_fax":"","billing_address_street":"67321 West Siam St.","billing_address_street_2":"","billing_address_street_3":"","billing_address_street_4":"","billing_address_city":"Santa Fe","billing_address_state":"NY","billing_address_postalcode":"44150","billing_address_country":"USA","rating":"","phone_office":"(949) 400-8060","phone_alternate":"","website":"www.imim.name","ownership":"","employees":"","ticker_symbol":"","shipping_address_street":"67321 West Siam St.","shipping_address_street_2":"","shipping_address_street_3":"","shipping_address_street_4":"","shipping_address_city":"Santa Fe","shipping_address_state":"NY","shipping_address_postalcode":"44150","shipping_address_country":"USA","email":[{"email_address":"phone95@example.it","invalid_email":false,"opt_out":false,"primary_address":true,"reply_to_address":false},{"email_address":"qa.qa@example.tv","invalid_email":false,"opt_out":false,"primary_address":false,"reply_to_address":false}],"email1":"phone95@example.it","parent_id":"","sic_code":"","parent_name":"","email_opt_out":false,"invalid_email":false,"campaign_id":"","campaign_name":"","my_favorite":false,"_acl":{"fields":{}},"following":true,"_module":"Accounts"}

SugarCRM中,使用Redis进行队列中消息的存储,SugarCRM/Requests”队列存储层Redis的 “List”形式,而SugarCRM/Replies存储层Redis的Hash形式,ReplyTo是key,mesageId是value.

这里请求和回复都作为消息被放入redis消息队列,那说明请求的回复是异步返回的。那请求的发起方在发送完请求后会阻塞当前请求等待回复吗?如果不等待,要是是BS架构的网站,如果告诉用户结果呢?
[该贴被tangxuehua于2013-10-23 09:09修改过]

如在HTML实现的网页游戏中,用户每次提交操作请求和每30秒一次的轮询中都可以返回之前的操作结果。

2013-10-23 09:09 "@tangxuehua"的内容
如果不等待,要是是BS架构的网站,如果告诉用户结果呢? ...

两个办法:
1. 如楼上所说,采取轮询方式
2. 浏览器支持html5以上(现在基本都是),使用websocket直接将结果从服务器推到浏览器中,这样浏览器只要发出请求,也无需堵塞等待返回结果,无论后端或前端都要杜绝堵塞,因为堵塞是违背线程本质的。

参考reactive应用使用可观察模型,事件流和有状态的客户端:http://www.jdon.com/45811/5#23143638