源本科技 | 码上会

SCA Nacos 服务消费者

2026/05/19
1
0

引言

服务消费者

服务消费者泛指微服务架构中,需要调用其他外部服务完成业务逻辑的应用程序。在传统架构中,服务调用通常硬编码对方服务地址,耦合度极高;而在基于注册中心的微服务架构下,服务消费者无需硬编码服务提供者的 IP 与端口,而是动态从注册中心拉取实例信息。该方式彻底解除服务间的强依赖,实现服务之间松耦合设计,便于服务独立迭代、扩容与维护

服务发现机制

服务发现是服务消费者获取服务实例、完成远程调用的核心流程。消费者不会直连服务提供者,而是以 Nacos 作为中间枢纽,完成服务查询、筛选、调用全过程。整个流程自动化执行,搭配负载均衡策略,保障调用平稳、流量均匀分发,具体执行流程如下:

  • 查询服务实例:当服务消费者需要发起远程调用时,主动向 Nacos 注册中心发送查询请求,并明确指定需要调用的目标服务名称;

  • 返回可用实例列表:Nacos 自动过滤宕机、异常的不健康实例,筛选出正常存活的服务实例,整理列表后返回给服务消费者;

  • 发起远程调用:消费者接收实例列表后,依据内置负载均衡策略(随机、轮询、权重配比等)挑选合适实例,最终发起远程网络调用。

创建流程

创建服务模块

  • sca-service 模块下创建一个名为 sca-service-consumer 的子模块pom.xml 如下

注意: 不要忘记将该模块添加进 sca-servicemodules

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.lusifer</groupId>
        <artifactId>sca-service</artifactId>
        <version>${revision}</version>
    </parent>

    <artifactId>sca-service-consumer</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}</name>
    <description>服务消费者</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- 微服务请求用的 HTTP 客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- 熔断限流 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- 负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

编写测试代码

  • 编写启动类 com.lusifer.sca.service.consumer.ConsumerApplication

package com.lusifer.sca.service.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {

  public static void main(String[] args) {
    SpringApplication.run(ConsumerApplication.class, args);
  }
}
  • 编写 OpenFeign 接口 com.lusifer.sca.service.consumer.feign.EchoClient

package com.lusifer.sca.service.consumer.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "service-provider", fallback = EchoClientFallback.class)
public interface EchoClient {

  @GetMapping("/echo/{str}")
  String echo(@PathVariable("str") String str);

  @GetMapping("/divide")
  String divide(@RequestParam("a") Integer a, @RequestParam("b") Integer b);
}
  • 编写熔断器 com.lusifer.sca.service.consumer.feign.EchoClientFallback

package com.lusifer.sca.service.consumer.feign;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

@Component
public class EchoClientFallback implements EchoClient {
  @Override
  public String echo(@PathVariable("str") String str) {
    return "echo fallback";
  }

  @Override
  public String divide(@RequestParam Integer a, @RequestParam Integer b) {
    return "divide fallback";
  }
}
  • 编写控制器 com.lusifer.sca.service.consumer.controller.TestController

package com.lusifer.sca.service.consumer.controller;

import com.lusifer.sca.service.consumer.feign.EchoClient;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

  @Resource private EchoClient echoClient;

  @GetMapping("/echo/{str}")
  public String echo(@PathVariable String str) {
    return echoClient.echo(str);
  }

  @GetMapping("/divide")
  public String divide(@RequestParam Integer a, @RequestParam Integer b) {
    return echoClient.divide(a, b);
  }
}

编写配置文件

  • 编写 application.yml 配置文件

server:
  port: 18080

spring:
  application:
    name: service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.203.200:8848
        fail-fast: true
        username: nacos
        password: 123456
    loadbalancer:
      nacos:
        # 启用负载均衡器
        enabled: true

feign:
  sentinel:
    enabled: true # 开启熔断功能

management:
  endpoints:
    web:
      exposure:
        include: '*'

项目结构图

启动服务消费者

  • 运行 ConsumerApplication,再通过 Nacos 查看服务是否注册成功

测试请求消费者

  • 浏览器输入:http://localhost:18080/echo/hello

  • 看到如下结果表示成功

Hello Nacos Discovery hello