工程概况父pomdubbo-provider
通过proto3定义服务打包发布服务dubbo-provider-service实现服务dubbo-provider-web提供服务 dubbo-consumer
dubbo-consumer-apidubbo-consumer-servicedubbo-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文件主要用于统一管理一些包的依赖
dubbo-provider 通过proto3定义服务4.0.0 com.demo.dubbo.provider dubbo-provider1.0-SNAPSHOT pom UTF-8 UTF-8 2.7.13 1.40.1 0.0.2 3.7.0 ... org.apache.dubbo dubbo-spring-boot-starter${dubbo.version} org.apache.dubbo dubbo-dependencies-zookeeper${dubbo.version} org.apache.dubbo dubbo-serialization-protobuf${dubbo.version} ... ... ... dubbo-provider-api dubbo-provider-service dubbo-provider-web
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进行打包发布。
dubbo-provider-service实现服务4.0.0 dubbo-provider-api com.demo.dubbo.provider dubbo-provider1.0-SNAPSHOT org.apache.dubbo dubbo-serialization-protobufkr.motd.maven os-maven-plugin1.6.1 org.xolstice.maven.plugins protobuf-maven-plugin0.5.1 com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier} src/main/java false dubbo org.apache.dubbo dubbo-compiler${dubbo.compiler.version} org.apache.dubbo.gen.dubbo.Dubbo3Generator compile test-compile org.codehaus.mojo build-helper-maven-plugingenerate-sources add-source src/main/java org.apache.maven.plugins maven-compiler-plugin${maven-compiler-plugin.version} 1.8 1.8
dubbo-provider-service将实现dubbo-provider-api中的接口。
4.0.0 dubbo-provider-service com.demo.dubbo.provider dubbo-provider1.0-SNAPSHOT com.demo.dubbo.provider dubbo-provider-api
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) {
logger.info("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
HelloReply response = HelloReply.newBuilder()
.setMessage("Hello " + request.getName() + ", response from provider: "
+ RpcContext.getContext().getLocalAddress())
.build();
logger.info("response:{}", response);
return response;
}
@Override
public CompletableFuture sayHelloAsync(HelloRequest request) {
return CompletableFuture.completedFuture(sayHello(request));
}
}
dubbo-provider-web提供服务
pom.xml
4.0.0 dubbo-provider-web com.demo.dubbo.provider dubbo-provider1.0-SNAPSHOT jar dubbo-provider-web dubbo-provider-web project for Spring Boot 2.4.0 1.8 org.springframework.boot spring-boot-starter-web${springboot.version} org.apache.dubbo dubbo-spring-boot-starterorg.apache.dubbo dubbo-dependencies-zookeeper2.7.13 pom com.demo.dubbo.provider dubbo-provider-service1.0-SNAPSHOT dubbo-provider-web src/main/resources true **/application.properties **/logback.xml org.springframework.boot spring-boot-maven-plugin${springboot.version} repackage
application.properties
dubbo.application.name=dubbo-provider-provider dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.protocol.name=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-servicedubbo-consumer-service将依赖dubbo-provider-api,以便直接使用其中服务定义。
4.0.0 dubbo-consumer-service com.demo.dubbo.consumer dubbo-consumer1.0-SNAPSHOT com.demo.dubbo.provider dubbo-provider-api1.0-SNAPSHOT org.apache.dubbo dubbo-common2.7.13 compile
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.protocol.name=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);
}
}



