zoukankan      html  css  js  c++  java
  • dubbo源码阅读-容器启动(六)

    说明

    前面demo都是我们手动在main方法粗创建容器再star(),dubbo提供了一个main方法更友好的容器启动

        public static void main(String[] args) throws Exception {
            //<1>使用dubbo 提供的main方法启动容器
            com.alibaba.dubbo.container.Main.main(args);
        }

    接口定义

    @SPI("spring")//SPI配置 缺省值是Spring
    public interface Container {
    
        /**
         * start.
         */
        void start();
    
        /**
         * stop.
         */
        void stop();
    
    }

    可以发现是SPI接口

    类图

    Main

        public static void main(String[] args) {
            try {
                //如果没有启动参数
                if (args == null || args.length == 0) {
                    //获得系统变量 如jvm参数配置的-Ddubbo.container=spiKey 如果没有则使用loader.getDefaultExtensionName()"spring" 即 @SPI("spring")
                    String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());
                    //,分割
                    args = Constants.COMMA_SPLIT_PATTERN.split(config);
                }
    
    
                //容器集合 可以多容器启动
                // SPI扩展点 private static final ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);
                final List<Container> containers = new ArrayList<Container>();
                for (int i = 0; i < args.length; i++) {
    
                    //spi获取对应容器实现
                    containers.add(loader.getExtension(args[i]));
                }
                logger.info("Use container type(" + Arrays.toString(args) + ") to run dubbo serivce.");
                /**
                 * 埋点  jvm关闭时 关闭容器
                 *kill pid会优雅关闭  则有新的请求拒绝 等没有进行中的请求 才关闭
                 *kill -9并不会优雅关闭
                 */
                if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
                    Runtime.getRuntime().addShutdownHook(new Thread("dubbo-container-shutdown-hook") {
                        @Override
                        public void run() {
                            for (Container container : containers) {
                                try {
                                    //遍历容器执行stop
                                    container.stop();
                                    logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");
                                } catch (Throwable t) {
                                    logger.error(t.getMessage(), t);
                                }
                                try {
                                    LOCK.lock();
                                    STOP.signal();
                                } finally {
                                    LOCK.unlock();
                                }
                            }
                        }
                    });
                }
                //循环启动容器
                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);
            }
            try {
    
                //加锁
                LOCK.lock();
                //使用Condition 等待 防止线程退出
                STOP.await();
            } catch (InterruptedException e) {
                logger.warn("Dubbo service server stopped, interrupted by other thread!", e);
            } finally {
                LOCK.unlock();
            }
        }

    SpringContainer

    /**
     * SpringContainer. (SPI, Singleton, ThreadSafe)
     */
    public class SpringContainer implements Container {
    
        public static final String SPRING_CONFIG = "dubbo.spring.config";
        public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";
        private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class);
        static ClassPathXmlApplicationContext context;
    
        public static ClassPathXmlApplicationContext getContext() {
            return context;
        }
    
        @Override
        public void start() {
            /**
             * 获取spring.xml配置
             * ConfigUtils spring工具类
             * 1.先从系统变量获取
             * 2.加载系统变量 dubbo.properties.file 配置的file
             * 3 2没加载到加载dubbo.properties file
             *
             */
            String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
            //如果没有配置spring file则获取 classpath*:META-INF/spring/*.xml
            if (configPath == null || configPath.length() == 0) {
                configPath = DEFAULT_SPRING_CONFIG;
            }
            //启动springXML 容器
            context = new ClassPathXmlApplicationContext(configPath.split("[,\s]+"));
            context.start();
        }
    
        @Override
        public void stop() {
            try {
                if (context != null) {
                    context.stop();
                    context.close();
                    context = null;
                }
            } catch (Throwable e) {
                logger.error(e.getMessage(), e);
            }
        }
    
    }

    LogbackContainer

    /**
     * 接入logback
     * 
     */
    public class LogbackContainer implements Container {
    
        public static final String LOGBACK_FILE = "dubbo.logback.file";
    
        public static final String LOGBACK_LEVEL = "dubbo.logback.level";
    
        public static final String LOGBACK_MAX_HISTORY = "dubbo.logback.maxhistory";
    
        public static final String DEFAULT_LOGBACK_LEVEL = "ERROR";
        @Override
        public void start() {
            String file = ConfigUtils.getProperty(LOGBACK_FILE);
            if (file != null && file.length() > 0) {
                String level = ConfigUtils.getProperty(LOGBACK_LEVEL);
                if (level == null || level.length() == 0) {
                    level = DEFAULT_LOGBACK_LEVEL;
                }
                // maxHistory=0 Infinite history
                int maxHistory = StringUtils.parseInteger(ConfigUtils.getProperty(LOGBACK_MAX_HISTORY));
    
                doInitializer(file, level, maxHistory);
            }
        }
    
        @Override
        public void stop() {
        }
    
        /**
         * Initializer logback
         *
         * @param file
         * @param level
         * @param maxHistory
         */
        private void doInitializer(String file, String level, int maxHistory) {
            LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
            Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
            rootLogger.detachAndStopAllAppenders();
    
            // appender
            RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<ILoggingEvent>();
            fileAppender.setContext(loggerContext);
            fileAppender.setName("application");
            fileAppender.setFile(file);
            fileAppender.setAppend(true);
    
            // policy
            TimeBasedRollingPolicy<ILoggingEvent> policy = new TimeBasedRollingPolicy<ILoggingEvent>();
            policy.setContext(loggerContext);
            policy.setMaxHistory(maxHistory);
            policy.setFileNamePattern(file + ".%d{yyyy-MM-dd}");
            policy.setParent(fileAppender);
            policy.start();
            fileAppender.setRollingPolicy(policy);
    
            // encoder
            PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            encoder.setContext(loggerContext);
            encoder.setPattern("%date [%thread] %-5level %logger (%file:%line\) - %msg%n");
            encoder.start();
            fileAppender.setEncoder(encoder);
    
            fileAppender.start();
    
            rootLogger.addAppender(fileAppender);
            rootLogger.setLevel(Level.toLevel(level));
            rootLogger.setAdditive(false);
        }
    
    }

    Log4jContainer

    /**
     * Log4jContainer. (SPI, Singleton, ThreadSafe)
     */
    public class Log4jContainer implements Container {
    
        public static final String LOG4J_FILE = "dubbo.log4j.file";
    
        public static final String LOG4J_LEVEL = "dubbo.log4j.level";
    
        public static final String LOG4J_SUBDIRECTORY = "dubbo.log4j.subdirectory";
    
        public static final String DEFAULT_LOG4J_LEVEL = "ERROR";
    
        /**
         * 接入log4j
         */
        @Override
        @SuppressWarnings("unchecked")
        public void start() {
            String file = ConfigUtils.getProperty(LOG4J_FILE);
            if (file != null && file.length() > 0) {
                String level = ConfigUtils.getProperty(LOG4J_LEVEL);
                if (level == null || level.length() == 0) {
                    level = DEFAULT_LOG4J_LEVEL;
                }
                Properties properties = new Properties();
                properties.setProperty("log4j.rootLogger", level + ",application");
                properties.setProperty("log4j.appender.application", "org.apache.log4j.DailyRollingFileAppender");
                properties.setProperty("log4j.appender.application.File", file);
                properties.setProperty("log4j.appender.application.Append", "true");
                properties.setProperty("log4j.appender.application.DatePattern", "'.'yyyy-MM-dd");
                properties.setProperty("log4j.appender.application.layout", "org.apache.log4j.PatternLayout");
                properties.setProperty("log4j.appender.application.layout.ConversionPattern", "%d [%t] %-5p %C{6} (%F:%L) - %m%n");
                PropertyConfigurator.configure(properties);
            }
            String subdirectory = ConfigUtils.getProperty(LOG4J_SUBDIRECTORY);
            if (subdirectory != null && subdirectory.length() > 0) {
                Enumeration<org.apache.log4j.Logger> ls = LogManager.getCurrentLoggers();
                while (ls.hasMoreElements()) {
                    org.apache.log4j.Logger l = ls.nextElement();
                    if (l != null) {
                        Enumeration<Appender> as = l.getAllAppenders();
                        while (as.hasMoreElements()) {
                            Appender a = as.nextElement();
                            if (a instanceof FileAppender) {
                                FileAppender fa = (FileAppender) a;
                                String f = fa.getFile();
                                if (f != null && f.length() > 0) {
                                    int i = f.replace('\', '/').lastIndexOf('/');
                                    String path;
                                    if (i == -1) {
                                        path = subdirectory;
                                    } else {
                                        path = f.substring(0, i);
                                        if (!path.endsWith(subdirectory)) {
                                            path = path + "/" + subdirectory;
                                        }
                                        f = f.substring(i + 1);
                                    }
                                    fa.setFile(path + "/" + f);
                                    fa.activateOptions();
                                }
                            }
                        }
                    }
                }
            }
        }
    
        @Override
        public void stop() {
        }
    
    }
  • 相关阅读:
    oracle 认证方式
    Oracle
    深入理解Java的接口和抽象类
    mongoDB的学习【小白的福音】
    对于vertical-align的学习
    flex的学习 flexBox的学习
    用伪类添加翘边阴影::before和::after
    icon小图标
    url 中的 ? 和 & 还有 # 的作用
    解决img的1px空白问题
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12462550.html
Copyright © 2011-2022 走看看