Skip to content

总部与分公司数据交互方案

设想有这样一个场景:总部通过统一接口访问多个分公司的数据,并且请求中包含多个查询参数。这虽然是一个分布式系统场景,涉及总部和多个分公司之间的数据交互,但解决方案依然可以通过单体项目的思维来实现。本文将详细描述如何通过 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 验证),确保只有授权用户可以访问敏感数据。

通过以上设计,可以高效地完成总部与分公司的数据交互需求,同时支持复杂的查询参数传递。