Spring Boot微服务实战:从拆分到监控的全链路落地技巧

服务拆分:别把单体拆成“碎纸片”

很多新手刚接触微服务,总想着“拆得越细越好”,结果拆完发现调用链比面条还乱——查一个订单问题要翻5个服务的日志,接口响应时间从200ms变成了2秒。其实拆分的核心是“按业务边界切”,不是为了拆而拆。

Spring Boot微服务实战:从拆分到监控的全链路落地技巧

我总结了3个不会踩坑的拆分原则:
单一职责:一个服务只做一件事(比如“用户服务”只处理用户注册、登录,别掺订单逻辑);
避免循环依赖:比如“订单服务”依赖“商品服务”查库存,就别让“商品服务”再依赖“订单服务”查销量;
最小粒度:如果一个功能拆出来后,调用量只有主服务的1%,那不如留在主服务里(比如“用户备注”功能,没必要单独拆成“用户备注服务”)。

举个电商系统的例子,合理拆分后的结构应该是这样:

服务名称 核心职责 依赖服务
用户服务 注册、登录、信息修改
商品服务 商品详情、库存查询
订单服务 下单、查订单、取消订单 用户服务、商品服务
支付服务 支付回调、退款 订单服务

记住:拆分的目的是提升效率,不是“为了微服务而微服务”。如果拆完反而更麻烦,不如先保持单体。

服务通信:用OpenFeign告别手写HTTP

微服务之间要通信,总不能每次都写RestTemplate调接口吧?既要处理超时,还要重试,代码写得像“重复代码生成器”。试试OpenFeign——只需要写个接口,就能像调本地方法一样调其他服务。

第一步:加依赖

Spring Boot 3.x下,引入OpenFeign和Nacos Discovery(服务注册发现)的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

第二步:写Feign客户端

比如订单服务要调用用户服务的“查用户信息”接口,只需要定义一个接口:

// 指向用户服务的服务名(Nacos里注册的名字)
@FeignClient(name = "user-service", path = "/api/user")
public interface UserFeignClient {
    // 对应用户服务的GET /api/user/{id}接口
    @GetMapping("/{id}")
    UserDTO getUserById(@PathVariable("id") Long userId);
}

第三步:直接调用

在订单服务的业务类里,注入UserFeignClient就能用:

@Service
public class OrderService {
    @Autowired
    private UserFeignClient userFeignClient;

    public OrderDTO createOrder(OrderRequest request) {
        // 调用用户服务查信息,像调本地方法一样
        UserDTO user = userFeignClient.getUserById(request.getUserId());
        // 后续业务逻辑...
    }
}

注意:别忘在启动类加@EnableFeignClients注解,否则Feign客户端不会被扫描到!

服务治理:Nacos一站式解决注册与配置

服务多了,两个问题立刻冒出来:怎么找到其他服务?(注册中心)怎么统一管理配置?(配置中心)——Nacos一句话解决:“我全都要”。

1. 服务注册与发现

先启动Nacos(官网下载压缩包,双击startup.cmd就行),然后在Spring Boot项目里配置Nacos地址:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos地址
  application:
    name: order-service # 服务名(Nacos里显示的名字)

启动项目后,打开Nacos控制台(http://localhost:8848/nacos),就能在“服务列表”里看到order-service了。

2. 配置中心:改配置不用重启

以前改数据库密码要改application.yml,还要重启服务——现在把配置放到Nacos里,改完直接生效

比如我们把用户服务的数据库配置放到Nacos:
– 登录Nacos,点击“配置管理”→“配置列表”→“新建配置”;
– 配置集ID填user-service-dev.yaml(格式:服务名-环境.后缀);
– 配置内容写数据库信息:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/user_db
    username: root
    password: new_password_2025 # 新密码

然后在用户服务的application.yml里配置Nacos配置中心:

spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml # 配置文件后缀
  profiles:
    active: dev # 激活dev环境

最后在代码里用@Value获取配置:

@Service
public class UserService {
    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.password}")
    private String dbPassword;
}

以后要改数据库密码,直接在Nacos里改user-service-dev.yaml,不用重启服务——是不是爽翻了?

流量防护:用Sentinel挡住“突发流量”

秒杀活动一来,订单服务直接被冲垮?用户疯狂刷新页面,导致接口返回500?——用Sentinel做限流、降级、熔断,把突发流量挡在外面。

1. 快速接入Sentinel

先启动Sentinel Dashboard(下载地址:https://github.com/alibaba/Sentinel/releases),然后在项目里加依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置Sentinel地址:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel Dashboard地址

2. 给接口加“流量防护盾”

比如对订单服务的/api/order/create接口限流,每秒最多处理100个请求

@RestController
@RequestMapping("/api/order")
public class OrderController {
    // value是资源名,fallback是降级方法
    @PostMapping("/create")
    @SentinelResource(value = "createOrder", fallback = "fallbackCreateOrder")
    public ResponseEntity<String> createOrder(@RequestBody OrderRequest request) {
        // 正常业务逻辑
        return ResponseEntity.ok("订单创建成功");
    }

    // 降级方法:当限流或出错时调用
    public ResponseEntity<String> fallbackCreateOrder(OrderRequest request, Throwable e) {
        return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
                .body("当前请求过多,请稍后重试~");
    }
}

3. 在Sentinel里配置规则

启动项目后,访问几次/api/order/create接口(让Sentinel捕获到资源),然后打开Sentinel Dashboard:
– 点击“簇点链路”→找到createOrder资源;
– 点击“流控”→设置“阈值类型”为QPS,“阈值”为100→保存。

这样当每秒请求超过100次时,Sentinel会直接返回降级信息,不会把订单服务压垮。

链路追踪:用SkyWalking看清“调用链”

用户说“下单慢”,怎么查?是用户服务卡了?还是商品服务查库存慢?——用SkyWalking把调用链“画出来”,一眼就能找到问题。

1. 启动SkyWalking

下载SkyWalking OAP和UI(官网:https://skywalking.apache.org/),解压后:
– 启动OAP:双击bin/startup.bat
– 启动UI:双击bin/webappService.bat(默认端口8080)。

2. 给服务加“追踪探针”

启动Spring Boot服务时,加上SkyWalking的Agent参数:

java -javaagent:D:skywalking-agentskywalking-agent.jar ^
-Dskywalking.agent.service_name=order-service ^ # 服务名
-Dskywalking.collector.backend_service=localhost:11800 ^ # OAP地址
-jar order-service.jar

3. 查看调用链

访问几次下单接口后,打开SkyWalking UI(http://localhost:8080):
– 点击“追踪”→选择“order-service”→就能看到每一次请求的调用链;
– 比如某条请求的耗时分布:order-service用了500ms,其中user-servicegetUserById用了300ms——问题出在用户服务!

再点进去看getUserById的详细信息,发现是SQL查询慢(比如没加索引),直接优化SQL就行。

监控告警:用Prometheus+Grafana看住服务状态

微服务跑起来后,得知道“服务有没有挂?”“QPS多少?”“内存用了多少?”——用Prometheus采集数据,Grafana可视化,完美组合。

1. 让Spring Boot暴露监控端点

在项目里加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

配置暴露Prometheus端点:

management:
  endpoints:
    web:
      exposure:
        include: prometheus # 暴露/prometheus端点
  metrics:
    tags:
      application: ${spring.application.name} # 给 metrics 加服务名标签

启动项目后,访问http://localhost:8080/actuator/prometheus,就能看到监控数据(比如jvm_memory_used_bytes是JVM已用内存)。

2. 用Prometheus采集数据

下载Prometheus(官网:https://prometheus.io/),修改prometheus.yml配置:

scrape_configs:
  - job_name: 'spring-boot-apps' # 任务名
    metrics_path: '/actuator/prometheus' # 监控端点路径
    static_configs:
      - targets: ['localhost:8080', 'localhost:8081'] # 多个服务地址(订单服务、用户服务)

启动Prometheus后,访问http://localhost:9090,就能看到采集到的 metrics。

3. 用Grafana做可视化

下载Grafana(官网:https://grafana.com/),启动后访问http://localhost:3000(默认账号admin/admin):
– 点击“Add your first data source”→选择Prometheus→配置Prometheus地址(http://localhost:9090)→保存;
– 点击“Dashboards”→“Import”→输入Spring Boot的Dashboard ID(比如12856,这是官方维护的Spring Boot监控面板)→选择Prometheus数据源→导入。

导入后,你会看到一个漂亮的监控面板:包含各服务的QPS、错误率、JVM内存、GC次数——所有状态一目了然。

最后提醒一句:微服务不是银弹,它解决了单体的“扩容难”“协作慢”问题,但也带来了“调用链复杂”“治理成本高”的新问题。先想清楚需求,再选择架构——如果你的项目只有10个接口,用户量不到1万,保持单体反而更高效。

原创文章,作者:,如若转载,请注明出处:https://zube.cn/archives/393

(0)

相关推荐