繁体   English   中英

从多个客户端上载文件会减慢Java Spring应用程序的速度

[英]File uploads from multiple clients slowing Java Spring application

我有一个带有Java Spring,mysql后端和AngularJS前端的应用程序。 它托管在Amazon ec2 m4.xlarge实例上。

我使用HTML5相机捕获功能来拍照,并通过RESTful Web服务将base64编码的图像和一些其他元数据发送到后端。 在后端,我将base64数据转换为png文件并保存到磁盘,并在MySQL数据库中输入有关文件状态的条目。 在许多用户开始同时上传图像之前,这种方法一直运行良好。 系统中有4000多个用户,在高峰时,大约有1000个并发用户试图同时上传图像数据。 用户太多会减慢我的应用程序的速度,返回任何页面需要10到15秒的时间(通常不到2秒)。 我检查了服务器统计信息,CPU利用率低于20%,并且未使用SWAP内存。 我不确定瓶颈在哪里以及如何衡量。 关于如何解决该问题有什么建议吗? 我知道自动缩放ec2并在后端进行图像数据处理可能会有所帮助,但是在做任何事情之前,我都想找出问题的根本原因。

Java代码来处理base64图像:

/**
 * POST  /rest/upload/studentImage -> Upload a photo of the user and update the Student (Student History and System Logs)
 */
@RequestMapping(value = "/rest/upload/studentImage",
    method = RequestMethod.POST,
    produces = "application/json")
@Timed
public Integer create(@RequestBody StudentPhotoDTO studentPhotoDTO) {
    log.debug("REST request to save Student : {}", studentPhotoDTO);
    Boolean success = false;
    Integer returnValue = 0;

    final String baseDirectory = "/Applications/MAMP/htdocs/studentPhotos/";

    Long studentId = studentPhotoDTO.getStudent().getStudentId();

    String base64Image = studentPhotoDTO.getImageData().split(",")[1];
    byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
    try {
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));

        String filePath = baseDirectory + 'somestring';
        log.info("Saving uploaded file to: " + filePath);

        File f = new File(filePath);
        Boolean bool = f.mkdirs();

        File outputfile = new File(filePath + studentId + ".png");
        success = ImageIO.write(image, "png", outputfile);

    } catch (IOException e) {
        success = false;
        e.printStackTrace();
    } catch(Exception ex){
        success = false;
        ex.printStackTrace();
    }

    if(success) {
        returnValue = 1;
        // update student
        studentPhotoDTO.getStudent().setPhotoAvailable(true);
        studentPhotoDTO.getStudent().setModifiedOn(new Date());

        studentRepository.save(studentPhotoDTO.getStudent());
    }
    return returnValue;
}

这是我的Cloudwatch网络监控的图像

网络输入

更新(06/17/2015):

我正在使用ajp ProxyPass在Apache前端提供Spring Boot Tomcat应用程序。 我试图直接在不使用apache的情况下直接为tomcat应用程序提供服务,这似乎可以显着提高性能。 我的应用程序没有像以前那样放慢速度。 仍在寻找根本原因。

我建议您采用一种能够解决此问题的好的设计,而不是使用技术方法来解决此问题。 我认为,这是完全根据您提供的信息使用的,我认为这是一个设计问题。 为了找到此问题的根本原因,我需要看一下您的代码。

但是到目前为止,一种设计应该是使用在后端处理图像的队列,而在前端,则通知用户其图像已排队处理。 处理完成后,应该说它已被处理(或由于某些错误而未处理)。

如果可以显示代码,我可以尝试找出问题所在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM