GitLab CI/CD 搭建与 Pipeline 语法精讲

把 15 步手动操作变成一次 git push 一、⚡ 周五下午 5 点上线——你手动执行了 15 步操作——到第 12 步出错了 回想一下你现在的发布流程: 发布一个微服务的流程: ① git pull latest ② mvn clean package -DskipTests("测试先跳过——着急") ③ 手动改 application-prod.yml 中的配置("这个值上次没改对") ④ docker build -t order-service:v1.2.3 . ⑤ docker tag order-service:v1.2.3 harbor.internal/order-service:v1.2.3 ⑥ docker push harbor.internal/order-service:v1.2.3 ⑦ ssh root@k8s-master ⑧ kubectl set image deployment/order-service order-service=harbor.internal/order-service:v1.2.3 ⑨ kubectl rollout status deployment/order-service ⑩ curl 验证——啊——404——服务没起来 ⑪ kubectl logs——发现是 application.yml 中的 Nacos 地址配错了 ⑫ kubectl rollout undo——回滚 ⑬ 改配置——重新来——docker build + push + deploy ⑭ 又发现 product-service 没同步上线——接口报错了 ⑮ 告警响了——用户已经在群里骂了 → 每次发布都像拆炸弹——不知道哪一步会出问题 CI/CD 要解决的就是:把人从 15 步中解放出来——每次 git push——自动编译、自动测试、自动构建镜像、自动部署——15 步变成 1 步。 ...

十二月 24, 2022 · 9 分钟 · 1883 字 · yaomingye

DDD 重构实战——什么时候该用 DDD?什么时候 MVC 就够了?

DDD vs MVC:如何选择? 📖 前置阅读:本文假设读者已理解 DDD 的核心概念(实体/值对象/聚合根/限界上下文)和战术代码模板(四层架构/Repository/Domain Service)。如果还不熟悉,建议先阅读 DDD 本质 和 DDD 战术落地。 一、⚡ DDD 这么好——是不是所有服务都要重构一遍? 看完前两篇——概念清楚了——代码模板也有了——冲动上来了: "先把所有微服务用 DDD 重构一遍!" ① user-service → DDD ② order-service → DDD ③ product-service → DDD ④ account-service → DDD ⑤ inventory-service → DDD → 加班 2 个月——重构了一堆——代码没更好——反而更复杂了 DDD 不是银弹——不是所有代码都值得用 DDD。这篇的核心就是告诉你:什么该改、什么不改、改到什么程度。 二、🔍 诊断——我们现有的三个服务——各自是什么情况 2.1 user-service——经典 MVC——不改 // user-service——现有结构 controller/ └─ UserController.java @RestController——GET/POST/PUT service/ └─ UserService.java 简单的增删改查 + 缓存操作 mapper/ └─ UserMapper.java MyBatis——selectById/insert/update model/ └─ User.java 15 个字段——getter/setter // UserService 最复杂的方法——也就 20 行 @Service public class UserService { @Autowired private UserMapper userMapper; @Autowired private RedisTemplate<String, User> redisTemplate; public User getUser(Long userId) { String cacheKey = "user:" + userId; User cached = redisTemplate.opsForValue().get(cacheKey); if (cached != null) return cached; User user = userMapper.selectById(userId); if (user != null) redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES); return user; } public void updateUser(User user) { user.setUpdatedAt(LocalDateTime.now()); userMapper.updateById(user); redisTemplate.delete("user:" + user.getId()); // 失效缓存 } } 判断——不需要 DDD: ...

十二月 23, 2022 · 13 分钟 · 2614 字 · yaomingye

DDD 战术落地——代码怎么写

DDD 代码怎么写? 📖 前置阅读:本文假设读者已理解实体、值对象、聚合根、限界上下文、领域事件的核心概念。如果还不熟悉,建议先阅读 DDD 本质——领域驱动设计的核心概念。 一、⚡ 概念都懂了——但代码从哪个 package 开始建? 上一篇搞清楚了实体和值对象的区别、聚合根是"一致性边界"——但回到 IDE 中: 现有项目结构(MVC——三层): controller/ ├─ OrderController.java service/ ├─ OrderService.java (3000 行——上帝类) mapper/ ├─ OrderMapper.java ├─ UserMapper.java ← 跨表调用——OrderMapper 也调 UserMapper ├─ ProductMapper.java ← 跨表调用 model/ ├─ Order.java ← 只有 getter/setter——贫血 ├─ User.java ├─ Product.java 问题——现在要改成 DDD——应该怎么建目录?Repository 放哪?Domain Service 放哪? 这篇就是答案——从目录结构开始——到每一层的代码——完整的落地模板。 二、📂 项目结构——DDD 四层架构 2.1 四层——不是"三层 + 一层" 传统 MVC 三层: Controller → Service → Mapper → Service 层无限膨胀——3000 行——什么都往里塞 DDD 四层: interfaces(接口层) → 接收请求、返回响应——薄薄一层 application(应用层) → 编排业务流程——调 Repository、发事件——没有业务逻辑 domain(领域层) → 业务逻辑——聚合根、值对象、Repository 接口、领域事件 infrastructure(基础设施层)→ 技术实现——Repository 实现、数据库访问、MQ 发送 order-service/ ├── interfaces/ ← ① 接口层 │ ├── rest/ │ │ └── OrderController.java # HTTP 接口——接受请求——转给 application 层 │ ├── dto/ │ │ ├── CreateOrderRequest.java # 入参 DTO │ │ └── OrderResponse.java # 出参 DTO │ └── mq/ │ └── OrderEventListener.java # MQ 消息消费——转到 application 层 │ ├── application/ ← ② 应用层 │ ├── OrderApplicationService.java # 编排——调 Repository + 发事件——不包含业务逻辑 │ ├── command/ │ │ └── CreateOrderCommand.java # 应用层自己的命令对象——DTO 转换后的内部对象 │ └── event/ │ └── OrderEventPublisher.java # 事件发布接口——实现在 infrastructure │ ├── domain/ ← ③ 领域层——核心——不依赖任何外部框架 │ ├── model/ │ │ ├── aggregate/ │ │ │ └── Order.java # 聚合根 │ │ ├── entity/ │ │ │ └── OrderItem.java # 聚合内部实体 │ │ ├── valueobject/ │ │ │ ├── Money.java # 值对象——金额 │ │ │ ├── Address.java # 值对象——地址 │ │ │ └── OrderStatus.java # 枚举——订单状态 │ │ └── event/ │ │ ├── OrderCreatedEvent.java # 领域事件 │ │ └── OrderPaidEvent.java │ ├── repository/ │ │ └── OrderRepository.java # Repository 接口——只有接口——没有实现 │ └── service/ │ ├── OrderDomainService.java # 领域服务——跨聚合的逻辑 │ └── PricingService.java # 领域服务——价格计算策略 │ └── infrastructure/ ← ④ 基础设施层 ├── persistence/ │ ├── OrderRepositoryImpl.java # Repository 实现——调 JPA/MyBatis │ ├── mapper/ │ │ ├── OrderMapper.java # MyBatis Mapper │ │ └── OrderItemMapper.java │ └── converter/ │ └── OrderConverter.java # DO ↔ Domain 对象转换 ├── messaging/ │ └── RocketMQEventPublisher.java # 事件发布实现——发到 RocketMQ └── external/ └── UserServiceAdapter.java # 防腐层——隔离外部 User 服务 依赖方向——只能是单向的: ...

十二月 22, 2022 · 12 分钟 · 2499 字 · yaomingye

DDD 本质——领域驱动设计的核心概念

搞懂 DDD 的核心概念 一、⚡ 一个下单方法 800 行——你知道拆不开是因为什么吗? 先看一段熟悉的代码——我们所有微服务的 Controller/Service 大概都长这样: @Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private UserMapper userMapper; @Autowired private ProductMapper productMapper; @Autowired private InventoryMapper inventoryMapper; public Order createOrder(CreateOrderRequest request) { // ① 查用户——有没有被封号 User user = userMapper.selectById(request.getUserId()); if (user == null || user.getStatus() == UserStatus.BANNED) { throw new BusinessException("用户不存在或已封号"); } // ② 查商品——库存够不够 BigDecimal totalAmount = BigDecimal.ZERO; List<OrderItem> items = new ArrayList<>(); for (CreateOrderItemRequest itemReq : request.getItems()) { Product product = productMapper.selectById(itemReq.getProductId()); if (product == null || product.getStatus() != ProductStatus.ON_SALE) { throw new BusinessException("商品 " + itemReq.getProductId() + " 不可售"); } if (product.getStock() < itemReq.getQuantity()) { throw new BusinessException("商品 " + itemReq.getProductId() + " 库存不足"); } // ③ 扣库存——直接在 Service 里 UPDATE product.setStock(product.getStock() - itemReq.getQuantity()); productMapper.updateById(product); totalAmount = totalAmount.add(product.getPrice() .multiply(BigDecimal.valueOf(itemReq.getQuantity()))); items.add(new OrderItem(itemReq.getProductId(), itemReq.getQuantity(), product.getPrice())); } // ④ 扣余额——直接操作 Account 表 Account account = accountMapper.selectByUserId(request.getUserId()); if (account.getBalance().compareTo(totalAmount) < 0) { throw new BusinessException("余额不足"); } account.setBalance(account.getBalance().subtract(totalAmount)); accountMapper.updateById(account); // ⑤ 创建订单 Order order = new Order(); order.setOrderNo(generateOrderNo()); order.setUserId(request.getUserId()); order.setTotalAmount(totalAmount); order.setStatus(OrderStatus.PENDING_PAY); order.setItems(items); orderMapper.insert(order); // ⑥ 发通知——MQ rocketMQTemplate.syncSend("order-created", order); return order; } } 问题不是代码长——问题是:你想加一个"首单 9 折"的功能——该加在哪? ...

十二月 21, 2022 · 12 分钟 · 2357 字 · yaomingye

SkyWalking 中间件集成与链路分析实战

SkyWalking 中间件集成 📖 前置阅读:本文假设读者已搭建 SkyWalking 并了解 Trace/Span/Segment 概念。如果还不熟悉,建议先阅读 SkyWalking 分布式链路追踪——从零搭建 APM 平台。 一、⚡ 全链路通了——但只有 HTTP 调用——Dubbo 和 gRPC 看不到 上一篇搭好了 SkyWalking——/api/orders 的调用链能看到了——HTTP → Feign → MySQL 都有。 但我们的系统不止 HTTP: 真实调用链路: Browser → Gateway → order-service ├─ Feign → user-service (HTTP) ✅ SkyWalking 自动追踪 ├─ Dubbo → account-service (RPC) ❌ 看不到——Dubbo Span 没出来 ├─ gRPC → inventory-service (RPC) ❌ 看不到——gRPC Span 没出来 ├─ Sentinel → 限流熔断 ❌ 看不到——被限流的请求没有标记 ├─ RocketMQ → payment-service (异步) ❌ 看不到——MQ 跨进程 Trace 断了 └─ @Async → sendEmail (异步) ❌ 看不到——异步线程 Trace 丢了 Agent 不是万能的——不同中间件需要不同配置——有些还需要手动埋点。 ...

十二月 20, 2022 · 15 分钟 · 3027 字 · yaomingye

SkyWalking 分布式链路追踪——从零搭建 APM 平台

SkyWalking 分布式链路追踪 📖 前置阅读:本文假设读者已了解微服务基本概念和 Docker。如果已搭建 Prometheus + Grafana,理解本文会更快——两者互补。建议先阅读 Prometheus + Grafana 环境搭建与指标采集。 一、⚡ QPS 正常——但用户说"下单很慢"——是哪个服务慢了? 前两篇搭好了 Prometheus + Grafana——指标面板很漂亮——QPS、RT、错误率一目了然。 但凌晨 3 点的告警是这样的: PagerDuty:order-service P99 延迟从 50ms 涨到 3s——错误率 2%——还没触发告警阈值(5%) 你打开 Grafana: ✅ order-service:QPS 正常——RT 涨了但不知道原因 ✅ user-service:所有指标正常——没问题 ✅ product-service:所有指标正常——没问题 ✅ inventory-service:所有指标正常——没问题 ✅ payment-service:所有指标正常——没问题 → 你盯着仪表盘——所有服务看起来都"还行"——但订单就是慢了 有了 SkyWalking 链路追踪: ① 找到那条慢了 3s 的 /api/orders 请求的完整调用链路 ② 看到调用链:order-service → user-service(50ms) → product-service(45ms) → inventory-service(2800ms!!!) ← 找到了 ③ 展开 inventory-service 的 Span——MySQL SELECT 语句执行了 2.5s ④ 点开 SQL——SELECT * FROM inventory WHERE product_id = ?——没有索引——全表扫描 → 2 分钟定位——加索引——P99 回到 50ms Prometheus 告诉你"出问题了"——SkyWalking 告诉你"为什么出问题"。两者不是替代关系——是互补关系: ...

十二月 19, 2022 · 11 分钟 · 2142 字 · yaomingye

所有中间件指标接入 Prometheus——统一仪表盘实战

所有中间件指标接入 Prometheus 📖 前置阅读:本文假设读者已掌握 Prometheus + Grafana 的基础搭建和 PromQL 语法。如果还不熟悉,建议先阅读 Prometheus + Grafana 环境搭建与指标采集。 一、⚡ 你有 6 种中间件——但你知道一个请求穿过它们时发生了什么吗? 一个请求穿过整个微服务体系要走多少中间件? 浏览器请求 GET /api/orders/100: ① Gateway 收到请求——鉴权、路由匹配 ② Gateway 转发到 order-service(OpenFeign 或 Dubbo) ③ order-service 调 user-service(OpenFeign) ④ order-service 调 product-service(Dubbo) ⑤ 所有服务都在 Nacos 中发现对方 ⑥ Sentinel 在整个过程中限流/熔断 这 6 步中——任何一步慢了——整个请求就慢了 没有统一监控时——你不知道是 Gateway 慢了、OpenFeign 慢了、还是 Dubbo 慢了 这篇的目标——把每种中间件的指标接入 Prometheus,在一张 Grafana 仪表盘上看到全貌。 二、🏗️ 搭建教程——完整的 Docker Compose + Prometheus 配置 上一篇讲了 Prometheus + Grafana 的基础搭建——但那只是两个容器。这篇要接入 6 种中间件——需要一个完整的 Docker Compose 把 Prometheus、Grafana 和所有微服务编排在一起。 ...

十二月 18, 2022 · 9 分钟 · 1867 字 · yaomingye

Prometheus + Grafana 环境搭建与指标采集

Prometheus + Grafana 环境搭建 一、⚡ 微服务上线了——但你知道它现在是死是活吗? 前面写了 6 种中间件、拆了 5 个微服务、配了限流熔断、布了集群——一切看起来很完美。 凌晨 3 点,电话响了:“用户说下单超时——你看一下”。你打开电脑——但你能看什么? 没有监控时: ① SSH 到服务器——tail -f 看日志——满屏 WARN——不知道哪个先出问题 ② 查数据库——慢查询一大堆——不知道是不是今天的查询就变慢了 ③ 调 JVM 看线程——200 个线程在 BLOCKED——不知道是哪个接口引起的 → 30 分钟过去了——你在猜问题在哪 有了 Prometheus + Grafana: ① 打开 Grafana 看板——QPS 正常——但 RT 从 50ms 涨到 3s ② 看 JVM 仪表盘——线程数飚到 500——GC 频繁 ③ 看中间件面板——Dubbo 线程池满了——Sentinel 开始熔断 → 2 分钟定位——是商品服务的 Dubbo 线程池被打满了 监控不是运维的事——是每个后端开发必须掌握的技能。 二、🧩 Prometheus 是什么——拉模型 + 时序数据库 + PromQL 2.1 Prometheus 的 pull model——和传统监控的区别 大多数监控系统是push model——应用主动把指标推给监控 server。Prometheus 是pull model——它定期去应用那里"拉"指标: ...

十二月 17, 2022 · 5 分钟 · 1061 字 · yaomingye

Nacos 集群与生产部署——中间件整合总览

集群与生产部署——中间件整合总览 📖 前置阅读:本文假设读者已掌握 Nacos 的服务发现和配置中心机制。如果还不熟悉,建议先阅读前三篇:核心概念、服务发现、配置中心。 一、⚡ 单机 Nacos 挂了——整个微服务体系全部变瞎子 单机 Nacos 开发环境跑得挺好——但生产环境下,Nacos 是整个微服务体系的命脉: Nacos 挂了 → 后果: ① 新服务无法注册——滚动更新时新实例注册不上 ② 新调用无法发现——Consumer 拿不到最新实例列表(本地缓存还能撑一会) ③ 配置改不了——Sentinel 规则、Gateway 路由、业务开关全改不了 ④ Dashboard 看不了——不知道哪些服务在线、哪些不在线 虽然本地缓存能兜底——但这是"缓兵之计"不是"长久之计" Nacos 集群是必须的——而且要做高可用 二、🏗️ Nacos 集群架构——三个节点 + MySQL 2.1 为什么需要 MySQL? Nacos 内嵌了一个 Derby 数据库(单机默认)。集群模式下 必须用外部 MySQL——所有节点共享同一个数据源: Nacos 集群架构: ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Nacos 1 │ │ Nacos 2 │ │ Nacos 3 │ ← Nacos 节点(无状态) │ :8848 │ │ :8848 │ │ :8848 │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └───────────────┼───────────────┘ │ ┌──────▼──────┐ │ MySQL │ ← 共享数据库——存注册信息和配置 │ (主从/集群) │ └─────────────┘ Nacos 节点之间用 Raft 协议选举 Leader → Leader 负责写 MySQL → Follower 从 MySQL 读数据并同步到内存 → 任何节点收到客户端请求——都能处理读请求 2.2 配置 MySQL -- 初始化 Nacos 数据库 -- 执行 Nacos 安装包中 conf/mysql-schema.sql -- 创建数据库 CREATE DATABASE IF NOT EXISTS nacos_config DEFAULT CHARACTER SET utf8mb4; -- 配置 Nacos 数据源 # nacos/conf/application.properties # ① MySQL 配置 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://mysql-cluster:3306/nacos_config?useSSL=false&allowPublicKeyRetrieval=true db.user.0=nacos db.password.0=nacos_password_123 # ② 切换为集群模式 nacos.core.auth.enabled=true 2.3 集群节点配置 # nacos/conf/cluster.conf——每个节点一行 IP:Port # 注意:端口是 Raft 通信端口——默认 7848(不是 8848!) 10.0.1.11:7848 10.0.1.12:7848 10.0.1.13:7848 三、🐳 Docker Compose——一键启动 Nacos 集群 version: '3.8' services: # ===== MySQL——Nacos 共享存储 ===== mysql: image: mysql:8.0 container_name: nacos-mysql environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: nacos_config MYSQL_USER: nacos MYSQL_PASSWORD: nacos_password_123 ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql - ./mysql-schema.sql:/docker-entrypoint-initdb.d/01-schema.sql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 5 # ===== Nacos 集群——3 节点 ===== nacos1: image: nacos/nacos-server:v2.3.0 container_name: nacos1 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true - NACOS_AUTH_IDENTITY_KEY=nacos - NACOS_AUTH_IDENTITY_VALUE=nacos - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 ports: - "8848:8848" - "7848:7848" volumes: - nacos1-logs:/home/nacos/logs nacos2: image: nacos/nacos-server:v2.3.0 container_name: nacos2 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true - NACOS_AUTH_IDENTITY_KEY=nacos - NACOS_AUTH_IDENTITY_VALUE=nacos - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 ports: - "8849:8848" - "7849:7848" nacos3: image: nacos/nacos-server:v2.3.0 container_name: nacos3 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true ports: - "8850:8848" - "7850:7848" # ===== Prometheus——采集 Nacos 指标 ===== prometheus: image: prom/prometheus:v2.48.0 ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml volumes: mysql-data: nacos1-logs: prometheus.yml global: scrape_interval: 15s scrape_configs: - job_name: 'nacos' metrics_path: '/nacos/actuator/prometheus' static_configs: - targets: - 'nacos1:8848' - 'nacos2:8848' - 'nacos3:8848' 四、📊 Nacos 监控——Prometheus + Grafana Nacos 内置了 Prometheus 指标暴露——访问 http://nacos:8848/nacos/actuator/prometheus 即可获取。 ...

十二月 16, 2022 · 5 分钟 · 951 字 · yaomingye

Nacos 配置中心全操作

配置中心:从接入到动态刷新 📖 前置阅读:本文假设读者已掌握 Nacos 的基本概念和 @RefreshScope。如果还不熟悉,建议先阅读 Nacos 核心概念与快速上手。 一、⚡ 数据库密码改了——5 个服务 15 个实例要一个个改? 先来看看没有配置中心时的情况: 场景:MySQL 主库切换——数据库地址从 mysql-master-1 变成 mysql-master-2 没有配置中心: ① 改 5 个服务的 application.yml——每个服务改一次 ② 重新打包/重启 15 个实例——顺序不能错(先启 DB 相关的) ③ 改到一半发现有个服务漏了——生产故障 耗时:30 分钟 + 心跳加速 有了 Nacos 配置中心: ① 在 Nacos Dashboard 改一个配置——mysql.host ② 点发布——15 个实例自动收到推送 ③ @RefreshScope 的 Bean 自动重建——新配置生效 耗时:1 分钟 + 淡定 配置中心的价值就是一句话:改一次——推所有——不用重启。 二、🧩 配置的三级组织——shared-configs / extension-configs / 本地 Nacos 配置有三层——从最共享到最专属: shared-configs(共享配置) ← 所有服务通用的配置 ↓ 可以被覆盖 extension-configs(扩展配置) ← 一组服务共享的配置 ↓ 可以被覆盖 ${spring.application.name}-${profile}.${ext}(服务专属配置) ← 每个服务自己的配置 ↓ 兜底 application.yml(本地配置) ← 开发环境兜底——生产通常不放关键配置 2.1 三层配置在 yml 中怎么配 # bootstrap.yml(早于 application.yml 加载——连 Nacos 必须放这里) spring: application: name: order-service profiles: active: dev cloud: nacos: config: server-addr: localhost:8848 namespace: dev group: DEFAULT_GROUP file-extension: yaml # ① shared-configs——所有服务共享的公共配置 shared-configs: - data-id: common-mysql.yaml # 数据库公共配置——所有服务共用一个 DB 集群 group: DEFAULT_GROUP refresh: true # 允许动态刷新 - data-id: common-redis.yaml # Redis 公共配置 group: DEFAULT_GROUP refresh: true - data-id: common-log.yaml # 日志公共配置 group: DEFAULT_GROUP refresh: false # 日志配置不动态刷新——改日志级别才需要 # ② extension-configs——当前服务专属——比 shared 优先级高 extension-configs: - data-id: order-service-custom.yaml group: DEFAULT_GROUP refresh: true 2.2 Nacos Dashboard 中创建公共配置 Nacos Dashboard → 配置管理 → 配置列表 → 新建配置 ① common-mysql.yaml (DEFAULT_GROUP): spring: datasource: url: jdbc:mysql://mysql-master:3306/ username: app_user password: ${MYSQL_PASSWORD} # ← 密码用环境变量——不写在配置中心 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 3000 ② common-redis.yaml (DEFAULT_GROUP): spring: redis: host: redis-cluster.internal port: 6379 lettuce: pool: max-active: 20 max-idle: 10 ③ order-service-dev.yaml (DEFAULT_GROUP): # 订单服务专属配置——覆盖或扩展公共配置 spring: datasource: url: jdbc:mysql://mysql-master:3306/order_db?useSSL=false # 覆盖——订单库 hikari: maximum-pool-size: 50 # 覆盖公共配置——订单服务连接池要大一些 app: order: max-items-per-order: 50 payment-timeout-seconds: 1800 2.3 配置加载的优先级——哪个生效? 当同一个配置在多个地方出现时——后加载的覆盖先加载的: ...

十二月 15, 2022 · 5 分钟 · 953 字 · yaomingye
Cat Radio