多渠道接入系统总结

在业务系统中会出现对接外部服务的场景,可能需要对接不同公司的接口,而且功能相似。比如:

  • 支付网关调用支付渠道商的支付类接口
  • 登录服务需要调用其他公司的登录授权相关接口
  • 广告投放服务需要把用户的注册、完件、授信信息回传给广告商

在这类渠道接入服务中需要对接的外部服务功能、协议、参数是相似的,如何最大化的复用代码,快速接入是这类服务的设计难点。

一般的流程:


在代码实现上一般放在一个map里,然后根据请求去执行相对应的 handler 逻辑。

// 初始化
Map<String, ChannelHandler> callBackHandlerMap = new HashMap();

// 具体执行
callBackHandlerMap.get("channelA").callback();

本文主要讨论 ChannelHandler 逻辑部分的实现,路由不在本文的讨论之类。

实现大致可分为三种模式:

暴力模式

这种模式简单粗暴,直接根据外部服务提供的接口文档实现对用的 ChannelHandler 即可。

// 实现
class ChannelAHandler extends ChannelHandler {
    @Override
    public void callback() {
        // 逻辑实现 
        return;
    }
}

// 注册
callBackHandlerMap.put("ChannelA", ChannelAHandler);

// 调用
callBackHandlerMap.get("ChannelA").callback(); 

但是缺点也很明显,如果出现变化,比如:
- 渠道商测试环境和线上环境不一致
- 渠道接口升级
- 新增渠道
这些都需要重新修改代码,然后发布,效率相对较低。

外挂模式

外挂模式就是在服务中嵌入脚本执行器如lua,处理函数调用解释器执行配置的脚本,解释器返回固定格式的数据,处理完成后返回数据给调用方。

流程如下:

外挂模式解决了暴力模式的上述三个缺点,随时可以更新脚本,新增渠道只需重新配置一个即可。缺点是通用的脚本解释器过重,大部分的功能是用不到的,针对这个问题可用下面一种方式解决。

DSL 模式

外挂模式内置的一般使用的 GPL(General Purpose Language) 通用编程语言,而 DSL 相对的就是,而是 DSL (Domain Specific Language) 领域特定语言:通过在表达能力上做的妥协换取在某一领域内的高效执行,如正则/html等。显然 DSL 完美的符合我们的需求。

其流程图和外挂模式是一样的,唯一的区别在内置的解释器替换成我们自己开发的 DSL 解释器。

总结

在实际的业务场景中我们可以根据需求来选择一种合适的模式。

如果项目刚开始,业务场景不明朗,那么暴力合适是合适的,可以快速的实现需求,实现业务试错。

如果对接的渠道逐渐增多,而且场景复杂,需要负责的流程控制和计算,那么外挂模式合适的。

如果对接的渠道多,但是回传不复杂,那么自己实现一个 DSL 解释器是合适的。

没有绝对的优劣,只要合适的。

原文地址:https://www.cnblogs.com/benjaming/p/14110399.html