Dubbo3.X初探
SpringCloudAlibaba+Nacos+Dubbo3.0+Gradle
版本说明
SpringCloud:Hoxton.SR8
SpringCloudAlibaba:2.2.3.RELEASE
SpringBoot:2.3.4.RELEASE
Nacos:2.0.1
Dubbo:3.1.0
Gradle:7.4
构建Gradle多Module项目
项目结构
添加依赖(父工程的build.gradle)
plugins {
//正式环境建议使用RELEASE版本
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
//全局依赖
allprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
//maven仓库
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'https://repo1.maven.org/maven2/' }
}
//指定SpringCloud版本
ext {
set 'springCloudAlibabaVersion', "2.2.3.RELEASE"
set 'springCloudVersion', "Hoxton.SR8"
}
//依赖管理
dependencyManagement {
imports {
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
//Nacos依赖
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config'
//Web容器
implementation 'org.springframework.boot:spring-boot-starter-web'
//Dubbo依赖
implementation 'org.apache.dubbo:dubbo-spring-boot-starter:3.1.0'
implementation 'org.apache.dubbo:dubbo-registry-nacos:3.1.0'
implementation 'com.alibaba.nacos:nacos-client:2.1.1'
}
}
服务提供者
结构图
添加提供者Module依赖
plugins {
id 'java'
}
group 'com.demo'
//设置打包、否则consumer依赖provider会产生不可预知的错误
jar{
enabled = true
}
添加配置文件bootstrap.yml
这里没有什么好解释的,目前由于SpringCloudAlibaba暂未支持Dubbo3.x,现阶段的方案依旧是双注册中心。与之前传统的方案的区别仅仅是替换了Zookeeper。
server:
port: 8099
nacos:
discovery:
server-addr: 192.168.9.224:50099
namespace: a75768af-458a-45ee-add6-b42d4464c0ee
userName: nacos
password: 74qjJyRA1OTtF90o1PTROi
spring:
application:
name: dubbo-demo-provider
cloud:
nacos:
discovery:
server-addr: ${nacos.discovery.server-addr}
userName: ${nacos.discovery.userName}
password: ${nacos.discovery.password}
config:
server-addr: ${nacos.discovery.server-addr}
file-extension: yaml
auto-refresh: true
group: DEFAULT_GROUP
namespace: ${nacos.discovery.namespace}
userName: ${nacos.discovery.userName}
password: ${nacos.discovery.password}
dubbo:
application:
name: dubbo-demo-provider
protocol:
port: 21000
host:
registry:
id: nacos
address: nacos://192.168.9.224:50099?namespace=a75768af-458a-45ee-add6-b42d4464c0ee
username: nacos
password: 74qjJyRA1OTtF90o1PTROi
group: DUBBO_GROUP
启动类
@EnableDubbo:启用dubbo注解方式,需要在启动类添加。
scanBasePackages:扫描的服务提供者的包路径。
package com.demo.provider;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.demo.provider"})
public class ProviderApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
System.out.println("ProviderApp started...");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ProviderApp.class);
}
}
提供者接口
package com.demo.provider;
/**
* dubbo服务提供者
*/
public interface IDubboProvider {
/**
* 获取服务名称
* @return
*/
String getAppName();
}
提供者实现
@DubboService:使用Dubbo的service注解,这里不能使用Spring的。在Dubbo2.7.x已经升级了此注解。
package com.demo.provider;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;
/**
* dubbo服务提供实现类
*/
@DubboService
public class DubboProvider implements IDubboProvider{
@Value("${spring.application.name}")
private String appName;
@Override
public String getAppName() {
return appName;
}
}
提供者API(Http)
package com.demo.provider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 通过SpringMVC暴露http访问接口
*/
@RestController
@RequestMapping(value = "/api/provider")
public class DubboApi {
@Resource
private IDubboProvider dubboProvider;
@GetMapping("/getAppName")
public String getAppName() {
return dubboProvider.getAppName();
}
}
测试使用Http访问服务
服务消费者
结构图
添加服务消费者依赖
plugins {
id 'java'
}
group 'com.demo'
dependencies {
//引入提供者依赖
implementation project(':provider')
}
添加配置文件bootstrap.yml
dubbo.consumer.check:服务提供者检查,建议关闭,否则在生产环境版本发布版本的时候可能导致其中一个提供者未启动或者异常会导致当前服务无法启动。
server:
port: 8098
nacos:
discovery:
server-addr: 192.168.9.224:50099
namespace: a75768af-458a-45ee-add6-b42d4464c0ee
userName: nacos
password: 74qjJyRA1OTtF90o1PTROi
spring:
application:
name: dubbo-demo-consumer
cloud:
nacos:
discovery:
server-addr: ${nacos.discovery.server-addr}
userName: ${nacos.discovery.userName}
password: ${nacos.discovery.password}
config:
server-addr: ${nacos.discovery.server-addr}
file-extension: yaml
auto-refresh: true
group: DEFAULT_GROUP
namespace: ${nacos.discovery.namespace}
userName: ${nacos.discovery.userName}
password: ${nacos.discovery.password}
dubbo:
application:
name: dubbo-demo-consumer
protocol:
port: 22000
host:
registry:
id: nacos
address: nacos://192.168.9.224:50099?namespace=a75768af-458a-45ee-add6-b42d4464c0ee
username: nacos
password: 74qjJyRA1OTtF90o1PTROi
group: DUBBO_GROUP
consumer:
check: false
消费者启动类
package com.demo.consumer;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.demo.consumer"})
public class ConsumerApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
System.out.println("ConsumerApp started...");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ConsumerApp.class);
}
}
消费者接口
package com.demo.consumer;
/**
* 消费者接口
*/
public interface IConsumerService {
/**
* 获取服务提供者的appName
*/
String getProviderAppName();
}
消费者实现
@DubboReference: 与 @DubboService 类似,使用dubbo提供的注解进行注入。
package com.demo.consumer;
import com.demo.provider.IDubboProvider;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
/**
* 消费者实现类
*/
@Service
public class ConsumerService implements IConsumerService{
@DubboReference
private IDubboProvider dubboProvider;
@Override
public String getProviderAppName() {
return dubboProvider.getAppName();
}
}
消费者Api(Http)
package com.demo.consumer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 通过SpringMVC暴露http访问接口
*/
@RestController
@RequestMapping(value = "/api/consumer")
public class ConsumerApi {
@Resource
private IConsumerService consumerService;
@GetMapping("/getProviderAppName")
public String getProviderAppName() {
return consumerService.getProviderAppName();
}
}
测试使用Http访问消费者
成功使用Dubbo进行数据调用。
Rest特性
暂时没有发现在项目中有比较大的作用,暂时不做研究,正式项目中暂不推荐使用。如SpringCloud架构中,Dubbo作为内部通讯,Http作为外部通讯。