这是一项任务 - 有必要根据来自 UI 端 (JavaScript) 的一些数据生成文件。架构非常简单:
UI 向服务器发出异步 POST HTTP 请求并提供一些 JSON 数据:
$.ajax({ url: '/reports', type: "POST", data: JSON.stringify({...}), success: function (uuid) { window.location = "/reports/" + uuid; } });
服务器接收请求,生成一个文件,将它放到文件系统中并返回唯一 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; }
UI 端获取生成的文件的唯一 id 并请求它:
success: function (uuid) { window.location = "/reports/" + uuid; }
服务器输出请求的文件:
@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_A和Server_B以及它们前面的负载均衡器,那么我们需要确保上面提到的两个请求都发送到同一台服务器。因此需要粘性会话。为像http://server_a/reports/123这样指定的服务器提供绝对路径并不是一个好的选择,因为我们想让所有服务器都无法从外部世界访问。
那么有哪些选项可用于实现下载生成的文件以及避免粘滞会话?