forked from xuxing409/blog-demo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/(?<division_code>[^/]+)/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; | ||
} | ||
} | ||
} | ||
``` | ||
|
||
#### 配置说明 | ||
- **捕获 `{子公司编号}`**:使用正则表达式 `(?<division_code>[^/]+)` 捕获 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<ApiResponse<ListModel<OutputReportVo>>> 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 验证),确保只有授权用户可以访问敏感数据。 | ||
|
||
--- | ||
|
||
通过以上设计,可以高效地完成总部与分公司的数据交互需求,同时支持复杂的查询参数传递。 |