项目使用SpringBoot做微服务,Nacos作为注册和配置中心,服务之间调用使用Dubbo
项目结构
dubbo架构图
微服务代码结构
说明:
- xxx-client 提供 dubbo service 接口,供消费者调用
- xxx-service 提供具体 service 实现
一个服务如果需要调用另一个服务,引用这个服务的client就可以。
添加maven依赖
微服务的pom.xml使用dubbo+nacos时需额外引入以下依赖
<properties>
<dubbo.version>2.7.15</dubbo.version>
<nacos-client.version>2.0.3</nacos-client.version>
<nacos.spring.version>1.1.0</nacos.spring.version>
</properties>
<!-- Dubbo dependency -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Dubbo Nacos configcenter dependency -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-nacos</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Dubbo Nacos registry dependency -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Nacos Spring dependency -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${nacos.spring.version}</version>
</dependency>
因为nacos-spring-boot-starter 不支持springboot2.4+版本,所以我们用nacos-spring-context就行。
配置文件
bootstrap.yml 配置 dubbo application name,建议配置为spring.project.name
dubbo:
application:
name: @project.name@
在每个运行环境的yml单独配置duubo config center 和 nacos config,例如,dev环境
dubbo:
config-center:
address: nacos://${dubbo_server_url}:8848?username=username&password=password
namespace: dubbodev
nacos:
config:
server-addr: ${nacos_server_url}:8848
namespace: dev_namespace
username: dev
password: dev_password
上述dubbo config center的namespace和nacos config的namespace是不同的,方便开发时进行隔离区分。
这里的dubbo使用nacos的用户名密码也最好根据环境区分开来,如dubbodev,dubbotest,dubboprod等。
dubbodev用于下存放dubbo的配置文件,在这个命名空间下新增dubbo.properties,
dataId:dubbo.properties,group:dubbo,内容如下(dev示例)
dubbo.registry.address=nacos:/nacos://${dubbo_server_url}:8848?username=username&password=password
dubbo.registry.check=false
dubbo.registry.simplified=true
dubbo.provider.timeout=30000
dubbo.provider.retries=0
dubbo.provider.loadbalance=leastactive
dubbo.provider.version=DEV
dubbo.consumer.check=false
dubbo.consumer.version=DEV
dubbo.application.qos-enable=false
dubbo.service.shutdown.wait=6000
dev_namespace存放项目中实际需要用到的各种配置文件。
Application类增加注解
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@EnableNacosConfig
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
额外添加两个注解 @EnableDubbo 和 @EnableNacosConfig,用于开启dubbo调用和启用nacos配置。
Dubbo远程调用接口示例
服务提供
client包定义dubbo接口
public interface CountryService {
ServiceResult<List<CountryDTO>> getAllCountry();
}
在service中实现client包的接口,使用@DubboService注解注册服务。
@DubboService
public class CountryServiceImpl implements CountryService {
@Override
public ServiceResult<List<CountryDTO>> getAllCountry() {
return ServiceResult.ok(getAllCountryList());
}
}
服务调用
先添加dubbo服务提供者的client包依赖,然后进行远程调用。
import org.apache.dubbo.config.annotation.DubboReference;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue;
@SpringBootTest
public class CountryTest {
@DubboReference(check = false)
private CountryService countryDubboService;
@Test
public void testGetSelect() {
ServiceResult<List<CountryDTO>> res = countryDubboService.getAllCountry();
assertTrue(res.isSuccess());
assertTrue(res.getData().size() > 0);
}
}
使用@DubboReference注入dubbo client的接口即可调用,check = false 关闭启动时检查接口可用,防止服务依赖问题因为启动顺序不正确导致服务起不来。
Nacos获取配置信息示例
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
public class NacosTest {
@NacosInjected
private ConfigService configService;
@Test
public void testNacos() {
try {
configService.getConfig("data_id", "group", 2000L);
} catch (NacosException e) {
log.info("get nacos config error.", e);
}
}
}
主要使用 @NacosInjected 注入NacosConfigService来获取配置信息。
动态刷新配置,需要使用监听器:
1、添加listener
configService.addListener(DATA_ID, DEFAULT_GROUP, new AbstractListener() {
@Override
public void receiveConfigInfo(String config) {
assertEquals("9527", config); // asserts true
}
});
2、使用注解方式
@NacosConfigListener(dataId = DATA_ID)
public void onMessage(String config) {
assertEquals("mercyblitz", config); // asserts true
}
更多特性,参考nacos spring,地址: https://nacos.io/zh-cn/docs/nacos-spring.html