diff --git "a/docs/\345\274\200\345\217\221/\344\270\200\345\257\271\345\244\232\347\232\204\346\225\260\346\215\256\344\272\244\344\272\222\346\226\271\346\241\210\350\256\276\350\256\241.md" "b/docs/\345\274\200\345\217\221/\344\270\200\345\257\271\345\244\232\347\232\204\346\225\260\346\215\256\344\272\244\344\272\222\346\226\271\346\241\210\350\256\276\350\256\241.md" new file mode 100644 index 0000000..4979f1a --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\344\270\200\345\257\271\345\244\232\347\232\204\346\225\260\346\215\256\344\272\244\344\272\222\346\226\271\346\241\210\350\256\276\350\256\241.md" @@ -0,0 +1,157 @@ +--- + +# 总部与分公司数据交互方案 + +设想有这样一个场景:总部通过统一接口访问多个分公司的数据,并且请求中包含多个查询参数。这虽然是一个分布式系统场景,涉及总部和多个分公司之间的数据交互,但解决方案依然可以通过单体项目的思维来实现。本文将详细描述如何通过 Nginx 反向代理实现统一接口调用,并展示具体的前端、Nginx 和后端实现方式,实现在局域网环境,动态获取不同数据接口源的信息。 + +--- + +## 1. 场景描述 + +- **背景**:总部和四个分公司各自部署一个服务器,使用同一套源码实现相同接口功能。 +- **目标**:总部希望通过一个统一接口(如 `http://localhost:8080/api/{子公司编号}/monitor/report/output`)查看不同分公司的数据,同时支持传递查询参数(如 `factoryCode`, `lineCode`, `startDate`, `endDate`, `pageIndex`, `pageSize`)。 +- **技术选型**: + - 前端负责调用接口并展示数据。 + - Nginx 作为反向代理服务器进行请求转发。 + - 后端实现具体业务逻辑,处理查询参数。 + +--- + +## 2. 实现方案 + +### 2.1 请求示例 + +前端发起的请求如下: +```shell +http://10.0.0.93:8080/api/5B20/monitor/report/output?factoryCode=5B20&lineCode=5B200101&startDate=20250218&endDate=20250218&pageIndex=1&pageSize=50 +``` + +其中: +- `{子公司编号}` 是动态部分,例如 `5B20`。 +- 查询参数包括 `factoryCode`, `lineCode`, `startDate`, `endDate`, `pageIndex`, 和 `pageSize`。 + +--- + +### 2.2 Nginx 配置 + +#### 主要任务 +- 捕获 `{子公司编号}` 并动态匹配到对应的分公司服务器。 +- 确保查询参数完整传递到目标服务器。 + +#### 示例配置 +```nginx +http { + upstream server_5B20 { + server 10.0.0.94:8080; # 子公司5B20的服务器地址 + } + + upstream server_5B30 { + server 10.0.0.95:8080; # 子公司5B30的服务器地址 + } + + upstream server_5B40 { + server 10.0.0.96:8080; # 子公司5B40的服务器地址 + } + + upstream server_5B50 { + server 10.0.0.97:8080; # 子公司5B50的服务器地址 + } + + server { + listen 8080; + + location ~ ^/api/(?[^/]+)/monitor/report/output$ { + set $target_server "server_$division_code"; + proxy_pass http://$target_server/monitor/report/output; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # 确保查询参数完整传递 + proxy_pass_request_headers on; + proxy_pass_request_body on; + } + } +} +``` + +#### 配置说明 +- **捕获 `{子公司编号}`**:使用正则表达式 `(?[^/]+)` 捕获 URL 中的 `{子公司编号}`。 +- **动态匹配目标服务器**:通过 `set $target_server "server_$division_code";` 动态设置目标服务器。 +- **路径重写**:将原始路径 `/api/{子公司编号}/monitor/report/output` 转发为 `/api/monitor/report/output`。 +- **查询参数传递**:`proxy_pass_request_headers on;` 和 `proxy_pass_request_body on;` 确保所有查询参数和请求头被正确转发。 + +--- + +### 2.3 后端接口设计 + +#### 接口定义 +后端接口接收以下参数: +- `factoryCode`: 工厂编号 +- `lineCode`: 生产线编号 +- `startDate`: 开始日期 +- `endDate`: 截止日期 +- `pageSize`: 分页大小 +- `pageIndex`: 分页索引 + +#### 示例代码(Spring Boot) +```java +@RestController +@RequestMapping("/monitor/report/") +public class MonitorController { + + @ApiOperation("产量明细") + @GetMapping("output") + public ResponseEntity>> output( + @RequestParam String factoryCode, + @RequestParam String lineCode, + @RequestParam Integer startDate, + @RequestParam Integer endDate, + @RequestParam int pageIndex, + @RequestParam int pageSize) { + + // 参数校验 + // ... + + // 调用服务逻辑 + // ... + + return ResponseEntity.ok(ApiResponse.success(result)); + } +} +``` + +#### 关键点 +- **参数校验**:确保接收到的参数合法。 +- **业务逻辑**:根据参数计算产量明细并返回结果。 + +--- + +### 2.4 整体流程 + +1. **前端调用**: + - 请求示例:`http://10.0.0.93:8080/api/5B20/monitor/report/output?factoryCode=5B20&lineCode=5B200101&startDate=20250218&endDate=20250218&pageIndex=1&pageSize=50` + - 请求到达 Nginx。 + +2. **Nginx 转发**: + - 捕获 `{子公司编号}`(如 `5B20`)。 + - 将请求转发到对应子公司的服务器地址,例如 `http://10.0.0.94:8080/api/monitor/report/output?factoryCode=5B20&lineCode=5B200101&startDate=20250218&endDate=20250218&pageIndex=1&pageSize=50`。 + +3. **后端处理**: + - 子公司服务器接收到完整请求,解析参数并执行业务逻辑。 + - 返回计算结果。 + +4. **响应返回**: + - 数据经 Nginx 返回给前端。 + +--- + +## 3. 扩展性建议 + +- **负载均衡**:如果某个子公司服务器压力较大,可以在 Nginx 中为该子公司配置多个上游服务器。 +- **日志记录**:在 Nginx 和后端服务中记录请求日志,便于后续排查问题。 +- **安全性**:在 Nginx 中添加身份验证机制(如 Token 验证),确保只有授权用户可以访问敏感数据。 + +--- + +通过以上设计,可以高效地完成总部与分公司的数据交互需求,同时支持复杂的查询参数传递。 \ No newline at end of file