What are the potential consequences of continuing high server usage, and what steps can we take to mitigate these risks?

Hello @darrylnuydaph

Based on our case when handling client with thousand of journal in our hosting infrastructure. For example with one of very active OJS that have 32 CPUs (dedicated server) need much more configuration that using the default configuration provided by the default configuration. Here what we can share :

  1. OJS relies on multiple branches of subqueries, which can significantly increase database resource consumption, leading to performance bottlenecks during various operations. Our testing has shown that the most efficient storage engine for OJS is InnoDB, as it provides better transaction handling and concurrency control compared to other options.

To maintain optimal performance, it is crucial to ensure collation consistency across all database components. This includes aligning MySQL or MariaDB’s default collation with the collation used by OJS for database connections. A mismatch in collation settings, especially under heavy loads, can result in unnecessary processing overhead, slowing down queries and increasing the strain on the database server.

You also need to revisit your my.cnf for configure the optimal configuration for your database engine. You can use this free tool to help you to analyze the culprit :
https://github.com/major/MySQLTuner-perl

  1. You should also regularly watching to the access log of the journal. This is to make sure that you can block that some traffic that intended to scan your OJS for bad intention such as scanning some wordpress path in your OJS that does not exist. Although this turn out 404, the 404 actually such the resource of webserver to provide such response. You better return 444 to significantly lower your webserver response. This online web scanning also become a threat for your journal as if it found some unintended file located in your public_html can be exposed to security such as backup.bak or config.txt to your journal path. You need to disable some extension to be scanned in your webserver. You can also complement this with fail2ban that automatically block the IP that doing malicious traffic to your OJS.

  2. Static caching, you need to enable static caching in your OJS installation. For example if you are using Apache, you can use the mod_expires and mod_headers modules. These modules allow you to set expiration dates and cache-control headers for static files, which can improve website performance by reducing the number of requests made to the serve you can use this in your .htaccess file :

# Enable caching for static files

<IfModule mod_expires.c>

ExpiresActive On

# Default expiration time: 1 day

ExpiresDefault "access plus 1 day"

# Cache images for 1 month

ExpiresByType image/jpeg "access plus 1 month"

ExpiresByType image/png "access plus 1 month"

ExpiresByType image/gif "access plus 1 month"

ExpiresByType image/webp "access plus 1 month"

ExpiresByType image/svg+xml "access plus 1 month"

ExpiresByType image/x-icon "access plus 1 month"

# Cache CSS and JavaScript for 1 week

ExpiresByType text/css "access plus 1 week"

ExpiresByType application/javascript "access plus 1 week"

ExpiresByType application/x-javascript "access plus 1 week"

# Cache fonts for 1 month

ExpiresByType font/ttf "access plus 1 month"

ExpiresByType font/otf "access plus 1 month"

ExpiresByType font/woff "access plus 1 month"

ExpiresByType font/woff2 "access plus 1 month"

ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# Cache other static files for 1 day

ExpiresByType text/html "access plus 1 day"

ExpiresByType application/pdf "access plus 1 day"

ExpiresByType application/x-shockwave-flash "access plus 1 day"

</IfModule>

# Set Cache-Control headers

<IfModule mod_headers.c>

<FilesMatch "\.(ico jpe?g png gif webp svg css js woff2? ttf otf)$">

Header set Cache-Control "public, max-age=2592000, immutable"

</FilesMatch>

</IfModule>

If you are using Nginx you can use this :

|location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|ttf|eot|svg|mp4|webp|webm|ogg|mp3|wav|zip|tar.gz)$ {

expires max;

add_header Cache-Control "public, max-age=31536000, immutable";

}|

By using above configuration, you can make sure that any additional request is handled by cached version of static file by your webserver in which will make the response process much more efficient.

  1. Protecting your OJS with SPAM. For minimal effort you should make sure that you have installed the Google Recaptcha in your registration for to make sure that your journal not become bloated with user that will also make the process of retrieving the list of user become resource intensive. You can also read this useful post to removing spam user in your database (caution we never tested this as usually technical team is handled by specialist personil in our company)

https://forum.pkp.sfu.ca/t/strategies-for-cleaning-spam-users-from-ojs3-databases/94801

https://forum.pkp.sfu.ca/t/collaborative-list-of-spam-user-patterns/65190

  1. If you need more customization you can also need to setup micro caching in your Nginx to make sure that it will reduce much of the process of retrieving content fro the database and PHP processing as it will get the content from the static file kept by Nginx using their micro cache alogarithm. You can read on how to implement nginx micro cache please read here :
    https://blog.nginx.org/blog/benefits-of-microcaching-nginx

However, using this strategy have a disadvantages. If you have many activity in the OJS, your should manually free up the static file created by Nginx. (This is the reason the approach is no longer viable for our infrastructure as we have created OJT Blazing Cache to handle this issue on overall of our clients).

Other tips :
You should also monitoring the optimal configuration for your PHP-FPM (static, dynamic, on demand), note that we don’t have silver bullet tips for this as this will be unique based on the CPUs and Memory that you have in your server. Look something in your PHP Log some like this line :
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it.

The PHP status page as explained in this page will be your friend in analyzing the optimal configuration of the PHP :

https://statuslist.app/uptime-monitoring/guides/php-fpm-status-page/#:~:text=Open%20http%3A%2F%2F127.0.0.1,statistics%20and%20per-process%20stats

This resource will be useful :
https://geoligard.com/a-deeper-dive-into-optimal-php-fpm-settings. If you have better knowledge on server we also recommend using Redis on configure it as session caching.

On our case doing monitoring is regular process that should be done to make sure that there is no bottleneck in the process of OJS, such as regularly removing some spammy submission and user and other activity.

I hope this will be useful for you.

Regards
Hendra
OJT Team

2 Likes