0

这是一项任务 - 有必要根据来自 UI 端 (JavaScript) 的一些数据生成文件。架构非常简单:

  1. UI 向服务器发出异步 POST HTTP 请求并提供一些 JSON 数据:

        $.ajax({
            url: '/reports',
            type: "POST",
            data: JSON.stringify({...}),
            success: function (uuid) {                    
                window.location = "/reports/" + uuid;
            }                
        });
    
  2. 服务器接收请求,生成一个文件,将它放到文件系统中并返回唯一 ID:

    @RequestMapping(value = "/reports", method = RequestMethod.POST)
    public String generateReport(ReqData data) throws IOException {
      final String fileUuid = UUID.randomUUID();
      ...
      //generate a report and return filename
      ...
      return fileUuid;
    }
    
  3. UI 端获取生成的文件的唯一 id 并请求它:

    success: function (uuid) {                    
      window.location = "/reports/" + uuid;
    }  
    
  4. 服务器输出请求的文件:

      @RequestMapping(value = "/reports/{uuid}", method = RequestMethod.GET)
      public ResponseEntity<InputStreamResource> downloadReport(@PathVariable("uuid") String fileUuid) throws IOException {
    
        final String resultFileName = fileUuid + ".txt";
        final Path resultFile = Paths.get(resultFileName);
    
        return ResponseEntity
                .ok()
                .header("Content-Disposition", "attachment; filename=\"" + resultFileName + "\"")
                .contentLength(Files.size(resultFile))
                .contentType(MediaType.parseMediaType("text/plain"))
                .body(new InputStreamResource(Files.newInputStream(resultFile)));
    } 
    

当我们考虑这个具有多个服务器的模式时,问题就开始了。如果我们有两个实例Server_AServer_B以及它们前面的负载均衡器,那么我们需要确保上面提到的两个请求都发送到同一台服务器。因此需要粘性会话。为像http://server_a/reports/123这样指定的服务器提供绝对路径并不是一个好的选择,因为我们想让所有服务器都无法从外部世界访问。

那么有哪些选项可用于实现下载生成的文件以及避免粘滞会话?

4

1 回答 1

0

有几种方法可以解决这个问题。虽然会话粘性开始并在负载平衡器上配置。

方法 1: -- 使 NFS 空间可用并将其安装在所有应用程序服务器上并在该位置生成报告。安装后,可以从任何服务器提供相同的文件。

方法 2:在其中一台服务器上实现本地文件存储库,并在生成报告时通过 ftp 协议将文件推送到存储库,这种方法可能会对性能产生一点影响,因为它们是通过 FTP 存储和检索文件的开销.

方法3:将报告存储在数据库本身并通过数据库从任何服务器检索。

方法4:为什么不在生成时将报告发送给客户端,为什么不与第一次调用一起实现文件的传递。无论如何,在您的 javascript 中,您似乎正在设置 window.location 在生成文件后接收响应时。

于 2015-12-09T01:31:58.877 回答