[apache/dubbo]如何获取某个服务名下的所有实例?

2024-06-24 326 views
6
举例
  1. 接口:org.apache.dubbo.registry.client.ServiceDiscovery#getInstances(java.lang.String)

  2. 期待的使用方式


public class A {
  @Autowired
  private ServiceDiscovery serviceDiscovery;

public void m1(){
          List<ServiceInstance> serviceInstances = serviceDiscovery.getInstances("serviceName")
   }
}
  1. 如何得到 ServiceDiscovery 实例呢?

回答

1

ServiceDiscovery这个对象是给 Dubbo 内部使用的,为什么要从这里获取实例信息呢

6

如果非要使用ServiceDiscovery。可以根据不同的协议,构造不同的ServiceDiscovery实例。例如nacos协议, ServiceDiscovery serviceDiscovery= new NacosServiceDiscovery( ApplicationModel.defaultModel(),URL.valueOf("nacos://127.0.0.1:8848"));

5

事实上我的需求是:如何获取某个服务名下的所有实例? 已经修改了 issue title

如果能够获取到某个服务名下的所有实例,任何方式都可以。感谢!

5

org.apache.dubbo.registry.support.RegistryManager 这个对象存储了所有的注册中心

org.apache.dubbo.registry.support.RegistryManager.getInstance(ApplicationModel.defaultModel()) 可以获取

3
测试
  • 使用的 zookeeper 作为注册中心
  • 使用 dubbo 泛化调用
  • dubbo 版本 3.0.4
1. 构建 Bean
import org.apache.dubbo.registry.support.RegistryManager;

    @Bean
    public RegistryManager registryManager() {
        return ApplicationModel.defaultModel().getBeanFactory().getBean(RegistryManager.class);
    }
2. 使用 Bean
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery;

@RestController
public class ServiceDiscoveryController {

    private String key = "service-discovery-registry://192.168.2.228:2181/infra-dubbo/org.apache.dubbo.registry.RegistryService";

    @Autowired
    private RegistryManager registryManager;

    /**
     * curl http://localhost:8082/getInstances
     */
    @GetMapping("/getInstances")
    public Set<String> getInstances() {

        Registry registry = registryManager.getRegistry(key);

        ServiceDiscoveryRegistry serviceDiscoveryRegistry = (ServiceDiscoveryRegistry)registry;
        ZookeeperServiceDiscovery serviceDiscovery = (ZookeeperServiceDiscovery)serviceDiscoveryRegistry.getServiceDiscovery();
        Set<String> services = serviceDiscovery.getServices();
        List<ServiceInstance> instances = serviceDiscovery.getInstances("A.dubbo.service");

        return services;

    }
}
测试问题列表
  1. 默认使用的 basePath 为 services :org.apache.curator.x.discovery.details.ServiceDiscoveryImpl#pathForName 。而我实际使用的 basePath 为 infra-dubbo
  2. 当然可以通过在 url 添加参数 rootPath 来修改 basePath :org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery#doInitialize
    @Override
    public void doInitialize(URL registryURL) throws Exception {
        this.registryURL = registryURL;
        this.curatorFramework = buildCuratorFramework(registryURL);
        this.rootPath = ROOT_PATH.getParameterValue(registryURL);
        this.serviceDiscovery = buildServiceDiscovery(curatorFramework, rootPath);
        this.serviceDiscovery.start();
    }
  1. 在 paramers 上添加了 rootPath KV对,但是 registryURL 上添加不了 rootPath 参数,导致无法修改默认值services
  2. 即便是第2步能够满足,这个也是每次通过 org.apache.curator.x.discovery.ServiceDiscovery<ZookeeperInstance> serviceDiscovery; 去 zk 注册中心获取的,而没有缓存到本地,也是不可取的。
问题:当 A 服务名调用 B 服务名,假设 B 服务名的实例集合为S,A的某个实例本地一定缓存得有集合S,并且A实例本地会监听 B 实例的变化并对集合S进行增删改,那么 A实例能不能得到B的实例集合 S 呢?
3

ServiceDiscovery 有 ServiceInstanceChangedListstener 可以监听变更

3

问题没有得到解决,还是关了吧!