# 项目规则文档 ## ⚠️ 重要提示 **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.properties` 和 `application-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 脚本: ```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. **构建项目**: ```bash cd FlinkDataSync mvn clean package -DskipTests ``` 2. **启动服务**: ```bash 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.1`、`flink-sync.log.2` 等 #### 日志监控 ```bash # 实时查看日志 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` - **错误信息**:`ERROR` 或 `Exception` ### 配置说明 #### 数据库配置 配置文件位置:`FlinkDataSync/src/main/java/com/lianda/flink/sync/MySqlCdcSync.java` ```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") ``` #### 编码和时区配置 ```java // 编码配置 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:服务启动失败 - **现象**:启动时报错 `ClassNotFoundException` 或 `NoClassDefFoundError` - **解决**: 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. 并行度配置 ```java // 设置并行度 env.setParallelism(1); // 根据服务器资源调整 ``` #### 2. 检查点配置 ```java // 配置检查点间隔 env.enableCheckpointing(60000); // 60秒 // 配置检查点模式 env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE); ``` #### 3. 状态后端配置 ```java // 使用 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**:只在必要时使用固定定位,过多会影响性能