点击上方蓝色字体,关注我们
泛化调用指在不知道Provider接口定义信息的情况下,访问Provider提供的服务。与泛化调用对应的方式包括透明RPC(POJO)和RestTemplate。透明RPC需要提供Provider对应的接口,RestTemplate需要提供Provider对应的URL和数据模型。泛化调用需要提供提供者的服务元数据:微服务名称、版本、模式ID、操作ID、绑定参数等信息。
java-chassis很早就提供了泛化调用,本文重点介绍了2.0.1的功能。2.0.1对于泛化调用的接口进行了优化,支持指定响应类型,早期版本的响应类型必须运行,是不确定的。
使用泛化调用
假设Provider采用透明RPC的方式提供了如下服务:
@RpcSchema(schemaId = "InvokerEndpoint")
public class InvokerEndpoint {
public ServerModel model(ServerModel request) {
return request;
}
}
public class ServerModel {
private String name;
private int code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
可以采用InvokerUtils访问这个服务:
Map<String, Object> args = new HashMap<>();
ClientModel model = new ClientModel();
model.setCode(200);
model.setName("hello");
args.put("request", model);
ClientModel modelResult = InvokerUtils.syncInvoke("pojo", "InvokerEndpoint", "model", args, ClientModel.class);
TestMgr.check(model.getCode(), modelResult.getCode());
TestMgr.check(model.getName(), modelResult.getName());
public class ClientModel {
private String name;
private int code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
可以抛光,在泛化调用的情况下,Provider和Consumer可以使用不一样package的Model。Consumer还可以不使用任何Model,而采用Map的方式访问:
Map<String, Object> args = new HashMap<>();
Map model = new HashMap();
model.put("code", 20);
model.put("name", "hello");
args.put("request", model);
ClientModel modelResult = InvokerUtils.syncInvoke("pojo", "InvokerEndpoint", "model", args, ClientModel.class);
TestMgr.check(model.get("code"), modelResult.getCode());
TestMgr.check(model.get("name"), modelResult.getName());
需要特别说明的是参数 swaggerArguments
,这个参数是和Provider内部生成的契约对应的,不关注Provider是采用透明RPC,还是采用Spring MVC,或者JAX RS开发的服务。需要注意 swaggerArguments
可能和Provider的接口定义的参数列表不一样,某些透明RPC开发模式下多个参数的场景,Spring MVC的Bean Param的场景等等。
采用反应性API
2.0.1泛化调用还增加了对应的react API,这样更方便采用采取react方式调用Provider的服务。
CountDownLatch countDownLatch = new CountDownLatch(1);
InvokerUtils.reactiveInvoke("pojo", "InvokerEndpoint", "model", args, ClientModel.class, response -> {
ClientModel reactiveResult = response.getResult();
TestMgr.check(model.getCode(), reactiveResult.getCode());
TestMgr.check(model.getName(), reactiveResult.getName());
countDownLatch.countDown();
});
countDownLatch.await();
2.0.1版本之前的API
2.0.1版本之前的API不能够指定 responseType
,因此返回值类型是不确定的,这个逐步运行的上下文。如果Consumer没有加载任何 @RpcReference
信息,并且不存在Provider返回值Model,那么返回值类型是Map;否则由于这种不确定性,早期的API使用声明 @Deprecated
为废弃。将 responseType
设置为null,能够获得和早期的API 。 返回结果可能是和提供者具有相同的包类的实例,这个返回接口的类型还可能和加载顺序有关。一样的效果。
-----
-----
如您对开源开发、微服务感兴趣
欢迎扫描下方二维码添加
ServiceComb小助手
咱们一起做点有意思的事情~
加小助手不迷路
进群论英雄
加入我们吧!
在看一点 bug退散
戳原文,更有料!
水电费水电费
发鬼地方