Collin Nam


dubbo之整合springboot,zk,mq,mybatis等

Frank 2019-04-29 1610浏览 2条评论
首页/ 正文
分享到: / / / /

      很久没有更新博客了,之前也一直在分享一些底层jdk和源码相关的知识,有人反映来点第三方架构方面的干货,今天带领大家进入dubbo的入门。

1. 教程大纲

1、 了解什么是dubbo

2、 我们使用dubbo能做什么

3、 Dubbo快速入门案例

4、 Dubbo监控、admin控制台

 

参考资料:

http://dubbo.io/

https://www.gitbook.com/@dubbo

Dubbo项目GitHub主页:

https://github.com/alibaba/dubbo

 

2. 什么是dubbo

2.1. 简介

       DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

 

 

        Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。Dubbo框架使得使用者可以像调用本地方法一样调用远程方法,而这一切只需要简单的配置。Dubbo完全兼容Spring配置方式注入,也与Spring boot无缝整合。

 

 

Provider: 暴露服务的服务提供方。 

Consumer: 调用远程服务的服务消费方。 

Registry: 服务注册与发现的注册中心。 

Monitor: 统计服务的调用次数和调用时间的监控中心。

 

调用流程 

0.服务容器负责启动,加载,运行服务提供者。 

1.服务提供者在启动时,向注册中心注册自己提供的服务。 

2.服务消费者在启动时,向注册中心订阅自己所需的服务。 

3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 

4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 

5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀; 

对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。 

而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即既需要提供服务,有需要消费服务。

 

      通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。

 

Dubbo提供的注册中心有如下几种类型可供选择:

 

Multicast注册中心

Zookeeper注册中心

Redis注册中心

Simple注册中心

 

本文我们选择dubbo最常用最适合的注册中心zookeeper。

安装zookeeper可以参考我的博客

https://blog.csdn.net/u010199866/article/details/81742866

 

      相信玩微服务架构的开发者也不是新人了,而且文章中有分享源码,由于项目类文件过多不会一一贴出来,这里创建项目就简单说明了。

 

打开idea创建maven项目名称为springboot-dubbo

然后在springboot-dubbo下建立3个module,分别是springboot-api,springboot-server,springboot-client。

主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>com.example</groupId>
   <artifactId>springboot-dubbo-parent</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>pom</packaging>
   <name>springboot-dubbo-parent</name>
   <description>Demo project for Spring Boot</description>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.9.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <modules>
      <module>springboot-dubbo-api</module>
      <module>springboot-dubbo-server</module>
      <module>springboot-dubbo-client</module>
        <module>springboot-rabbitmq-receive</module>
      <module>springboot-rabbitmq-sender</module>
   </modules>
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <!-- 在properties中统一控制依赖包的版本,更清晰-->
      <dubbo.version>2.5.3</dubbo.version>
      <zk.version>3.4.5</zk.version>
      <zkclient.version>0.1</zkclient.version>
   </properties>
   <dependencyManagement>   <!--dependencyManagement用于管理依赖版本号-->
      <dependencies>
          <!--删除spring-boot-starter和spring-boot-starter-test,-->
            <!--因为parent中继承的祖先中已经有了,并且一般dependencyManagement管理的依赖都要写版本号-->
         <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
         </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
         </dependency>-->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>1.5.9.RELEASE</version>
         </dependency>
         <!--新增后续dubbo项目中所需依赖,dubbo、zk-->
         <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version><!--使用properties中配置的版本号-->
            <exclusions>
               <exclusion>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring</artifactId>
               </exclusion>
            </exclusions>
         </dependency>
         <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>${zk.version}</version>
            <exclusions>
               <exclusion>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-log4j12</artifactId>
               </exclusion>
               <exclusion>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
               </exclusion>
            </exclusions>
         </dependency>
         <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>${zkclient.version}</version>
         </dependency>
      </dependencies>
   </dependencyManagement>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

 

api依赖

<?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>com.example</groupId>
   <artifactId>springboot-dubbo-api</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>springboot-dubbo-api</name>
   <description>Demo project for Spring Boot with dubbo api</description>
   <parent>
      <groupId>com.example</groupId>
      <artifactId>springboot-dubbo-parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
   </parent>
   <properties>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

 

server依赖

<?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>com.example</groupId>
   <artifactId>springboot-dubbo-server</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>springboot-dubbo-server</name>
   <description>Demo project for Spring Boot</description>
   <parent>
      <groupId>com.example</groupId>
      <artifactId>springboot-dubbo-parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
   </parent>
   <properties>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <!--新增后续dubbo项目中所需依赖,dubbo、zk。
           父模块pom中使用dependencyManagement来管理依赖版本号,子模块pom中不需要再写版本号,exclusion也不需要-->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>dubbo</artifactId>
      </dependency>
      <dependency>
         <groupId>org.apache.zookeeper</groupId>
         <artifactId>zookeeper</artifactId>
      </dependency>
      <dependency>
         <groupId>com.github.sgroschupf</groupId>
         <artifactId>zkclient</artifactId>
      </dependency>
      <dependency>
         <groupId>com.example</groupId>
         <artifactId>springboot-dubbo-api</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>1.3.1</version>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.4</version>
            <configuration>
               <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
               <overwrite>true</overwrite>
               <verbose>true</verbose>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

 

client依赖

 

<?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>com.example</groupId>
   <artifactId>springboot-dubbo-client</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>springboot-dubbo-client</name>
   <description>Demo project for Spring Boot</description>
   <parent>
      <groupId>com.example</groupId>
      <artifactId>springboot-dubbo-parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
   </parent>
   <properties>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!--新增后续dubbo项目中所需依赖,dubbo、zk。
           父模块pom中使用dependencyManagement来管理依赖版本号,子模块pom中不需要再写版本号,exclusion也不需要-->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>dubbo</artifactId>
      </dependency>
      <dependency>
         <groupId>org.apache.zookeeper</groupId>
         <artifactId>zookeeper</artifactId>
      </dependency>
      <dependency>
         <groupId>com.github.sgroschupf</groupId>
         <artifactId>zkclient</artifactId>
      </dependency>
      <dependency>
         <groupId>com.example</groupId>
         <artifactId>springboot-dubbo-api</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

server的dubbo配置

<?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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="demo-provider" />
    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry protocol="zookeeper" address="47.107.134.157:2181" timeout="60000"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 暴露dubbo服务的方式一-->
    <!-- 使用注解方式暴露接口,会自动扫描package下所有包中dubbo相关的注解,这样就不用在xml中再针对每个服务接口配置dubbo:service interface-->
    <dubbo:annotation package="com.example.demo.impl"/>
    <!-- 暴露dubbo服务的方式二 -->
    <!-- 使用xml配置方式申明暴露一个接口服务,在程序启动的时候会自动注册到zookeeper。
         等同于在类上打@service注解,打了注解就必须要用annotation指定启动扫描路径,使用这种方式,就不需要指定annotation了-->
    <!--<dubbo:service interface="com.example.demo.api.UserService" ref="userService"/>-->
    <!-- 具体的实现bean,id与上面的ref要一致-->
    <!--<bean id="userService" class="UserServiceImpl" />-->
</beans>

client的dubbo配置:

<?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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="demo-consumer"/>
    <!--zookeeper注册中心 -->
    <dubbo:registry  protocol="zookeeper" address="47.107.134.157:2181" timeout="60000"/>
    <!--关闭服务消费方所有服务的启动检查。dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成。-->
    <dubbo:consumer check="false" />
    <!-- 使用注解方式创建远程服务代理-->
    <dubbo:annotation package="com.example.demo.controller"/>
    <!-- 使用xml配置方式创建远程服务代理,id即为provider.xml中暴露的服务的id-->
    <!-- 等同于dubbo:annotation 加上代码里的@Reference注解-->
    <!--<dubbo:reference id="userService" interface="com.example.demo.api.UserService"/>-->
</beans>

 

    将数据库jdbc配置为自己的数据库,zookeeper改为自己的,我们先启动server服务,再启动client服务测试一下我们在dubbo-zk这一套架构上编写的restful风格的api能否调用成功。

 

 

 

http://127.0.0.1:8080/user/findAll

 

ok,我们简单的dubbo-demo就搭建好了,我们可以启动多个服务提供者server或者client,进行服务负载均衡配置,减轻单服务的压力,我们开始搭建dubbo监控中心,dubbo-admin进行查看配置

 

直接去github下载他们打包好的源代码吧:

https://github.com/apache/incubator-dubbo/archive/dubbo-2.6.0.tar.gz

打开命令行 wget https://github.com/apache/incubator-dubbo/archive/dubbo-2.6.0.tar.gz

 

tar -zxvf dubbo-2.6.0.tar.gz

 

 

1、解压后,根目录里存在dubbo-admin,进入 mvn package -Dmaven.test.skip=true 安装完后,生成target目录,进入这个目录,找到dubbo-admin-2.6.0这个目录,把这个目录全部copy到tomcat的目录webapps下的ROOT下面(删除tomcat webapps目录下ROOT原有内容)

2、解压后,根目录里存在dubbo-admin,进入 mvn install -Dmaven.test.skip=true 安装完后,生成target目录,进入这个目录,找到dubbo-admin-2.6.0.war,把这个war包copy到tomcat的目录webapps下的ROOT下面(删除tomcat webapps目录下ROOT原有内容),然后使用jar xvf dubbo-admin-2.6.0.war解压war包,把解压后的内容全部放到ROOT目录下

在目录/home/admin/apache-tomcat-8.5.24/webapps/ROOT/WEB-INF下的配置dubbo.properties,修改帐号密码,以及注册信息

启动成功之后,打开8083端口 

使用配置的账号和密码登录。

 

 

我们可以看到我们的服务者和消费者的状态,并且可以对服务者配置负载均衡策略

     到了这里我们一个简单强大基于dubbo-zk的架构就搭好了,整合了mybatis,mysql,generator生成插件,下面我们继续整合主流消息队列rabbitMq。

第一步我们打开rabbitMq官网下载rabbitMq安装的文件

http://www.rabbitmq.com/

安装Erlang

由于RabbitMQ依赖Erlang, 所以需要先安装Erlang。

 

Erlang的安装方式大概有两种:

 

从Erlang Solution安装(推荐)

 

 # 添加erlang solutions源

 $ wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm

 $ sudo rpm -Uvh erlang-solutions-1.0-1.noarch.rpm

 

 $ sudo yum install erlang

从EPEL源安装(这种方式安装的Erlang版本可能不是最新的,有时候不能满足RabbitMQ需要的最低版本)

 

 # 启动EPEL源

 $ sudo yum install epel-release 

 # 安装erlang

 $ sudo yum install erlang  

完成后安装RabbitMQ:

 

先下载rpm:

 

wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-3.6.6-1.el7.noarch.rpm

下载完成后安装:

 

yum install rabbitmq-server-3.6.6-1.el7.noarch.rpm 

 

开启web管理接口

如果只从命令行操作RabbitMQ,多少有点不方便。幸好RabbitMQ自带了web管理界面,只需要启动插件便可以使用。

 

$ sudo rabbitmq-plugins enable rabbitmq_management

然后通过浏览器访问

 

http://localhost:15672

 

输入用户名和密码访问web管理界面了。

 

配置RabbitMQ

关于RabbitMQ的配置,可以下载RabbitMQ的配置文件模板到/etc/rabbitmq/rabbitmq.config, 然后按照需求更改即可。

关于每个配置项的具体作用,可以参考官方文档。

更新配置后,别忘了重启服务哦!

 

开启用户远程访问

默认情况下,RabbitMQ的默认的guest用户只允许本机访问, 如果想让guest用户能够远程访问的话,只需要将配置文件中的loopback_users列表置为空即可,如下:

 

{loopback_users, []}

另外关于新添加的用户,直接就可以从远程访问的,如果想让新添加的用户只能本地访问,可以将用户名添加到上面的列表, 如只允许admin用户本机访问。

 

{loopback_users, ["admin"]}

更新配置后,别忘了重启服务哦!

 

 

 

 

可以看到rabbitMQ登录成功了,我们的rabbitMQ安装并且配置好了。

下面我们把rabbitMQ整合到我们刚刚的dubbo架构里。

我们在项目父级springboot-dubbo下建立两个新的module,分别是:

springboot-rabbitmq-recive

springboot-rabbitmq-sender

recive的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">
    <parent>
        <artifactId>springboot-dubbo-parent</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>com.rabbitmq.receive</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- rabbitmq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </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>
        </dependency>
    </dependencies>
</project>

sender的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">
    <parent>
        <artifactId>springboot-dubbo-parent</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>com.springboot.rabbitmq</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- rabbitmq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </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>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>com.rabbitmq.receive</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

 

receive里的一些配置

package com.rabbitmq.recive.config;
import com.rabbitmq.recive.mqcallback.MsgSendConfirmCallBack;
import com.rabbitmq.recive.mqcallback.MsgSendReturnCallback;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: Frank
* @Description: RabbitMq配置
* @Date: Create in  2018/11/29 10:01 PM
* @params:
* @return:
*/
@Configuration
public class RabbitMqConfig {

    /** 消息交换机的名字*/
    public static final String EXCHANGE = "exchangeTest";
    /*对列名称*/
    public static final String QUEUE_NAME1 = "first-queue";
    public static final String QUEUE_NAME2 = "second-queue";
    /*
    *
    * key: queue在该direct-exchange中的key值,当消息发送给direct-exchange中指定key为设置值时,
    *   消息将会转发给queue参数指定的消息队列
    */
    /** 队列key1*/
    public static final String ROUTINGKEY1 = "queue_one_key1";
    /** 队列key2*/
    public static final String ROUTINGKEY2 = "queue_one_key2";
    @Autowired
    private QueueConfig queueConfig;
    @Autowired
    private ExchangeConfig exchangeConfig;
    /**
     * 连接工厂
     */
    @Autowired
    private ConnectionFactory connectionFactory;
    /**
     * 将消息队列1和交换机进行绑定,指定队列key1
     */
    @Bean
    public Binding binding_one() {
        return BindingBuilder.bind(queueConfig.firstQueue()).to(exchangeConfig.directExchange()).with(RabbitMqConfig.ROUTINGKEY1);
    }

    /**
     * 将消息队列2和交换机进行绑定,指定队列key2
     */
    @Bean
    public Binding binding_two() {
        return BindingBuilder.bind(queueConfig.secondQueue()).to(exchangeConfig.directExchange()).with(RabbitMqConfig.ROUTINGKEY2);
    }

    /**
     * queue listener  观察 监听模式
     * 当有消息到达时会通知监听在对应的队列上的监听对象
     * @return
     */
    /*@Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer_one(){
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
        simpleMessageListenerContainer.addQueues(queueConfig.firstQueue());
        simpleMessageListenerContainer.setExposeListenerChannel(true);
        simpleMessageListenerContainer.setMaxConcurrentConsumers(5);
        simpleMessageListenerContainer.setConcurrentConsumers(1);
        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        return simpleMessageListenerContainer;
    }*/
    /**
     * 自定义rabbit template用于数据的接收和发送
     * 可以设置消息确认机制和回调
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        // template.setMessageConverter(); 可以自定义消息转换器  默认使用的JDK的,所以消息对象需要实现Serializable
        /**若使用confirm-callback或return-callback,
         * 必须要配置publisherConfirms或publisherReturns为true
         * 每个rabbitTemplate只能有一个confirm-callback和return-callback
         */
        template.setConfirmCallback(msgSendConfirmCallBack());
        /**
         * 使用return-callback时必须设置mandatory为true,或者在配置中设置mandatory-expression的值为true,
         * 可针对每次请求的消息去确定’mandatory’的boolean值,
         * 只能在提供’return -callback’时使用,与mandatory互斥
         */
        template.setReturnCallback(msgSendReturnCallback());
        template.setMandatory(true);
        return template;
    }

    /*  关于 msgSendConfirmCallBack 和 msgSendReturnCallback 的回调说明:
        1.如果消息没有到exchange,则confirm回调,ack=false
        2.如果消息到达exchange,则confirm回调,ack=true
        3.exchange到queue成功,则不回调return
        4.exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)
    */
    /**
     * 消息确认机制
     * Confirms给客户端一种轻量级的方式,能够跟踪哪些消息被broker处理,
     * 哪些可能因为broker宕掉或者网络失败的情况而重新发布。
     * 确认并且保证消息被送达,提供了两种方式:发布确认和事务。(两者不可同时使用)
     * 在channel为事务时,不可引入确认模式;同样channel为确认模式下,不可使用事务。
     * @return
     */
    @Bean
    public MsgSendConfirmCallBack msgSendConfirmCallBack(){
        return new MsgSendConfirmCallBack();
    }

    @Bean
    public MsgSendReturnCallback msgSendReturnCallback(){
        return new MsgSendReturnCallback();
    }
}


package com.rabbitmq.recive.config;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: Frank
* @Description:消息交换机配置  可以配置多个
* @Date: Create in  2018/11/29 10:01 PM
* @params:
* @return:
*/
@Configuration
public class ExchangeConfig {

    /**
     *   1.定义direct exchange,绑定queueTest
     *   2.durable="true" rabbitmq重启的时候不需要创建新的交换机
     *   3.direct交换器相对来说比较简单,匹配规则为:如果路由键匹配,消息就被投送到相关的队列
     *     fanout交换器中没有路由键的概念,他会把消息发送到所有绑定在此交换器上面的队列中。
     *     topic交换器你采用模糊匹配路由键的原则进行转发消息到队列中
     */
    @Bean
    public DirectExchange directExchange(){
        DirectExchange directExchange = new DirectExchange(RabbitMqConfig.EXCHANGE,true,false);
        return directExchange;
    }
}


package com.rabbitmq.recive.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: Frank
* @Description: 队列配置  可以配置多个队列
* @Date: Create in  2018/11/29 10:01 PM
* @params:
* @return:
*/
@Configuration
public class QueueConfig {

    @Bean
    public Queue firstQueue() {
        /**
         durable="true" 持久化 rabbitmq重启的时候不需要创建新的队列
         auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
         exclusive  表示该消息队列是否只在当前connection生效,默认是false
         */
        return new Queue(RabbitMqConfig.QUEUE_NAME1,true,false,false);
    }

    @Bean
    public Queue secondQueue() {
        return new Queue(RabbitMqConfig.QUEUE_NAME2,true,false,false);
    }
}

yml配置

 

spring:
  rabbitmq:
    host: XX.XX.XX.XX
    port: 5672
    username: admin
    password: admin
    publisher-confirms: true  #  消息发送到交换机确认机制,是否确认回调
    publisher-returns: true
  devtools:
    restart:
      enabled: false
server:
  port: 8081

sender的一些代码

 

package com.rabbitmq.sender.controller;
import com.rabbitmq.sender.service.FirstSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* @Author: Frank
* @Description: 测试发送
* @Date: Create in  2018/11/29 10:02 PM
* @params:
* @return:
*/
@RestController
public class SendController {

    @Autowired
    private FirstSender firstSender;
    @GetMapping("/send")
    public String send(String message){
        String uuid = UUID.randomUUID().toString();
        System.out.println("准备发型mq消息了:message="+message);
        firstSender.send(uuid,message);
        return uuid;
    }
}




package com.rabbitmq.sender.service;
import com.rabbitmq.recive.config.RabbitMqConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @Author: Frank
* @Description: 消息发送  生产者
* @Date: Create in  2018/11/29 10:02 PM
* @params:
* @return:
*/
@Slf4j
@Component
public class FirstSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 发送消息
     * @param uuid
     * @param message  消息
     */
    public void send(String uuid,Object message) {
        CorrelationData correlationId = new CorrelationData(uuid);
        /**
         * RabbitMqConfig.EXCHANGE  指定消息交换机
         * RabbitMqConfig.ROUTINGKEY2  指定队列key2
         */
        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE, RabbitMqConfig.ROUTINGKEY1,
                message, correlationId);
    }
}

我们配置好receive和sender之后启动测试一下,

 

 

 

 

监听者收到了消息推送:

 

        到这里我们dubbo整合springBoot,zookeeper,rabbitMq,mybatis等就结束了,该有的有,不该有的没有,精简但不完美,为什么说不完美,后面我们继续整合主流插件或者技术,比如redis缓存数据库,swagger自动api生产和测试等来完善我们的架构,以备以后工作中使用和参考。

 

相关代码:https://github.com/nanjunyu/springBoot-dubbo.git

 

 

 

原创公众号

     关注java 设计模式,JVM特性,

    并发编程、分布式、微服务,

    linux高可用集群,等相关技术。

         扫一扫关注我吧! 😀😀😀

                      

 

 

 

 

最后修改:2019-04-29 13:52:15 © 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

上一篇

发表评论

说点什么吧~

评论列表

จุ๊บLFrank 2019-07-10 11:24:35
测试
回复
Frank 2019-05-10 15:46:08
aaa
回复