WordPress with HyperDB on PHP 7.0

I was configuring WordPress with HyperDB plugin on PHP 7.0 but the only I get were constant 500 errors. As I found here PHP 7.0 is not supported by HyperDB for now – it rely on mysql php extension but in PHP 7.0 there is only mysqli. Helpfully few folks fixed it and it’s possible to use it.

curl -O https://raw.githubusercontent.com/soulseekah/hyperdb-mysqli/master/db.php
mv db.php /var/www/wordpress/wp-content/

And configure it ex. like this:

cat <<DBCONFIG > /var/www/wordpress/db-config.php
<?php
\$wpdb->save_queries = false;
\$wpdb->persistent = false;
\$wpdb->max_connections = 10;
\$wpdb->check_tcp_responsiveness = true;

\$wpdb->add_database(array(
'host'     => "master.db.host",
'user'     => "wordpress",
'password' => "random_password",
'name'     => "wordpress",
'write'    => 1,
'read'     => 1,
));
\$wpdb->add_database(array(
'host'     => "slave.db.host",
'user'     => "wordpress",
'password' => "random_password",
'name'     => "wordpress",
'write'    => 0,
'read'     => 1,
));
DBCONFIG

Now WordPress could handle crash of master database.

Source:
https://www.digitalocean.com/community/tutorials/how-to-optimize-wordpress-performance-with-mysql-replication-on-ubuntu-14-04

Apache – Force caching dynamic PHP content with mod_headers

Normally you want dynamic content to be fresh and not catchable. But sometimes it may be useful to cache it, like when you have website behind reverse proxy. To do this try something like this:

<filesmatch "\.(php|cgi|pl)$">
Header unset Pragma
Header unset Expires
Header set Cache-Control "max-age=3600, public"
</filesmatch>

Source:
http://www.askapache.com/htaccess/speed-up-your-site-with-caching-and-cache-control.html

Running Apache with mod_spdy and PHP-FPM

SPDY is new protocol proposed by Google as an alternative for HTTP(S). Currently Chrome and Firefox browsers are using it as default if available on server. It is faster in most cases by few to several percent. The side effect of using mod_spdy is that it’s working well only with thread safe Apache’s modules. PHP module for Apache is not thread safe so we need to use PHP as CGI or FastCGI service. CGI is slow – so running mod_spdy for performance gain with CGI is simply pointless. FastCGI is better but it’s not possible to share APC cache in FastCGI mode (ex. using spawn-fcgi), so it’s poor too. Best for PHP is PHP-FPM which is FastCGI service with dynamic process manager and could use full advantages of APC. In such configuration I could switch from apache prefork to worker which should use less resources and be more predictable.

Installation

On Squeeze we need to install dot.deb repository – instructions are here: http://www.dotdeb.org/instructions/

Then we could install:

apt-get install apache2-mpm-worker php5-fpm libapache2-mod-fastcgi

Now, mod_spdy – packages are available here: https://developers.google.com/speed/spdy/mod_spdy/ Choose your architecture.

wget https://dl-ssl.google.com/dl/linux/direct/mod-spdy-beta_current_i386.deb
dpkg -i mod-spdy-beta_current_i386.deb

Installation of this package will add automatically a new apt repository for mod_spdy.

If you have Apache’s module for PHP still installed you should remove it (you won’t need in anymore):

apt-get purge libapache2-mod-php5

Configuring PHP-FPM

First I’m changing php-fpm default pool configuration file – edit /etc/php5/fpm/pool.d/www.conf

; I want it to listen on socket, not on port
listen = /var/run/php5-fpm/site1.socket

;uncomment to set proper permission for socket
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

;uncomment and change to - PHP leaks, so kill child after 100 requests
pm.max_requests = 100

; for proper chroot handling we will need also
php_admin_value[doc_root] = /var/www/site1
php_admin_value[cgi.fix_pathinfo] = 0

Now restart php-fpm:

service php5-fpm restart

Connecting Apache with PHP-FPM

In VirtualHost paste this:

<IfModule mod_fastcgi.c>
  Alias /php5.fcgi /var/www/site1/php5.fcgi
  FastCGIExternalServer /var/www/site1/php5.fcgi -socket /var/lib/apache2/fastcgi/site1.socket
  AddType application/x-httpd-fastphp5 .php
  Action application/x-httpd-fastphp5 /php5.fcgi

  <Directory "/var/www/site1/">
    Order deny,allow
    Deny from all
    <Files "php5.fcgi">
      Order allow,deny
      Allow from all
    </Files>
  </Directory>
</IfModule>

Enable needed modules and restart Apache:

a2enmod actions
a2enmod fastcgi
service apache2 restart

SSL

SPDY requires encrypted connection so you need configured SSL (virtualhost running on port 443). Typical configuration for SSL looks similar to this:


# some random stuff - exactly like in you NON SSL configuration :-)
SSLEngine on

SSLCertificateFile    /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.priv.key
SSLCACertificateFile  /etc/ssl/private/ca.crt

Testing

Should work now 🙂
So, use Chromium, enter the site you just configured and then on second tab go to: chrome://net-internals/#spdy. You should see your site there if it’s running on SPDY.
You could also use plugins for Firefox or Chromium to test if site is running on SPDY.

Advertise SPDY on HTTP

When you test if SPDY is working fine (and is faster in your configuration) you could advertise availability of SPDY protocol on your HTTP VirtualHost. Thanks to that when browser supports SPDY it will use it for faster access. To do this just add header in configuration:

Header set Alternate-Protocol "443:spdy/2"

There are more options that could be used, if you need just check docs here.

GearmanManager: wygodne zarządzanie workerami

Niedawno zainteresowałem się usługą Gearman i jedynej rzeczy której mi brakowało to jakiegoś łatwego mechanizmu zarządzającego workerami. Ale jak zwykle okazało się że inni mieli już ten problem i odpowiednie narzędzie istnieje – mowa o GearmanManagerze.

Instalacja GearmanManagera

Aby zainstalować GeramanManagera na serwerze gdzie już mamy Gearmana trzeba wykonać kilka kroków (wcześniej powinniśmy też zainstalować moduł gearmana do php’a):

apt-get install git -y
git clone https://github.com/brianlmoon/GearmanManager.git
cd GearmanManager/install
chmod +x install.sh 
./install.sh

Sam proces instalacji nie jest zbyt skomplikowany:

Detecting linux distro as redhat- or debian-compatible
Where is your php executable? (usually /usr/bin)
/usr/bin
Which PHP library to use, pecl/gearman or PEAR::Net_Gearman?
1) pecl
2) pear
#? 1   
Installing to /usr/local/share/gearman-manager
Installing executable to /usr/local/bin/gearman-manager
Installing configs to /etc/gearman-manager
Installing init script to /etc/init.d/gearman-manager

Install ok!  Run /etc/init.d/gearman-manager to start and stop
Worker scripts can be installed in /etc/gearman-manager/workers, configuration can be edited in /etc/gearman-manager/config.ini

Mamy działającego GearmanManagera. Zalecam przyglądnięcie się plikowi config-advanced.ini bo jest tam kilka opcji, które warto dodatkowo ustawić.

Sprawdzenie działania Geramana i GearmanManagera

Przykład workera można znaleźć tutaj http://brian.moonspot.net/GearmanManager. Po pobraniu go i zapisaniu w pliku /etc/gearman-manager/workers/fetch_url.php możemy ręcznie zakolejkować zadanie dla Geramana:

gearman -f fetch_url -- http://google.pl/robots.txt

Źródło:
https://github.com/brianlmoon/GearmanManager
http://brian.moonspot.net/GearmanManager

Instalacja gearman-job-server 1.0.6 na Debianie Wheezy

Ostatnio trafiłem na ciekawą usługę, która pozwala oddelegować długo trwające zadania z usługi webowej. Mowa o Gearman’ie. Usługa jest o tyle ciekawa że nie narzuca ani języka dla klienta (większość popularnych ma gotowe biblioteki), ani język dla skryptów w tej usłudze nie jest narzucany. Można tę usługę wykorzystać jako most pomiędzy PHP a np. Javą/Pythonem lub do zlecenia zadań z serwera na Linux’ie do wykonania na serwerze Windowsowym (bo np. narzędzia dostępne są tylko dla Windowsa). O innych zaletach można poczytać na stronce więc nie będę przynudzać.
Standardowo zainstalowałem paczkę z repo Debiania i rozbiłem się przy kompilacji modułu z PECL’a – w repo była jakaś prehistoryczna wersja. Postanowiłem uruchomić aktualną wersje 1.0.6 z gałęzi testowej przekompilowując ją na Wheezym (by uniknąć zależności z wersji testowej).

Instalacja gearman’a

Dorzucamy źródła z testing – dzięki temu nie aktualizujemy systemu ale będziemy mogli pobrać świeże paczki źródłowe:

echo "deb-src http://ftp.pl.debian.org/debian jessie main non-free contrib" >> /etc/apt/sources.list
apt-get update

Przygotowujemy katalog roboczy, pobieramy paczki i kompilujemy:

mkdir gearman
cd gearman

apt-get build-dep gearman-job-server -y
apt-get install bzr
apt-get source gearman-job-server
cd gearmand-1.0.6
./debian/rules clean
./debian/rules binary
cd ..
dpkg -i gearman-job-server_1.0.6-2_i386.deb gearman-tools_1.0.6-2_i386.deb libgearman-dev_1.0.6-2_i386.deb libgearman7_1.0.6-2_i386.deb
apt-get install -f -y

Musiałem ręcznie doinstalować bazar (paczka bzr), bo w czasie kompilacji pojawiały się błędy z tym poleceniem – nie jestem pewien na ile jest potrzebne ale oczywiście możemy to posprzątać po skompilowaniu paczek.
P.S. Jestem przekonany że zamiast “rules clean/binary” jest jakieś polecenie, którego powinno się użyć ale nie mogłem sobie go przypomnieć…

Instalacja modułu dla PHP’a

Ponieważ wcześniej zainstalowaliśmy aktualne biblioteki libgearman-dev to instalacja modułu dla PHP powinna być bardzo prosta:

pecl install gearman
echo "extension=gearman.so" > /etc/php5/conf.d/gearman.ini

P.S. W paczkach PHP 5.3 z dotdeb’a można znaleźć już skompilowany moduł dla gearman’a.

Na razie tyle – muszę teraz poszukać jak w wygodny, zautomatyzowany sposób zarządzać skryptami zleconymi do gearman’a.