project_rules.md 20 KB

项目规则文档

⚠️ 重要提示

FlinkDataSync 是本系统的关键数据同步服务,必须首先启动!

  • 启动顺序:FlinkDataSync → com.lianda.auth → JavaBackend → vue-frontend
  • 重要性:FlinkDataSync负责实时同步TugboatCommon和LiandaTugboatMIS数据库的数据,如果未启动,系统将无法正常工作
  • 检查标志:看到 "Keepalive thread is running" 表示服务已正常运行
  • 禁止修改:严禁修改FlinkDataSync的同步配置、数据库结构等关键配置

获取Sys_DictionaryItem的方式不能只传递Value值,因为这是个字典集合,很多个字典都会有同样的Value,应当增加DictionaryCode的校验,数据库结构的markdown文件中的说明列里,会告诉你每个字段对应的是哪个DictionaryCode 先找到项目里的.pdm文件或用户上传的上下文,如果能从中导出表和字段的信息,则以此为准,不能随意修改数据库的结构和数据 上下文中的数据库设计文档集才是最终的数据库结构标准 必须完全信任数据库文档,数据库的结构和文档必然是一致的 单一SQL语句返回完整的列表信息是最优的选择 SQLServer数据库的版本是2008 R2,选择使用它的存储过程和函数时,要注意版本兼容性问题,避免使用2012及以上版本的功能 只有tugboatcommon和liandatugboatmis这两个库同时存在的表才需要读写分离,即写入到tugboatcommon库里,从liandatugboatmis库读取数据,其他表都在各自的数据库里读写即可 为了方便理解,说明一下:tugboatcommon库是系统公共库,liandatugboatmis是分支机构的业务库,公共库存放所有机构共享的数据,而分支机构的业务库则存放各自机构的业务数据,他们并不是单纯的读库和写库的区别 修改哪个项目就重新调试哪个项目,不要每次都全部重新启动调试 技能文档永远是对的 不要改变项目的端口号,这是个多个项目协作的项目,修改端口号会带来一系列问题 严禁修改任何让用户参考的文件或配置,包括但不限于:FlinkDataSync的同步配置、数据库结构、端口配置等

项目端口配置规则

本项目是一个多项目协作系统,共包含四个项目,各项目端口配置如下,严禁随意修改

项目名称 端口 说明
com.lianda.auth 8083 认证服务,上下文路径 /auth
JavaBackend 8080 主后端服务,上下文路径 /api
vue-frontend 8082 前端应用,开发服务器端口
FlinkDataSync - CDC 数据同步服务(无端口,后台运行)

端口配置文件位置

  • com.lianda.auth: src/main/resources/application.properties 中的 server.port=8083
  • JavaBackend: src/main/resources/application.propertiesapplication-dev.properties 中的 server.port=8080
  • vue-frontend: vue.config.js 中的 devServer.port: 8082
  • FlinkDataSync: 无端口配置,运行 java -cp target/flink-data-sync-1.0-SNAPSHOT.jar com.lianda.flink.sync.MySqlCdcSync

端口修改流程

如需修改端口,必须:

  1. 更新所有相关项目的配置文件
  2. 更新前端代理配置(vue.config.js)
  3. 更新所有 API 调用中的端口号
  4. 更新项目规则文档
  5. 通知所有团队成员

项目启动说明

⚠️ 启动前必读

FlinkDataSync 是系统的核心服务,必须首先启动!

  • 为什么重要:FlinkDataSync负责实时监控TugboatCommon数据库的变化,并将变更同步到LiandaTugboatMIS数据库
  • 不启动的后果:如果FlinkDataSync未启动,系统将无法获取最新的公共数据,导致功能异常
  • 启动检查:启动后必须看到 "Keepalive thread is running" 日志,表示服务已正常运行

本项目包含四个服务,启动方式如下:

一键启动

运行 PowerShell 脚本:

.\start-all.ps1

手动启动

  1. com.lianda.auth: 进入 com.lianda.auth 目录,运行 mvn spring-boot:run
  2. JavaBackend: 进入 JavaBackend 目录,运行 mvn spring-boot:run
  3. vue-frontend: 进入 vue-frontend 目录,运行 npm run serve
  4. FlinkDataSync: 进入 FlinkDataSync 目录,先运行 mvn clean package -DskipTests 构建,然后运行 java -jar target/flink-data-sync-1.0-SNAPSHOT.jar

FlinkDataSync CDC 数据同步服务

服务说明

FlinkDataSync 是基于 Apache Flink 的 CDC(Change Data Capture)数据同步服务,负责实时监控 TugboatCommon 数据库的变化,并将变更同步到 LiandaTugboatMIS 数据库。

核心功能

  • 实时数据同步:监控 MySQL binlog,实时捕获数据变更
  • 数据一致性保证:确保 TugboatCommon 和 LiandaTugboatMIS 数据库的数据一致性
  • 增量同步:只同步变更的数据,提高效率
  • 断点续传:支持从上次同步位置继续,避免数据丢失

监控的数据表

FlinkDataSync 监控以下 TugboatCommon 数据库的表:

  • Bus_Holiday(节假日)
  • Bus_ShipPaymentType(船舶付款类型)
  • Bus_ShipPaymentType_ShipType(船舶付款类型船舶类型关联)
  • Disp_Port(港口)
  • Disp_PortDictionary(港口字典)
  • Disp_Tugboat(拖轮)
  • Disp_DeepLevel(深水等级)
  • Disp_Berthage(泊位)
  • Disp_BerthageDictionary(泊位字典)
  • Disp_Pilot(引航员)
  • Disp_Tugboatowner(拖轮船东)
  • Disp_Waterway(航道)
  • Fin_AssistCode(财务辅助代码)
  • Fin_AssistCodeItem(财务辅助代码项)
  • Fin_Subject(财务科目)
  • Fin_Subject_AssistCode(财务科目辅助代码)
  • Fin_TaxRule(税务规则)
  • Pro_FeeItemAssistCode(项目费用项辅助代码)
  • Pro_FeeItemSettings(项目费用项设置)
  • Sal_Holiday(薪酬节假日)
  • Sal_SocialInsuranceStandard(薪酬社保标准)
  • Sal_TaxLevel(薪酬税务等级)
  • Tug_Certificate(拖轮证书)

启动和调试

启动步骤

  1. 构建项目

    cd FlinkDataSync
    mvn clean package -DskipTests
    
  2. 启动服务

    java -jar target/flink-data-sync-1.0-SNAPSHOT.jar
    

启动成功标志

服务启动成功后会显示以下日志:

  • Starting execution of job 'MySQL CDC Data Sync'
  • Job MySQL CDC Data Sync switched from state CREATED to RUNNING
  • Reading structure of database
  • Received record from streaming binlog phase

服务状态检查

  • 初始快照阶段:服务启动时会先读取所有监控表的当前数据(快照)
  • 实时同步阶段:快照完成后,进入实时 binlog 监控阶段
  • 正常运行标志:看到 Received record from streaming binlog phase 表示服务已进入正常运行状态

日志查看

日志文件位置

  • 主日志文件FlinkDataSync/flink-sync.log
  • 历史日志FlinkDataSync/flink-sync.log.1flink-sync.log.2

日志监控

# 实时查看日志
tail -f FlinkDataSync/flink-sync.log

# 查看最近的日志
tail -n 100 FlinkDataSync/flink-sync.log

# 搜索错误日志
grep -i "error" FlinkDataSync/flink-sync.log

关键日志信息

  • 数据库连接Connecting to MySQL database
  • 快照进度Snapshot step 1/2/3 - ...
  • 数据同步Received record from streaming binlog phase
  • 错误信息ERRORException

配置说明

数据库配置

配置文件位置:FlinkDataSync/src/main/java/com/lianda/flink/sync/MySqlCdcSync.java

// 源数据库配置
.hostname("192.168.0.77")           // MySQL 服务器地址
.port(3306)                          // MySQL 端口
.databaseList("TugboatCommon")         // 监控的数据库
.tableList("TugboatCommon.xxx", ...)   // 监控的表列表
.username("root")                      // 数据库用户名
.password("bowin@2023")              // 数据库密码

// 目标数据库配置
MySqlSink("192.168.0.77", 3306, "LiandaTugboatMIS", "root", "bowin@2023")

编码和时区配置

// 编码配置
properties.setProperty("database.character.set", "utf8mb4");
properties.setProperty("database.collation.name", "utf8mb4_unicode_ci");
properties.setProperty("database.connection.properties", "useUnicode=true&characterEncoding=UTF-8");

// 时区配置
properties.setProperty("database.time_zone", "Asia/Shanghai");
properties.setProperty("database.serverTimezone", "Asia/Shanghai");

常见问题解决

问题1:服务启动失败

  • 现象:启动时报错 ClassNotFoundExceptionNoClassDefFoundError
  • 解决
    1. 检查是否正确构建项目:mvn clean package -DskipTests
    2. 检查 JAR 文件是否存在:target/flink-data-sync-1.0-SNAPSHOT.jar
    3. 检查 Java 版本是否为 1.8 或以上

问题2:数据库连接失败

  • 现象:启动时报错 Communications link failure
  • 解决
    1. 检查 MySQL 服务是否启动
    2. 检查数据库地址和端口是否正确
    3. 检查数据库用户名和密码是否正确
    4. 检查网络连接是否正常
    5. 检查数据库权限是否足够(需要 REPLICATION CLIENT 和 REPLICATION SLAVE 权限)

问题3:binlog 未启用

  • 现象:启动时报错 The MySQL server is not configured to use a binlog
  • 解决
    1. 检查 MySQL 配置文件(my.cnf 或 my.ini)
    2. 确保以下配置存在: ini [mysqld] server-id=1 log-bin=mysql-bin binlog-format=ROW binlog-row-image=FULL
    3. 重启 MySQL 服务

问题4:同步延迟

  • 现象:数据变更后,目标数据库没有及时更新
  • 解决
    1. 检查 FlinkDataSync 日志,确认服务是否正常运行
    2. 检查网络连接是否稳定
    3. 检查数据库性能是否正常
    4. 检查是否有大量数据变更导致同步延迟

问题5:数据不一致

  • 现象:源数据库和目标数据库数据不一致
  • 解决
    1. 检查 FlinkDataSync 日志,确认是否有同步错误
    2. 检查目标数据库是否有写入权限
    3. 检查表结构是否一致
    4. 手动触发全量同步(删除目标表数据,重启 FlinkDataSync)

性能优化

1. 并行度配置

// 设置并行度
env.setParallelism(1);  // 根据服务器资源调整

2. 检查点配置

// 配置检查点间隔
env.enableCheckpointing(60000);  // 60秒

// 配置检查点模式
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);

3. 状态后端配置

// 使用 RocksDB 状态后端(适用于大状态)
env.setStateBackend(new RocksDBStateBackend("file:///path/to/checkpoints"));

监控和维护

1. 服务监控

  • 定期检查日志:查看是否有错误或异常
  • 监控同步延迟:检查数据变更后多久同步到目标数据库
  • 监控资源使用:CPU、内存、网络使用情况

2. 数据验证

  • 定期数据对比:对比源数据库和目标数据库的数据
  • 检查数据完整性:确保所有数据都正确同步
  • 检查数据一致性:确保数据关系正确

3. 故障恢复

  • 服务重启:如果服务异常,重启服务
  • 检查点恢复:Flink 会从检查点自动恢复
  • 手动修复:如果自动恢复失败,手动修复数据

安全注意事项

  1. 不要修改数据库配置:FlinkDataSync 的数据库配置是系统关键配置,严禁随意修改
  2. 保护数据库密码:不要将数据库密码提交到版本控制
  3. 限制数据库权限:只给 FlinkDataSync 必要的数据库权限
  4. 定期更新依赖:保持 Flink 和 CDC 连接器的版本更新
  5. 监控异常访问:监控数据库的异常访问和操作

调试最佳实践

调试流程

⚠️ 重要:服务启动顺序

必须严格按照以下顺序启动服务,否则系统将无法正常工作!

  1. 第一步:启动 FlinkDataSync(CDC数据同步服务)最重要

    • 为什么必须先启动:FlinkDataSync是数据同步的核心,其他服务依赖它提供的数据
    • 启动命令bash cd FlinkDataSync mvn clean package -DskipTests java -jar target/flink-data-sync-1.0-SNAPSHOT.jar
    • 启动成功标志:看到 "Keepalive thread is running" 日志
    • 等待时间:约30-60秒(需要读取数据库结构)
    • ⚠️ 警告:如果未看到 "Keepalive thread is running",不要启动其他服务!
  2. 第二步:启动 com.lianda.auth(认证服务)

    • 启动命令cd com.lianda.auth && mvn spring-boot:run
    • 启动成功标志:看到 "Started AuthApplication"
  3. 第三步:启动 JavaBackend(主后端服务)

    • 启动命令cd JavaBackend && mvn spring-boot:run
    • 启动成功标志:看到 "Started Application"
  4. 第四步:启动 vue-frontend(前端应用)

    • 启动命令cd vue-frontend && npm run serve
    • 启动成功标志:看到 "App running at"

服务就绪检查清单

启动每个服务后,请按照以下清单检查:

  • FlinkDataSync:看到 "Keepalive thread is running"(⭐ 必须首先检查)
  • com.lianda.auth:看到 "Started AuthApplication"
  • JavaBackend:看到 "Started Application"
  • vue-frontend:看到 "App running at"

⚠️ 重要提醒:只有FlinkDataSync成功启动后,才能启动其他服务!

调试技巧

1. 选择性重启

  • 原则:修改哪个项目就重新调试哪个项目,不要每次都全部重新启动调试
  • 方法:只重启修改过的服务,其他服务保持运行
  • 优势:节省时间,提高开发效率

2. 终端管理

  • 可用终端:最多支持5个终端同时运行
  • 查看状态:使用 CheckCommandStatus 工具查看服务运行状态
  • 停止服务:在对应终端按 Ctrl+C 停止服务

3. 日志查看

  • 后端服务(com.lianda.auth、JavaBackend):

    • 查看启动日志和控制台输出
    • Spring Boot 应用日志在控制台实时显示
    • 使用 Spring DevTools 支持热重载
  • 前端服务(vue-frontend):

    • 查看浏览器控制台(F12)
    • 查看终端编译日志
    • Vue CLI 实时编译错误提示
  • FlinkDataSync

    • 查看日志文件:FlinkDataSync/flink-sync.log
    • 查看控制台输出
    • 关注 CDC 数据同步状态

4. 端口检查

  • 检查端口占用:使用 netstat -ano | findstr "端口号" 检查端口是否被占用
  • 常用端口
    • 8080: JavaBackend
    • 8082: vue-frontend
    • 8083: com.lianda.auth
    • 35729: Spring DevTools LiveReload
    • 35730: Spring DevTools LiveReload

5. 浏览器调试

  • 打开开发者工具:按 F12 打开浏览器开发者工具
  • 网络请求:在 Network 标签查看 API 请求和响应
  • 控制台:在 Console 标签查看 JavaScript 错误和警告
  • 元素检查:在 Elements 标签检查 DOM 结构和样式
  • Vue DevTools:安装 Vue.js devtools 浏览器扩展,方便调试 Vue 组件

常见问题解决

问题1:端口被占用

  • 现象:启动服务时报错 "Address already in use"
  • 解决
    1. 使用 netstat -ano | findstr "端口号" 查找占用端口的进程
    2. 使用 taskkill /PID 进程ID 杀死占用进程
    3. 或者修改配置文件使用其他端口

问题2:数据库连接失败

  • 现象:后端服务启动时报错 "Could not connect to database"
  • 解决
    1. 检查数据库服务是否启动
    2. 检查数据库连接配置是否正确
    3. 检查网络连接是否正常
    4. 检查数据库用户名和密码是否正确

问题3:前端无法访问后端API

  • 现象:前端页面显示网络错误或超时
  • 解决
    1. 检查后端服务是否启动
    2. 检查 API 地址和端口是否正确
    3. 检查浏览器控制台是否有 CORS 错误
    4. 检查后端 CORS 配置是否正确

问题4:FlinkDataSync 同步失败

  • 现象:CDC 同步服务无法读取数据库变更
  • 解决
    1. 检查 MySQL binlog 是否启用
    2. 检查数据库配置是否正确
    3. 检查 FlinkDataSync 日志文件
    4. 检查数据库权限是否足够

问题5:热重载不生效

  • 现象:修改代码后浏览器没有自动刷新
  • 解决
    1. 检查 Spring DevTools 是否正确配置
    2. 检查浏览器是否禁用了缓存
    3. 手动刷新浏览器(Ctrl+F5)
    4. 清除浏览器缓存

性能优化建议

1. 开发环境优化

  • 后端服务

    • 使用 Spring DevTools 热重载,避免频繁重启
    • 调整 JVM 内存参数:-Xmx1024m -Xms512m
    • 使用多线程编译:mvn -T 4 spring-boot:run
  • 前端服务

    • 使用 Vue CLI 的热模块替换(HMR)
    • 禁用 ESLint 检查以提高编译速度(仅开发环境)
    • 使用缓存:npm run serve --cache

2. 调试效率提升

  • 使用断点调试

    • 后端:在 IDE 中设置断点,使用 Debug 模式启动
    • 前端:在浏览器开发者工具中设置断点
    • 使用 Chrome DevTools 的 Sources 面板
  • 使用日志调试

    • 后端:使用 @Slf4j 注解和 logger.info/debug/error
    • 前端:使用 console.log/debug/error
    • 生产环境注意关闭详细日志

安全注意事项

  1. 不要在生产环境使用开发配置
  2. 不要将敏感信息提交到版本控制(密码、密钥等)
  3. 定期更新依赖以修复安全漏洞
  4. 使用 HTTPS 在生产环境中
  5. 实施认证和授权机制

前端开发最佳实践

1. 布局和定位

  • 固定定位元素:对于需要始终可见的元素(如导航栏、标签页头部),使用 position: fixed 固定定位
  • 避免滚动遮挡:固定定位的元素应该设置合适的 z-index,确保不会被其他元素遮挡
  • 响应式适配:固定定位元素需要考虑不同屏幕尺寸下的位置调整

2. 标签页组件优化

  • 固定标签页头部:使用 position: fixed 固定标签页头部,避免滚动时被遮挡
  • 正确设置位置css .tabs-header { position: fixed !important; top: 64px !important; /* 顶部导航栏高度 */ left: 220px !important; /* 侧边栏宽度 */ right: 0 !important; z-index: 1000 !important; }
  • 内容区域适配:为内容区域添加 padding-top,避免被固定头部遮挡 css .tabs-content { padding-top: 40px !important; /* 标签页头部高度 */ }
  • 响应式处理:在不同屏幕尺寸下调整固定定位元素的位置 ```css @media (max-width: 1200px) { .tabs-header { left: 200px !important; /* 中等屏幕侧边栏宽度 */ } }

@media (max-width: 768px) {

.tabs-header {
  left: 180px !important; /* 小屏幕侧边栏宽度 */
}

} ```

3. 常见布局问题解决

  • 问题1:滚动时固定元素被遮挡

    • 解决:增加 z-index 值,确保固定元素在最上层
    • 示例:z-index: 1000 !important;
  • 问题2:固定定位元素遮挡内容

    • 解决:为内容区域添加 padding-top,值为固定元素的高度
    • 示例:padding-top: 40px !important;
  • 问题3:响应式布局错位

    • 解决:使用媒体查询调整不同屏幕下的固定定位
    • 示例:使用 @media 查询调整 left

4. CSS 样式优先级

  • 使用 !important:在需要覆盖第三方库样式时使用 !important
  • 避免滥用:只在必要时使用 !important,优先使用更具体的选择器
  • 样式隔离:使用 scoped 样式避免全局污染

5. 性能优化

  • 减少重排重绘:固定定位元素不会影响文档流,但频繁修改样式仍会导致重排
  • 使用 transform:对于动画效果,优先使用 transform 而非 top/left
  • 避免过度使用 fixed:只在必要时使用固定定位,过多会影响性能