服务发现
docker run -d --name nacos -e MODE=standalone -p 8848:8848 nacos/nacos-server:1.4.1
本地开发环境地址:http://127.0.0.1:8848/nacos/#/login
用户名和密码默认是nacos
<?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>org.example</groupId>
<artifactId>hello-spring-cloud-dubbo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>dubbo-provider-sample</module>
<module>dubbo-consumer-sample</module>
<module>dubbo-sample-api</module>
</modules>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建服务接口
按照传统的 Dubbo 开发模式,在构建服务提供者之前,第一个步骤是为服务提供者和服务消费者定义 Dubbo 服务接口。
为了确保契约的一致性,推荐的做法是将 Dubbo 服务接口打包在第二方或者第三方的 artifact(jar)中,该 artifact 甚至无需添加任何依赖。
对于服务提供方而言,不仅通过依赖 artifact 的形式引入 Dubbo 服务接口,而且需要将其实现。对应的服务消费端,同样地需要依赖该 artifact,并以接口调用的方式执行远程方法。接下来的步骤则是创建 artifact。
创建 api 工程 - dubbo-sample-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">
<parent>
<artifactId>hello-spring-cloud-dubbo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-sample-api</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
命令执行后,名为“dubbo-sample-api” 的项目目录生成,切换至该目录,内部结构如下:
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── dubbo
│ │ └── api
│ │ └── EchoService.java
│ └── resources
└── test
└── java
定义 Dubbo 服务接口
Dubbo 服务接口是服务提供方与消费方的远程通讯契约,通常由普通的 Java 接口(interface)来声明,如EchoService接口
package com.example.dubbo.api;
public interface EchoService {
String echo(String message);
}
该接口非常简单,仅有一个方法,接下来将 dubbo-sample-api 部署到本地 Maven 仓库。
部署 api 工程 - dubbo-sample-api
利用 Maven 命令, 将 dubbo-sample-api 部署到本地 Maven 仓库:
mvn clean install
服务端开发
前面的准备工作,已经创建了服务端工程,本节主要完成了针对服务接口的实现工作
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── dubbo
│ │ └── provider
│ │ ├── DubboProviderApplication.java
│ │ └── service
│ │ └── EchoServiceImpl.java
│ └── resources
│ └── application.yaml
└── test
└── java
添加 api 依赖 - dubbo-sample-api
打开 dubbo-provider-sample 的 文件;
将 artifact dubbo-sample-api 依赖信息添加到应用 dubbo-provider-sample 中的 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">
<parent>
<artifactId>hello-spring-cloud-dubbo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-provider-sample</artifactId>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Dubbo 服务 artifact -->
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-sample-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
依赖增加之后,下一步实现 Dubbo 服务 -EchoService
实现 Dubbo 服务
在应用 dubbo-provider-sample 中的 com.example.dubbo.provider.service 包下创建实现类
package com.example.dubbo.provider.service;
import com.example.dubbo.api.EchoService;
import org.apache.dubbo.config.annotation.DubboService;
@DubboService
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String s) {
return s;
}
}
其中,@org.apache.dubbo.config.annotation.Service是 Dubbo 服务注解,仅声明该 Java 服务(本地)实现为 Dubbo 服务。 因此,下一步需要将其配置 Dubbo 服务(远程)。
配置 Dubbo 服务提供方
server:
port: 8081
spring:
application:
name: dubbo-provider-sample
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: public
dubbo:
scan:
base-packages: com.example.dubbo.provider.service
protocol:
name: dubbo
port: -1
cloud:
subscribed-services: ""
在暴露 Dubbo 服务方面,推荐开发人员外部化配置的方式,即指定 Java 服务实现类的扫描基准包。
Dubbo Spring Cloud 继承了 Dubbo Spring Boot 的外部化配置特性,也可以通过标注 @DubboComponentScan 来实现基准包扫描。
application.properties 的配置项说明:
- dubbo.scan.base-packages: 指定 Dubbo 服务实现类的扫描基准包
- dubbo.protocol: Dubbo 服务暴露的协议配置,其中子属性name为协议名称,port为协议端口( -1 表示自增端口,从 20880 开始)
- spring.application.name: Spring 应用名称,用于 Spring Cloud 服务注册和发现。
该值在 Dubbo Spring Cloud 加持下被视作dubbo.application.name,因此,无需再显示地配置dubbo.application.name
- spring.cloud.nacos.discovery: Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
完成以上步骤后,还需编写一个 Dubbo Spring Cloud 引导类。
引导 Dubbo Spring Cloud 服务提供方应用
package com.example.dubbo.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
}
}
客户端开发
增加 api 依赖 - dubbo-sample-api
与服务提供方 Maven 工程类似,将 artifact dubbo-sample-api 依赖信息添加到应用 dubbo-consumer-sample 中的 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">
<parent>
<artifactId>hello-spring-cloud-dubbo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-consumer-sample</artifactId>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Dubbo 服务 artifact -->
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-sample-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
目录结构
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── dubbo
│ │ └── consumer
│ │ ├── DubboConsumerApplication.java
│ │ └── controller
│ │ └── EchoController.java
│ └── resources
│ └── application.yaml
└── test
└── java
restful
package com.example.dubbo.consumer.controller;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.example.dubbo.api.EchoService;
@RestController
public class EchoController {
@DubboReference
private EchoService echoService;
// http://127.0.0.1:8080/echo?msg=hello
@GetMapping("/echo")
public String echo(@RequestParam(name = "msg", defaultValue = "hello world") String msg) {
return echoService.echo(msg);
}
}
入口程序
package com.example.dubbo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
}