架构常识:当调用方需要关心执行结果时,通常使用RPC调用。ret=PassportService::userAuth(name,pass);switch(ret){case(YES):returnYesHTML();case(NO):returnNoHTML();case(JUMP):return304HTML():default:return500HTML();}之前的文章《服务化,耦合却更加严重》提到,执行结果的处理与业务强相关,所以switchcase应该放在上游业务端,而不是底层的通用服务。登录页面调用passport服务,根据passport服务的返回结果,区分登录成功、登录失败、执行错误。当调用者关注执行结果时,不适合使用MQ通信。使用MQ通信,调用方无法直接告诉用户登录成功还是失败。阻塞等待MQ通知回调,不仅编码复杂,还会引入消息丢失的风险。中间多加一层是画蛇添足,基本没人这么玩。但是,如果调用者不关心执行结果,仍然使用RPC调用,就会造成上下游很大的耦合和瓶颈。场景还原有一个通用的上游服务,比如“postpublishing”服务,负责公司通用的postpublishing业务。有一些个性化服务会关心“用户发帖”事件,例如:用户发帖后,大数据部门需要更新用户画像用户发帖后,信息质量部门需要异步更新用户画像检查帖子是否合规。用户推广,如果用户发布招聘帖,需要加分……个性化下游关注这个事件,但是“帖子发布”服务不关心事件的下游执行结果。如果“发布后”服务通过RPC有办法通知下游的话,问题就大了。为什么耦合存在?发布服务,这应该是一个非常基础的服务。上游上层通过RPC调用将事件同步给事件关注的业务方biz1/biz2/biz3:一旦有新的业务需求关注这个事件,修改代码就是通用上游上层。总服老板此时心中暗骂,“为什么需要的是你,修改代码的却是我?”一旦业务端出现问题,就会影响到上游的通用基础服务。这时,总服老板又在心里骂了一句,“我的ca,稳定的kpi都被兄弟部门给毁了。”业务端接口升级后,需要升级上游基础服务。这时候,总服老板可能又会抱怨了,“你怎么被动升级了?”《人永远是我》结构不合理,近乎痛彻心扉。如何解耦?如果事件发送者不关心订阅者的执行结果,则不能使用RPC,应该使用MQ。MQ可以同时实现上下游的物理和逻辑解耦:Physicaldecoupling。添加MQ后,上游不知道对方的存在,不会建立物理连接。大家只是和MQ建立物理连接,解决逻辑上的问题。耦合,事件发布者甚至不需要知道有哪些下游订阅了这条消息,新消息的订阅者只需要连接MQ,不需要关注上游。MQ是一个非常常用的物理和逻辑解耦工具。.关注下游执行结果,使用RPC;不关注下游执行结果,用MQ代替RPC;这只是一个很小的优化点,但是对于通知解耦是非常有效的。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文
