Java 弹簧启动应用程序阻止流入阀体

Java 弹簧启动应用程序阻止流入阀体,java,spring-boot,streamingresponsebody,Java,Spring Boot,Streamingresponsebody,我有一个springboot应用程序,我在其中创建了一个POST方法,该方法以流式方式向调用者发送数据。代码如下: @RequestMapping(value = "/mapmatchstreaming", method = RequestMethod.POST) public ResponseEntity<StreamingResponseBody> handleRequest(@RequestParam(value = "data", re

我有一个springboot应用程序,我在其中创建了一个POST方法,该方法以流式方式向调用者发送数据。代码如下:

@RequestMapping(value = "/mapmatchstreaming", method = RequestMethod.POST)
public ResponseEntity<StreamingResponseBody> handleRequest(@RequestParam(value = "data", required = true) String data, @RequestParam(value = "mnr", required = true) Boolean mnr) {
    logger.info("/mapmatchstreaming endpoint");

    try {
        Semaphore semaphore = new Semaphore(1);
        ObjectMapper mapper = new ObjectMapper();

        StreamingResponseBody responseBody = new StreamingResponseBody() {
            @Override
            public void writeTo (OutputStream outputStream) throws IOException {
                // For each map
                DataReader dataReader = new DataReader(data, "2020.06.011");

                for(String mapRoot: dataReader.getMapsFolders()) {
                    dataReader = new DataReader(data, "2020.06.011");
                    DistributedMapMatcherStreaming distributedMapMatcher = new DistributedMapMatcherStreaming(dataReader.getTraces(), mapRoot, dataReader.getBoundingBox());
                    distributedMapMatcher.mapMatchBatch(new DistributedMapMatcherResult() {
                        @Override
                        public void onCorrectlyMapMatched(MapMatchedTrajectory mapMatchedTrajectory) {
                            try {
                                semaphore.acquire();
                                outputStream.write(mapper.writeValueAsString(mapMatchedTrajectory).getBytes());
                                outputStream.flush();
                            }
                            catch (Exception e) {
                                e.printStackTrace();
                                logger.error(String.format("Writing to output stream error: %s", e.getMessage()));
                            } finally{
                                semaphore.release();
                            }
                        }
                    });
                }
            }
        };

        return new ResponseEntity<StreamingResponseBody>(responseBody, HttpStatus.OK);
    }
    catch (Exception e) {
        logger.error(String.format("Map-matching result ERROR: %s", ExceptionUtils.getStackTrace(e)));
        return new ResponseEntity<StreamingResponseBody>(HttpStatus.BAD_REQUEST);
    }
}
@RequestMapping(value=“/mapmatchstreaming”,method=RequestMethod.POST)
公共响应句柄请求(@RequestParam(value=“data”,required=true)字符串数据,@RequestParam(value=“mnr”,required=true)布尔mnr){
logger.info(“/mapmatchstreaming endpoint”);
试一试{
信号量信号量=新信号量(1);
ObjectMapper mapper=新的ObjectMapper();
StreamingResponseBody responseBody=新的StreamingResponseBody(){
@凌驾
public void writeTo(OutputStream OutputStream)引发IOException{
//每张地图
DataReader DataReader=新的DataReader(数据,“2020.06.011”);
for(字符串映射根:dataReader.getMapsFolders()){
dataReader=新的dataReader(数据,“2020.06.011”);
DistributedMapMatcherStreaming distributedMapMatcher=新的DistributedMapMatcherStreaming(dataReader.getTraces(),mapRoot,dataReader.getBoundingBox());
distributedMapMatcher.mapMatchBatch(新DistributedMapMatcherResult(){
@凌驾
未正确匹配的公共无效(MapMatchedTrajectory MapMatchedTrajectory){
试一试{
semaphore.acquire();
outputStream.write(mapper.writeValueAsString(mapmachedTrajectory.getBytes());
outputStream.flush();
}
捕获(例外e){
e、 printStackTrace();
logger.error(String.format(“写入输出流错误:%s”,e.getMessage());
}最后{
semaphore.release();
}
}
});
}
}
};
返回新的ResponseEntity(responseBody,HttpStatus.OK);
}
捕获(例外e){
logger.error(String.format(“映射匹配结果错误:%s”,ExceptionUtils.getStackTrace(e));
返回新的响应属性(HttpStatus.BAD_请求);
}
}
它工作得很好,但问题是,如果有多个调用到达此方法,即使我设置了
server.tomcat.threads.max=1,所有调用都将并行运行。在非流式版本中,下一次调用都会等待当前调用完成

在Spring中是否可能有阻塞流式调用?谢谢


编辑:我通过使用只有1个许可证的全局信号量暂时解决了问题,但我认为这不是理想的解决方案。

响应不是由tomcat的请求处理线程处理的,因此将其设置为1将没有帮助,因为它是非阻塞的。另外,只允许对该方法发出一个请求有什么意义?将tomcat设置为只处理整个应用程序的一个请求(这是
server.tomcat.threads.max=1
所做的!)是一个坏主意,它会降低应用程序的性能,或者至少会降低应用程序对多个用户的可用性(即使是一个浏览器已经对一个页面发出最多6个请求以同时下载资源!)。感谢您的评论。不幸的是,每个请求都必须进行大量的批处理,这需要几分钟的时间和大量的内存。要求用户等待回复(我不能异步完成)。我必须一次处理一次请求。该软件位于AKS集群上,因此多个请求将由不同的Kubernetes吊舱处理。我知道这不是一个理想的设置,但这是最好的,我可以考虑的要求。