做爲一個php程序員轉java開發,一直停留在 hello world 的水平上,最近因爲一時發熱想試一下 dubbo 的新版本,可是 github 找了一遍又一遍都沒有看到有demo,而官方給出的例子複製出來是沒辦法單獨運行的,不是這個錯就那個錯,反正搞了一下午也沒有解決。php
因而決定本身試一試,填補一下搜索引擎空白。java
廢話少說,show me the code !git
如今開始用 IDEA 建立一個沒有代碼的 Spring boot maven 工程程序員
選擇 Spring Initializr 初始化項目github
建立 api 模塊,即 interface 定義 web
建立 service 模塊,即 provider 服務提供者spring
建立 web 模塊,即 consumer 服務消費者 apache
建立完這個模塊以後來執行個 mvn clean install 試一下,結果報錯了api
[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
複製代碼
找到 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 裏的啓動類,由於這個模塊主要保存的是接口的定義。
增長 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>
複製代碼
這個模塊主要的功能是接口的實現,業務功能的服務提供者。
先來看看該模塊的 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 方法實現響應:
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 的 consumer 服務,用於消費提供者提供的服務,服務啓動後會與提供者進行鏈接,完成服務調用。
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 兩個服務,而後打開瀏覽器訪問,擼了這麼久,終於出來了。
以上是是我花了兩天才調試通的 dubbo-2.7.1 版本調用服務的demo,若是你也正準備使用 dubbo 嘗試新版原本作服務化開發,但願本文對你有一點點的幫助,很是感謝** 阿里團隊**開源出來這麼優秀的RPC解決方案。