十二:Dubbo高级特性(四)服务分组和版本

服务分组和版本

  1. Apache Dubbo的服务分组和版本是强隔离属性
  2. 服务分组和版本可以实现业务平滑升级
  3. 服务分组和版本可以实现业务隔离

演示

provider
public class ServiceDemoImpl implements ServiceDemo {
    @Override
    public String getSelf(String context) {
        return "ServiceDemoImpl :" + context;
    }
}
public class ServiceDemoImpl2 implements ServiceDemo {
    @Override
    public String getSelf(String context) {
        return "ServiceDemoImpl2 :" + context;
    }
}
    <bean id="iServiceDemo" class="com.jiangzheng.course.dubbo.provider.service.ServiceDemoImpl" />
    <bean id="iServiceDemo2" class="com.jiangzheng.course.dubbo.provider.service.ServiceDemoImpl2" />
    
    <dubbo:service id="serviceDemo" group="service" version="0.0.1"  interface="com.jiangzheng.course.dubbo.api.service.ServiceDemo" ref="iServiceDemo"/>
    <dubbo:service id="serviceDemo2" group="service2" version="0.0.2" interface="com.jiangzheng.course.dubbo.api.service.ServiceDemo" ref="iServiceDemo2"/>

consumer
    <dubbo:reference id="serviceDemo" group="service2" version="0.0.2" interface="com.jiangzheng.course.dubbo.api.service.ServiceDemo"/>

@SpringBootApplication
@ImportResource(locations = {"classpath:springContext-dubbo.xml"})
public class DubboDemoApplication {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ConfigurableApplicationContext context = SpringApplication.run(DubboDemoApplication.class, args);
        ServiceDemo serviceDemo = context.getBean("serviceDemo", ServiceDemo.class);
        //调用
        String result = serviceDemo.getSelf("hello wwy");

/*        //获取异步结果
        CompletableFuture<String> completableFuture = RpcContext.getContext().getCompletableFuture();
        String result = completableFuture.get();*/
        System.out.println(result);
    }

}
输出结果
ServiceDemoImpl2 :hello wwy

源码解析

首先再注册的时候 因为在provider的配置中是两个 dubbo:service/标签,所有会注册两个上去, consumer在获取的时候 调用org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#lookup方法,我们看下这个方法

    @Override
    public List<URL> lookup(URL url) {
        if (url == null) {
            throw new IllegalArgumentException("lookup url == null");
        }
        try {
        	//通过url获取提供服务的provider
            List<String> providers = new ArrayList<>();
            for (String path : toCategoriesPath(url)) {
                List<String> children = zkClient.getChildren(path);
                if (children != null) {
                    providers.addAll(children);
                }
            }
            //获取匹配上的provider,查看此方法
            return toUrlsWithoutEmpty(url, providers);
        } catch (Throwable e) {
            throw new RpcException("Failed to lookup " + url + " from zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }
	//org.apache.dubbo.registry.support.CacheableFailbackRegistry#toUrlsWithoutEmpty
    protected List<URL> toUrlsWithoutEmpty(URL consumer, Collection<String> providers) {
        // keep old urls
        Map<String, ServiceAddressURL> oldURLs = stringUrls.get(consumer);
        // create new urls
        Map<String, ServiceAddressURL> newURLs;
        URL copyOfConsumer = removeParamsFromConsumer(consumer);
        if (oldURLs == null) {
            newURLs = new HashMap<>();
            for (String rawProvider : providers) {
                rawProvider = stripOffVariableKeys(rawProvider);
                ServiceAddressURL cachedURL = createURL(rawProvider, copyOfConsumer, getExtraParameters());
                if (cachedURL == null) {
                    logger.warn("Invalid address, failed to parse into URL " + rawProvider);
                    continue;
                }
                newURLs.put(rawProvider, cachedURL);
            }
        } else {
            newURLs = new HashMap<>((int) (oldURLs.size() / .75 + 1));
            // maybe only default , or "env" + default
            for (String rawProvider : providers) {
                rawProvider = stripOffVariableKeys(rawProvider);
                ServiceAddressURL cachedURL = oldURLs.remove(rawProvider);
                if (cachedURL == null) {
                	//此处会对group、version进行筛选
                    cachedURL = createURL(rawProvider, copyOfConsumer, getExtraParameters());
                    if (cachedURL == null) {
                        logger.warn("Invalid address, failed to parse into URL " + rawProvider);
                        continue;
                    }
                }
                //加入到集合中
                newURLs.put(rawProvider, cachedURL);
            }
        }

        stringUrls.put(consumer, newURLs);

        // destroy used urls
        try {
            if (oldURLs != null && oldURLs.size() > 0) {
                Long currentTimestamp = System.currentTimeMillis();
                for (Map.Entry<String, ServiceAddressURL> entry : oldURLs.entrySet()) {
                    waitForRemove.put(entry.getValue(), currentTimestamp);
                }
                if (CollectionUtils.isNotEmptyMap(waitForRemove)) {
                    if (semaphore.tryAcquire()) {
                        cacheRemovalScheduler.schedule(new RemovalTask(), cacheRemovalTaskIntervalInMillis, TimeUnit.MILLISECONDS);
                    }
                }
            }
        } catch (Exception e) {
            logger.warn("Failed to evict url for " + consumer, e);
        }
		//返回
        return new ArrayList<>(newURLs.values());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值