如何在实施文件下载时避免粘性会话?

时间:2015-12-09 01:17:13

标签: javascript ajax download stateless sticky-session

这是一项任务 - 必须根据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)));
    } 
    
  5. 当我们考虑使用多个服务器的此架构时,问题就开始了。如果我们有两个实例 Server_A Server_B ,并且前面有一个负载均衡器,那么我们需要确保上述两个请求都转到同一台服务器。因此需要粘性会话。提供与http://server_a/reports/123指定的服务器的绝对路径不是一个好的选择,因为我们希望使所有服务器无法从外部世界访问。

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

1 个答案:

答案 0 :(得分:0)

有几种方法可以围绕此实现解决方案..虽然会话粘性开始并在负载均衡器上配置。

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

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

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

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