159 lines
6.0 KiB
YAML
159 lines
6.0 KiB
YAML
# 所有环境共享的配置。环境差异只放在 application-{profile}.yml 与 K8s ConfigMap 里,
|
||
# 真实密钥一律走环境变量(K8s Secret),仓库和镜像里不出现任何一个真值。
|
||
# 见 07-config-governance.md。
|
||
|
||
spring:
|
||
application:
|
||
name: conti-backend
|
||
|
||
# ---- 数据源(03-persistence.md)----
|
||
datasource:
|
||
# url 里不带库名:每个 domain 有自己的库,由 Flyway/JPA 的 schema 指定。
|
||
# connectionTimeZone=UTC + preserveInstants=true:让驱动按 UTC 读写,Instant 不被本地时区拧一遍。
|
||
# rewriteBatchedStatements=true:不加它 Hibernate 的 batch_size 在 MySQL 上等于没配。
|
||
url: >-
|
||
jdbc:mysql://${DB_HOST}:3306/?sslMode=REQUIRED&connectionTimeZone=UTC&preserveInstants=true&rewriteBatchedStatements=true
|
||
username: ${DB_USERNAME}
|
||
password: ${DB_PASSWORD}
|
||
hikari:
|
||
maximum-pool-size: 15
|
||
minimum-idle: 5
|
||
connection-timeout: 3000 # 拿不到连接就快速失败,不要让请求线程堆在这里
|
||
max-lifetime: 570000 # 略小于 MySQL 的 wait_timeout,避免用到已被服务端关闭的连接
|
||
transaction-isolation: TRANSACTION_READ_COMMITTED
|
||
|
||
jpa:
|
||
open-in-view: false # 必须显式关掉,Boot 默认是 true
|
||
hibernate:
|
||
ddl-auto: validate # 表结构只由 Flyway 改,Hibernate 只做校验
|
||
properties:
|
||
hibernate:
|
||
jdbc:
|
||
time_zone: UTC
|
||
batch_size: 50
|
||
order_inserts: true
|
||
order_updates: true
|
||
query:
|
||
fail_on_pagination_over_collection_fetch: true
|
||
|
||
flyway:
|
||
enabled: false # 关掉 Boot 的单实例自动配置,改由 DomainFlywayConfig 接管
|
||
|
||
# ---- 配置中心(07-config-governance.md)----
|
||
cloud:
|
||
kubernetes:
|
||
config:
|
||
enabled: true
|
||
sources:
|
||
- name: conti-backend-config
|
||
reload:
|
||
enabled: true
|
||
mode: polling # 定期轮询 ConfigMap(event 模式需要 watch 权限)
|
||
strategy: refresh # 只刷新 @RefreshScope bean,不重启容器
|
||
period: 15s
|
||
|
||
# ---- 优雅停机(09-build-deploy.md)----
|
||
lifecycle:
|
||
timeout-per-shutdown-phase: 25s
|
||
|
||
server:
|
||
shutdown: graceful # Boot 默认是 immediate,收到 SIGTERM 直接掐断在途请求
|
||
|
||
# ---- 安全(04-security-auth.md)----
|
||
# 密钥来自 K8s Secret;base64 解码后必须 ≥ 32 字节,否则 JwtProperties 在启动时就报错。
|
||
security:
|
||
jwt:
|
||
active-key-id: ${SECURITY_JWT_ACTIVE_KEY_ID:v1}
|
||
keys:
|
||
v1: ${SECURITY_JWT_SECRET}
|
||
access-token-ttl-minutes: 30
|
||
refresh-token-ttl-days: 30
|
||
|
||
# ---- 外部系统(05-integration-layer.md)----
|
||
integration:
|
||
clients:
|
||
f6:
|
||
base-url: ${F6_BASE_URL}
|
||
connect-timeout-ms: 1000
|
||
read-timeout-ms: 2000
|
||
connection-request-timeout-ms: 500
|
||
max-connections: 60
|
||
max-connections-per-route: 30
|
||
mini:
|
||
base-url: ${MINI_BASE_URL}
|
||
connect-timeout-ms: 500
|
||
read-timeout-ms: 1000
|
||
connection-request-timeout-ms: 300
|
||
max-connections: 60
|
||
max-connections-per-route: 30
|
||
|
||
resilience4j:
|
||
# 叠加顺序由这几个 *-aspect-order 属性决定,跟注解写在方法上的先后顺序无关。
|
||
# 这里显式写死,避免依赖框架默认值——默认值会随版本变,而顺序变了语义就变了。
|
||
retry:
|
||
retry-aspect-order: 3 # 最外层:每次重试都被熔断器单独统计
|
||
instances:
|
||
f6-api:
|
||
max-attempts: 2
|
||
wait-duration: 200ms
|
||
exponential-backoff-multiplier: 2
|
||
retry-exceptions:
|
||
# 同步栈下真实会抛出来的类型:ResourceAccessException 包住了
|
||
# SocketTimeoutException/ConnectException 等所有 IO 异常,写后者是无效配置。
|
||
- org.springframework.web.client.ResourceAccessException
|
||
- com.continental.retailapp.integration.f6.F6ServerException
|
||
ignore-exceptions:
|
||
# 熔断已打开时抛的异常,重试它毫无意义,只会白白多等一轮 wait-duration
|
||
- io.github.resilience4j.circuitbreaker.CallNotPermittedException
|
||
- com.continental.retailapp.integration.f6.F6ClientException
|
||
circuitbreaker:
|
||
circuit-breaker-aspect-order: 2
|
||
instances:
|
||
f6-api:
|
||
sliding-window-type: COUNT_BASED
|
||
sliding-window-size: 20
|
||
minimum-number-of-calls: 10 # 样本太少时不做判断,避免启动后头几个请求就把熔断打开
|
||
failure-rate-threshold: 50
|
||
slow-call-duration-threshold: 1500ms
|
||
slow-call-rate-threshold: 80 # 慢调用也算故障:"每次都卡满 2 秒但最终成功"也必须能熔断
|
||
wait-duration-in-open-state: 10s
|
||
permitted-number-of-calls-in-half-open-state: 5
|
||
record-exceptions:
|
||
- org.springframework.web.client.ResourceAccessException
|
||
- com.continental.retailapp.integration.f6.F6ServerException
|
||
bulkhead:
|
||
bulkhead-aspect-order: 1 # 最内层,贴着真实调用
|
||
instances:
|
||
f6-api:
|
||
max-concurrent-calls: 20
|
||
max-wait-duration: 0 # 拿不到名额立刻失败走降级,排队等于把阻塞换个地方
|
||
mini-o2o:
|
||
max-concurrent-calls: 20
|
||
max-wait-duration: 0
|
||
|
||
# ---- 可观测性(08-observability.md)----
|
||
management:
|
||
tracing:
|
||
enabled: true # 这是 traceId 进 MDC 的前提,关掉连日志里的 traceId 都没有
|
||
export:
|
||
enabled: false # 但不往任何后端上报 span——现在只要日志关联,不建全链路追踪系统
|
||
sampling:
|
||
probability: 1.0 # 不上报就没有采样成本,全采即可
|
||
endpoints:
|
||
web:
|
||
exposure:
|
||
include: health, prometheus, info
|
||
endpoint:
|
||
health:
|
||
probes:
|
||
enabled: true # 暴露 /actuator/health/liveness、/readiness 供 K8s 探针使用
|
||
metrics:
|
||
tags:
|
||
application: conti-backend
|
||
|
||
springdoc:
|
||
api-docs:
|
||
enabled: false # 默认关掉,只在 local/dev/uat 打开(见各 profile)
|
||
swagger-ui:
|
||
enabled: false
|