Nedavno je Crometeo portal počeo pokazivati znakove “umora”. Preuzeli smo brigu za njega i prebacili ga na meteoadriatic server. Odlučili smo s vama podijeliti koje smo sve korake poduzeli kako bi portal ponovo počeo raditi živahno i sretno. Možda će ove upute nekome pomoći da optimizira svoj web, posebice ako koristi wordpress.

Najprije smo na meteoadriatic serveru kreirali openvz container za Crometeo. Kreiranom VPS-u smo dodijelili i više nego dovoljne resurse: 2 CPU jezgre, 6GB RAM-a i 512MB swap-a te 250GB diskovnog prostora. U VPS-u smo instalirali Centos 7 x86_64 minimal OS. Na njega smo instalirali VestaCP s nginx web serverom, php-fpm PHP serverom, mariadb database serverom i standardnim ostatkom “društva” – exim, dovecot, vsftpd…

Za keširanje PHP sadržaja u memoriji instalirali smo APCu: https://pecl.php.net/package/APCu/4.0.11

Sa starog servera preuzet je Cpanel-ov full backup, koji je importiran pomoću izvrsne skripte za import cpanel accounta u VestaCP okruženje:

https://forum.vestacp.com/viewtopic.php?t=11075

Mi smo koristili verziju 0.4 koja je odradila posao importa datoteka, baza, e-mailova i raznih postavki potpuno besprijekorno. Ovime smo uštedjeli 200 dolara godišnje, izbacivanjem Cpanel-a iz priče.

Nginx mora znati kako raditi redirekcije WordPress-ovih “seo URL-ova”, pa je zbog toga u nginx.conf nužno dodati:

location / {
        try_files $uri $uri/ /index.php?$args;

Sljedeći korak bio je interno testiranje portala i foruma, što je prošlo relativno OK. No tu smo odlučili napraviti potpuni update, s obzirom da je WordPress instalacija iz nekog razloga bila neažurirana praktički godinama. Kreirali smo novi korisnički račun u VestaCP sučelju, kopirali datoteke, kreirali bazu, “dumpali” i importirali podatke u bazu te napravili update na testnoj instalaciji. Poneki instalirani plugin unutar wordpress-a je pritom prestao raditi, ali ništa značajno. Kako se pokazalo da će update biti moguć i relativno jednostavan, zamijenili smo datoteke u “pravom” korisničkom računu sa ažuriranima iz testnoga i time je WP instalacija postala spremna za prihvat najnovije baze sa starog servera.

Pri prebacivanju DNS-a na nove DNS poslužitelje, “dump-ali” smo zadnje baze weba i foruma i kopirali ih na novi server:

mysqldump imebazeweba > imebazeweba.sql
mysqldump imebazeforuma > imebazeforuma.sql
scp -P <sshport> *.sql root@ipnovogservera:/direktorij/odredišta

te uvezli baze na novom serveru:

mysql /direktorij/odredišta/imebazeweba < imebazeweba.sql
mysql /direktorij/odredišta/imebazeforuma < imebazeforuma.sql

Nakon uvoza baze iz neažuriranog WordPress-a u ažurirani, potrebno je napraviti update baze browserom:

http://example.com/wp-admin/upgrade.php

Kako bi baza nešto brže radila, konvertirali smo sve myisam tabele u innodb verzije iz mysql prompt-a:

ALTER TABLE table_name ENGINE=InnoDB;

Ili koristeći phpmyadmin.

Optimizirali smo my.cnf; aktualni sadržaj:

[mysqld]
skip-name-resolve
symbolic-links=0

skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 32M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 16
query_cache_type = 1
query_cache_limit = 256K
query_cache_min_res_unit = 2k
query_cache_size = 40M
thread_concurrency = 4
tmp_table_size= 64M
max_heap_table_size= 64M

innodb_file_per_table
innodb_fast_shutdown=1
innodb_buffer_pool_size=512M
aria_pagecache_buffer_size=32M

max_connections=250
max_user_connections=100
wait_timeout=15
interactive_timeout=50

 

Optimizacija mysql servera time nije završena; ovo je samo početna verzija konfiguracije. Daljnja optimizacija će se uraditi koristeći odličan http://mysqltuner.com/ alat nakon što web dođe pod nešto veće opterećenje tijekom idućih snježnih ciklona 🙂

Kad smo već kod optimizacije baze, iz nje smo izbrisali nepotrebnu tabelu wp_cn_track_post koja je poprimila zavidnu veličinu korištenjem nekog od statističkih pluginova u prošlosti. Također smo sa diska izbrisali sve nepotrebne logove i slično smeće, kao npr:

cd public_html
find . -name "error_log" -type f -delete

Problem s kojim smo se susreli bio je sam WordPress odnosno njegovi pluginovi. Nakon što je broj posjetitelja prešao 30-tak, load servera se popeo na nevjerojatnih 50-tak i web je postao praktično neupotrebljiv. Vrijeme je bilo za traženje krivca. Prvi korak je bio napraviti backup direktorij za pluginove i prebaciti ih sve iz wp_contents/plugins u backup direktorij. Load je odmah pao na minimalne vrijednosti, što je bio znak da je neki od plugina stvarao problem. Vraćanje natrag jednog po jednog iz backup direktorija i praćenjem load-a servera, dovelo je do krivca. Riječ je o pluginu “WP Photo Album Plus” čijim paljenjem load servera skače u nebo, a gašenjem pada na upotrebljive vrijednosti. Nakon što smo se njega riješili, idući korak bio je instalacija P3 plugina:

https://wordpress.org/plugins/p3-profiler/

Ovaj plugin daje informacije o tome koliko vremena je potrebno svakom pojedinom instaliranom pluginu za njegovo izvršavanje pri učitavanju stranica portala. Time smo dobili uvid u preostale “gladne” plugine, te smo eliminirali većinu takvih, kao i sve one plugine koji nemaju neku bitnu funkciju bez obzira na rezultat P3 analize. Minimiziranje broja aktivnih pluginova na apsolutni nužni minimum obično je najvažniji korak u optimizaciji WordPress instalacije. Zatim smo zamijenili cache plugin, brisanjem starog i instalacijom WP Super Cache te finim podešavanjem iste i usklađivanjem s nginx konfiguracijom:

location / {
 # WP Super cache:
        try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html
        $uri $uri/ /index.php;
# Without WP Super cache:
        #try_files $uri $uri/ /index.php?$args;

Još smo u WordPress dodali “APCu Object Cache Backend” kako bi optimizirali instalaciju za APCu framework. Ovdje nismo baš sigurni radi li ovaj dodatak išta korisno ili WP Super Cache pokriva već “suradnju” s APCu, što je ipak jedna od tema za neko buduće istraživanje.

https://wordpress.org/plugins/apcu/

Krajnji rezultat svih ovih zahvata je smanjenje server load-a na prosječnih ~0.5 pri stotinjak istovremenih unique visitora. Razlika u odnosu na ~50 je očita 🙂