dubbo角色及运转流程分析

dubbo中的角色

Container  容器

Provider 生成者

Consumer 消费者

Registry 注册中心

Monitor 监控中心

dubbo的流程

首先,加载dubbo容器,这里我们来看下源码dubbo都加载了哪些容器:

这里我们使用的是dubbo的main方法启动dubbo,首先找到dubbo的main方法:com.alibaba.dubbo.container.Main  

public class Main {

    public static final String CONTAINER_KEY = "dubbo.container";

    public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";
    
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    private static final ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);
    
    private static volatile boolean running = true;

    public static void main(String[] args) {
        try {
            if (args == null || args.length == 0) {
                String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());
                args = Constants.COMMA_SPLIT_PATTERN.split(config);
            }
            
            final List<Container> containers = new ArrayList<Container>();
            for (int i = 0; i < args.length; i ++) {
                containers.add(loader.getExtension(args[i]));
            }
            logger.info("Use container type(" + Arrays.toString(args) + ") to run dubbo serivce.");
            
            if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
	            Runtime.getRuntime().addShutdownHook(new Thread() {
	                public void run() {
	                    for (Container container : containers) {
	                        try {
	                            container.stop();
	                            logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");
	                        } catch (Throwable t) {
	                            logger.error(t.getMessage(), t);
	                        }
	                        synchronized (Main.class) {
	                            running = false;
	                            Main.class.notify();
	                        }
	                    }
	                }
	            });
            }
            
            for (Container container : containers) {
                container.start();
                logger.info("Dubbo " + container.getClass().getSimpleName() + " started!");
            }
            System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!");
        } catch (RuntimeException e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            System.exit(1);
        }
        synchronized (Main.class) {
            while (running) {
                try {
                    Main.class.wait();
                } catch (Throwable e) {
                }
            }
        }
    }
    
}

看下这个源码中有一个关键的部分:启动容器,然后我们到container

Container是一个接口,在idea下使用ctrl+Alt+B快捷键看下,该接口的实现类:

这四个便是dubbo的全部容器,但是这四个容器并不会全部加载,如果在启动dubbo时不传参数的话,默认是只会加载Spring容器的,这里可以自行debugger一下,我这里也演示下:

首先会进入这个判断:

然后这里反射调用到了SpringContainer并将它添加到了containers中

然后再到这,启动容器:

启动SpirngContainer时会去加载Spring的配置文件,这里我们再看下源码:

如果传入了启动容器的参数则会加载传入的容器名的容器,这里有个前提,你的maven库中得有这个容器的jar包,比如我的maven库没有jetty的jar包我这里加入jetty容器就报错了:

然后生产者注册服务,这里的注册中心可以是zookeeper,redis等,我们这里注册中心以zookeeper为例,注册服务时将服务url添加到了providers下

 启动服务前:生产者为空

启动服务后:

可以看到,生产者将url信息以临时节点的方式注册到了zookeeper上

然后dubbo订阅服务,如果没有订阅到自己想获得的服务,它会不断的尝试订阅。新的服务注册到注册中心以后,注册中心会将这些服务通过notify到消费者(这里我觉着就是利用了zookeeper的watcher监听事件)

Monitor是监控中心,Consumer 和Provider通过异步的方式发送消息至Monitor,Consumer和Provider会将信息存放在本地磁盘,平均1min会发送一次信息。Monitor在整个架构中是可选的,Monitor功能需要单独配置,不配置或者配置以后,Monitor挂掉并不会影响服务的调用。Monitor也是一个dubbo服务

registry的可视化war包(dubbo-admin)和Monitor的源码包都可以从dubbo官网下载,dubbo从2.6.0以后就没有dubbo-admin了,在使用时需要先修改配置文件中的注册中心地址为你的实际地址

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值