Very Siberian's picture

Hi, everyone! For a fairly busy TKL WordPress site, what would be the recommended reboot schedule for server maintenance? I have been rebooting the server manually only when the site seems to be loading extra slowly, but I'm interested in what would be considered best practice. Second, is there a way to automate server reboots at a fixed time and interval (e.g., once per week at 2:00 AM Sunday)?

Thanks,

Very Siberian / Rob

Forum: 
Jeremy Davis's picture

In a perfect world, where everything works exactly as it should, you would never need to reboot a server, regardless of how busy it is. Obviously that is excluding having to reboot to apply kernel updates (a reboot is required to use the new kernel).

Obviously though, we don't live in that universe. My guess is that there is a memory leak somewhere in your site (most likely in a WP plugin). Assuming that I'm right, actually finding (and fixing) the real culprit would be ideal. But I suspect that that may be quite tricky, not to mention time consuming.

My first recommendation would be to disable (and remove) as many WP plugins as possible (i.e. obviously any that you aren't using or don't need). Then monitor how it goes. If it still slows down after time, then double check the resource usage (I suggest installing 'htop' and running that in one terminal session, while you run commands in the other).

If I'm on the right track, then the memory usage should be quite high. And restarting Apache ('systemctl restart apache2') should resolve it. If it's RAM usage that's slowing things down and restarting Apache resolves the issue, then one thing that you could try is tweaking the systemd unit to die (and get restarted) when it hits a memory limit. Here's an example tweak (limiting it to 80% RAM usage and kill (and restart it) if it hits the limit):

mkdir -p /etc/systemd/system/apache2.service.d
cat > /etc/systemd/system/apache2.service.d/override.conf <<EOF
[Unit]
MemoryMax=80%

[Service]
Restart=on-failure
EOF
systemctl restart apache2

You can double check that the config changes are being used like this:

systemctl cat apache2

It should return something like this:

# /lib/systemd/system/apache2.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=https://httpd.apache.org/docs/2.4/

[Service]
Type=forking
Environment=APACHE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/sbin/apachectl start
ExecStop=/usr/sbin/apachectl graceful-stop
ExecReload=/usr/sbin/apachectl graceful
KillMode=mixed
PrivateTmp=true
Restart=on-abort

[Install]
WantedBy=multi-user.target

# /etc/systemd/system/apache2.service.d/override.conf
[Unit]
MemoryMax=80%

[Service]
Restart=on-failure

If the load is instead on your DB (i.e. MariaDB; also referred to as MySQL) then you might benefit from DB object caching (not page caching or opcode caching; they're different things). I wouldn't expect that to actually be the cause of slowdowns over time, but it might help reduce the need for restarts. Memcache (or Memcached) are common tools that can do that, but there are others and I can't offer any WP specific advice. To install an object cacher, you'll need to install the caching daemon/service, the relevant php module and a WordPress plugin and/or WP config.

I'm happy to discuss further, but I doubt that this is directly relevant to your current issue.


But to actually answer your explicit question about restarting/rebooting on a schedule:

If I'm completely on the wrong track above (which is quite possible - I'm only guessing after all) then you could create a simple cron job to restart Apache (or whatever service - or reboot completely) on a time frame. The simplest way to create a cron job that you wish to run daily/weekly/etc is to just drop a(n executable) script into the relevant 'cron.' directory. E.g. say you wish to restart Apache weekly, put it in /etc/cron.weekly:

cat > /etc/cron.weekly/restart-apache 

The name and the command to run can be changed as appropriate, including rebooting the server instead ('/usr/sbin/reboot'). Also, to change how often the script runs, change the timing. I.e. to run it daily, move to /etc/cron.daily/.

If you know what the peak is and whether it's CPU or RAM causing the slowdown, then you could check for that condition first, then only restart if the condition is met. If you go that path, then I suggest running the cron job much more often (perhaps hourly?).

If you want to have more specific control over when/how often it runs, add your script to /etc/cron.d directory instead. But note that the format of cron.d scripts is the same as crontab format (i.e. different to the example normal bash script I dropped in /etc/cron.weekly above). So instead of a script, you need to note when a command will run. With a simple command, you can put it directly in the cron.d script. If it's a couple of commands, you can string them together, separating "lines" with a semi-colon (or logic conditions, i.e. '&&'/'||'). If it's more complex and includes more than a couple of commands, I'd suggest putting your commands in a (separate) script in /usr/local/bin (and call your script, using it's full path, from your cron.d job file).

For more details about crontab format, please see the Debian crontab man page. A super handy online tool for generating the time code (at the start of the line) can be found at crontab.guru/.

I hope that helps.

Very Siberian's picture

Dear Jeremy,

Thank you very, very much for this detailed and thoughtful reply! You have given me many things to investigate and consider, which I look forward to doing soon. I will work to unpack all of these excellent suggestions and see which ones apply.

Thanks your excellent support,

Rob

Add new comment