def _routing_with_wight(self, interface): """ 根据接口名称以及配置好的权重信息获取一个host :param interface: :return: """ hosts = self.hosts[interface] if not hosts: raise RegisterException( 'no providers for interface {}'.format(interface)) # 此接口没有权重设置,使用朴素的路由算法 if interface not in self.weights or not self.weights[interface]: return random.choice(hosts) weights = self.weights[interface] hosts_weight = [] for host in hosts: hosts_weight.append(int(weights.get(host, 100))) hit = random.randint(0, sum(hosts_weight) - 1) for i in range(len(hosts)): if hit <= sum(hosts_weight[:i + 1]): return hosts[i] raise RegisterException( 'Error for finding [{}] host with weight.'.format(interface))
def __init__(self, interface, version='1.0.0', dubbo_version='2.4.10', zk_register=None, host=None): """ :param interface: 接口名,例如:com.qianmi.pc.es.api.EsProductQueryProvider :param version: 接口的版本号,例如:1.0.0,默认为1.0.0 :param dubbo_version: dubbo的版本号,默认为2.4.10 :param zk_register: zookeeper注册中心管理端,参见类:ZkRegister :param host: 远程主机地址,用于绕过zookeeper进行直连,例如:172.21.4.98:20882 """ if not zk_register and not host: raise RegisterException('zk_register和host至少需要填入一个') logger.debug('Created client, interface={}, version={}'.format( interface, version)) self.__interface = interface self.__version = version self.__dubbo_version = dubbo_version self.__zk_register = zk_register self.__host = host
def _get_providers_from_nacos(self, interface, version): """ 从nacos中根据interface获取到providers信息 :param interface: :param version: :return: """ service = DUBBO_NC_PROVIDERS.format(interface, version) providers = self.nc.get_service_list(timeout=self.timeout, group_name=self.group_name, namespace_id=self.namespace_id) if not providers or service not in providers: raise RegisterException( 'no providers for service {}'.format(service)) self.nc.subscribe([], service_name=service) services = self.nc.subscribed_local_manager.get_local_instances( service) or {} self.close() for k, v in services.items(): service = v.__dict__ instance = service.get('instance') if not isinstance(instance, list): instance = [instance] hosts = [] for ins in instance: host = '{}:{}'.format(ins.get('ip'), ins.get('port')) hosts.append(host) self.hosts[interface] = hosts
def _routing_with_wight(self, interface): """ 根据接口名称获取一个host :param interface: :return: """ hosts = self.hosts.get(interface) if not hosts: raise RegisterException( 'no host or providers for interface {}'.format(interface)) return random.choice(hosts)
def _get_providers_from_zk(self, path, interface): """ 从zk中根据interface获取到providers信息 :param path: :param interface: :return: """ providers = self.zk.get_children(path, watch=self._watch_children) providers = filter(lambda provider: provider['scheme'] == 'dubbo', map(parse_url, providers)) if not providers: raise RegisterException('no providers for interface {}'.format(interface)) self._register_consumer(providers) self.hosts[interface] = map(lambda provider: provider['host'], providers)
def get_provider_host(self, interface): """ 从zk中可以根据接口名称获取到此接口某个provider的host :param interface: :return: """ if interface not in self.hosts: self.lock.acquire() try: if interface not in self.hosts: path = DUBBO_ZK_PROVIDERS.format(interface) if self.zk.exists(path): self._get_providers_from_zk(path, interface) self._get_configurators_from_zk(interface) else: raise RegisterException('No providers for interface {0}'.format(interface)) finally: self.lock.release() return self._routing_with_wight(interface)