系列文章导航: Spring Cloud Alibaba微服务解决方案
Nacos是一款注册、发现、配置、管理微服务的组件,由server和client两部分组成。本文仅探讨基于Spring Cloud Alibaba微服解决方案中涉及的基于Nacos的服务注册及发现。
搭建Nacos Server
从选用的Spring Cloud Alibaba版本的配置文件中,获取对应的Nacos版本号。
从Nacos官方github下载对应版本的Nacos,解压缩后启动server。windows使用 cmd startup.cmd,Linux使用sh startup.sh -m standalone启动Nacos Server。
通过浏览器ip:port/nacos访问Nacos Server控制台,默认用户名/密码为nacos/nacos。
代码集成Nacos Client
Nacos基于服务发现的领域模型如下图:
层级由高到低依次为:
命名空间NameSpace,主要用于环境的隔离,例如开发环境、测试环境。
分组Group,主要用于按模块对微服务进行分组。
微服务Service,注册的微服务。
集群Cluster,多个同类型的微服务实例可以建立集群,同一个微服务可以存在多个集群。例如异地多活场景下的容灾备份,访问路由等功能可以基于集群实现。
实例Instance,微服务的运行实例。
领域模型中的各项参数可以在控制台中进行配置,也可以在代码中集成Nacos Client的时候通过配置文件指定(命名空间的创建除外,必须在控制台创建,代码集成时配置命名空间的ID)。
首先需要引入Spring Boot、Spring Cloud、Spring Cloud Alibaba、Nacos的相关依赖。
</dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
配置微服务注册信息
启动项目后,可以在Nacos Server控制台看到注册的微服务。
服务发现和微服务间的通信
微服务注册至Nacos后,可以通过Spring Cloud提供的DiscoveryClient来发现并获取微服务实例,通过微服务实例的元数据解析可以获取服务的URL,进行微服务间的通信。
下面是模拟两个微服务,通过DiscoveryClient获取微服务实例的URL进行请求后,组合数据返回的示例:
/**
* @author xiawei
* @date 2020/7/10 17:51
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ShareServiceImpl implements IShareService {
private final @NonNull RestTemplate restTemplate;
private final @NonNull ShareMapper shareMapper;
private final @NonNull DiscoveryClient discoveryClient;
@Override
public ShareDTO findShareById(Integer id) {
Share share = shareMapper.selectByPrimaryKey(id);
//通过微服务名称,即注册配置中的spring.application.name,获取服务实例的URL
String targetUrl = discoveryClient.getInstances("user-center")
.stream()
.map(instance -> instance.getUri().toString() + "/users/{id}")
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("服务未发现实例"));
log.info("请求的地址为:{}",targetUrl);
UserDTO userDTO = restTemplate.getForObject(targetUrl, UserDTO.class, share.getUserId());
ShareDTO shareDTO = ShareDTO.builder().build();
BeanUtils.copyProperties(share, shareDTO);
shareDTO.setWxNickname(userDTO.getWxNickname());
return shareDTO;
}
}