自学内容网 自学内容网

微服务架构 --- Nacos的项目实战操作

目录

一.什么是Nacos?

二.什么是注册中心?

1.注册中心的定义:

2.为什么需要使用注册中心?

3.注册中心原理:

三.Nacos的使用:

1.安装与启动Nacos:

2.集成 Nacos 服务注册与发现:

(1)导入Nacos依赖:

 (2)配置Nacos注册中心:

(3)使用Nacos发现并调用服务:

3.常见错误以及解决方案:

总结:


资源参考:SpringCloud微服务开发与实战 --- java黑马商城项目微服务实战开发文档

一.什么是Nacos?

Nacos 是阿里巴巴开源的一款服务发现、配置管理和动态 DNS的工具,适用于微服务架构。它是 Spring Cloud Alibaba 生态的重要组件,用于解决微服务之间的服务注册与发现,以及配置的集中管理问题。

  • 特点:服务注册与发现 + 配置管理一体化,支持健康检查和动态配置。
  • 优点:支持多种协议(HTTP、gRPC),UI 管理方便,适用于 Spring Cloud。

二.什么是注册中心?

1.注册中心的定义:

注册中心是微服务架构中的一个核心组件,用于服务注册与发现。在分布式系统中,多个微服务实例需要互相通信,但每个服务的地址可能动态变化,比如因为自动扩展、实例重启、故障恢复等。因此,注册中心充当了服务地址的目录,实现了服务实例的动态管理和发现,保证服务间的高效通信。

2.为什么需要使用注册中心?

 假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署:

 

此时,每个item-service的实例其IP或端口不同,问题来了:

  • item-service这么多实例,cart-service如何知道每一个实例的地址?

  • http请求要写url地址,cart-service服务到底该调用哪个实例呢?

  • 如果在运行过程中,某一个item-service实例宕机,cart-service依然在调用该怎么办?

  • 如果并发太高,item-service临时多部署了N台实例,cart-service如何知道新实例的地址?

带着这四个问题,我们开始学习注册中心: 

在微服务架构中,每个服务可能分布在不同的节点或容器内。由于这些服务的IP地址和端口号可能会变化,传统的静态配置方法无法满足需求。注册中心解决了以下问题:

  1. 动态服务地址管理:当服务实例启动或关闭时,地址会自动更新到注册中心。
  2. 自动负载均衡:注册中心记录了所有可用的服务实例,可以根据策略实现负载均衡。
  3. 故障恢复:如果某个实例不可用,注册中心会标记其状态,避免请求发送到无效实例。
  4. 去中心化:客户端可以动态发现服务,不需要硬编码服务地址。

3.注册中心原理:

按照上面箭头进行流程分析如下:

  • 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

  • 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可多实例部署)

  • 调用者自己对实例列表负载均衡,挑选一个实例

  • 调用者向该实例发起远程调用

当服务提供者的实例宕机或者启动新实例时,调用者如何得知呢?(心跳请求机制)

  • 服务提供者会定期向注册中心发送请求,报告自己的健康状态(心跳请求机制)

  • 当注册中心长时间收不到提供者的心跳时,会认为该实例宕机,将其从服务的实例列表中剔除

  • 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表

  • 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表

三.Nacos的使用:

1.安装与启动Nacos:

我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以我们需要将资料中的SQL文件导入到我们自己的Docker中的MySQL容器中:Nacos的相关资料-CSDN博客

导入后再Linux虚拟机内的/root/nacos目录内导入custom.env文件,文件内容见Nacos的相关资料-CSDN博客

进入root目录后执行下面的Docker命令:

docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

随后启动完成后,访问下面的地址:http://虚拟机IP地址:8848/nacos/,首次访问会跳转到登录页,账号密码都是nacos。

2.集成 Nacos 服务注册与发现:

如果我们想在cart-service模块远程调用item-service的接口,我们进行下面操作:

(1)导入Nacos依赖:

在两模块导入依赖: 

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

任何一个微服务都可以调用别人,也可以被别人调用,即可以是调用者,也可以是提供者。 

 (2)配置Nacos注册中心:

在item-service的application.yml中添加Nacos地址配置:

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 虚拟机IP地址:8848 # nacos地址

在cart-service的application.yml中添加Nacos地址配置:

spring:
  application:
    name: cart-service # 服务名称
  cloud:
    nacos:
      server-addr: 虚拟机IP地址:8848 # nacos地址

(3)使用Nacos发现并调用服务:

可参考下面博客进行理解: 微服务架构 --- OpenFeign的项目实战操作-CSDN博客

在启动类中添加 @EnableDiscoveryClient 注解:

@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
@EnableDiscoveryClient  
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }

    //RestTemplate
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

随后在Service层使用discoveryClient客户端来完成远程服务的拉取: 

@Service
@RequiredArgsConstructor //推荐restTemplate以构造方法导入,这个注解仅构造final修饰的成员属性
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {
    private final RestTemplate restTemplate;

    //用discoveryClient客户端完成服务的拉取
    private final DiscoveryClient discoveryClient;

    private void handleCartItems(List<CartVO> vos) {
        // TODO 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds);

        //  2.1根据服务名称获取服务的实例列表
        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
        if(CollUtils.isEmpty(instances)){
            return ;
        }
        //  2.2手写负载均衡,从实例列表中挑选实例
        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));

        //  2.3利用RestTemplate发起http请求,得到http的响应
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                serviceInstance.getUri() + "/items?{ids}",
                HttpMethod.GET,
                null,
                //写集合泛型的class,因为new的对象可以拿到泛型,随后用反射就可以拿到对象的数据类型返回值
                new ParameterizedTypeReference<List<ItemDTO>>() {},
                Map.of("ids",CollUtils.join(itemIds,","))//集合拼接
        );
        //  2.4解析响应
        if(!response.getStatusCode().is2xxSuccessful()){
            //查询失败,直接结束11
            return ;
        }
        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            return;
        }
        // 剩余操作...
    }
}

3.常见错误以及解决方案:

  • 无法连接到 Nacos 服务器

    • 检查 Nacos 是否启动,并确保端口号 8848 未被占用。
    • 如果是集群模式,检查集群节点的状态。
  • 服务无法注册到 Nacos

    • 检查 application.yml 中的服务名是否正确。
    • 确保网络连接正常,且服务能访问到 Nacos。
  • 配置未刷新

    • 检查是否在 Controller 中添加了 @RefreshScope 注解。
    • 检查是否已触发 /actuator/refresh 端点。

总结:

Nacos 是一款功能强大的工具,集成了服务注册与发现配置管理动态 DNS等功能,非常适合微服务架构。通过与 Spring Boot 的深度集成,开发者可以轻松地使用 Nacos 管理微服务的生命周期和配置,提升系统的灵活性可维护性。所以我们可以通过使用Nacos来轻松的管理微服务模块。


原文地址:https://blog.csdn.net/2302_79840586/article/details/142895910

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!