ARTIFACTORY: How to improve a Large Maven Virtual's Performance in 3 Easy Steps
This article implements the information described in the "Virtual Repository Best Practices" and "Offline backups of remote caches" articles. A very common performance problem can happen with large Maven Virtual repositories. It can be solved with a straightforward procedure.
This is common for Maven in particular because there are a lot of public sources of Maven packages. The advice can also be applied to Virtuals which contain a lot of Remote repositories.
Will this Work for Me?
Do you have a Virtual Repository that aggregates many public package sources? In other words, do you have more than 15 Remote Repositories in 1 Virtual?
If so, yes this advice applies to you!
The performance problem happens when a "mvn install" checks for a package's maven-metadata.xml file. The Maven Virtual repository has to check every Remote Repository for this metadata file, resulting in a lengthy download time:
2023-03-01T12:00:00.000Z|df0b890004ecd3a6|10.0.0.1|jenkins-build-user|GET|/maven-public/com/public/proxy/plugins/proxy-plugin/maven-metadata.xml | 200 |-1| 10453 [10.4 KB] | 10848 [10.8 seconds] |Apache-Maven/3.6.3 (Java 11.0.14.1.101; Linux 3.10.0-1062.12.1.el7.x86_64)
This is due to the concept of "metadata freshness." Artifactory has to check every remote site to answer these questions:
2. If so, is there an updated version?
Whenever you pull a Maven package, Artifactory checks all the remote sites every 5 minutes. This is defined by the Metadata Cache Retrieval Period (MCRP).
If the remote site returns a 404 Not Found, the next check is done after 30 minutes have passed. The 30 minute period is defined by the Missed Cache Retrieval Period.
When a large set of remotes is aggregated by a Virtual, a simple HEAD check on a POM file can take multiple seconds because of this cache miss:
2023-03-01T12:00:00.000Z|df0b890004ecd3a6|10.0.0.1|jenkins-build-user|HEAD|/maven-public/com/public/proxy/plugins/proxy-plugin/proxy-plugin.pom | 404 |-1| 0 [bytes] | 12566 [12.5 seconds] |Apache-Maven/3.6.3 (Java 11.0.14.1.101; Linux 3.10.0-1062.12.1.el7.x86_64)
Increasing both the MCRP and Missed Cache Retrieval Period values means most builds will run more quickly.
Please note the tradeoff here: You are improving overall performance by making update checks less frequent. If frequent update checks are important to your team, implement the "Zap cache" API in important builds or make due with the slower, more frequent checks.
The Steps
1. Copy the remote repository list from the UI
From the Admin -> Repositories -> <Virtual> menu, there is an "Included Repository" list towards the bottom. It shows the repository resolution order, the remotes should be below the locals.
This menu is a text list, and it can be copied with your mouse:
Copy the text and paste it into a text file:
vim remotes-to-update.txt
2. Create this simple BASH script
This script will iterate over each Remote Repository name in the list and raise its settings. Try raising the MCRP to 3,600 seconds (1 hour) and the Missed Cache to 14,400 seconds (4 hours).
vim scripted-fix.sh
!/bin/bash
#
# Note: Update admin:password with an admin account and ID Token
#
cat remotes-to-update.txt | while read ITEM
do
echo "Updating: $ITEM"
curl -u admin:password -X POST -H "Content-type: application/json" --data '{"retrievalCachePeriodSecs":"3600", "missedRetrievalCachePeriodSecs": "14400"}' http://localhost:8082/artifactory/api/repositories/$ITEM
sleep 1s
done
Don't forget to update the URL if you plan to run this externally, "localhost:8082" probably won't work from your laptop or build server.
3. Run the Script
chmod +x scripted-fix.sh; ./scripted-fix.sh
# Expected Output
That's it, you're done! The remote repositories should start to serve requests from their metadata cache more frequently.
Feel free to use cache period numbers that your team is comfortable with, the above settings are a good baseline, but everybody has different needs when it comes to metadata.