重构Legacy SOA系统以使用非阻塞异步微服务

时间:2016-03-02 12:30:19

标签: java reactive-programming project-reactor

我刚刚开始试图了解RxJava,以便我可以使用项目反应器重构Legacy SOA系统来使用非阻塞异步微服务。

目前我正在进行可行性研究,并考虑使用勺子之类的东西来改造遗留服务代码(但这与此问题无关)

我想知道如何使用reactor-bus请求/回复语法来替换此同步服务代码。或者即使我应该使用完全不同的反应堆构造。

以下是传统Soa服务的示例,它是设计的,因此它可能没有完全合理意义,但基本上每个服务都依赖于最后的结果。

 public static Map<String, Object> createAccount(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();

    String accountPartyId = (String) context.get("partyId");

    Map<String, Object> input = UtilMisc.toMap("groupName", context.get("accountName"), "groupNameLocal", context.get("groupNameLocal"), "officeSiteName", context.get("officeSiteName"), "description", context.get("description"), "partyId", accountPartyId);

    Map<String, Object> serviceResults1 = dispatcher.runSync("createPartyGroup", input);

    Map<String, Object> serviceResults2 = dispatcher.runSync("createPartyRole", UtilMisc.toMap("partyId", (String) serviceResults1.get("partyId"), "roleTypeId", "ACCOUNT"));

    String dataSourceId = (String) context.get("dataSourceId");
    Map<String, Object> serviceResults3 = null;
    if (dataSourceId != null) {
        serviceResults3 = dispatcher.runSync("crmsfa.addAccountDataSource", UtilMisc.toMap("partyId", (String) serviceResults2.get("partyId"), "dataSourceId", dataSourceId));
    }

    String marketingCampaignId = (String) context.get("marketingCampaignId");
    Map<String, Object> serviceResults4 = null;
    if (marketingCampaignId != null) {
        serviceResults4 = dispatcher.runSync("crmsfa.addAccountMarketingCampaign", UtilMisc.toMap("partyId", (String) serviceResults3.get("partyId"), "marketingCampaignId", marketingCampaignId));

    }

    String initialTeamPartyId = (String) context.get("initialTeamPartyId");
    Map<String, Object> serviceResults5 = null;
    if (initialTeamPartyId != null) {
        serviceResults5 = dispatcher.runSync("crmsfa.assignTeamToAccount", UtilMisc.toMap("accountPartyId", (String) serviceResults4.get("partyId"), "teamPartyId", initialTeamPartyId, "userLogin", userLogin));
    }

    Map<String, Object> results = ServiceUtil.returnSuccess();
    results.put("groupId", (String) serviceResults1.get("groupId"));
    results.put("roleId", (String) serviceResults2.get("roleId"));
    results.put("dataSourceId", (String) serviceResults3.get("dataSourceId"));
    results.put("marketingCampaignId", (String) serviceResults4.get("marketingCampaignId"));
    results.put("teamPartyId", (String) serviceResults5.get("teamPartyId"));
    return results;
}

基本上这是一个使用dispatcher.runSync调用其他服务的服务......我只是在寻找一个起点来研究如何使用reactor甚至另一个库将这种类型的语法转换为异步非 - 阻止代码。

此时我正在以非常模糊的方式思考回调/某种Promise类型结构。

就像第一次打电话给另一个服务一样

Map<String, Object> serviceResults = dispatcher.runSync("createPartyGroup", input);

如果这返回了包含serviceResults映射的Promise对象,则该方法的其余部分可以移动到Promise onComplete块中,结果将是构成此服务方法的一组深度嵌套的onComplete代码块。

Promise p = task {
    // createPartyGroup service call
}
p.onComplete { result ->

Promise p2 = task {
    // createPartyRole sevice call
}

p2.onComplete { result ->
//next service call
}   
}  
}

或者看看反应堆总线文档,如下所示,在许多层面上没有意义,我只是对反应堆知之甚少,不知道为什么它没有意义或接下来要学习什么明白为什么没有意义

bus.send("service.createPartyGroup", Event.wrap(input, "reply.service.createPartyGroup")); 
bus.receive($("reply.service.createPartyGroup"), ev -> {
Map<?> input2 = UtilMisc.toMap("partyId", (String) ev.get("partyId"), "roleTypeId", "ACCOUNT")
  bus.send("service.createPartyRole", Event.wrap(input2, "reply.service.createPartyRole")); 
}); 

我意识到开始研究反应式编程范式是一个相当奇怪的地方。但是替换这个同步服务代码是我的最终目标,如果我至少理解了语法,我可以从中做出反向。

1 个答案:

答案 0 :(得分:0)

您只需要使用Observable,在您的流程中,一个发出的项目将通过流传递。 查看文档https://github.com/ReactiveX/RxJava

这将是一个顺序流程

  Observable.just(methodThatCallFirstServiceAndReturnObservable(params))
            .flatMap(resul1 -> methodThatCallSecondAndReturnObservable(resul1))
            .flatMap(resul2 -> methodThatCallThirdAndReturnObservable(resul2))
            .subscribe(result3->"Last value emmited here:");

您可以并行运行三个服务调用,并使用Observable.zip或merge来获取所有值。但我相信这不是你需要的。