Dubbo快速入门

2020-05-31  本文已影响0人  小艾咪

学习完zookeeper顺便搭建一个dubbo的hello world,在学习的过程中感觉重启后的dubbo好像并没有焕发生机。打算就学到hello world了,如果真用到再深入学习下。
Dubbo的快速开始分为三个项目,一个是通用API主要用来声明服务提供方和服务消费方都会使用的公共接口。一个是服务提供方,一个是服务消费方。

演示项目均使用Maven管理且创建时不使用模板

示例API项目名称:dubbo-common

示例服务方项目名称:dubbo-provider

示例消费方项目名称:dubbo-consumer

开始搭建

开始将会使用Multicast注册中心搭建,随后会将注册中心改为zookeeper

API项目

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wxm</groupId>
    <artifactId>dubbo-common</artifactId>
    <version>0.1</version>
    <packaging>jar</packaging>
</project>

项目结构


服务提供方

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wxm</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>0.1</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>com.wxm</groupId>
            <artifactId>dubbo-common</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>
</project>

项目结构


其中log4j.properties和logback.xml根据日志框架任选其一且当前没有实际用处,后文使用zookeeper做注册中心时会用到。

服务消费方

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wxm</groupId>
    <artifactId>dubbo-consumer</artifactId>
    <version>0.1</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>com.wxm</groupId>
            <artifactId>dubbo-common</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>
</project>

项目结构


同服务提供方一样log4j.properties在当前模式中没有使用,可忽略。

基本配置

API项目

只需提供公共接口

DemoService.java

package service;

public interface DemoService {
    String say(String msg);
}

服务提供方

编写provider.xml配置dubbo注册中心信息、通信协议、暴漏服务等。这里复制官方quick start进行修改

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="hello-world-app"  />
 
    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <dubbo:registry address="multicast://225.1.1.1:1234?unicast=false" />
 
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
 
    <!-- 声明需要暴露的服务接口,即API项目中的接口 -->
    
    <dubbo:service interface="service.DemoService" ref="demoService" />
 
    <!-- 和本地bean一样实现服务 -->
    <!-- class指定API接口实现类的全路径 -->
    <bean id="demoService" class="provider.service.DemoServiceImp" />
</beans>

这里可以看到暴漏服务地址时有一个unicast=false参数,当两个服务运行在同一台计算机上时需要添加该参数,原因官方文档有解释这里不复制粘贴,转至Multicast注册中心查看原因

DemoServiceImp.java

package provider.service;

import service.DemoService;

public class DemoServiceImp implements DemoService {

    public String say(String msg) {
        // TODO Auto-generated method stub
        return "服务提供:"+msg;
    }
}

App.java/服务提供方的

package provider;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.DemoService;

public class App {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("provider.xml");
        c.start();
        DemoService bean = c.getBean(DemoService.class);
        System.out.println(bean.say("serve"));
        System.in.read();
    }
}

服务消费方

编写consumer.xml声明需要的服务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer-of-helloworld-app" >
        <dubbo:parameter key="qos.port" value="33333"/>
    </dubbo:application>
 
    <!-- 使用multicast广播注册中心暴露发现服务地址 -->
    <!-- 和服务提供方一样也要写unicast=false -->
    <dubbo:registry address="multicast://225.1.1.1:1234?unicast=false" />
 
    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" interface="service.DemoService" />
</beans>

这里注意多了<dubbo:parameter key="qos.port" value="33333"/>如果在同一台计算机上需要配置该参数,因为两个服务默认都会尝试绑定22222端口。

App.java/服务消费方的

package consumer;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.DemoService;

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("consumer.xml");
        c.start();
        DemoService demo = (DemoService)c.getBean("demoService");
        System.out.println(demo.say("client"));
    }
}

至此配置完成,启动服务提供方的App.java

控制台

五月 27, 2020 5:21:59 下午 org.apache.dubbo.registry.multicast.MulticastRegistry warn
警告:  [DUBBO] Ignore empty notify urls for subscribe url provider://192.168.64.1:20880/service.DemoService?anyhost=true&application=hello-world-app&bean.name=service.DemoService&bind.ip=192.168.64.1&bind.port=20880&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=service.DemoService&methods=say&pid=10692&register=true&release=2.7.3&side=provider&timestamp=1590571316867, dubbo version: 2.7.3, current host: 192.168.64.1
服务提供:serve

启动服务消费方App.java

控制台

五月 27, 2020 5:28:41 下午 org.apache.dubbo.config.AbstractConfig info
信息:  [DUBBO] Refer dubbo service service.DemoService from url multicast://225.1.1.1:1234/org.apache.dubbo.registry.RegistryService?anyhost=true&application=consumer-of-helloworld-app&check=false&dubbo=2.0.2&generic=false&interface=service.DemoService&lazy=false&methods=say&pid=6720&qos.port=33333&register.ip=192.168.64.1&release=2.7.3&remote.application=hello-world-app&side=consumer&sticky=false&timestamp=1590571718957, dubbo version: 2.7.3, current host: 192.168.64.1
服务提供:client

demo搭建完成,这里记录过程中的坑

将注册中心改为zookeeper

dubbo推荐使用zookeeper作为注册中心。dubbo关于zookeeper做注册中心的官方文档似乎并没有因为dubbo重启维护而更新。甚至文档中还在使用Netflix的curator。在maven仓库中Netflix的curator最后更新时间为2013年。现在的curator似乎隶属于apache。但从报错信息中我们可以得到以下结论。dubbo使用zookeeper作为注册中心时还需要依赖以下项目

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.1</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>

开始我使用的是2.6.3版本的dubbo,该版本不依赖curator-recipes,但2.7.3需要添加此依赖。

修改配置文件

现在分别修改provider.xml和cuonsumer.xml

provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="hello-world-app"  />
 
    <!-- 这里发生了变化 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
 
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
 
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="service.DemoService" ref="demoService" />
 
    <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="provider.service.DemoServiceImp" />
</beans>

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer-of-helloworld-app" >
        <dubbo:parameter key="qos.port" value="33333"/>
    </dubbo:application>
 
    <!-- 这里发生了变化 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
 
    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" interface="service.DemoService" />
</beans>

添加日志配置文件

curator引入了zookeeper而zookeeper又引入了log4j,所以此时项目的日志模块已被log4j接手,所以我们需要为项目添加log4j的配置文件,内容如下

log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,CONSOLE,file

#log4j.logger.org.apache.zookeeper.ClientCnxn=error
#log4j.logger.org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator = error

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n

但注意这里打印的日志信息并不包含zookeeper以及curator。什么日志框架是curator引入的不打印curator的日志?????别急先运行示例,看看控制台怎么说。

启动服务

首先要启动zookeeper服务,zookeeper安装部署在另一篇文章中,这里直接用。

重新运行App.java/服务提供方的

控制台

[DEBUG] 2020-05-27 17:30:40,220 org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
[DEBUG] 2020-05-27 17:30:40,221 org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'demoService'
服务提供:serve

重新运行App.java/服务消费方的

控制台

[DEBUG] 2020-05-27 17:32:12,244 io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@239d3e1c
[DEBUG] 2020-05-27 17:32:12,322 org.apache.dubbo.remoting.transport.DecodeHandler -  [DUBBO] Decode decodeable message org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult, dubbo version: 2.7.3, current host: 192.168.64.1
服务提供:client

虽然不会打印curator和zookeeper的日志但程序是会运行成功的,可以看到远程调用成功。

你可能看到会有许多日志但那都是dobbo打印的

在两个App.java运行过程中可以在控制台看到如下信息

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.

加载StaticLoggerBinder失败,猜测是缺少slf4j-log4j12库,这时去查看下当前项目的全部依赖

可以看到存在slf4j-api和log4j依赖但缺少slf4j-log4j12猜测正确,但为什么dubbo却可以正常打印日志信息呢,这里应该是dubbo项目本身做了一些处理,例如打包时已经将slf4j-log4j12打包到源码中这里不做深究。

所以现在还需要引入slf4j-log4j12,添加如下依赖至dubbo-provider和dubbo-consumer项目当中。

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>

至此以zookeeper为注册中心的demo也完美运行。

自定义Spring版本

dubbo依赖中含有spring且具有传递性,所以说引入dubbo的同时一会一并引入dubbo所需要的spring依赖。

本文使用的dubbo版本为2.7.3内置的spring版本为4.3.16,如果想要自定义spring版本也可以自己引入想要的spring版本。

查看dubbo的pom文件可以看到dubbo仅依赖spring-context即可正常工作,根据maven对相同依赖的选择原则只需要在当前项目中引入想要的spring版本即可,这里以spring5为例,修改后的pom.xml为

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wxm</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>0.1</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.3</version>
            <!--这个exclusions实际上是不需要的,添加目的是为了使意图更为明显以及避免不必要的麻烦。功能            是引入依赖时排除<exclusions></exclusions>中声明的依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        //添加部分
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        ....只显示发生变动的部分。
    </dependencies>
</project>

自定义zookeeper版本

替换思路与自定以spring一样,curator中是会引入zookeeper的,默认版本为3.5.3-beta。这里以zookeeper 3.4.6为例,替换后pom.xml为

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wxm</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>0.1</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.1</version>
            <!--和上文一样,可以省略。目的相同-->
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        ....只显示发生变动的部分。
    </dependencies>
</project>

闲的蛋疼,更换日志框架

排除多余依赖

更换默认日志框架,更换目标logback,首先查看当前项目中都谁引入过log4j相关框架并一一清除,经过排查curator直接或间接引入了log4j和slf4j-log4j12,所以首先排除curator中的log4j相关依赖,修改pom.xml

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

然后是自定义zookeeper时引入的zookeeper,修改pom.xml

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

这里说明下,以防回来看时有疑惑。根据maven对相同依赖的选择原则(选层数最小那个)实际上当前项目中引入的zookeeper是我自己引入的那个,curator中的zookeeper并没有生效,并且curator中的log4j框架也是它通过zookeeper间接引入的,所以说curator中对log4j相关框架的排除操作在当前项目中依然是可以省略的。还是那句话,为了使意图更加明确且避免不必要的麻烦,所以依然选择保留。

添加目的依赖

添加logback相关依赖,将如下依赖添加到pom.xml中

        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>test</scope>
        </dependency>

添加logback配置文件

在classpath下新建logback.xml并键入如下内容

<configuration>
    <appender name="STDOUT"
        class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder 
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <logger name="org.apache.zookeeper.ClientCnxn" level="error" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>
    <logger name="o.a.d.c.e.AdaptiveClassCodeGenerator" level="error" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

启动项目即可打印日志,但这里还有一个小坑。可以看到前面的log4j的配置文件有如下两行

log4j.logger.org.apache.zookeeper.ClientCnxn=error
log4j.logger.org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator = error

log4j.logger.org.apache.zookeeper.ClientCnxn=error用来屏蔽zookeeper心跳日志log4j.logger.org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator = error用来屏蔽dubbo一个很长的日志,它长下面这样,但这个是由logback打出的

21:49:01.058 [main] DEBUG o.a.d.c.e.AdaptiveClassCodeGenerator -  [DUBBO] package org.apache.dubbo.rpc.clusteshishir;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class ConfiguratorFactory$Adaptive implements org.apache.dubbo.rpc.cluster.ConfiguratorFactory {
public org.apache.dubbo.rpc.cluster.Configurator getConfigurator(org.apache.dubbo.common.URL arg0)  {
if (arg0 == null) throw new IllegalArgumentException("url == null");
org.apache.dubbo.common.URL url = arg0;
String extName = url.getProtocol();
if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.ConfiguratorFactory) name from url (" + url.toString() + ") use keys([protocol])");
org.apache.dubbo.rpc.cluster.ConfiguratorFactory extension = (org.apache.dubbo.rpc.cluster.ConfiguratorFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.cluster.ConfiguratorFactory.class).getExtension(extName);
return extension.getConfigurator(arg0);
}
}, dubbo version: 2.7.3, current host: 192.168.64.1

但是不知处于什么原因控制台告诉我们该日志是o.a.d.c.e.AdaptiveClassCodeGenerator打出的,通过原来的log4j可以知道该日志实际是org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator打出的,所以logback配置文件中logger的name要按找log4j中的日志名进行配置。

<logger name="o.a.d.c.e.AdaptiveClassCodeGenerator" level="error" additivity="false">
    <appender-ref ref="STDOUT"/>
</logger>

修改为

<logger name="com.alibaba.dubbo.common.extension.ExtensionLoader" level="error" additivity="false">
        <appender-ref ref="STDOUT"/>
</logger>

最后:大幻梦森罗万象狂气断罪眼\ (•◡•) /

上一篇下一篇

猜你喜欢

热点阅读