今天在B站上学习尚硅谷雷丰阳老师的SpringBoot课程,跟着视频完成SpringBoot和Dubbo+Zookeeper的整合,遇到了一堆坑,心态炸裂,在这里记录一下遇到的问题。
- linux服务器安装好zookeeper,并处于启动状态,由于这不是重点,我就省略了。
- 建立项目
由于要创建服务端模块和消费端模块,我们选择创建一个空工程,在此基础上创建两个模块。
空项目创建好后自动弹出这个页面
接着我点击图中的“+”创建模块,两个模块都是通过spring initializr创建,然后问题来了,我发现创建后的模块是这个样子
什么问题呢?大家注意看图中pom.xml的图标,我们对比一个正常的maven项目
能够明显看出区别,也就是,第一种情况下,我们在pom.xml中引入的依赖,maven压根不会去从仓库中导入项目,它就是一个普通的xml文件,那这要怎么处理,我百度了好久看到的多模块创建都是先创建一个普通的maven项目,然后删除src目录,并在pom.xml中加入
然后让它作为一个父模块,在创建子模块时,把它选择为parent,这是没有问题的,但并不是我想要的效果,我要的就是单独的两模块,没有任何关联,最终并没有找出解决方案。 - 于是仔细看视频,发现老师在创建了一个空项目后,并没有选择那个“+”号,而是把那个窗口关了,选择此处的file->new modular进行子模块创建
于是我按照步骤尝试了一下,的确是成功了,成功后是这样子的
- 但是我手贱啊,因为.mvn,.gitignore,mvnw这些都是没用的,于是我就都给删了。。。。然后就不知道咋了,一个模块就消失了,我很郁闷,于是又重新创建了一次,这下学乖了,啥也不要删!!!!果然没出事。。。
好了,接下来开始做正事
先创建服务
-
在服务端创建一个TicketService,只有一个String sellTicket()方法;
-
写实现类
先不要管那个@Component和@Service,我们还没导入依赖 -
引入Dubbo和springboot整合的依赖,zkclient的依赖
这里老师用的是下面的依赖<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>
springboot和dubbo整合的依赖是直接去dubbo的官网找到github上的示例,我查看的时候已经变成下面这个了,我引入的也是这个
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.4.1</version> </dependency>
-
在application.properties配置包扫描和注册中心
这个server.port没有必要,但因为我的8080端口已用,否则我们的web项目启动会端口占用(sopringboot内嵌tomcat默认8080),address填你linux主机ip就行了。 -
我们在要发布的服务实现类TicketServiceImpl上添加注解,表示把这个服务发布出去,在注册中心注册,注意这个@Service是dubbo提供的!!!!
-
接着我们启动服务端主配置类
这个@EnableDubbo是我之后加上去的,好像是springboot 2.x之后的改变造成的,如果不加的话,之后我们在消费端的注入会失败(可能是null,反正我是直接报错了)具体大家试一下就知道了。 -
至此,我们服务端没有问题了,正常启动
接下来进行消费端的创建和配置,
-
引入dubbo和springboot的依赖,以及zkclient的依赖
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.4.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>
-
创建UserService接口,包含 String getTicket()方法.
-
在application.properties中配置服务名和注册中心
由于是消费,我们不需要配置包扫描发布,至于那个server.port依旧是防止端口冲突 -
创建接口实现类
注意此处我画出来的地方一定要注意导包不要导错,还有就是既然我们要注入TicketService,肯定要有这个接口,只是这里我们不需要它的实现,通过@Reference实现注入即可,这个@Reference也是dubbo提供的。
此处注意视频中说,这个TicketServcie的全路径类名必须和provider中的一致,也就是说它所在的包名和层级结构要完全一致。 -
然后我们在测试类中进行测试
注意springboot2.x之后这个测试类注解好像变了,1.x的时候一般都是@RunWith(SpringRunner.class) @SpringBootTest
刚开始我不知道,还以为自动生成的不完整,手动加上了@RunWith,还导了个junit的包,然后一启动直接报错SELF4J Multiple binding… 悲剧了,于是删掉,
加下来就出来了一个我看不懂的错,也不知道是不是新特性Caused by: java.lang.NoClassDefFoundError: org/apache/curator/framework/api/CuratorWatcher
百度一下,发现需要导入这个依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.2.0</version> </dependency>
然后导进入之后又是这个错误
java.lang.NoSuchMethodError: org.apache.zookeeper.ZooKeeper.<init>(Ljava/lang/String;ILorg/apache/zookeeper/Watcher;
百度得到的结果是jar包冲突。
-
于是在pom.xml文件鼠标右击,show diagrams查看依赖关系,发现是zkclient和刚导入的那个东西都引入了zookeeper依赖,而版本不同,所以进行exclude操作,把zkclient中的zookeeper依赖去除,然后重新运行,又报了这个错误
Class path contains multiple SLF4J bindings.
也就是说导入了两个到多个slf4j的实现,然后和刚才一样进行依赖冲突检查,发现那个zkclient里也导入了log4j,那既然你两个都冲突我还要你干啥???直接把zkclient的依赖给删了,然后单独导入了zookeeper的依赖,但因为会和curator-framework中的zookeeper冲突,所以把curator-framework中的zookeeper排除,于是接下来又报了个错,我心态崩了
java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener
百度发现需要导入下面这个依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency>
-
导入之后再次运行,又报错jar包冲突什么NoSuchMethod,原来是curator-recipes中已经引入了之前导入的curator-framework,所以我们把这个删掉。
到此,我终于成功了,真的是累啊。写的乱七八糟,可能大家看不下去了,见谅一下,我第一次写改bug的文章,就是怕下次再发生这种问题,我就大概有思路了,不用再耽误三小时查错。
总结一下,我最终的pom文件引入的依赖是这样的
provider:
<!--引入zkclient相关依赖-->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入dubbo和springboot整合包-->
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.4.1</version>
</dependency>
<!--不知道为啥报错,引入这个依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
<exclusions>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
consumer:
<!--引入zkclient相关依赖-->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入dubbo和springboot整合包-->
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.4.1</version>
</dependency>
<!--不知道为啥报错,引入这个依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
<exclusions>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
web-starter和test模块springboot自己导进来的我没粘出来,主要是上面的部分,我没有尝试过删掉zookeeper的依赖会不会失败(curator-recipes有引入zookeeper),心累啊,不想瞎搞了,但这样引入进来是没有问题的。
总的来说,需要注意这些问题:
- springboot2.x之后很多配置变了,依赖也变了,除了看官方文档就得自己摸索
- jar包冲突一定要解决,不要导入了就不管了。
- 版本冲突,有些模块之间版本依赖关系是由一定限制的,要去看官网,如dubbo和springboot整合时
到此,这篇乱七八糟的文章就结束了,但愿能对大家有所帮助,如果没有,就不要回复我没用了。。。。如果哪位大佬有更好的方法或者导入的依赖没这么复杂,希望能告知我一下,非常感谢!