前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系统设计中的泛化调用

系统设计中的泛化调用

作者头像
CBeann
发布2024-05-26 14:02:53
600
发布2024-05-26 14:02:53
举报
文章被收录于专栏:CBeann的博客CBeann的博客

背景

目前在学习一些中间件,里面看到了一个词是叫泛化调用, 其实这个场景在JAVA中比较常见。我们常用的有反射,反射就是我知道类名称、类方法和参数,调用一个Object的类,但是在HTTP或者RPC远程调用过程中,我们一般会引入对方的SDK,从而引入接口规范和协议。 但是从一个中间件的角度触发,少依赖实现解耦,接入的低成本,少发布都是一个必须考虑的点。 因此本文从HTTP和DUBBO角度分析系统设计中泛化调用。

基于Cloud的泛化调用

以RocketMQ的事务消息场景为例,假设我是一个独立消息微服务,如下图所示。正常的ClientA完成了步骤1和步骤2后为一次正常结束,但是如果出现了ClientB的情况,那么就需要独立消息微服务(我)取回调ClientB的某个方法。当然你可以要求各个Client都用你定义的接口,但是我想玩花活,因此我的目标:各个Client可定义自己的方法,当然返回协议要统一,独立消息微服务可以在消息有问题的时候去调用各方且不需要引入各方的SDK。

当然我们也需要约定一种协议,只不过是不需要引入SDK的协议。

代码语言:javascript
复制
appName://methodPath/msgKey

以上面的场景的为例,步骤1的发送内容有

字段

含义

bizCode

多租户场景,每一个Client都有唯一的标识

msgBody

消息内容,需要独立消费微服务发送的消息

appName

服务提供者名称,即注册到Eureka中心的名称

msgKey

1)用于回调消息用 2)用于消息上的key

methodPath

HTTP类型为路径

代码语言:javascript
复制
	/**
	 * ribbon 负载均衡客户端
	 */
	@Autowired
	private LoadBalancerClient loadBalancerClient;

	/**
	 * 消息微服务(我)向支付微服务(clientA)发起状态查询,并且支付微服务返回业务执行状态。
	 * @param msg
	 * @return
	 */
	public boolean checkMsgByHTTP(Msg msg){
		//解析订单号
		String msgKey=msg.getMsgKey();
		String methodPath = msg.getMethodPath();

		//拿到IP和端口
		ServiceInstance si=loadBalancerClient.choose(msg.getAppName());
		StringBuffer sb=new StringBuffer("");
		sb.append("http://");
		sb.append(si.getHost());
		sb.append(":");
		sb.append(si.getPort());
		sb.append("/");
		sb.append(methodPath);
		sb.append("/");
		sb.append(msgKey);
		LOGGER.info("回调服务地址:{}",sb.toString());

		调接口
		RestTemplate restTemplate=new RestTemplate();
		Boolean bo = restTemplate.getForObject(sb.toString(), Boolean.class, "java");
		return bo;
	}

基于DUBBO的泛化调用

目前公司中有一个消费MQ的中间件是AMB,解决的痛点是 各个MQ的消费者自己做限流、转换、不好调试。正常下游提供的就是RPC的接口,所以AMB要解决的问题之一就是调用下游的RPC接口。

代码DEMO如下图所示,

代码语言:javascript
复制
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService;

public class GenericInvokeDemo {

    public static void main(String[] args) {
        // 初始化 Dubbo 应用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("generic-consumer");

        // 创建 Dubbo 泛化服务引用配置
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        reference.setApplication(application);
        reference.setInterface("com.example.service.SomeService"); // 设置服务接口名
        reference.setUrl("dubbo://127.0.0.1:20880"); // 设置服务提供者地址
        reference.setGeneric(true); // 开启泛化调用

        // 引用远程服务
        GenericService genericService = reference.get();

        // 构造泛化调用参数
        Object[] parameters = new Object[] { "parameter1", "parameter2" };

        // 进行泛化调用
        Object result = genericService.$invoke("someMethod", new String[] { "java.lang.String", "java.lang.String" }, parameters);

        // 处理调用结果
        System.out.println("Result: " + result);
    }
}

总结

稳定性在大厂是重要的,所以少发布是重点。 泛化调用等价解耦,引入过多的SDK解决包冲突就是个坑。


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 基于Cloud的泛化调用
  • 基于DUBBO的泛化调用
  • 总结
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档