flyingsaucerproject / flyingsaucer

XML/XHTML and CSS 2.1 renderer in pure Java
Other
1.99k stars 556 forks source link

How to improve tps in multithreading #340

Closed shiyong-1224 closed 2 months ago

shiyong-1224 commented 3 months ago

I am using a ThreadPoolExecutor to execute a pdf rendering task (flying-saucer-pdf:9.1.22 Java 11), here is the main code of each task:

ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);

It performs best when I set corePoolSize = 2 As I increase the corePoolSize, the time consuming of 'layout' and 'createPDF' method increases and the tps decreases. Even if I increased the CPU from 2 cores to 8 cores, it didn't help. so I wonder if there is any resource contention or lock between threads, and how can I improve the tps of single machine

asolntsev commented 3 months ago

@shiyong-1224 Sorry, but I cannot reproduce this issue. When I generate PDFs in parallel threads, they work fast. More threads -> faster generation. Can you create a sample project for reproducing the problem?

shiyong-1224 commented 3 months ago

@asolntsev Thanks for your Reply,here is a sample project https://github.com/shiyong-1224/test-pdf.git

asolntsev commented 3 months ago

@shiyong-1224 Thank you for sharing the project, but ... again, how I could easily reproduce the problem? What script should I run? I assume (from README) that you use JMeter, but you haven't committed any JMeter scripts.

  1. I just executed your code in plain JUnit tests (not in Spring app), and I still don't see a performance degradation in parallel execution.
  2. however, when I run your project (in Spring app), then I see the performance degradation.

Is it possible that the problem is caused by Spring/Tomcat/servlets/etc... ?

Anyway, I've found few candidates for performance improvement in FlyingSaucer. I will release these improvements soon, but not sure it entirely fixes your problem.

shiyong-1224 commented 3 months ago

@asolntsev Sorry I didn't describe it clearly. That is how to reproduce the problem:

  1. run the sample project as Spring web app
  2. curl http://localhost:15000/pdf
  3. then you can I see the time consumed of each execution of PdfUtils.renderPdf() method

I changed corePoolSize from 2 to 8 to 16, and use Jmeter(uploaded a script) to make full use of threads, Then I saw the time consumed increasing by num of threads. I found these 2 methods layout() & createPDF consumed more time. I've read some source codes of these 2 methods, have no idea about the appearance. As for Spring/Tomcat/servlets or any other frameworks, I don't known how they affect the performance of layout() & createPDF Anyway, in my real production environment, I can increase the tps by adding more instances of the pdf service cluster.

asolntsev commented 2 months ago

@shiyong-1224 Hi. Can you check if the problem was fixed in FlyingSaucer 9.9.0?