文章
108 篇笔记 · 64 个分类
2026
-
2026/08/25
项目里的分布式锁支持多种实现,但默认实现是 Redis: zjc: distributed-lock: provider: redis mysql: table-name: t_distributed_lock ...
-
2026/08/25
微服务部署脚本最怕“清单漂移”:Compose 里新增了服务,脚本里却还维护着四个硬编码模块名。这次 Windows 侧 deploy.ps1 的做法是把 docker-compose.yml 当作唯一服务清单。 脚本先解析 Compose 中的镜...
-
2026/08/25
Ubuntu 侧的 manage.sh 不是把 Docker 命令随便包一层,而是把几个容易误用的操作语义拆开了。最关键的是 restart 和 apply。 脚本完整源码较长,正文不贴全文,最新版本直接看 GitHub:manage.sh。 重...
-
2026/08/25
商品购买接口确实要加分布式锁,但 Swagger 文档不应该告诉调用方“我们用的是 Redisson”。这次把描述里的实现名拿掉了: @Operation( summary = "购买商品", description = "按商品维...
-
2026/08/25
部署配置里有一类文件适合进 Git,另一类绝对不适合。这次部署目录把两者拆开:application.yaml.template 是可公开的初始模板,服务器上的 application.yaml 是运行配置,只保存在部署机。 忽略规则很直接: ....
-
2026/08/25
部署脚本如果只负责“把文件传上去并启动”,很容易掩盖一个危险场景:服务器缺少外置 application.yaml,服务带着镜像内置配置启动,看起来成功了,实际连的是错误环境。 这次脚本只上传模板: & scp "deploy\confi...
-
2026/08/25
容器重启不是只有“进程消失”一种结果。如果应用正在处理请求,直接杀掉会把用户请求、邮件发送和链路记录一起切断。这次四个服务统一启用了 Spring Boot 优雅停机。 Provider、Consumer、Gateway 的配置是: server...
-
2026/08/25
日志先要能被找到,然后才谈得上分析。这次把四个服务的 Logback 滚动文件名统一成“应用名 + 级别 + 日期”的格式。 应用名来自 Spring 属性: <springProperty name="application" ...
-
2026/08/25
这次容器化没有走“本机 docker build”的路线,而是用 Jib 的 buildTar 直接生成 OCI 镜像 tar。它的好处很实际:Windows 开发机不需要安装 Docker Desktop,也不需要启动 Docker daemon;...
-
2026/08/25
容器化后最容易混淆的一组概念是 expose 和 ports。这次 Compose 文件把它们用得很清楚:Provider、Consumer、Mail 只在 Docker 网络内声明端口,Gateway 才发布宿主机端口。 四个服务先进入同一个 b...
-
2026/08/24
邮件发送是有副作用的写操作。service-mail 不可用时,Consumer 不能在本地造一条“发送成功”的响应,否则调用方会以为邮件已经发出,问题会延迟到用户收不到邮件时才暴露。 这次提交给 MailFeignApi 显式接入降级工厂: @...
-
2026/08/24
用户 Feign 接口之前的降级策略是:单个查询返回 data=null 的成功响应,列表返回空列表。这个写法对演示很友好,但有一个语义问题: 查询成功但数据不存在 -> success=true, data=null 下游服务不可用 ...
-
2026/08/24
这次提交把 Gateway 的 CORS 配置从 application-dev.yaml 移到独立的 config/application-cors.yaml,再由基础配置引入: spring: profiles: include: ...
-
2026/08/24
商品购买是这套项目里第一个真正需要跨实例互斥的业务。Provider 多实例部署后,同一个商品的扣库存请求可能被 LoadBalancer 分到不同 JVM,本地锁失效,库存就可能超卖。 这次实现的链路是: Consumer -> Good...
-
2026/08/24
商品购买最初直接注入 RedissonClient,能跑通,但业务代码被迫知道锁的获取、中断、续期、解锁异常等细节。这次提交把这些细节下沉到公共模板: public interface DistributedLockTemplate { &...
-
2026/08/24
网关限流不能只写一条兜底规则。全站默认流量和邮件发送这种容易触发外部依赖的接口,承载能力完全不同。这次提交把原来的单接口规则改成两层: interfaces: - name: non-mail-interfaces pattern: /...
-
2026/08/24
这次提交没有新增独立的 service-cache 服务,而是把 Redis 缓存基础设施放在 service-common,把具体缓存放回数据拥有方 service-provider 的 Service 层。 公共配置: spring: c...
-
2026/08/24
Redis 缓存里的 JSON 会携带类型信息。如果反序列化允许任意 @type,一旦 Redis 数据被篡改,应用就可能实例化不该实例化的类型。项目的原则是:Redis 不是可信边界。 基础白名单包含: com.zjc.* 项目内部 DTO S...
-
2026/08/24
引入 Redisson 后,最容易出现的配置漂移是:Spring Cache 连接一套 Redis,Redisson 又维护一套地址、密码和超时。环境一多,两边不同步的风险就会变成线上问题。 这次提交使用 Redisson Core,并在 Prov...
-
2026/08/24
浏览器打开任何 HTML 页面时,都会自动请求一次 /favicon.ico。如果网关没有提供这个文件,请求会走到 ErrorWebExceptionHandler,并产生一条 404 WARN 日志。这个 404 不是接口问题,也不是攻击信号,但每...
-
2026/08/22
这篇笔记记录在一台全新的 Windows 机器上搭建本博客本地运行环境的过程。目标很明确:进入项目目录后,能够用 Bundler 启动 Jekyll,并通过 http://127.0.0.1:4000/ 访问站点。 最终环境如下: ...
-
2026/08/21
service-provider 是这套微服务的业务核心,负责用户、商品、订单和连通性测试接口。它注册到 Nacos,对外提供 /api/v1/provider/** API,既可以直接被 Gateway 转发,也可以被 Consumer 通过 Fe...
-
2026/08/21
service-mail 是独立邮件微服务,负责发送纯文本和 HTML 邮件,并把每次发送过程写入 t_mail_log。其他服务不需要自己配置 SMTP,也不需要知道发件账号;只要调用 MailFeignApi 或通过 Gateway 请求 /ap...
-
2026/08/21
service-gateway 是整套微服务的流量入口,基于 Spring Cloud Gateway 和 WebFlux。它不实现业务接口,也不访问数据库;它的职责是把外部请求路由到 Provider、Consumer、Mail,并在入口处做限流、...
-
2026/08/21
service-consumer 是这套微服务里的调用方示例。它自己没有数据库,也不承载核心业务数据,而是通过 OpenFeign 调用 service-provider,再对外暴露 /api/v1/consumer/** 接口。这个模块把三件事讲清...
-
2026/08/21
service-common 是这套微服务的公共库,不是可独立运行的服务。它的目标很明确:把业务服务反复需要的响应结构、异常处理、接口日志、API 路径约定、共享 DTO、共享 Feign 契约和配置加密能力集中到一个标准 JAR 里,让 Provi...
-
2026/08/21
引入 Nacos 后很容易把“注册中心”和“配置中心”混在一起讨论。这个项目明确当前只使用 Nacos Discovery,不使用 Nacos Config 管业务配置。 一、Nacos 承担什么 服务启动时向 Nacos 注册实例,并通过服务发...
-
2026/08/20
表配置了逻辑删除后,删除并不是真正的 DELETE,而是把标记字段更新为已删除。主表和明细如果分开处理,很容易留下一边可见、一边不可见的数据。 一、服务层统一删除 @Transactional(rollbackFor = Exception.cl...
-
2026/08/20
订单是最典型的主表加明细结构:只保存主表成功、明细失败,会出现一个没有商品的空订单;反过来则会出现孤儿明细。项目把这笔业务动作封装到事务方法里。 一、事务方法 @Transactional(rollbackFor = Exception.clas...
-
2026/08/20
分页接口最常见的滥用是 size=100000。一次请求就能把数据库和内存打出压力。项目对分页参数加了明确边界,并统一了新增、修改、删除的结果反馈。 一、参数边界 @Min(value = 1, message = "当前页码必须从1开始") @...
-
2026/08/20
Sentinel 在这套系统里主要守在 Gateway:按接口做 QPS 限流,按客户端 IP 做参数流控,并为路由配置异常比例和慢请求熔断。 一、规则配置化 zjc: gateway: sentinel: enabled...
-
2026/08/20
业务 WebMVC 服务可以用 @RestControllerAdvice 统一异常,但 Gateway 是 WebFlux 应用,异常处理链完全不同。项目为 Gateway 单独实现 ErrorWebExceptionHandler。 一、为什么...
-
2026/08/19
网关是所有请求的入口,也是观察请求生命周期最好的位置。项目实现了 ServiceGlobalFilter,在每个经过网关的请求前后输出日志。 一、GlobalFilter 的位置 @Component public class ServiceGl...
-
2026/08/19
路径规范如果只靠约定文档,迟早会跑偏。项目把 /api/{版本}/{模块} 做成自动配置,由服务名和配置推导前缀,Controller 只保留资源路径。 一、路径结构 /api/v1/provider/user/1 │ │ │ │ ...
-
2026/08/19
Gateway 开了链路追踪后,可能会遇到一个诡异现象:Zipkin 有 trace,日志里却没有 traceId。原因通常是 Reactor 异步切换线程后,ThreadLocal 里的 MDC 上下文没有跟过去。 一、问题根源 传统日志 MD...
-
2026/08/19
Micrometer Tracing 负责 traceId、spanId 的创建和跨进程传播。它是日志与调用链能串起来的前提,不负责存储和展示调用链。 一、Reactor 场景要开启上下文传播 @PostConstruct public void...
-
2026/08/19
一次请求经过 Gateway、Provider、Consumer 后,如果每个服务只有自己的日志,拼事故时间线会很痛苦。项目为四个可运行服务引入 Micrometer Tracing、Brave 和 Zipkin,用同一个 traceId 串联调用链...
-
2026/08/18
很多 Gateway 示例会在转发前把 /api/provider/user/1 重写成 /user/1。这个项目反而对业务路由不做重写,因为下游服务已经统一接受 /api/{版本}/{模块} 前缀。 一、业务路由 /api/*/provider...
-
2026/08/18
这套 Spring Cloud Alibaba 项目有两种主要运行方式:本地开发默认使用 dev Profile,直接连接共享开发环境;生产运行显式切换到 prod Profile,Nacos、MySQL、Zipkin 都通过本机 127.0.0.1...
-
2026/08/18
Lombok 用来减少 Java 的样板代码。项目里常见的用法是 @Slf4j、@Getter、@Setter。它让代码短一些,但仍然只是编译期工具,不应改变类的职责设计。 一、日志声明 @Slf4j @Component public clas...
-
2026/08/18
多模块 Maven 项目的 CI 除了“构建成功”,还要回答一个很现实的问题:构建产物在哪里。这个项目用 GitHub Actions 构建,并只收集真正可执行的 JAR 作为 Artifact。 一、触发和权限 工作流在 main 的 push...
-
2026/08/17
配置管理的关键不是文件数量,而是每类信息只有一个固定位置。项目最终采用本地 Profile 打包方案:服务包内保留环境配置,启动时按 dev 或 prod 切换。 一、基础配置保持稳定 application.yaml 只保留: 应用名。...
-
2026/08/17
Zipkin 用来接收微服务上报的 trace 数据,并展示 Gateway、Consumer、Provider、Mail 之间的调用链。Windows 和 Ubuntu 直接运行官方 zipkin.jar,macOS 使用 Homebrew 安装,...
-
2026/08/17
快捷键: Win+i 直接打开设置,按下面顺序操作,拒绝 C 盘爆红、广告弹窗、开机卡顿。 一、系统更新、激活、卸载预装垃圾 Windows 更新 → 检查更新,把系统、驱动全部装好,反复重启直到没有更新;不要彻底关闭 Windows 更新...
-
2026/08/17
Sentinel Dashboard 是规则的可视化控制台,可以查看接口 QPS、拒绝数、响应耗时,并动态下发限流规则。你当前项目里的 Sentinel 规则已经在配置文件中声明,Dashboard 接入后要分清“配置里的启动规则”和“控制台临时修改...
-
2026/08/17
Seata 用于解决跨服务操作的一致性问题。后续如果订单、库存、邮件这些动作要拆到多个服务里,并要求“要么都成功,要么整体回滚”,再评估 AT、TCC、Saga 或 XA 模式,不要为了引入分布式事务而强行拆业务。 端口和用途 ...
-
2026/08/16
RocketMQ 更适合后续承接订单事件、延时消息、事务消息和顺序消息。它和 Spring Cloud Alibaba 体系同源,接入时可以优先评估 rocketmq-spring-boot-starter。 端口和用途 ...
-
2026/08/16
Redis 后续可以承担验证码、登录态、接口幂等锁、热点数据缓存这类短生命周期数据。它不适合替代 MySQL 保存业务主数据,接入时要先想清楚 key 的命名、过期时间和淘汰策略。 端口和边界 端口 用途...
-
2026/08/16
RabbitMQ 适合后续做邮件异步发送、低延迟任务分发、失败重试这类业务消息。它强在路由能力和确认机制,不适合当超高吞吐日志管道使用。 端口和用途 端口 用途 ...
-
2026/08/16
Nacos 在这套微服务里只做服务注册与发现,不用它做配置中心。本文部署 standalone 模式,适合本机学习和单机部署;页面访问、端口检查、开机自启都会覆盖到。 先安装 JDK 21。Nacos 启动脚本本质上是启动一个 Java 进程...
-
2026/08/16
MySQL 8 用来保存业务数据和邮件发送记录。这套项目需要数据库 spring_cloud_alibaba,应用通过 spring_cloud_alibaba 用户连接,并且 JDBC URL 使用 sslMode=REQUIRED。本文从零开始安...
-
2026/08/15
MailHog 是本地开发环境的测试邮箱。它会假装成一个 SMTP 服务器,接收 service-mail 发出来的邮件,并在网页里查看内容。这样调试邮件功能时不会把测试邮件发到真实用户邮箱。 端口和用途 端口 ...
-
2026/08/15
MP-Generator 是这个项目里的 MyBatis-Plus 代码生成工具模块。它连接 MySQL,根据表结构生成 Entity、Mapper、Service、ServiceImpl 和 Mapper XML。它不是一个运行时微服务,不注册 N...
-
2026/08/15
Kafka 更适合后续承接高吞吐事件流、行为日志、审计事件和数据管道。它强在吞吐、分区并行和日志保留,如果只是少量业务任务分发,RabbitMQ 或 RocketMQ 可能更合适。 端口和用途 端口 用途...
-
2026/08/15
JDK 21 是这套 Spring Cloud Alibaba 微服务的运行基线。Gateway、Provider、Consumer、Mail 都是 Java 服务,Nacos 和 Zipkin 也建议直接跑在 JDK 21 上。本文按三个系统分别安...
-
2026/08/15
Elasticsearch 后续可以做商品搜索、文章搜索、日志检索和复杂聚合分析。它不是普通数据库的替代品,索引结构、分词、字段类型和刷新策略都会影响效果。 端口和用途 端口 用途 ...
-
2026/08/14
微服务拆分后,接口文档如果分散在三个端口,前端要来回切换。开发环境的 Gateway 使用 SpringDoc 聚合 Swagger UI,一个页面切换 Provider、Consumer 和 Mail。 一、聚合入口 http://localh...
-
2026/08/14
按客户端 IP 限流有一个前提:你要确定这个 IP 是真的。项目的 Sentinel 配置只允许可信代理的 X-Forwarded-For 生效,否则直接使用 TCP 远端地址。 一、伪造风险 X-Forwarded-For 是普通请求头,客户端...
-
2026/08/14
微服务依赖链很长,某个传递依赖出安全问题时,如果每个模块各管各的版本,修复会非常慢。项目把关键版本集中在父 POM,并用 BOM 管理框架族。 一、三层版本管理 Spring Boot Parent Spring Cloud BOM Spring...
-
2026/08/14
公共模块最容易变成垃圾桶:为了几个 DTO,把 Web、数据库、Swagger、Sentinel 全部传递给下游。项目后来重构了 service-common 的依赖边界,让它只做公共库,不替业务服务决定运行时栈。 一、公共模块只声明直接用到的 A...
-
2026/08/14
限流保护的是入口流量,熔断保护的是故障扩散。Gateway 为业务路由统一挂上 CircuitBreaker,下游异常比例或慢请求比例过高时,后续请求会快速失败。 一、两类熔断条件 项目同时配置: 异常比例:异常请求数 / 总请求数 慢请求比例...
-
2026/08/13
OpenFeign 本来已经很声明式,但如果没有共享契约,消费者仍要在自己模块里重抄一份 provider 接口。路径改了、响应类型变了,两个项目不会同时提醒你。这个项目把跨服务 Feign 接口放进 service-common,让调用方直接注入。...
-
2026/08/13
Linux 设置静态 IP,就是让机器重启后地址不变。方便 SSH 远程连接,不用每次查 IP。搭建网站、数据库、集群服务时,其他设备能稳定访问。防火墙规则、端口映射、内网同步任务也不会因 IP 变动失效。缺点是要规划地址,容易出现 IP 冲突。 ...
-
2026/08/13
MapStruct 负责 Entity 和 DTO 之间的转换。它在编译期生成实现类,不走反射,字段映射错误尽量在构建阶段暴露,而不是等到运行时才发现。 一、映射规则写在接口上 @Mapper(componentModel = "spring")...
-
2026/08/13
BeanUtils.copyProperties 写起来最省事,代价藏得很深:字段名悄悄拼错时没有编译错误,类型不一致要运行时才发现,性能 also 依赖反射。项目改用 MapStruct,把 Entity 和 DTO 的转换提前到编译期。 一、转...
-
2026/08/13
远程调用一定会有失败。OpenFeign 支持在失败时走 fallback,但项目选择的是 FallbackFactory,因为它能拿到失败原因。排查线上问题时,这一件事非常关键。 2026-08-24 更新:用户接口的降级策略已从“返回空数...
-
2026/08/12
微服务部署时,很多端口都需要监听,但不都应该对外暴露。这个项目的网络原则很简单:公网只访问 Gateway,业务服务和基础设施全部留在内网。 一、端口角色 service-gateway 80 对外入口 service-provide...
-
2026/08/12
Zipkin 负责接收、查询和展示服务调用链。Micrometer Tracing 生成 trace/span,Zipkin 把这些数据变成可以查看的调用树。 一、导出地址 management: tracing: export: ...
-
2026/08/12
网关限流不能只按路由粗略控制,因为同一条路由里可能有高频只读接口,也有低频写接口。项目使用 Sentinel Gateway 的 API 分组,把规则挂到更细的接口模式上。 一、API 分组用正则匹配 例如: /api/[^/]+/provid...
-
2026/08/12
Jasypt 用来处理配置文件里的敏感值。数据库密码、SMTP 授权码这类信息不以明文提交,而是保存为 ENC(...) 密文,运行时通过外部注入的密钥解密。 一、算法显式固定 jasypt: encryptor: algorithm...
-
2026/08/12
数据库密码、SMTP 授权码这类配置,明文放在仓库里迟早会变成事故。项目使用 Jasypt 把敏感值加密成 ENC(xxx),启动时再通过环境变量或 JVM 参数注入密钥。 一、加密配置 公共配置使用同一组参数: jasypt: encry...
-
2026/08/11
排查接口问题时,最有价值的三条信息通常是:请求带来了什么、返回了什么、耗时多久。项目把这些信息统一放在 WebLogAspect,所有 @RestController 自动被拦截,业务代码不用手写日志。 一、切点只看 RestController ...
-
2026/08/11
接口写多了以后,最怕的不是异常本身,而是异常的形状不一致:有的返回 Tomcat 默认错误页,有的把完整堆栈给前端,有的只在日志里留一句模糊提示。这个项目把 WebMVC 服务的异常处理收敛到 service-common 的 GlobalExcep...
-
2026/08/11
统一前缀不只是 URL 好看,还直接影响接口文档分组。项目的 ApiPathAutoConfiguration 同时做两件事:给 MVC 追加路径前缀,并为每个版本生成 SpringDoc 分组。 一、按版本追加 MVC 前缀 自动配置注册 We...
-
2026/08/11
Hutool 是项目里的通用工具库,目前最典型的使用点是 Web 日志切面中的 JSON 序列化。它减少手写工具方法,但也要控制边界,避免业务代码逐渐依赖一个大杂烩。 一、用于日志对象格式化 import cn.hutool.json.JSONU...
-
2026/08/11
统一错误码最容易被做坏的地方,是把所有枚举都塞进一个公共类。项目里用 ErrorCode 接口切开这个耦合:公共模块只定义标准码段,业务模块自己扩展自己的错误码。 一、错误码抽象 public interface ErrorCode { ...
-
2026/08/10
邮件接口被滥用时,最常见的问题不是发送失败,而是把非法地址、超长内容和无法追踪的请求送进 SMTP。项目在邮件服务里做了两道很实用的防线:先校验收件人,再持久化发送过程。 一、地址格式先拦住 收件人、抄送、密送都支持逗号分隔,解析时会逐个 tri...
-
2026/08/10
邮件看起来是一个小功能,一旦多个业务模块都要发信,它就会变成公共能力。项目把发送邮件独立成 service-mail,统一管理 SMTP 配置、格式处理和发送记录。 一、模块边界 调用方只提交业务字段: 收件人 / 抄送 / 密送 主题 正文 ...
-
2026/08/10
微服务项目的测试最容易变重:一跑测试就要 Nacos、MySQL、网络和一堆环境变量。这个项目的原则是绝大多数测试不启动完整应用,也不依赖外部组件,让 mvn test 可以在本机随手执行。 一、测试栈 项目使用: JUnit 5 Mockit...
-
2026/08/10
写测试不能只靠感觉,JaCoCo 能把测试执行后的字节码覆盖情况生成报告。项目把 JaCoCo 挂在父 POM,所有 Maven 模块统一继承,不需要每个子模块重复配置。 一、两个执行阶段 <execution> <id&g...
-
2026/08/10
共享 Feign 契约里写 /user/{id},下游真实路径却是 /api/v1/provider/user/{id}。如果靠每个调用方手写完整前缀,服务名和模块名一变就要改契约。项目用 Feign RequestInterceptor 在发送前自...
-
2026/08/09
SpringDoc OpenAPI 负责把代码里的接口注解转换成 OpenAPI 文档,再通过 Swagger UI 查看。这个项目的原则是:接口定义变化时,文档跟着代码一起变化。 一、服务级元信息 @Bean public OpenAPI op...
-
2026/08/09
Gateway 是外部请求进入这套微服务系统的唯一入口。浏览器、脚本或第三方调用方只需要知道 Gateway 地址和统一路径规则,不需要知道 Provider、Consumer、Mail 分别部署在哪个端口和哪台机器上。 一、路由按服务名转发 -...
-
2026/08/09
接口参数校验不应该散落在 Service 里写 if。这个项目使用 Jakarta Validation,把规则贴在 DTO 和 Controller 参数上。 一、请求体校验 @PostMapping("/user") public ApiRe...
-
2026/08/09
JaCoCo 用来生成单元测试覆盖率报告。它不能证明系统没有缺陷,但能回答另一个问题:这些测试到底执行了哪些代码。 一、父 POM 统一接入 <plugin> <groupId>org.jacoco</gro...
-
2026/08/09
OpenFeign 的 lb://service-provider 最终要经过 Spring Cloud LoadBalancer。它每次都去拉服务实例列表,会让调用链路多出一层不确定性。引入 Caffeine 后,实例列表可以在本地缓存一小段时间。...
-
2026/08/08
微服务项目拆模块时,最容易走两个极端:一是所有东西都塞进公共模块,二是每个服务重复复制一份代码。这个项目最终采用的边界是:公共模块只放稳定契约和横切能力,不替业务服务决定运行时技术栈。 一、模块划分 service-common 公共契...
-
2026/08/08
MySQL 是这套系统的业务数据后端,保存用户、商品、订单、订单明细和邮件记录。微服务拆分后,数据库仍然承担“事实来源”的角色,接口返回只是数据的某种投影。 一、数据源配置 spring: datasource: driver-cla...
-
2026/08/08
create_time 和 update_time 不应该依赖每个业务方法手动赋值。人工赋值一定会漏,而且不同开发写法可能不同。 一、实体标记填充时机 @TableField(value = "create_time", fill = Field...
-
2026/08/08
单表 CRUD 代码很适合生成器处理。这个项目保留了一个独立的 MP-Generator 模块,用 MyBatis-Plus 的 FastAutoGenerator 根据数据库表生成 Entity、Mapper、Service、ServiceImpl...
-
2026/08/08
这套微服务没有把 Java 版本当成随手可选的参数,而是明确固定在 Java 21。它决定了编译产物、Spring Boot 4 的运行要求、GC 行为、虚拟线程能力,以及测试工具链要支持的字节码版本。 一、版本只写在一处 <propert...
-
2026/08/07
当 lb://service-provider 或 Feign 通过服务名发起调用时,总要有人回答一个问题:这个服务当前有多个实例,这次选哪一个?在这套项目里,答案由 Spring Cloud LoadBalancer 给出。 一、作为调用链的一环...
-
2026/08/07
Spring Boot Mail 提供的是 SMTP 发送抽象。项目把它封装在独立的 service-mail 中,让邮件成为微服务能力,而不是散落在各业务服务里的工具方法。 一、服务封装 @Resource private JavaMailSe...
-
2026/08/07
Actuator 是四个可运行服务共同引入的观测基础。它提供运行端点,也为链路追踪相关自动装配提供入口。 一、统一依赖 <dependency> <groupId>org.springframework.boot&...
-
2026/08/07
OpenFeign 把 HTTP 服务间调用变成接口声明。Consumer 想调用 Provider,不需要手写 HTTP 客户端、拼接 URL、处理响应反序列化,而是注入一个带注解的接口。 一、共享契约 @FeignClient( ...
-
2026/08/07
微服务之间不能把下游服务 IP 写死。服务发现负责找到实例,OpenFeign 负责用接口声明的方式发起 HTTP 调用。 一、启用 Feign 启动类上开启扫描: @EnableFeignClients(basePackages = {"co...
-
2026/08/06
用户、商品这类单表资源很适合抽象成统一 CRUD 形状。这个项目的用户接口是: GET /user/{id} GET /user/list GET /user/page POST /user PUT /user DELE...
-
2026/08/06
MyBatis-Plus 是 Provider 和 Mail 的数据访问组件。它没有替代数据库设计,而是把单表 CRUD、分页、逻辑删除、审计填充这类通用模式标准化,让业务代码集中处理业务规则。 一、分页拦截器 @Bean public Myba...
-
2026/08/06
业务数据通常不允许物理删除。订单、用户、邮件记录一旦删除,审计和问题排查就没有依据。这个项目统一使用逻辑删除。 一、全局配置 mybatis-plus: global-config: db-config: logic-de...
-
2026/08/06
这个项目的数据层采用很朴素的三层: Entity 对应数据库表 Mapper 继承 BaseMapper Service 继承 IService ServiceImpl 继承 ServiceImpl 这不是为了套层次...
-
2026/08/06
很多刚用 MyBatis-Plus 的人会以为传入 Page 就自动分页,其实还差一步:注册分页拦截器。 一、配置拦截器 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() {...
-
2026/08/06
接口直接返回 Entity 很省事,但代价是数据库结构被泄漏成 API 契约。以后加一个内部字段,前端可能收到不该看到的数据;改一个列名,接口也可能跟着变。 一、分离原则 Entity:数据库映射,只在服务模块内部使用 DTO:对外契约,放在 c...
-
2026/08/05
后端接口如果没有统一响应结构,前端就要面对各种形状的数据:有的直接返回对象,有的返回字符串,出错时可能返回默认错误页。这个项目的做法是所有 REST 接口都返回 ApiResponse<T>。 一、响应结构 { "success"...
-
2026/08/05
Spring Cloud 本身不是一个功能点,而是一组微服务协作规范。这个项目用它统一管理 Gateway、OpenFeign、LoadBalancer、CircuitBreaker 等依赖版本,让这些组件在同一套版本语义下工作。 一、BOM 固定...
-
2026/08/05
如果把 Nacos、Gateway、OpenFeign 看成微服务的协作组件,Spring Boot 就是每个服务自己的底座。它负责自动装配、配置体系、Web 服务器、Actuator、测试支持和打包方式。 一、父级版本统一管理 <pare...
-
2026/08/05
Nacos 在这套系统里承担“服务台账”的角色:服务启动时注册自己的地址,调用方通过服务名拿到可用实例。它不参与业务请求转发,真正的转发由 Gateway、OpenFeign 和 LoadBalancer 完成。 一、公共认证配置 spring:...
-
2026/08/05
微服务项目最怕的不是依赖少,而是每个模块各自声明一套版本。时间一长,provider 用一个版本的库,consumer 用另一个版本,本地能跑,部署后行为却不一样。这个项目一开始就把版本治理放进父 POM,子模块只声明“我要用什么”,不关心“它是什么...
2025
-
2025/12/31
这篇博客已经内置 GitHub Pages 自动部署工作流:只要代码推送到 main 分支,Actions 会自动完成 Jekyll 构建、JS/CSS 压缩和站点发布。下面按实际部署顺序走一遍,最后是我踩过或者最容易踩的坑。 一、准备仓库 先把...