# java-distributed_system **Repository Path**: hlw422/java-distributed_system ## Basic Information - **Project Name**: java-distributed_system - **Description**: 基于 Spring Cloud Alibaba 微服务架构的患者就医分布式系统,涵盖患者注册、登录、挂号、缴费、日志查询、消息通知等核心业务功能。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-17 - **Last Updated**: 2026-07-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 患者就医分布式系统 基于 **Spring Cloud Alibaba** 微服务架构的患者就医分布式系统,涵盖患者注册、登录、挂号、缴费、日志查询、消息通知等核心业务功能。 > **技术栈**: Spring Boot 3.1 + Dubbo 3.2 + Nacos 2.2 + Sentinel 1.8 + Seata 1.7 + SkyWalking 9.7 + PostgreSQL 15 + Elasticsearch 8 + MyBatis-Plus 3.5 + Spring Cloud Gateway --- ## 目录 - [项目架构](#项目架构) - [技术选型](#技术选型) - [模块说明](#模块说明) - [数据库设计](#数据库设计) - [快速开始](#快速开始) - [API 文档](#api-文档) - [基础设施](#基础设施) - [高可用与容错](#高可用与容错) - [开发指南](#开发指南) - [部署说明](#部署说明) --- ## 项目架构 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 客户端 (Browser / App) │ └────────────────────────────┬─────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ API Gateway (:8080) │ │ Spring Cloud Gateway + JWT 鉴权 │ │ Sentinel 网关限流 (QPS 200/s) │ └────────┬──────────┬──────────┬──────────┬──────────┬────────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ User │ │ Regis- │ │ Payment │ │ Notifi- │ │ Log │ │ Service │ │ tration │ │ Service │ │ cation │ │ Service │ │ (:8081) │ │ (:8082) │ │ (:8083) │ │ (:8084) │ │ (:8085) │ │ │ │ │ │ │ │ │ │ │ │ Dubbo │ │ Dubbo │ │ Dubbo │ │ Dubbo │ │ Dubbo │ │ 20881 │ │ 20882 │ │ 20883 │ │ 20884 │ │ 20885 │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ ┌───────┴────────────┴────────────┴──────────────┘ │ │ ▼ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 中间件集群 │ │ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌──────────────────┐ │ │ │PostgreSQL│ │ Nacos │ │ Sentinel │ │ Seata Server │ │ │ │ 15 │ │ Cluster │ │Dashboard │ │ (AT Mode) │ │ │ │ :5432 │ │ ×3 节点 │ │ :8858 │ │ :8091 │ │ │ └──────────┘ └───────────┘ └──────────┘ └──────────────────┘ │ │ ┌──────────┐ ┌──────────────────────────────────────────────┐ │ │ │Elastic- │ │ SkyWalking 9.7 │ │ │ │search 8 │ │ OAP (:11800) + UI (:8086) │ │ │ │ :9200 │ │ 全链路追踪 & 性能监控 │ │ │ └──────────┘ └──────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ ``` ### 服务调用关系 - **网关层**: 所有外部请求统一入口,JWT 鉴权 + Sentinel 限流 - **RPC 层**: 服务间通过 Dubbo 协议通信,Nacos 注册发现 - **事务层**: 挂号→通知、支付→通知 使用 Seata AT 模式保证分布式事务一致性 - **追踪层**: SkyWalking Java Agent 无侵入式全链路追踪 - **容错层**: Sentinel 对 Dubbo RPC 和 Gateway 进行熔断降级与限流 --- ## 技术选型 | 类别 | 技术 | 版本 | 说明 | |------|------|------|------| | **JDK** | Java | 17 | LTS 长期支持版本 | | **框架** | Spring Boot | 3.1.5 | 微服务基础框架 | | **微服务** | Spring Cloud | 2022.0.4 | 服务治理体系 | | **微服务** | Spring Cloud Alibaba | 2022.0.0.0 | 阿里云微服务组件 | | **RPC** | Apache Dubbo | 3.2.8 | 高性能 RPC 通信 | | **注册/配置中心** | Nacos | 2.2.3 | 服务注册发现 + 配置管理(集群模式) | | **网关** | Spring Cloud Gateway | 4.x | 统一 API 网关 | | **熔断降级** | Sentinel | 1.8.6 | 流量控制 + 熔断降级 | | **分布式事务** | Seata | 1.7.1 | AT 模式分布式事务 | | **链路追踪** | Apache SkyWalking | 9.7.0 | 全链路追踪 + 性能监控 | | **ORM** | MyBatis-Plus | 3.5.4 | 增强型 ORM 框架 | | **数据库** | PostgreSQL | 15 | 关系型数据库 | | **搜索引擎** | Elasticsearch | 8.11.0 | 日志存储与全文检索 | | **认证** | JWT (jjwt) | 0.12.3 | 无状态身份认证 | | **工具库** | Hutool | 5.8.23 | Java 工具集 | | **API 文档** | SpringDoc OpenAPI | 2.2.0 | Swagger 3 / OpenAPI 3 | | **ID 生成** | Snowflake | 自研 | 分布式唯一 ID | | **构建工具** | Maven | 3.9+ | 项目构建与依赖管理 | --- ## 模块说明 ``` distributed_system/ ├── pom.xml # Maven 父 POM,统一依赖版本管理 ├── docker-compose.yml # Docker Compose 基础设施编排 ├── init-sql/ # 数据库初始化脚本 │ ├── 01-create-databases.sql # 创建 4 个独立数据库 │ ├── 02-init-user.sql # 用户服务表结构 │ ├── 03-init-registration.sql # 挂号服务表结构 + 初始数据 │ ├── 04-init-payment.sql # 缴费服务表结构 │ └── 05-init-notification.sql # 通知服务表结构 ├── patient-common/ # 🔧 公共模块(被所有服务依赖) │ ├── dto/ # 通用 DTO(ApiResponse, PageResult 等) │ ├── enums/ # 枚举类(性别、挂号状态、支付状态等) │ ├── exception/ # 业务异常 + 全局异常处理 │ ├── dubbo/ # Dubbo 服务接口定义 │ └── utils/ # 工具类(Snowflake ID 生成器) ├── patient-gateway/ # 🚪 API 网关 (:8080) │ ├── config/JwtAuthFilter.java # JWT 全局鉴权过滤器 │ ├── config/CorsConfig.java # 跨域配置 │ └── application.yml # 路由配置 + Sentinel 网关限流 ├── patient-user-service/ # 👤 用户服务 (:8081) │ ├── controller/AuthController.java # 注册、登录接口 │ ├── controller/PatientController.java # 患者信息管理 │ ├── service/impl/PatientServiceImpl.java # 用户业务逻辑 │ ├── service/impl/UserServiceDubboImpl.java # Dubbo RPC 暴露 │ └── config/JwtConfig.java # JWT 生成与校验 ├── patient-registration-service/ # 📋 挂号服务 (:8082) │ ├── controller/DepartmentController.java # 科室查询接口 │ ├── controller/RegistrationController.java # 挂号、取消挂号接口 │ └── service/impl/RegistrationServiceImpl.java # 挂号业务(含 @GlobalTransactional) ├── patient-payment-service/ # 💰 缴费服务 (:8083) │ ├── controller/PaymentController.java # 账单查询、缴费接口 │ └── service/impl/PaymentServiceImpl.java # 缴费业务(含 @GlobalTransactional) ├── patient-notification-service/ # 🔔 通知服务 (:8084) │ ├── controller/NotificationController.java # 通知查询接口 │ └── service/impl/NotificationDubboServiceImpl.java # 通知发送(Dubbo RPC) └── patient-log-service/ # 📝 日志服务 (:8085) ├── controller/LogController.java # 日志查询接口(多条件 + 全文检索) ├── repository/OperationLogRepository.java # ES Repository └── service/impl/LogServiceDubboImpl.java # 异步日志写入 ES ``` ### 各模块职责 | 模块 | 端口 | Dubbo 端口 | 数据库 | 职责 | |------|------|-----------|--------|------| | **patient-gateway** | 8080 | - | - | 统一入口、JWT 鉴权、路由转发、Sentinel 限流 | | **patient-user-service** | 8081 | 20881 | db_patient_user | 患者注册、登录、信息管理、JWT 签发 | | **patient-registration-service** | 8082 | 20882 | db_patient_registration | 科室查询、号源管理、挂号/取消挂号(分布式事务) | | **patient-payment-service** | 8083 | 20883 | db_patient_payment | 账单生成、缴费、退费(分布式事务) | | **patient-notification-service** | 8084 | 20884 | db_patient_notification | 消息通知发送与查询 | | **patient-log-service** | 8085 | 20885 | Elasticsearch | 操作日志异步写入、多条件全文检索 | | **patient-common** | - | - | - | 公共 DTO、枚举、异常、Dubbo 接口、工具类 | --- ## 数据库设计 系统采用 **Database-per-Service** 模式,每个微服务拥有独立数据库: | 数据库 | 所属服务 | 核心表 | |--------|----------|--------| | **db_patient_user** | 用户服务 | `t_patient`(患者信息)、`t_login_record`(登录记录)、`undo_log`(Seata) | | **db_patient_registration** | 挂号服务 | `t_department`(科室)、`t_schedule`(号源)、`t_registration`(挂号记录)、`undo_log` | | **db_patient_payment** | 缴费服务 | `t_bill`(账单)、`t_payment_record`(支付记录)、`undo_log` | | **db_patient_notification** | 通知服务 | `t_notification`(通知记录)、`undo_log` | ### 设计要点 - **主键策略**: 全部使用 BIGINT 雪花 ID,由 `SnowflakeIdGenerator` 全局唯一生成 - **Seata AT 模式**: 每个库包含 `undo_log` 表,用于分布式事务的回滚 - **初始数据**: `03-init-registration.sql` 预置 8 个科室,自动生成未来 7 天的号源数据 - **索引优化**: 核心查询字段均建立索引(phone、registration_date、status 等) --- ## 快速开始 ### 环境要求 | 软件 | 最低版本 | 说明 | |------|----------|------| | JDK | 17+ | 编译和运行 | | Maven | 3.9+ | 项目构建 | | Docker | 20.10+ | 运行基础设施 | | Docker Compose | 2.0+ | 容器编排 | | 内存 | 8GB+ | 运行全部中间件和服务 | ### 1. 克隆项目 ```bash # GitHub git clone https://github.com/YOUR_USERNAME/patient-distributed-system.git cd patient-distributed-system # Gitee git clone https://gitee.com/YOUR_USERNAME/patient-distributed-system.git cd patient-distributed-system ``` ### 2. 启动基础设施 ```bash # 启动所有中间件(PostgreSQL、ES、Nacos 集群、Sentinel、Seata、SkyWalking) docker-compose up -d # 等待所有服务就绪(约 2-3 分钟) docker-compose ps ``` 等待以下容器状态均为 `healthy`: - `patient-postgres` - `patient-es` - `patient-nacos1 / patient-nacos2 / patient-nacos3` - `patient-sentinel` - `patient-seata` - `patient-skywalking-oap` - `patient-skywalking-ui` ### 3. 构建项目 ```bash # 编译打包(跳过测试) mvn clean package -DskipTests ``` ### 4. 下载 SkyWalking Agent ```bash # 下载 SkyWalking Java Agent(用于链路追踪) wget https://dlcdn.apache.org/skywalking/java-agent/9.1.0/apache-skywalking-java-agent-9.1.0.tgz tar -xzf apache-skywalking-java-agent-9.1.0.tgz ``` ### 5. 启动微服务 按以下顺序启动各服务: ```bash # 1. 用户服务(基础服务,最先启动) java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-user-service \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-user-service/target/patient-user-service-1.0.0.jar # 2. 挂号服务 java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-registration-service \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-registration-service/target/patient-registration-service-1.0.0.jar # 3. 缴费服务 java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-payment-service \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-payment-service/target/patient-payment-service-1.0.0.jar # 4. 通知服务 java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-notification-service \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-notification-service/target/patient-notification-service-1.0.0.jar # 5. 日志服务 java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-log-service \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-log-service/target/patient-log-service-1.0.0.jar # 6. 网关(最后启动) java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -DSW_AGENT_NAME=patient-gateway \ -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \ -jar patient-gateway/target/patient-gateway-1.0.0.jar ``` ### 6. 验证服务 ```bash # 检查 Nacos 注册中心(所有 6 个服务已注册) curl http://localhost:8848/nacos/v1/ns/service/list # 测试用户注册 curl -X POST http://localhost:8080/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{ "name": "张三", "phone": "13800138000", "password": "123456", "gender": 1, "idCard": "110101199001011234" }' # 测试用户登录(获取 JWT Token) curl -X POST http://localhost:8080/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{ "phone": "13800138000", "password": "123456" }' # 测试查询科室(带 Token) curl http://localhost:8080/api/v1/department/list \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` --- ## API 文档 系统集成 **SpringDoc OpenAPI**(Swagger 3),启动后可访问: - **网关聚合文档**: http://localhost:8080/swagger-ui.html - **各服务独立文档**: - 用户服务: http://localhost:8081/swagger-ui.html - 挂号服务: http://localhost:8082/swagger-ui.html - 缴费服务: http://localhost:8083/swagger-ui.html - 通知服务: http://localhost:8084/swagger-ui.html - 日志服务: http://localhost:8085/swagger-ui.html ### 核心 API 一览 #### 用户服务 (Auth) | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | POST | `/api/v1/auth/register` | 患者注册 | 否 | | POST | `/api/v1/auth/login` | 患者登录(返回 JWT) | 否 | | GET | `/api/v1/patient/info` | 获取当前患者信息 | 是 | #### 挂号服务 (Registration) | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/v1/department/list` | 科室列表 | 是 | | GET | `/api/v1/department/{id}` | 科室详情 | 是 | | GET | `/api/v1/registration/schedule` | 查询号源(按科室/日期) | 是 | | POST | `/api/v1/registration/create` | 创建挂号 | 是 | | POST | `/api/v1/registration/{id}/cancel` | 取消挂号 | 是 | | GET | `/api/v1/registration/list` | 我的挂号列表 | 是 | #### 缴费服务 (Payment) | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/v1/payment/bill/list` | 我的账单列表 | 是 | | GET | `/api/v1/payment/bill/{id}` | 账单详情 | 是 | | POST | `/api/v1/payment/pay` | 支付账单 | 是 | | POST | `/api/v1/payment/refund` | 申请退费 | 是 | #### 通知服务 (Notification) | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/v1/notification/list` | 我的通知列表 | 是 | | GET | `/api/v1/notification/unread/count` | 未读通知数 | 是 | | PUT | `/api/v1/notification/{id}/read` | 标记已读 | 是 | #### 日志服务 (Log) | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/v1/log/list` | 日志列表(分页 + 多条件) | 是 | | GET | `/api/v1/log/search` | 全文搜索(关键词高亮) | 是 | | GET | `/api/v1/log/statistics` | 操作统计 | 是 | --- ## 基础设施 ### 中间件访问地址 | 组件 | 地址 | 账号 | 密码 | |------|------|------|------| | **Nacos Console** | http://localhost:8848/nacos | nacos | nacos | | **Sentinel Dashboard** | http://localhost:8858 | sentinel | sentinel | | **SkyWalking UI** | http://localhost:8086 | - | - | | **Elasticsearch** | http://localhost:9200 | - | - | | **PostgreSQL** | localhost:5432 | patient | patient123 | ### Docker 容器清单 | 容器名 | 镜像 | 端口映射 | 用途 | |--------|------|----------|------| | patient-postgres | postgres:15-alpine | 5432:5432 | 关系型数据库 | | patient-es | elasticsearch:8.11.0 | 9200:9200, 9300:9300 | 日志搜索引擎 | | patient-nacos1 | nacos-server:2.2.3 | 8848:8848, 9848:9848 | Nacos 集群节点 1 | | patient-nacos2 | nacos-server:2.2.3 | 8849:8848, 9849:9848 | Nacos 集群节点 2 | | patient-nacos3 | nacos-server:2.2.3 | 8850:8848, 9850:9848 | Nacos 集群节点 3 | | patient-sentinel | sentinel-dashboard:1.8.6 | 8858:8858 | Sentinel 控制台 | | patient-seata | seata-server:1.7.1 | 8091:8091, 7091:7091 | Seata 事务协调器 | | patient-skywalking-oap | skywalking-oap:9.7.0 | 11800:11800, 12800:12800 | SkyWalking 收集器 | | patient-skywalking-ui | skywalking-ui:9.7.0 | 8086:8080 | SkyWalking 可视化 | --- ## 高可用与容错 ### 1. Nacos 集群高可用 - 3 节点集群部署(nacos1 / nacos2 / nacos3) - 消除单点故障,任一节点宕机不影响服务注册发现 - 访问地址: http://localhost:8848/nacos ### 2. Sentinel 流量控制 | 场景 | 规则 | 效果 | |------|------|------| | 网关全局 | QPS > 200/s | 返回 429 Too Many Requests | | 用户登录 | QPS > 100/s | 限流 + 降级提示 | | 挂号创建 | QPS > 100/s | 排队等待 | | Dubbo RPC 调用 | RT > 1000ms | 熔断降级,返回兜底数据 | | Dubbo RPC 调用 | 异常比例 > 50% | 熔断 10s 后恢复探测 | ### 3. Seata 分布式事务 - **AT 模式**: 无侵入式,自动生成回滚日志(undo_log) - **事务场景**: 挂号 → 通知、支付 → 通知 保证最终一致性 - **事务协调器**: Seata Server (:8091),File 模式存储 ### 4. SkyWalking 全链路追踪 - **无侵入**: Java Agent 启动时挂载,无需修改代码 - **全链路**: 网关 → 业务服务 → Dubbo RPC → 数据库 完整调用链 - **性能监控**: 自动采集 QPS、RT、错误率等指标 ### 5. Elasticsearch 日志检索 - **异步写入**: 操作日志通过 Dubbo RPC 异步写入 ES,不阻塞主流程 - **月度索引**: 日志按月创建独立索引(`operation_log_2026_07`),便于管理和归档 - **全文检索**: 支持中文分词、多条件组合查询、关键词高亮 - **深分页**: 使用 `search_after` 替代 `from+size`,避免深分页性能问题 --- ## 开发指南 ### 项目导入 1. 使用 IntelliJ IDEA 打开项目根目录 2. IDEA 自动识别 Maven 多模块项目 3. 等待依赖下载完成 ### 代码规范 - **包命名**: `com.patient.{module}.{layer}` - **分层结构**: `controller` → `service` → `mapper` → `entity` - **DTO 与 Entity 分离**: Controller 层使用 DTO,Service 层使用 Entity - **统一响应**: 所有接口返回 `ApiResponse` 格式 - **异常处理**: 业务异常抛出 `BusinessException`,由 `GlobalExceptionHandler` 统一处理 - **ID 生成**: 使用 `IdGenerator.nextId()` 生成全局唯一 ID ### 新增 Dubbo 接口 1. 在 `patient-common` 的 `dubbo/` 包下定义接口 2. 在服务提供方实现接口,添加 `@DubboService` 注解 3. 在服务消费方使用 `@DubboReference` 注入引用 ### 新增网关路由 编辑 `patient-gateway/src/main/resources/application.yml`: ```yaml spring: cloud: gateway: routes: - id: new-service uri: lb://new-service predicates: - Path=/api/v1/new/** ``` ### 配置文件说明 | 配置项 | 说明 | |--------|------| | `spring.cloud.nacos.discovery.server-addr` | Nacos 集群地址 | | `spring.cloud.sentinel.transport.dashboard` | Sentinel 控制台地址 | | `dubbo.registry.address` | Dubbo 注册中心地址 | | `jwt.secret` | JWT 签名密钥(生产环境需修改) | | `snowflake.worker-id` | 雪花 ID 机器 ID(每个服务不同) | | `snowflake.data-center-id` | 雪花 ID 数据中心 ID | --- ## 部署说明 ### 环境变量 生产环境需修改以下配置: ```yaml # application.yml spring: datasource: url: jdbc:postgresql://{PROD_HOST}:5432/{DATABASE} username: {PROD_USER} password: {PROD_PASSWORD} jwt: secret: {PRODUCTION_JWT_SECRET} # 生产环境必须修改 expiration: 86400000 # Token 过期时间(毫秒) spring: cloud: nacos: discovery: server-addr: {NACOS_HOST}:8848,{NACOS_HOST}:8849,{NACOS_HOST}:8850 sentinel: transport: dashboard: {SENTINEL_HOST}:8858 ``` ### SkyWalking Agent 参数 ```bash -javaagent:/opt/skywalking/agent/skywalking-agent.jar -DSW_AGENT_NAME={SERVICE_NAME} -DSW_AGENT_COLLECTOR_BACKEND_SERVICES={OAP_HOST}:11800 ``` ### Docker Compose 生产优化 ```yaml # 建议调整的配置 elasticsearch: environment: - "ES_JAVA_OPTS=-Xms2g -Xmx2g" # 生产环境增大内存 postgres: environment: POSTGRES_PASSWORD: {STRONG_PASSWORD} # 使用强密码 ``` ### 资源要求 | 环境 | CPU | 内存 | 磁盘 | |------|-----|------|------| | 开发/测试 | 4 核 | 8 GB | 20 GB | | 生产(最小) | 8 核 | 16 GB | 50 GB SSD | | 生产(推荐) | 16 核 | 32 GB | 100 GB SSD | --- ## 许可证 MIT License --- ## 联系方式 如有问题或建议,欢迎提交 Issue 或 Pull Request。 - GitHub: https://github.com/YOUR_USERNAME/patient-distributed-system - Gitee: https://gitee.com/YOUR_USERNAME/patient-distributed-system