样例说明

通过本样例,您可以了解:

  1. 如何配置一个REMOTE类型的扩展点
  2. 一个远程扩展点调用样例
  3. 远程调用扩展点存在的限制
  4. 如何自定义远程调用实现

环境准备

您需要:

  1. 用于运行程序的IDE(集成开发环境),比如IntelliJ IDEA 或其类似工具;
  2. Java™ Development Kit (JDK),需要JDK 8及以上版本
  3. 已经完成Nacos安装,并能正常运行
  4. 已经完成 Quickstart Guide 样例

版本依赖

<dependency>
      <groupId>org.hiforce.lattice</groupId>
      <artifactId>lattice-model</artifactId>
      <version>1.0.8.3</version>
</dependency>
<dependency>
      <groupId>org.hiforce.lattice</groupId>
      <artifactId>lattice-runtime</artifactId>
      <version>1.0.8.3</version>
</dependency>

Step 1:定义REMOTE类型的扩展点

我们定义一个protocolType是REMOTE的扩展点,如下:

public interface RemoteSampleBusinessExt extends IBusinessExt {

    String EXT_REMOTE_HELLO_INVOKE = "EXT_REMOTE_HELLO_INVOKE";

    @Extension(
            name = "EXT_REMOTE_HELLO_INVOKE",
            code = EXT_REMOTE_HELLO_INVOKE,
            protocolType = ProtocolType.REMOTE,
            reduceType = ReduceType.FIRST
    )
    String remoteHelloInvoke(String word);
}

Step 2:构建业务插件服务器

在样例代码中,我们定义一个运行业务自定义插件的工程:lattice-plugin-server。 在这个工程中,需要在 pom.xml 中引入 Lattice插件容器,如下:

<dependency>
        <groupId>org.hiforce.lattice</groupId>
        <artifactId>lattice-remote-container</artifactId>
        <version>${version.lattice}</version>
</dependency>

然后将业务A的对这个远程扩展点的实现部署在这个工程下。业务A的自定义实现如下:

@Business(code = BusinessA.CODE, name = "Business A")
public class BusinessA {
    public static final String CODE = "business.a";
}

@Realization(codes = BusinessA.CODE)
public class BusinessAExt extends BlankRemoteSampleBusinessExt {

    @Override
    public String remoteHelloInvoke(String word) {
        String str = "Hello: " + word;
        System.out.println("=====> BusinessAExt: " + str);
        return str;
    }
}

然后,我们定义一个LatticeCommandRunner,让他在Spring Boot容器启动成功后,启动Lattice插件容器。如下:

@Component
public class LatticeCommandRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        LatticePluginContainer.getInstance().start();
        System.out.println(">>> Lattice Plugin Container started!");
    }
}

在样例中,我们使用了dubbo、nacos等中间件,大家需要自行修改 application.properties以及bootstrap.properties 中的nacos注册地址等参数。关于如何搭建Nacos,不在本文介绍范围之内。

Step 3:在业务主服务中,开启Lattice远程调用功能

在本样例中,lattice-fos-server是我们假定的业务主服务。我们需要在 pom.xml 中,引入lattice-remote-runner-dubbo开发以dubbo方式进行远程扩展点调用。

<dependency>
        <groupId>org.hiforce.lattice</groupId>
        <artifactId>lattice-remote-client</artifactId>
        <version>${version.lattice}</version>
</dependency>
<dependency>
        <groupId>org.hiforce.lattice</groupId>
        <artifactId>lattice-remote-runner-dubbo</artifactId>
        <version>${version.lattice}</version>
</dependency>

对于远程调用方式,除了dubbo以外,还可以有RESTFUL等其他协议。我们只要把 lattice-remote-runner-dubbo 换成其他协议的包即可。在后面,会介绍如何自定义与扩展。

在主服务中,我们定义了TestInvokeController来模拟对这个远程扩展点的点用,如下:

@RestController
public class TestInvokeController {

    @RequestMapping("/hello")
    public String hello() {
        LatticeRemoteInvokeAbility ability = new LatticeRemoteInvokeAbility(() -> new BizContext() {
           ......
        });
        return ability.remoteHelloInvoke();
    }
}

我们把业务主服务和业务插件容器都启动后,打开浏览器,输入 http://localhost:8088/hello ,我们可以看到在业务插件容器的后台,有如下打印:

=====> BusinessAExt: Hello: Jack

远程扩展点调用的限制

对于扩展点类型是REMOTE的,在Lattice中不支持 业务叠加。因为有大量的远程实现叠加后,在性能和稳定性上是会产生很大的影响。如果,需要在业务上进行叠加,我的建议是在远程的业务插件容器中,再进一步定义业务扩展点,实现业务叠加后再将叠加结果返回。

如何自定义远程调用实现

我们可以参考lattice-remote-runner-dubbo 这个工程的写法,可以参考DubboExtensionRunnerBuilder的写法,实现RemoteExtensionRunnerBuilderBean接口,如下:

@Service
public class DubboExtensionRunnerBuilder implements RemoteExtensionRunnerBuilderBean {
    @Override
    public <R> ExtensionRemoteRunner<R> build(
            IAbility ability, TemplateSpec templateSpec, 
            String extCode, String scenario) {
            ......
    }
}

这个Builder需要做成SpringBean。需要注意的是,目前Lattice同时支持一种远程接口BuilderBean的存在。

样例代码URL

本样例代码URL:https://github.com/hiforce/lattice-remote-sample