架构模式与术语
服务边界、API 网关、配置中心、注册发现。
架构模式与术语
这一课你将能做到
- 看懂一张典型微服务拓扑图,准确说出注册中心、网关、配置中心、熔断器各自的职责
- 用标准术语完整描述「用户提交一道题」从浏览器到判题完成的全链路
- 对任意一个业务交互,判断它该用同步调用还是异步消息,并给出理由
为什么要学
微服务的文档和面试里满屏 Gateway、Registry、Config Server、Circuit Breaker——术语对不齐,就没法和同事对齐需求,也没法答好架构题。更重要的是:拆微服务的第一步不是写代码,而是画架构图、定边界,这一课就是给你画图和说话的词汇表。
结合本站场景:假设把 CodeForge 拆成用户服务(user-service)、题目服务(problem-service)、判题服务(judge-service)。「提交一道题」会横跨三个服务,每种基础组件在哪个环节出场,学完本课你就能对着图讲清楚。
先建立图像
┌────────────────────┐
浏览器 / App ─────────► │ API Gateway:8080 │ 统一入口:路由/鉴权/限流
└─────────┬──────────┘
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
user-service:8081 problem-service:8082 judge-service:8083
│ │ │
▼ ▼ ▼
user_db problem_db judge_db + Redis
【后台基础设施】
Eureka:8761 注册中心 —— 各服务启动上报地址,调用方按名字查
Config Server:8888 —— 配置集中存放,各服务启动拉取
MQ(RabbitMQ/Kafka)—— 异步事件通道,如「判题结果已出」
一次「提交代码」的完整链路:
1. 浏览器 POST /api/submissions ──► Gateway 校验 JWT,路由到 judge-service
2. judge-service 落库「提交记录:PENDING」
3. judge-service 发事件「需要评测 submission#1024」到 MQ,立刻返回「已接收」
4. 评测 Worker 消费事件 → 同步调 problem-service 拿测试用例
5. 编译运行 → 写回结果 → 前端轮询/WebSocket 拿到判题结果
注意第 4 步是同步(必须拿到用例才能跑),第 3 步是异步(用户不必等判完)。
跟着做
步骤 1:先定服务间契约(DTO)
微服务第一原则:接口契约先行。在 judge-service 里定义它需要的数据结构:
package com.example.judge.dto;
/** 判题所需的题目信息——从 problem-service 获取 */
public record ProblemBrief(
Long id,
String title,
int timeLimitMs,
int memoryLimitMb,
int caseCount
) {}
用 Java 17 的 record 做不可变 DTO,Jackson 2.15+ 原生支持,不用手写 getter/setter。
步骤 2:同步调用的直觉代码
第 4 步「拿测试用例」是同步调用。Spring 6 自带 RestClient,先手写一次理解本质(后面课程会换成 Feign):
package com.example.judge.remote;
import com.example.judge.dto.ProblemBrief;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
@Component
public class ProblemClient {
private final RestClient rest = RestClient.builder()
.baseUrl("http://localhost:8082") // 问题:地址写死了!
.build();
public ProblemBrief getProblem(Long id) {
return rest.get()
.uri("/problems/{id}/brief", id)
.retrieve()
.body(ProblemBrief.class);
}
}