文章目录
- 工程概况
- 父pom
- dubbo-provider
- 通过proto3定义服务
- 打包发布服务
- dubbo-provider-service实现服务
- dubbo-provider-web提供服务
- dubbo-consumer
- dubbo-consumer-api
- dubbo-consumer-service
- dubbo-consumer-web提供服务
这里使用Protobuf作为IDL 定义Dubbo服务,并于SpringBoot相结合,搭建最原始的服务提供及消费模型。基于dubbo2.7.13,注册中心使用zookeeper。
工程概况
dubbo-provider$ tree -L 1 .
.
├── dubbo-provider-api
├── dubbo-provider-service
├── dubbo-provider-web
└── pom.xml
dubbo-consumer$ tree -L 1 .
.
├── dubbo-consumer-api
├── dubbo-consumer-service
├── dubbo-consumer-web
└── pom.xml
这里新建了两个SpringBoot项目,dubbo-provider用于提供对外服务,其中 dubbo-provider-api 用于提供api,会将其独立打包发布,用于第三方调用(如dubbo-consumer)。dubbo-consumer会远程调用dubbo-provider提供的服务。
两个项目中分别有3个子项组成,api仅仅用于定义对外提供服务接口(服务内部的接口不在此定义),service依赖api的接口,并给予具体的实现,而web则负责调用实现,对外提供服务。
父pom
先给出工程根目录下pom文件的内容,这个父pom文件主要用于统一管理一些包的依赖
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dubbo.version>2.7.13</dubbo.version>
<grpc.version>1.40.1</grpc.version>
<dubbo.compiler.version>0.0.2</dubbo.compiler.version>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
</properties>
<dependencies>
...
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf</artifactId>
<version>${dubbo.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
...
</profile>
</profiles>
<build>
<plugins>
...
</plugins>
</build>
<distributionManagement>
<repository>
...
</repository>
</distributionManagement>
<modules>
<module>dubbo-provider-api</module>
<module>dubbo-provider-service</module>
<module>dubbo-provider-web</module>
</modules>
</project>
dubbo-provider
通过proto3定义服务
dubbo-provider-api的结构如下,注意这里的service目录下的文件都是根据proto协议自动生成的,请不要修改它。
dubbo-provider/dubbo-provider-api$ ll
总用量 20
drwxrwxr-x 4 mi mi 4096 1月 14 16:34 ./
drwxrwxr-x 13 mi mi 4096 1月 13 09:32 ../
-rw-rw-r-- 1 mi mi 2802 1月 14 16:34 pom.xml
drwxrwxr-x 3 mi mi 4096 1月 11 17:49 src/
drwxrwxr-x 8 mi mi 4096 1月 14 16:35 target/
dubbo-provider/dubbo-provider-api$ tree .
.
├── pom.xml
├── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── demo
│ │ └── dubbo
│ │ └── provider
│ │ └── api
│ │ └── service
│ │ ├── DemoServiceDubbo.java
│ │ ├── DemoService.java
│ │ ├── DemoServiceProto.java
│ │ ├── HelloReply.java
│ │ ├── HelloReplyOrBuilder.java
│ │ ├── HelloRequest.java
│ │ └── HelloRequestOrBuilder.java
│ │
│ └── proto
│ └── DemoService.proto
└── target...
DemoService.proto定义如下:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.demo.dubbo.provider.api.service";
option java_outer_classname = "DemoServiceProto";
option objc_class_prefix = "DEMOSRV";
package demoservice;
// The demo service definition.
service DemoService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
这里通过message关键字定义了请求和响应的内容格式,通过service关键字定义服务的接口。
打包发布服务
借助 protobuf-maven-plugin 编译proto文件,并将生成的文件放到源码目录下,便于之后可以将dubbo-provider-api进行打包发布。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dubbo-provider-api</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf</artifactId>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
<outputDirectory>src/main/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
<protocPlugins>
<protocPlugin>
<id>dubbo</id>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-compiler</artifactId>
<version>${dubbo.compiler.version}</version>
<mainClass>org.apache.dubbo.gen.dubbo.Dubbo3Generator</mainClass>
</protocPlugin>
</protocPlugins>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
dubbo-provider-service实现服务
dubbo-provider-service将实现dubbo-provider-api中的接口。
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dubbo-provider-service</artifactId>
<dependencies>
<dependency>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider-api</artifactId>
</dependency>
</dependencies>
</project>
package com.demo.dubbo.provider.service;
import com.demo.dubbo.provider.api.service.DemoService;
import com.demo.dubbo.provider.api.service.HelloReply;
import com.demo.dubbo.provider.api.service.HelloRequest;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@DubboService
@Component
public class DemoServiceImpl implements DemoService {
private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);
@Override
public HelloReply sayHello(HelloRequest request) {
("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
HelloReply response = HelloReply.newBuilder()
.setMessage("Hello " + request.getName() + ", response from provider: "
+ RpcContext.getContext().getLocalAddress())
.build();
("response:{}", response);
return response;
}
@Override
public CompletableFuture<HelloReply> sayHelloAsync(HelloRequest request) {
return CompletableFuture.completedFuture(sayHello(request));
}
}
dubbo-provider-web提供服务
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:///POM/4.0.0 https:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dubbo-provider-web</artifactId>
<packaging>jar</packaging>
<name>dubbo-provider-web</name>
<description>dubbo-provider-web project for Spring Boot</description>
<properties>
<springboot.version>2.4.0</springboot.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.13</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>dubbo-provider-web</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application.properties</include>
<include>**/logback.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
application.properties
dubbo.application.name=dubbo-provider-provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
=dubbo
dubbo.protocol.serialization=protobuf
注意:dubbo.protocol.serialization=protobuf一定要添加,否则会用dubbo默认的序列化协议(Hessian2),将导致序列化失败,无法将参数写入请求体中。
通过EnableDubbo实现自动装配dubbo的配置
package com.demo.dubbo.provider.web;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.demo.dubbo.provider")
@EnableDubbo(scanBasePackages = "com.demo.dubbo.provider")
public class ProviderBootWebApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderBootWebApplication.class, args);
}
}
dubbo-consumer
dubbo-consumer-api
dubbo-consumer-api这里无需定义,因为我们不打算对外提供服务。
dubbo-consumer-service
dubbo-consumer-service将依赖dubbo-provider-api,以便直接使用其中服务定义。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.demo.dubbo.consumer</groupId>
<artifactId>dubbo-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dubbo-consumer-service</artifactId>
<dependencies>
<dependency>
<groupId>com.demo.dubbo.provider</groupId>
<artifactId>dubbo-provider-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
<version>2.7.13</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
package com.demo.dubbo.consumer.service;
import com.demo.dubbo.provider.api.service.DemoService;
import com.demo.dubbo.provider.api.service.HelloReply;
import com.demo.dubbo.provider.api.service.HelloRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class ConsumerService {
@DubboReference(version = "*", loadbalance = "random")
private DemoService demoService;
public String hello(String name) {
log.info("receiver:{}", name);
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response = demoService.sayHello(request);
log.info("response:{}", response);
return response.getMessage();
}
}
通过DubboReference引用dubbo-provider-api提供的服务。关于DubboReference注解的详细内容,在此不展开详述。在此,version用于版本控制:当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。loadbalance用于负载均衡,常见的算法有random,roundRobin,leastActive,consistentHash。
dubbo-consumer-web提供服务
pom文件参考 dubbo-provider-web.
application.properties
dubbo.application.name=dubbo-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
=dubbo
dubbo.protocol.serialization=protobuf
注意:dubbo.protocol.serialization=protobuf一定要添加,否则会用dubbo默认的序列化协议,将导致序列化失败,无法将请求参数序列化成功。
package com.demo.dubbo.consumer.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.demo.dubbo")
public class ConsumerBootWebApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerBootWebApplication.class, args);
}
}