Change From several extremely generous and useful answers, this question has already been received, it is obvious to me that I did not make the important part of this question clear when I asked it earlier in the morning. The answers I have received so far are about optimizing applications and eliminating bottlenecks at the code level. I know this is more important than trying to get an extra 3 or 5% of your JVM!
This question suggests that we have already done everything we could to optimize our application architecture at the code level. Now we want more, and the next place is at the JVM level and garbage collection; I changed the name of the question accordingly. Thanks again!
We have the basic architecture of the pipeline style, where messages are transferred from one component to another, and each component performs different processes at each stage of the path.
Components live inside WAR files deployed to Tomcat servers. In total, we have about 20 components in the pipeline living on 5 different Tomcat servers (I did not choose the architecture or WAR distribution for each server). We use Apache Camel to create all the routes between the components, effectively forming the “connective tissue” of the pipeline.
I was asked to optimize the GC and overall performance of each server running the JVM (5 in total). I spent several days reading on the GC and tuning performance, and I have a good pen on what each of the different JVM options do, how the heap is organized and how most of the parameters affect the overall performance of the JVM.
My thinking is that the best way to optimize each JVM is not to optimize it as standalone. I “feel” (that as far as I can justify it!), Trying to optimize each JVM locally, not considering how it will interact with other JVMs on other servers (both up and down), will not create a globally optimized solution.
It makes sense for me to optimize the entire pipeline as a whole. Therefore, my first question is: I agree, and if not, why?
To do this, I thought about creating a LoadTester that will generate input and feed it to the first endpoint in the pipeline. This LoadTester can also have a separate “monitor stream” that will check the last endpoint for bandwidth. Then I could do all kinds of processing, where we check the average end-to-end message passing time, maximum throughput before failure, etc.
LoadTester will generate the same message input pattern over and over again. The variable in this experiment will be the JVM parameter passed to each Tomcat server startup parameter. I have a list of about 20 different options that I would like to pass to the JVM, and decided that I can just change their values ​​until I find an almost optimal performance.
This may not be the best way to do this, but it is the best way with which I could design, from what time I was given this project (about a week).
Second question: what does this setting think? How would SO create an “optimizing solution” differently?
Last but not least, I am curious what indicators I could use as a basis for measurement and comparison. I really can only think:
- Find the JVM parameter configuration that provides the fastest average message transit time for messages.
- Find the JVM settings configuration that provides maximum volume throughput without failures on any of the servers.
Any others? Any reasons why these 2 are bad?
After watching the play, I could see how this could be interpreted as a monolithic question, but in fact I ask how SO optimizes the pipeline JVM, and feel free to cut my solution as you like.
Thanks in advance!