基于Protobuf协议的Dubbo与SpringBoot的结合

文章目录

这里使用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://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>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://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>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://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>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) {
        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<HelloReply> sayHelloAsync(HelloRequest request) {
        return CompletableFuture.completedFuture(sayHello(request));
    }
}

dubbo-provider-web提供服务

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 https://maven.apache.org/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.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-service

dubbo-consumer-service将依赖dubbo-provider-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">
    <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.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);
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值