转载

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

作为一个php程序员转java开发,一直停留在 hello world 的水平上,最近由于一时发热想试一下 dubbo 的新版本,但是 github 找了一遍又一遍都没有看到有demo,而官方给出的例子复制出来是没办法单独运行的,不是这个错就那个错,反正搞了一下午也没有解决。

于是决定自己试一试,填补一下搜索引擎空白。

开发环境

  • Spring Boot: 2.1.3.RELEASE
  • Dubbo: 2.7.1-SNAPSHOT
  • 开发工具:Mac IDEA

实战

废话少说,show me the code !

创建项目

现在开始用 IDEA 创建一个没有代码的 Spring boot maven 工程

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

选择 Spring Initializr 初始化项目

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目
一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目
一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

创建模块

创建 api 模块,即 interface 定义

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

创建 service 模块,即 provider 服务提供者

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

创建 web 模块,即 consumer 服务消费者

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

创建完这个模块之后来执行个 mvn clean install 试一下,结果报错了

[INFO] skip non existing resourceDirectory /Users/jeftom/workspace/java/dubbo-sample/dubbo-demo/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ dubbo-demo ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ dubbo-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/jeftom/workspace/java/dubbo-sample/dubbo-demo/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ dubbo-demo ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ dubbo-demo ---
[INFO] No tests to run.
[INFO] 
[INFO] --- maven-jar-plugin:3.1.1:jar (default-jar) @ dubbo-demo ---
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: /Users/jeftom/workspace/java/dubbo-sample/dubbo-demo/target/dubbo-demo-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:repackage (repackage) @ dubbo-demo ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.142 s
[INFO] Finished at: 2019-03-23T22:05:17+08:00
[INFO] Final Memory: 24M/395M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.3.RELEASE:repackage (repackage) on project dubbo-demo: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.1.3.RELEASE:repackage failed: Unable to find main class -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
复制代码
一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

找到 Tests 单元测试用例,加上 @Ignore 注释跳转先,剩下的先不管那么多了。

主模块配置

在根模块的 pom.xml 里增加

<packaging>pom</packaging>

<modules>
    <module>dubbo-demo-api</module>
    <module>dubbo-demo-service</module>
    <module>dubbo-demo-web</module>
</modules>
复制代码

打包插件也需要调整一下,因为根模板没有使用到 spring boot 的 main 启动类,换成 maven 的打包插件才能继续下去。

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</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>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-site-plugin</artifactId>
            <configuration>
                <locales>en,fr</locales>
            </configuration>
        </plugin>
    </plugins>

    <!-- 这里要把 spring boot 自带的 spring-boot-maven-plugin 插件换成 maven-site-plugin,否则 mvn 打包会报错 -->
    <!-- <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins> -->
</build>
复制代码

在其它三个子模块的 pom.xml 增加

<packaging>jar</packaging>
复制代码

修改完成之后,执行 mvn clean install 试一下

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] dubbo-demo-api ..................................... SUCCESS [  5.428 s]
[INFO] dubbo-demo-service ................................. SUCCESS [  1.299 s]
[INFO] dubbo-demo-web ..................................... SUCCESS [  3.195 s]
[INFO] dubbo-demo ......................................... SUCCESS [  0.039 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.258 s
[INFO] Finished at: 2019-03-23T22:21:46+08:00
[INFO] Final Memory: 50M/525M
[INFO] ------------------------------------------------------------------------
复制代码

离成功又近了一步,虽然还没有任何代码,但是起码几个模块已经 build 通过了。

dubbo-demo-api 模块

删除 dubbo-demo-api 里的启动类,因为这个模块主要保存的是接口的定义。

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

增加 DemoApi 接口类

package com.example.dubbo.demo.api;

/**
 * Demo 接口定义
 *
 * @author jeftom
 * @date 2019-03-23 22:35
 * @since 1.0.0
 */
public interface DemoApi {
   String sayHello(String name);
}
复制代码

pom 文件打包插件改为:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>
    </plugins>
</build>
复制代码

dubbo-demo-service 模块

这个模块主要的功能是接口的实现,业务功能的服务提供者。

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

先来看看该模块的 pom.xml 配置:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.dubbo</groupId>
    <artifactId>dubbo-demo-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>dubbo-demo-service</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- dubbo provider 启动不成功的主要问题在这里,没有添加 spring-boot-starter-web 依赖,所以启动日志里一直没有显示 “o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8087 (http)” 这行日志输出 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 这个是定义的接口包,在 provider 和 consumer 都需要引用的 -->
        <dependency>
            <groupId>com.example.dubbo</groupId>
            <artifactId>dubbo-demo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- 新增 dubbo 依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
复制代码

重点要说这里,因为创建模块的时候没有勾选 web 依赖,所以 pom 里只有 spring-boot-starter,并没包含 spring-boot-starter-web 的依赖,启动服务的时候总是完成之后就退出掉,mvn install 也是正常的,百思不得其姐,这里花费了我几个小时的时间。增加完 spring-boot-starter-web 依赖之后,启动日志里就能看到 tomcat 的日志了

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8087 (http)
复制代码

现在我们来创建一个 DemoApiImpl 类,对 sayHello 方法实现响应:

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目
package com.example.dubbo.demo.service.impl;

import com.example.dubbo.demo.api.DemoApi;
import org.apache.dubbo.config.annotation.Service;

/**
 * demo 实现类
 *
 * @author jeftom
 * @date 2019-03-23 23:04
 * @since 1.0.0
 */
@Service
public class DemoApiImpl implements DemoApi {
   /**
    * 实现 sayHello 接口
    *
    * @param name
    * @return
    */
   @Override
   public String sayHello(String name) {
      return "Hello, " + name + " (from Spring Boot with dubbo-2.7.1)";
   }
}
复制代码

DubboDemoServiceApplication 启动类需要增加 dubbo 配置注解:

package com.example.dubbo.demo.service;

import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 增加了 EnableDubboConfig 和 DubboComponentScan 的注解,启动时自动扫描
 *
 */
@EnableDubboConfig
@DubboComponentScan("com.example.dubbo.demo.service.impl")
@SpringBootApplication
public class DubboDemoServiceApplication {

   public static void main(String[] args) {
      SpringApplication.run(DubboDemoServiceApplication.class, args);
   }

}
复制代码

增加 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://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- 定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字 -->
    <dubbo:application name="${dubbo.application.name}" owner="jeftom" organization="jeftom"  />

    <!-- 使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
    <dubbo:registry id="zookeeper-registry" protocol="${dubbo.registry.protocol}" address="${dubbo.registry.address}" />

    <!-- dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="${dubbo.protocol.name}" port="${dubbo.protocol.port}" accesslog="dubbo-access.log"/>
    <dubbo:provider retries="0" timeout="30000"/>
    <dubbo:monitor protocol="registry"/>

    <!-- 使用 dubbo 协议实现定义好的 Service Api 接口-->
    <dubbo:service interface="com.example.dubbo.demo.api.DemoApi" ref="DemoApiImpl" retries="0" timeout="60000" />
</beans>
复制代码

spring 项目的 application.properties 配置文件:

spring.config.name=application

# spring 的环境配置
spring.profiles.active=dev
# 服务启动端口,即内置 tomcat 启动时占用的端口
server.port=8087

#dubbo config
#应用定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识
dubbo.application.name=dubbo-demo-service
#应用所属者
dubbo.application.owner=jeftom
#应用所属组织
dubbo.application.organization=jeftom

# 使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper
# 注册中心id
dubbo.registry.id=zookeeper-registry
# 注册中心协议
dubbo.registry.protocol=zookeeper
# 注册中心地址
dubbo.registry.address=zookeeper.tencus.com:2181

# dubbo协议在20880端口暴露服务
# 协议名称
dubbo.protocol.name=dubbo
# 协议端口
dubbo.protocol.port=20880
# 协议访问log
dubbo.protocol.accesslog=dubbo-access.log
# 重试次数
dubbo.provider.retries=0
# 超时时间
dubbo.provider.timeout=3000
# 注册监控中心
dubbo.monitor.protocol=registry
复制代码

至此,我们的服务提供者已经可以正常启动了,通过 dubbo-admin 可以看到服务已经注册到 zookeeper 里。

dubbo-demo-web 模块

这个模块是 dubbo 的 consumer 服务,用于消费提供者提供的服务,服务启动后会与提供者进行连接,完成服务调用。

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目

pom.xml 配置文件:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.dubbo</groupId>
    <artifactId>dubbo-demo-web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>dubbo-demo-web</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- dubbo provider 启动不成功的主要问题在这里,没有添加 spring-boot-starter-web 依赖,所以启动日志里一直没有显示 “o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8087 (http)” 这行日志输出 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 这个是定义的接口包,在 provider 和 consumer 都需要引用的 -->
        <dependency>
            <groupId>com.example.dubbo</groupId>
            <artifactId>dubbo-demo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- 新增 dubbo 依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
复制代码

spring 应用的 application.properties 配置:

spring.config.name=application

# spring 的环境配置
spring.profiles.active=dev
# 服务启动端口,即内置 tomcat 启动时占用的端口
server.port=8088

# Qos 运维监控
dubbo.application.qosEnable=true
dubbo.application.qosPort=33333
dubbo.application.qosAcceptForeignIp=false

# dubbo config
# 应用定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识
dubbo.application.name=dubbo-demo-service
# 应用所属者
dubbo.application.owner=jeftom
# 应用所属组织
dubbo.application.organization=jeftom

# 使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper
# 注册中心id
dubbo.registry.id=zookeeper-registry
# 注册中心协议
dubbo.registry.protocol=zookeeper
# 注册中心地址
dubbo.registry.address=zookeeper.tencus.com:2181

# dubbo协议在20880端口暴露服务
# 协议名称
dubbo.protocol.name=dubbo
# 协议端口
dubbo.protocol.port=20880
# 协议访问log
dubbo.protocol.accesslog=dubbo-access.log
# 重试次数
dubbo.provider.retries=0
# 超时时间
dubbo.provider.timeout=3000
# 注册监控中心
dubbo.monitor.protocol=registry
复制代码

如果同一台机器上同时启动两个服务,会导致 Qos 端口冲突:

main [server.Server] 102 [ERROR]  [DUBBO] qos-server can not bind localhost:22222
复制代码

DubboDemoWebApplication 消费者的启动类增加以下两行注解:

@EnableDubboConfig
@DubboComponentScan("com.example.dubbo.demo.web.service")
复制代码

分别创建 DemoService 服务类和 DemoController 控制器,

DemoService.java 类

package com.example.dubbo.demo.web.service;

import com.example.dubbo.demo.api.DemoApi;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 消费者服务层
 *
 * @author jeftom
 * @date 2019-03-24 00:49
 * @since 1.0.0
 */
@Service
public class DemoService {
   private static final Logger LOGGER = LoggerFactory.getLogger(DemoService.class);

   @Reference
   private DemoApi demoApi;

   public String sayHello(String name) {
      return demoApi.sayHello(name);
   }
}
复制代码

DemoController.java 控制器类

package com.example.dubbo.demo.web.controller;

import com.example.dubbo.demo.web.service.DemoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * demo 控制器
 *
 * @author jeftom
 * @date 2019-03-24 00:51
 * @since 1.0.0
 */
@RestController
@RequestMapping("/demo")
public class DemoController {
   private static Logger logger = LoggerFactory.getLogger(DemoController.class);

   @Autowired
   private DemoService demoService;

   /**
    * 测试方法,浏览器访问 /demo/index 可以看到响应结果了
    *
    * @return
    */
   @RequestMapping(value = "/index", method = RequestMethod.GET)
   @ResponseBody
   public String index() {
      return demoService.sayHello("dubbo");
   }
}
复制代码

好了,现在可以重新 reimport 和 mvn install 一下看看有没有报错,如果没有报了,启动 service 和 web 两个服务,然后打开浏览器访问,撸了这么久,终于出来了。

一步一步搭建 springboot-2.1.3+dubbo-2.7.1 项目
原文  https://juejin.im/post/5c966b14f265da60e73a074d
正文到此结束
Loading...