总部与分公司数据交互方案
设想有这样一个场景:总部通过统一接口访问多个分公司的数据,并且请求中包含多个查询参数。这虽然是一个分布式系统场景,涉及总部和多个分公司之间的数据交互,但解决方案依然可以通过单体项目的思维来实现。本文将详细描述如何通过 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 整体流程
前端调用:
- 请求示例:
http://10.0.0.93:8080/api/5B20/monitor/report/output?factoryCode=5B20&lineCode=5B200101&startDate=20250218&endDate=20250218&pageIndex=1&pageSize=50
- 请求到达 Nginx。
- 请求示例:
Nginx 转发:
- 捕获
{子公司编号}
(如5B20
)。 - 将请求转发到对应子公司的服务器地址,例如
http://10.0.0.94:8080/api/monitor/report/output?factoryCode=5B20&lineCode=5B200101&startDate=20250218&endDate=20250218&pageIndex=1&pageSize=50
。
- 捕获
后端处理:
- 子公司服务器接收到完整请求,解析参数并执行业务逻辑。
- 返回计算结果。
响应返回:
- 数据经 Nginx 返回给前端。
3. 扩展性建议
- 负载均衡:如果某个子公司服务器压力较大,可以在 Nginx 中为该子公司配置多个上游服务器。
- 日志记录:在 Nginx 和后端服务中记录请求日志,便于后续排查问题。
- 安全性:在 Nginx 中添加身份验证机制(如 Token 验证),确保只有授权用户可以访问敏感数据。
通过以上设计,可以高效地完成总部与分公司的数据交互需求,同时支持复杂的查询参数传递。