SpringBoot配合Dubbo,使用@Service和@Reference,group实现接口多实现


公司项目升级,需要实现springBoot + Dubbo,并支持一个接口多个实现的情况。遇到了几个坑,在这里记录下。

1. 安装Zookeeper

官网 上下载最新版本3.5.6(注意下载 bin 包)

  1. 将下载好的压缩包,解压到对应目录
  2. cd apache-zookeeper-3.5.6-bin/conf/ // 切换到配置目录
  3. mv zoo_sample.cfg zoo.cfg //更改默认配置文件名称
  4. vi zoo.cfg // 编辑配置文件,自定义dataDir,我的配置贴在下面

这里会遇到第一个坑:zk从3.5.5开始,带有bin名称的包才是我们想要的下载可以直接使用的里面有编译后的二进制的包,而tar.gz的包里面是只是源码,无法直接使用。不小心下了 apache-zookeeper-3.5.6.tar.gz 这个包,启动时会报错"错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain"。

zoo.cfg
# 发送心跳的间隔时间, 毫秒为单位
tickTime=2000
# 集群用到,初始化连接时,leader最多能容忍client多少个心跳间隔,默认是10,就代表10*2000=20000 , 毫秒
initLimit=10
# 集群用到,正常通信时,如果client超过此时间间隔没有心跳
syncLimit=5
# 保存数据的目录
dataDir=/Users/ouitsu/document/apache-zookeeper-3.5.6-bin/data
# 暴露的接口
clientPort=2181
# zk3.5的新特性,Zookeeper AdminServer,默认端口是8080,坑的一批
admin.serverPort=12181

这里是第二个坑,zk的Zookeeper AdminServer默认端口和Dubbo admin默认端口冲突,会报错:Unable to start AdminServer, exiting abnormally org.apache.zookeeper.server,在这里定义端口即可解决。

配置完成,开始启动zk

  1. cd到zookeeper的bin目录下
  2. ./zkServer.sh start 启动
  3. ./zkServer.sh stop 停止

开始搭建项目

1. 生产者

目录结构如下:

provider_pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.uaepay.pay.channel</groupId>
<artifactId>dubbo_provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo_provider</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency> <dependency>
<groupId>uaepay.cmf.channel</groupId>
<artifactId>dubbo_facade</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> <repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories> </project>
provider_application:
package com.uaepay.pay.channel.dubbo_provider;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@EnableDubbo //启动dubbo的配置
public class DubboProviderApplication { public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
}
两个生产实现
package com.uaepay.pay.channel.dubbo_provider.service;

import com.alibaba.dubbo.config.annotation.Service; // 这里要注意引用dubbo的Service
import org.springframework.stereotype.Component; // 对应的,使用spring的Component
import uaepay.cmf.channel.MockResponseService;
import uaepay.cmf.channel.vo.User; @Service(group = "mockResponseServiceImpl") // 定义group
@Component
public class MockResponseServiceImpl implements MockResponseService { @Override
public User getUserInfo() {
User user = new User();
user.setUserName("1111");
return user;
}
}
package com.uaepay.pay.channel.dubbo_provider.service;

import com.alibaba.dubbo.config.annotation.Service;// 使用alibaba.dubbo的Service注解
import org.springframework.stereotype.Component;// 使用Spring的Component注解
import uaepay.cmf.channel.MockResponseService;
import uaepay.cmf.channel.vo.User; @Service(group = "mockResponseServiceImpl2") //定义group
@Component
public class MockResponseServiceImpl2 implements MockResponseService { @Override
public User getUserInfo() {
User user = new User();
user.setUserName("222222");
return user;
}
}
application.properties
dubbo.application.name=dubbo-provider-service
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.port=20782
dubbo.protocol.dispatcher=message
dubbo.protocol.threadpool=fixed
dubbo.protocol.threads=200
server.port=8871

2. 消费者

目录结构如下:

pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.uaepay.pay.channel</groupId>
<artifactId>dubbo_consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo_consumer</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies> <dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency> <dependency>
<groupId>uaepay.cmf.channel</groupId>
<artifactId>dubbo_facade</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.0.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ConsumerApplication:
package com.uaepay.pay.channel.dubbo_consumer;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@EnableDubbo
public class DubboConsumerApplication { public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
}
消费者的实现类
package com.uaepay.pay.channel.dubbo_consumer.service;

import com.alibaba.dubbo.config.annotation.Reference;// 使用Dubbo的reference 获取对应实现
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import uaepay.cmf.channel.MockResponseService; import java.util.LinkedHashMap;
import java.util.TreeMap; @RestController
@RequestMapping("/test")
public class MockServiceImpl { @Reference(group = "mockResponseServiceImpl")//对应定义group
private MockResponseService mockResponseServiceImpl; @Reference(group = "mockResponseServiceImpl2")// 对应定义group
private MockResponseService mockResponseServiceImpl2; @RequestMapping("/getUserInfo")
public void getUserInfo(){
System.out.println("得到的详情为..."+JSON.toJSONString(mockResponseServiceImpl.getUserInfo()));
} @RequestMapping("/getUserInfo1")
public void getUserInfo11(){
System.out.println("得到的详情为..."+JSON.toJSONString(mockResponseServiceImpl2.getUserInfo()));
}
}
application.properties
dubbo.application.name=dubbo-consumer-service
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.consumer.check=false
server.port=8862

facade包

项目结构如下:

pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion> <groupId>uaepay.cmf.channel</groupId>
<artifactId>dubbo_facade</artifactId>
<version>1.0-SNAPSHOT</version> <name>dubbo_facade</name>
<url>http://www.example.com</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
</dependencies> <build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
实体类
package uaepay.cmf.channel.vo;
import java.io.Serializable; public class User implements Serializable {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

接口

package uaepay.cmf.channel;
import uaepay.cmf.channel.vo.User; public interface MockResponseService { public User getUserInfo(); }

运行项目

启动provider

Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x100000dd3c5000c, negotiated timeout = 30000

成功打印出这些,说明生产者已经注册成功,如果未出现,检查一下是不是没引入com.101tec.zkclient的依赖,或者zk是否成功启动。

启动Consumer

<dubbo:reference object="com.alibaba.dubbo.common.bytecode.proxy0@3da222de" singleton="true" interface="uaepay.cmf.channel.MockResponseService" uniqueServiceName="mockResponseServiceImpl/uaepay.cmf.channel.MockResponseService" generic="false" group="mockResponseServiceImpl" listener="" filter="" id="uaepay.cmf.channel.MockResponseService" /> has been built.
<dubbo:reference object="com.alibaba.dubbo.common.bytecode.proxy0@4aae626d" singleton="true" interface="uaepay.cmf.channel.MockResponseService" uniqueServiceName="mockResponseServiceImpl2/uaepay.cmf.channel.MockResponseService" generic="false" group="mockResponseServiceImpl2" listener="" filter="" id="uaepay.cmf.channel.MockResponseService" /> has been built.

成功打印这个,证明消费者配置成功。

如果打印的是 <dubbo:reference singleton="true" interface="uaepay.cmf.channel.MockResponseService..../> 且访问报空指针,打印参数中不包含 object时,说明消费者没有接收到生产者的代理对象。需要检查两个地方:

  1. 依赖是否加上了com.101tec.zkclient
  2. application.properties中是否加入了属性 dubbo.consumer.check=false

附加:Dubbo-admin

dubbo提供dubbo的后台管理,在github上下载,拉到本地的项目结构是这样的:

重要的子模块有两个:Dubbo-admin-server和Dubbo-admin-ui

  • Dubbo-admin-server:

    • 默认端口8080
    • 是一个springboot项目,直接启动即可
  • Dubbo-admin-ui:
    • 需要使用npm,没安装npm的点这里
    • cd到Dubbo-admin-ui路径,npm install 安装依赖
    • 依赖安装完成,npm run dev
    • 运行成功打开http://localhost:8081 即可

如果有具体步骤不懂,可以查看项目中的README.md(子模块中也有),写的很详细。

至此,大功告成!


欢迎访问我的个人博客

Dubbo配合SpringBoot,实现接口多个实现(group)的更多相关文章

  1. dubbo+zookeeper+springboot简单示例

    目录 dubbo+zookeeper+springboot简单示例 zookeeper安装使用 api子模块 生产者producer 消费者consumer @(目录) dubbo+zookeeper ...

  2. Dubbo与SpringBoot的结合

    前言 这段时间在接触分布式的内容,因为公司的技术栈是 dubbo ,所以我顺其自然地选择了 dubbo 作为我学习的框架. 看了任务清单,这篇文章应该是在6天前出来的,但是因为实习等等的一些事情耽误了 ...

  3. 手把手教你Dubbo与SpringBoot常用两种方式整合

    一.Dubbo整合SpringBoot的方式(1) 1)直奔主题,方式一: pom.xml中引入dubbo-starter依赖,在application.properties配置属性,使用@Servi ...

  4. Dubbo整合Springboot框架

    本文使用的是alibaba的Dubbo. Dubbo整合Springboot可以分为四步: 第一步:首先需要了解Dubbo官方给的建议,至少有三个工程: 接口工程:主要存实体bean和业务接口 服务提 ...

  5. dubbo+zookeeper+springboot构建服务

    本次和大家分享的是dubbo框架应用的初略配置和zookeeper注册中心的使用:说到注册中心现在我使用过的只有两种:zookeeper和Eureka,zk我结合dubbo来使用,而Eureka结合s ...

  6. SpringBoot项目接口第一次访问慢的问题

    SpringBoot的接口第一次访问都很慢,通过日志可以发现,dispatcherServlet不是一开始就加载的,有访问才开始加载的,即懒加载. 2019-01-25 15:23:46.264 IN ...

  7. DUBBO监控,设置接口调用数据的上报周期

    目录 DUBBO监控,设置接口调用数据的上报周期 dubbo已有的监控方案 针对已有方案的改进 DUBBO监控,设置接口调用数据的上报周期 dubbo是目前比较好用的,用来实现soa架构的一个工具,d ...

  8. springboot+swagger接口文档企业实践(下)

    目录 1.引言 2. swagger接口过滤 2.1 按包过滤(package) 2.2 按类注解过滤 2.3 按方法注解过滤 2.4 按分组过滤 2.4.1 定义注解ApiVersion 2.4.2 ...

  9. SpringBoot Restful 接口实现

    目录 SpringBoot 核心注解 SpringBoot Restful 接口实现 封装响应数据 SpringBoot 核心注解 SpringBoot 基础入门 注解 说明 Component 声明 ...

随机推荐

  1. RocketMQ学习 -> NameServer路由中心

    RocketMQ项目代码核心目录说明 broker:broker启动进程 client:消息客户端,包含消息生产者,消息消费者相关类 common:公共包 dev:开发者信息(非源代码) distri ...

  2. freemarker模版引擎技术总结

    FreeMarker语言概述 FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写. FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式 ...

  3. 节点操作--JavaScript

    1 - 概念 网页中的所有内容都是节点(标签.属性.文本.注释),在DOM中,节点使用node来表示. HTML DOM树中的所有节点均可通过JS进行访问,所有HTML元素(节点)均可被修改,也可以创 ...

  4. 快学Scala 第十三课 (类型层级,对象相等性)

    Scala 类型层级: 对象相等性: 和Java一样要重写equals方法和hashcode方法 class Student(val id: Int, val name: String) { over ...

  5. BootstrapVue 安装指南

    BootstrapVue 是基于 Bootstrap v4 + Vue.js 的前端 UI 框架.BootstrapVue 作为学习 Vue.js 框架本身的入门框架,我认为是非常不错的.Bootst ...

  6. JS时间格式CST转GMT

    转换方法:JS 时间格式CST转GMT 时区和Date:Java中的Date和时区转换

  7. Nullable Reference Types 可空引用类型

    在写C#代码的时候,你可能经常会遇到这个错误: 但如果想避免NullReferenceException的发生,确实需要做很多麻烦的工作. 可空引用类型 Null Reference Type 所以, ...

  8. synchronized块中的wait()、nofity()、nofityAll()方法

    前言 在Java并发编程实战,会经常遇到多个线程访问同一个资源的情况,这个时候就需要维护数据的一致性,否则会出现各种数据错误,其中一种同步方式就是利用Synchronized关键字执行锁机制,锁机制是 ...

  9. HDU - 1512  Monkey King

    Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they each ...

  10. 小白学 Python(1):开篇

    人生苦短,我用 Python 引言 大家好,可能大家都对我比较熟悉了,不熟悉请去面壁(现在熟悉一下也来得及)~ 简单做一个自我介绍,我是极客挖掘机的唯一作者,一位油腻的 Java 程序员[臭鸡蛋什么的 ...