High CPU Usage with GroupDocs.Watermark for Java on EC2

I am currently using the GroupDocs.Watermark for Java library in a Java 8 environment, and I have encountered an issue where the CPU usage exceeds 100% on our EC2 when invoking the watermarking service. Below is a brief overview of the code implementation:

@RequestMapping(value = "{fileSecKey}/link.do")
    public ModelAndView link(@PathVariable String fileSecKey
            , @RequestParam(value = "ubiYn", required = false, defaultValue = "N") String ubiYn
            , @RequestParam(value = "inline", required = false, defaultValue = "false") boolean inline
            , @RequestParam(value = "thumbYn", required = false, defaultValue = "N") String thumbYn
            , @RequestParam(value = "reqUsrId", required = false, defaultValue = "USR_ID") String reqUsrId
            , @RequestParam(value = "reqUsrNm", required = false, defaultValue = "USR_NM") String reqUsrNm
            , @RequestParam(value = "reqCorpNm", required = false, defaultValue = "CORP_NM") String reqCorpNm
            , @RequestParam(value = "reqBrchNm", required = false, defaultValue = "BRCH_NM") String reqBrchNm
            , @RequestParam(value = "watermarkYn", required = false, defaultValue = "N") String watermarkYn
            , @RequestParam(value = "useCookieYn", required = false, defaultValue = "N") String useCookieYn
            , HttpServletRequest request
            , HttpServletResponse response) throws Exception {

        String transactionAId = (String) request.getAttribute(TRANSACTION_ID);
        FileItemVO fileItem = fileMgrService.selectFileItemBySecKey(fileSecKey);
        log.info("fileUpload.link.do -info " + transactionAId + " fileSecKey :" + fileSecKey + " FileItemVO is null :" + (fileItem == null));

        String filePath = "";
        if (StringUtils.hasText(fileItem.getRemark())) {
            if (fileItem.getRemark().equals("sal") || fileItem.getRemark().equals("crm")) {
                //ubiReport๋กœ ๋งŒ๋“ค์–ด์ง„ PDF์ธ ๊ฒฝ์šฐ
                if (ubiYn.equals("Y")) {
                    filePath = UploadPathType.valueOf(fileItem.getRemark()).getUploadPath() + fileItem.getFileData() + "." + fileItem.getFileTp();
                } else {
                    filePath = UploadPathType.valueOf(fileItem.getRemark()).getUploadPath() + fileItem.getFileData();
                }
            } else {
                filePath = UploadPathType.valueOf(fileItem.getRemark()).getUploadPath() + fileItem.getFileData();
            }
        } else {
            filePath = fileItem.getFileData();
        }

        log.info("file requested : " + filePath);
        DownloadVO downloadVO = null;
        File file = new File(filePath);
        //ํŒŒ์ผ์ด ๋ฏธ์กด์žฌ ํ•˜๋ฉด(๋ฐ์ดํ„ฐ๋งŒ ์กด์žฌ)
        if (!file.exists()) {
            downloadVO = FileUtils.getWdmsImageResource(fileItem, resourceLoader, FileUtils.ResourceFilePathType.DEL_FILE_IMG_PATH);
        }else {
            //์ธ๋„ค์ผ ํ˜ธ์ถœ ์ด๋ฉด ์ธ๋„ค์ผ ์ด๋ฏธ์ง€ ๋Œ€์ƒ ํ™•์ธ ํ›„ ์š”์ฒญ
            if (ThumbnailGeneratorUtil.IS_OK_IMG_CONTENT_TYPE.contains(fileItem.getFileTp())//์ด๋ฏธ์ง€ ๋Œ€์ƒ
                    && "Y".equals(thumbYn)) {
                downloadVO = thumbnailGeneratorUtil.reImgThumbFile(fileItem, filePath, resourceLoader);
            } else {
            	// watermarked file outputFilePath
            	String outputFilePath = filePath;

            	// ์›Œํ„ฐ๋งˆํฌ ์—ฌ๋ถ€ํ™•์ธ
            	if("Y".equals(watermarkYn)) {           
            	    long startTime = System.currentTimeMillis(); // ์‹œ์ž‘ ์‹œ๊ฐ„ ๊ธฐ๋ก

            		// PDF ํŒŒ์ผ์ผ ๊ฒฝ์šฐ ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€
            		if ("application/pdf".equalsIgnoreCase(fileItem.getFileTp())) {
            			outputFilePath = watermarkService.addWatermarkToPdf(filePath, fileItem, reqUsrNm, reqUsrId, reqCorpNm, reqBrchNm);
            		}            		
            		// IMAGE ํŒŒ์ผ์ผ ๊ฒฝ์šฐ ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€
            		else if (fileItem.getFileTp().startsWith("image/")) {
            			outputFilePath = watermarkService.addWatermarkToImage(filePath, fileItem, reqUsrNm, reqUsrId, reqCorpNm, reqBrchNm);
            		}
            		
            	    long endTime = System.currentTimeMillis(); // ์ข…๋ฃŒ ์‹œ๊ฐ„ ๊ธฐ๋ก
            	    long duration = endTime - startTime; // ์‹คํ–‰ ์‹œ๊ฐ„ ๊ณ„์‚ฐ

            	    log.info("์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€ ์ž‘์—… ์‹คํ–‰ ์‹œ๊ฐ„: " + duration + "ms");
            		
//                // PPT ํŒŒ์ผ์ผ ๊ฒฝ์šฐ ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€
//                if ("application/vnd.ms-powerpoint".equalsIgnoreCase(fileItem.getFileTp()) ||
//                	    "application/vnd.openxmlformats-officedocument.presentationml.presentation".equalsIgnoreCase(fileItem.getFileTp())) {
//                	outputFilePath = watermarkService.addWatermarkToPpt(filePath, fileItem, reqUsrNm, reqUsrId, reqCorpNm, reqBrchNm);
//	            	}
            	}
                
                //์ธ๋„ค์ผ ์š”์ฒญ์ด ์•„๋‹Œ ํŒŒ์ผ
                downloadVO = new DownloadVO();
                // ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•œ ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์–ด ํ•ด๋‹น ํŒŒ์ผ์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ์ง์ ‘ ํ™•์ธํ•˜๋„๋ก ์ˆ˜์ •
                long fileSize = (new File(outputFilePath)).length();
                downloadVO.setFileName(fileItem.getFileNm());
                downloadVO.setFilePath(outputFilePath);
                downloadVO.setFileSize(fileSize);
                downloadVO.setContentType(fileItem.getFileTp());
            }
        }
        
        // ํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋‹ค์šด๋กœ๋“œ ์ฒ˜๋ฆฌ
        if (downloadVO != null && "Y".equals(useCookieYn)) {
            // Set-Cookie ํ—ค๋” ์ถ”๊ฐ€
        	response.setHeader("Set-Cookie", "fileDownload=true; path=/; Domain="+getDomain()+"; SameSite=None; Secure");
        }

        ModelAndView mav = new ModelAndView("downloadView");
        mav.addObject("FILE_INFO", downloadVO);
        mav.addObject("INLINE", inline);
        response.setHeader("Content-Type", fileItem.getFileTp() + "; charset=UTF-8;");

        return mav;
    }
    public String addWatermarkToImage(String filePath, FileItemVO fileItem, String userName, String userId, String corpNm, String brchNm) {
        String outputFilePath = filePath;
        ImageLoadOptions loadOptions = new ImageLoadOptions();
        Watermarker watermarker = null;

        try {
            watermarker = new Watermarker(filePath, loadOptions);

            String dateFormat = new SimpleDateFormat("yy-MM-dd").format(new Date());
            String baseText = String.format("%s_%s_%s_%s", corpNm, brchNm, userName, dateFormat);

            TextWatermark footerTextWatermark = new TextWatermark(baseText, new Font("BMWTypeNext Kr TT Regular", 15));
            footerTextWatermark.setForegroundColor(Color.getGray());
            footerTextWatermark.setHorizontalAlignment(HorizontalAlignment.Left);
            footerTextWatermark.setVerticalAlignment(VerticalAlignment.Bottom);
            footerTextWatermark.setOpacity(0.8);

            watermarker.add(footerTextWatermark);

            // ํŒŒ์ผ ํ™•์žฅ์ž ์ถ”์ถœ
            String extension = "";
            int i = fileItem.getFileTp().lastIndexOf('/');
            if (i > 0) {
                extension = fileItem.getFileTp().substring(i + 1).toLowerCase();
            }

            outputFilePath = filePath + "_watermarked." + extension;
            watermarker.save(outputFilePath);

        } finally {
            if (watermarker != null) {
                watermarker.close();
            }
        }

        return outputFilePath;
    }

I would appreciate any guidance or recommendations you could provide to help reduce the CPU usage during the watermarking process. Are there any specific optimizations or configurations within the GroupDocs.Watermark library that could help mitigate this issue?

Thank you for your assistance.

1 Like

@Kim_KyungMok

To better assist you, could you please clarify a couple of points?

  1. Are you experiencing high CPU usage with specific files, or does it occur with all files when using the watermarking service?
  2. If itโ€™s with specific files, could you share those files with us? This will help us in diagnosing the issue more effectively.
  3. Do you have a valid GroupDocs.Watermark for Java license, and have you applied it in your project, or are you just evaluating the API in trial mode?
  4. Additionally, could you provide the details of your development environment on the EC2 instance? Specifically, EC2 instance type, and any relevant configurations.
  5. Please share the GroupDocs.Watermark for Java API version that you are using.