posted in JavaWeb 

在对一个履约系统进行平台化改造过程中,沉淀了一套轻量化的平台化框架——shuke,供大家参考。

1. 背景

要重构的这一履约系统作为一个历史悠久的应用,各层代码中堆砌着各种针对不同业务的if else逻辑,进而导致了几个问题:

  1. 代码可读性很差。
  2. 业务代码和平台代码高度耦合。
  3. 新业务接入困难。

举一个例子,
履约平台在商家呼叫运力时,需要把履约任务下发给CP,而不同的业务下发的CP也是不一样的。

重构之前代码是这样的:

业务代码和平台代码混杂在一起,且层层if else嵌套

  1. 对业务的修改可能引起平台逻辑的问题
  2. 对A业务的修改可能引发B业务的问题
  3. 可读性很差,很难在一个业务包中找到所有的业务个性化定制
  4. 新业务接入成本高,需要找到各种需要修改的点,加if else

在系统重构的过程,通过shuke这一平台化框架,最终达到以下几个目标:

  1. 解耦业务逻辑和平台逻辑
  2. 提升代码可维护性
  3. 降低新业务的接入成本

2. 使用说明

talk is cheap, show me the code.

重构完之后,效果是这样的

  • 平台层定义spi
public interface DispatchNode {
    DispatchNO dispatch2Cp(DispatchNOParam param);
}
  • 平台使用spi
        DispatchNode dispatchNode = PluginRouter.routeNode(DispatchNode, FlowId.CHINA);
        DispatchNO dispatchNO = dispatchNode.dispatch2Cp(param);
        System.out.println(dispatchNO);
  • 业务A实现spi
@Component
@FlowInfo(FlowId.USA)   // 业务身份
public class UsaDispatchNode implements DispatchNode {
    @Resource
    private CainiaoService cainiaoService;
    
    @Override
    DispatchNO dispatch2Cp(DispatchNOParam param);
        String expressNumber = cainiaoService.dispatch(xxx);
        return DispatchNO.builder()
                .result(expressNumber)
                .build();
    }
}
  • 业务B实现spi
@Component
@FlowInfo(FlowId.CHINA) // 业务身份
public class ChinaDispatchNode implements DispatchNode {
    @Resource
    private FnService fnService;
    
    @Override
    DispatchNO dispatch2Cp(DispatchNOParam param);
        String expressNumber = fnService.dispatch(xxx);
        return DispatchNO.builder()
                .result(expressNumber)
                .build();
    }
}

通过以上代码,便可以把业务代码和平台代码解耦开来。以后无论是现有业务的维护还是新业务的接入,都可以快速高效进行。

3. 组成

shuke涉及的部分有以下以下几部分:

  • spi
    • 也就是平台留给业务的拓展点
  • 业务spi实现
    • 不同的业务对spi有其不同的实现
  • 平台
    • 通用的平台代码,通过spi来隔离不同业务的定制点
  • ability
    • 平台能力,提供给插件方来使用。

最终的各模块之前的关系如下:

4. 设计哲学 && 其他框架对比

KISS:Keep it simple, keep it stupid.

Shuke设计的一大初衷便是足够的简单和轻量化,这也是shuke区分于现有的一些重量级平台化框架的最重要的特点。

相比于那些花费漫长时间学习上手、理解的平台化框架,shuke的一大特点是可以在几十分钟内了解其如何使用。学习成本的降低,意味着开发成本和犯错的机会都会随之降低。

5. todo

做一个一个新生的框架,目前在一些地方还是待完善的,比方说不同业务方只有代码隔离没有容器隔离、业务插件不支持热部署等等,这些都是后续可以改进的地方。

6. 源码

git@gitlab.alibaba-inc.com:zhongzheng.czz/shuke.git

测试用例:
com.alibaba.ascp.shuke.core.test.ShukeTest#testDispatch

有什么意见或者建议,欢迎留言~

posted in JavaWeb 

在进行SOA系统设计,设计微服务的接口形式,会遇到一些问题,

  • 入参是多个入参还是包装在一个对象中
  • 异常返回是通过Exception还是返回码
Read on →
posted in JavaWeb 

Read on →
posted in JavaWeb 

Read on →
posted in JavaWeb 

最近工作中涉及到两个对批量用户进行离线处理的工作:

  1. 对若干用户进行打标记。
  2. 对若干用户进行消息推送。

联想到之前也有很多这种类似的工作,索性把其中共用的部分抽离出来做成了框架——取名叫绿萝。

通过使用该容器,使用者编写处理业务相关的代码,业务无关的部分交给容器来解决。好比 Servlet和Tomcat之间的关系,绿萝作为一个容器来运行业务代码。

Read on →
posted in JavaWeb 

项目组有两个老项目需要从resin迁移到tomcat,因为这两个项目的调用方比较多,所以要保证从resin迁移到tomcat过程中对调用方完全透明才行。这就需要对resin和tomcat的不同之处进行处理。

在修改过程中踩了若干坑,最终相关的Resin2Tomcat处理代码有了一个相对稳定的版本。于是把这部分相关处理代码抽成了一个maven工程,上传到公司仓库,方便以后其他同学使用。

Read on →