封面《golden marriage》
dubbo
Dubbo 是阿里开发的一个 RPC 服务框架,用于解决微服务架构下的服务治理与通信问题。后来捐献给了 Apache,现在是 Apache Dubbo。
dubbo 架构
节点
说明
Provider
暴露服务的服务提供方
Consumer
调用远程服务的服务消费方
Registry
服务注册与发现的注册中心
Monitor
统计服务的调用次数和调用时间的监控中心
Container
服务运行容器
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
demo 结构
在这次 demo 的结构如下,通过 tree
命令输出如下。其中 dubbo-demo-api
是服务提供端和消费端公用的 api,dubbo-demo-consumer
和 dubbo-demo-provider
分别是服务的消费端和提供端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 │ .gitignore │ pom.xml ├─dubbo-demo-api │ │ pom.xml │ │ │ └─src │ └─main │ └─java │ └─com │ └─qxdn │ └─demo │ └─dubbo │ └─api │ HelloService.java │ ├─dubbo-demo-consumer │ │ pom.xml │ │ │ └─src │ └─main │ ├─java │ │ └─com │ │ └─qxdn │ │ └─demo │ │ └─dubbo │ │ └─consumer │ │ ConsumerApplication.java │ │ │ └─resources │ application.yml │ log4j.properties │ └─dubbo-demo-provider │ pom.xml │ └─src └─main ├─java │ └─com │ └─qxdn │ └─demo │ └─dubbo │ └─provider │ EmbeddedZooKeeper.java │ HelloServiceImpl.java │ ProviderApplication.java │ └─resources application.yml log4j.properties
父级 POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 ... <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <packaging > pom</packaging > <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > <spring.version > 4.3.16.RELEASE</spring.version > <dubbo.version > 3.0.7</dubbo.version > <slf4j-log4j12.version > 1.7.25</slf4j-log4j12.version > <spring-boot.version > 2.7.5</spring-boot.version > </properties > <modules > <module > dubbo-demo-api</module > <module > dubbo-demo-provider</module > <module > dubbo-demo-consumer</module > </modules > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > ${spring-boot.version}</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-bom</artifactId > <version > ${dubbo.version}</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-dependencies-zookeeper</artifactId > <version > ${dubbo.version}</version > <type > pom</type > </dependency > </dependencies > </dependencyManagement > <dependencies > <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-api</artifactId > </dependency > <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > <version > ${slf4j-log4j12.version}</version > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.24</version > <scope > provided</scope > </dependency > ...
接口
POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <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 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <parent > <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <relativePath > ../pom.xml</relativePath > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > dubbo-demo-api</artifactId > <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > <skip_maven_deploy > true</skip_maven_deploy > </properties > </project >
接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.qxdn.demo.dubbo.api;import java.util.concurrent.CompletableFuture;public interface HelloService { String sayHello (String name) ; default CompletableFuture<String> sayHelloAsync (String name) { return CompletableFuture.completedFuture(sayHello(name)); } }
服务提供者
POM
这里使用 zookeeper 作为注册中心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <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 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <parent > <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <relativePath > ../pom.xml</relativePath > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > dubbo-demo-provider</artifactId > <dependencies > <dependency > <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo-api</artifactId > <version > ${project.parent.version}</version > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo</artifactId > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-dependencies-zookeeper</artifactId > <type > pom</type > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > <exclusions > <exclusion > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-autoconfigure</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <executions > <execution > <goals > <goal > repackage</goal > </goals > </execution > </executions > </plugin > </plugins > </build > </project >
配置
application.yml
服务注册中心选择自己的 zookeeper 的地址
1 2 3 4 5 6 7 8 9 10 11 12 13 dubbo: application: name: dubbo-demo-provider protocol: name: dubbo port: -1 registry: id: zk-registry address: zookeeper://127.0.0.1:2181 config-center: address: zookeeper://127.0.0.1:2181 metadata-report: address: zookeeper://127.0.0.1:2181
log4j.properties
1 2 3 4 5 6 7 log4j.rootLogger =info, stdout log4j.appender.stdout =org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target =System.out log4j.appender.stdout.layout =org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
Provider
Impl
这里完成 RPC 服务的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.qxdn.demo.dubbo.provider;import com.qxdn.demo.dubbo.api.HelloService;import lombok.extern.slf4j.Slf4j;import org.apache.dubbo.config.annotation.DubboService;import org.apache.dubbo.rpc.RpcContext;@Slf4j @DubboService public class HelloServiceImpl implements HelloService { @Override public String sayHello (String name) { log.info("Hello " + name + ", request from consumer: " + RpcContext.getServiceContext().getRemoteAddressString()); return "Hello " + name + "from: " + RpcContext.getServiceContext().getLocalAddressString(); } }
zookeeper
zookeeper 可以到 apache 的官网下载
这里我们使用别人的 embedzookeeper, 源码在 github
Application
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.qxdn.demo.dubbo.provider;import lombok.extern.slf4j.Slf4j;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@Slf4j @SpringBootApplication @EnableDubbo public class ProviderApplication { public static void main (String[] args) throws Exception { new EmbeddedZooKeeper (2181 , false ).start(); SpringApplication.run(ProviderApplication.class, args); log.info("dubbo service started" ); } }
服务消费者
POM
这里使用 zookeeper 作为注册中心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <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 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <parent > <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <relativePath > ../pom.xml</relativePath > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > dubbo-demo-consumer</artifactId > <dependencies > <dependency > <groupId > com.qxdn.demo</groupId > <artifactId > dubbo-demo-api</artifactId > <version > ${project.parent.version}</version > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo</artifactId > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-dependencies-zookeeper</artifactId > <type > pom</type > </dependency > <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > <exclusions > <exclusion > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-autoconfigure</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <executions > <execution > <goals > <goal > repackage</goal > </goals > </execution > </executions > </plugin > </plugins > </build > </project >
配置
application.yml
服务注册中心选择自己的 zookeeper 的地址
1 2 3 4 5 6 7 8 9 10 11 12 13 dubbo: application: name: dubbo-springboot-demo-consumer protocol: name: dubbo port: -1 registry: id: zk-registry address: zookeeper://127.0.0.1:2181 config-center: address: zookeeper://127.0.0.1:2181 metadata-report: address: zookeeper://127.0.0.1:2181
log4j.properties
1 2 3 4 5 6 7 log4j.rootLogger =info, stdout log4j.appender.stdout =org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target =System.out log4j.appender.stdout.layout =org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
Consumer
@DubboReference
中的 loadbalance
是负载均很的方案,这里选择随机,此外注解也可以使用 version
进行服务的过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.qxdn.demo.dubbo.consumer;import com.qxdn.demo.dubbo.api.HelloService;import lombok.extern.slf4j.Slf4j;import org.apache.dubbo.common.constants.LoadbalanceRules;import org.apache.dubbo.config.annotation.DubboReference;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.stereotype.Service;@SpringBootApplication @Service @EnableDubbo @Slf4j public class ConsumerApplication { @DubboReference(loadbalance = LoadbalanceRules.RANDOM) private HelloService helloService; public static void main (String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ConsumerApplication.class, args); ConsumerApplication application = context.getBean(ConsumerApplication.class); String result = application.doSayHello("java" ); log.info("result: " + result); } public String doSayHello (String name) { return helloService.sayHello(name); } }
效果
服务提供者的输出
1 2 3 4 5 6 7 8 9 ... [20/11/22 03:22:54:208 CST] NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181 INFO server.NIOServerCnxnFactory: Accepted socket connection from /127.0.0.1:51634 [20/11/22 03:22:54:208 CST] NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181 INFO server.ZooKeeperServer: Client attempting to establish new session at /127.0.0.1:51634 [20/11/22 03:22:54:209 CST] SyncThread:0 INFO server.ZooKeeperServer: Established session 0x1000cab1b92000a with negotiated timeout 60000 for client /127.0.0.1:51634 [20/11/22 03:22:54:352 CST] NettyServerWorker-3-9 INFO netty4.NettyServerHandler: [DUBBO] The connection of /192.168.31.35:51635 -> /192.168.31.35:20880 is established., dubbo version: 3.0.7, current host: 192.168.31.35 [20/11/22 03:22:54:455 CST] NettyServerWorker-3-9 INFO netty4.NettyServerHandler: [DUBBO] The connection of /192.168.31.35:51635 -> /192.168.31.35:20880 is disconnected., dubbo version: 3.0.7, current host: 192.168.31.35 [20/11/22 03:22:54:493 CST] ProcessThread(sid:0 cport:2181): INFO server.PrepRequestProcessor: Got user-level KeeperException when processing sessionid:0x1000cab1b92000a type:create cxid:0x3 zxid:0x4e txntype:-1 reqpath:n/a Error Path:/services/dubbo-demo-provider Error:KeeperErrorCode = NodeExists for /services/dubbo-demo-provider [20/11/22 03:22:55:081 CST] DubboServerHandler-192.168.31.35:20880-thread-25 INFO provider.HelloServiceImpl: Hello java, request from consumer: 192.168.31.35:51631 [20/11/22 03:37:05:560 CST] Dubbo-framework-cache-refreshing-scheduler-thread-1 INFO metadata.AbstractCacheManager$CacheRefreshTask: [DUBBO] Dumping mapping caches, latest entries 0, dubbo version: 3.0.7, current host: 192.168.31.35
服务消费者的输出
1 2 3 4 5 6 7 8 ... 2 03:22:54:588 CST] main INFO metadata.MetadataInfo: [DUBBO] metadata revision changed: null -> 0ef9521ed22939bb2e1da2ea8012f84d, app: dubbo-springboot-demo-consumer, services: 1, dubbo version: 3.0.7, current host: 192.168.31.35 [20/11/22 03:22:55:063 CST] main INFO deploy.DefaultApplicationDeployer: [DUBBO] Dubbo Application[1.1](dubbo-springboot-demo-consumer) is ready., dubbo version: 3.0.7, current host: 192.168.31.35 [20/11/22 03:22:55:068 CST] main INFO consumer.ConsumerApplication: Started ConsumerApplication in 3.234 seconds (JVM running for 4.244) [20/11/22 03:22:55:071 CST] pool-1-thread-1 INFO event.AwaitingNonWebApplicationListener: [Dubbo] Current Spring Boot Application is await... [20/11/22 03:22:55:084 CST] main INFO consumer.ConsumerApplication: result: Hello javafrom: 192.168.31.35:20880 [20/11/22 03:32:53:388 CST] Dubbo-framework-cache-refreshing-scheduler-thread-1 INFO metadata.AbstractCacheManager$CacheRefreshTask: [DUBBO] Dumping mapping caches, latest entries 1, dubbo version: 3.0.7, current host: 192.168.31.35 [20/11/22 03:32:54:201 CST] Dubbo-framework-cache-refreshing-scheduler-thread-1 INFO metadata.AbstractCacheManager$CacheRefreshTask: [DUBBO] Dumping meta caches, latest entries 1, dubbo version: 3.0.7, current host: 192.168.31.35
可以看到两边都有调用结果的输出
可能的问题
启动程序时候出现问题如下
1 2 3 4 5 6 7 8 9 10 11 12 Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/core/metrics/ApplicationStartup at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:251) at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:264) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) at com.example.simple.dubbo_demo_provider.ProviderApplication.main(ProviderApplication.java:10) Caused by: java.lang.ClassNotFoundException: org.springframework.core.metrics.ApplicationStartup at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 5 more
经过查找资料 发现是因为父 POM 的 parent
里是 spring-boot-parent
而且还自定义了 <dependencyManagement/>
使得子模块里找不到对应的依赖 module。
解决方法就是在原先的父 POM<dependencyManagement/>
里面加上
1 2 3 4 5 6 7 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies<artifactId > <version > ${spring-boot.version}</version > <type > pom</type > <scope > import</scope > </dependency >
SLF4J: Class path contains multiple SLF4J bindings
SLF4J 绑定多个实现
1 2 3 4 5 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/C:/Users/qianx/.m2/repository/ch/qos/logback/logback-classic/1.2.11/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/C:/Users/qianx/.m2/repository/org/slf4j/slf4j-log4j12/1.7.25/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
这是因为项目中 SLF4J 有多种实现,可以通过下面的命令或者 IDE 的依赖分析来找到,
结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 # result [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ dubbo-demo-provider --- [INFO] com.qxdn.demo:dubbo-demo-provider:jar:0.0.1-SNAPSHOT [INFO] +- com.qxdn.demo:dubbo-demo-api:jar:0.0.1-SNAPSHOT:compile [INFO] +- org.apache.dubbo:dubbo:jar:3.0.7:compile [INFO] | +- org.springframework:spring-context:jar:5.3.23:compile [INFO] | | +- org.springframework:spring-aop:jar:5.3.23:compile [INFO] | | +- org.springframework:spring-beans:jar:5.3.23:compile [INFO] | | \- org.springframework:spring-expression:jar:5.3.23:compile [INFO] | +- com.alibaba.spring:spring-context-support:jar:1.0.8:compile [INFO] | +- org.javassist:javassist:jar:3.28.0-GA:compile [INFO] | +- io.netty:netty-all:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-buffer:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-dns:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-haproxy:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-http:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-http2:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-memcache:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-mqtt:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-redis:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-smtp:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-socks:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-stomp:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-codec-xml:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-common:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-handler:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-native-unix-common:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-handler-proxy:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-resolver:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-resolver-dns:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-rxtx:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-sctp:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-udt:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-classes-epoll:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-classes-kqueue:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-resolver-dns-classes-macos:jar:4.1.84.Final:compile [INFO] | | +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.84.Final:runtime [INFO] | | +- io.netty:netty-transport-native-epoll:jar:linux-aarch_64:4.1.84.Final:runtime [INFO] | | +- io.netty:netty-transport-native-kqueue:jar:osx-x86_64:4.1.84.Final:runtime [INFO] | | +- io.netty:netty-transport-native-kqueue:jar:osx-aarch_64:4.1.84.Final:runtime [INFO] | | +- io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.1.84.Final:runtime [INFO] | | \- io.netty:netty-resolver-dns-native-macos:jar:osx-aarch_64:4.1.84.Final:runtime [INFO] | +- com.google.code.gson:gson:jar:2.9.1:compile [INFO] | +- org.yaml:snakeyaml:jar:1.30:compile [INFO] | \- com.alibaba:fastjson:jar:1.2.70:compile [INFO] +- org.apache.dubbo:dubbo-dependencies-zookeeper:pom:3.0.7:compile [INFO] | +- org.apache.curator:curator-x-discovery:jar:4.2.0:compile [INFO] | | +- org.apache.curator:curator-recipes:jar:4.2.0:compile [INFO] | | | \- org.apache.curator:curator-framework:jar:4.2.0:compile [INFO] | | | \- org.apache.curator:curator-client:jar:4.2.0:compile [INFO] | | | \- com.google.guava:guava:jar:27.0.1-jre:compile [INFO] | | | +- com.google.guava:failureaccess:jar:1.0.1:compile [INFO] | | | +- com.google.guava:listenablefuture:jar:9999.0-empty-to-avoid-conflict-with-guava:compile [INFO] | | | +- org.checkerframework:checker-qual:jar:2.5.2:compile [INFO] | | | +- com.google.errorprone:error_prone_annotations:jar:2.2.0:compile [INFO] | | | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile [INFO] | | | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.17:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-databind:jar:2.13.4.2:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.4:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.13.4:compile [INFO] | \- org.apache.zookeeper:zookeeper:jar:3.4.14:compile [INFO] | +- com.github.spotbugs:spotbugs-annotations:jar:3.1.9:compile [INFO] | | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile [INFO] | +- jline:jline:jar:0.9.94:compile [INFO] | \- org.apache.yetus:audience-annotations:jar:0.5.0:compile [INFO] +- org.apache.dubbo:dubbo-spring-boot-starter:jar:3.0.7:compile [INFO] | \- org.apache.dubbo:dubbo-spring-boot-autoconfigure:jar:3.0.7:compile [INFO] | \- org.apache.dubbo:dubbo-spring-boot-autoconfigure-compatible:jar:3.0.7:compile [INFO] +- org.springframework.boot:spring-boot-starter:jar:2.7.5:compile [INFO] | +- org.springframework.boot:spring-boot:jar:2.7.5:compile [INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.5:compile [INFO] | | +- ch.qos.logback:logback-classic:jar:1.2.11:compile [INFO] | | | \- ch.qos.logback:logback-core:jar:1.2.11:compile [INFO] | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile [INFO] | | | \- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile [INFO] | | \- org.slf4j:jul-to-slf4j:jar:1.7.36:compile [INFO] | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile [INFO] | \- org.springframework:spring-core:jar:5.3.23:compile [INFO] | \- org.springframework:spring-jcl:jar:5.3.23:compile [INFO] +- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.5:compile [INFO] +- org.slf4j:slf4j-api:jar:1.7.36:compile [INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.25:compile [INFO] +- log4j:log4j:jar:1.2.17:compile [INFO] \- org.projectlombok:lombok:jar:1.18.24:provided [INFO]
找到依赖后修改
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > <exclusions > <exclusion > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > </exclusion > </exclusions > </dependency >
Failed to execute goal on project xxx
执行 mvn dependency:tree
的时候错误如下
1 Failed to execute goal on project dubbo-demo-provider: Could not resolve dependencies for project com.qxdn.demo:dubbo-demo-provider:jar:0.0.1-SNAPSHOT: Could not find artifact com.qxdn.demo:dubbo-demo-api:jar:0.0.1-SNAPSHOT
运行
完整代码
完整代码地址在 github
参考文献
dubbo 文档
Maven_dependencyManagement 多模块覆盖问题
Introduction to the Dependency Mechanism
quick start fails
Spring Boot: multiple SLF4J bindings