P mint performancia (és mint PHP)

Néha úgy hozza a sors, hogy az embernek be kell piszkolnia a kezét. Apache-al, PHP-val, és mindennel ami ezzel jár.

Egy web szerver készítése általában egyszerű feladat.

apt install apache2
apt install php

A bonyodalmak általában ez után következnek, mivel ami ez után történik produkcióban az meglehetősen lassú, és erőforrás igényes. Mint régi új szerver tulajdonos meglepődve konstatáltam, hogy egy normális weboldal betöltése eltart 3 másodpercig, ami bár nem sok idő (főleg egy kazettás töltéshez képest a c64-en), de általában ezzel már nem vagyok túl elégedett.

Hogy ez ne így legyen ahhoz az alábbi dolgokat kell tenni:

Kezdjük az apache-al, ami alapesetben preforkol, de az lassú, főleg ha virtualizált környezetekről van szó, célszerűbb előre létrehozni kiszolgáló szálakat, és thread-eket. Ehhez mpm módot kell váltani. Itt lehet event-et is használni, de nekem a worker alapú megoldás optimálisabb, mivel egyszerűbb és nem számítok nagy egyidejű lekérdezésre:

a2dismod mpm_prefork
a2enmod mpm_worker

Ez előtt a php modult is ki kell kapcsolni. A worker alapú megoldással az alap php modul általában nem működik, mivel nem thread safe (Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP). De ez nem is akkora nagy probléma, mivel php terén is érdemes már a kezdetek kezdetén perspektívát váltani, és telepíteni a php-fpm-et:

apt install php-fpm
a2enmod proxy_fcgi
a2enconf php8.2-fpm

Ezek után a php beállításokat már az fpm-es php.ini-ben érdemes szerkeszteni (/etc/php/8.2/fpm/php.ini ). Ha ezzel megvagyunk akkor még egy opcache telepítést is érdemes megtenni.

apt install php-opcache

A telepítés után a beállítások itt találhatók: /etc/php/8.2/fpm/conf.d/10-opcache.ini

Az én beállításaim valahogy így néznek ki a teszt site-on:

zend_extension=opcache.so
opcache.jit=on
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=240
opcache.validate_timestamps=1

Érdemes továbbá a PHP által kezelt objektumokat perzisztens módon tárolni, pl. memcached-ben.

apt install memcached

A konfiguráció itt található: /etc/memcached.conf de nagyon nem kell bántani, talán a memória méretét érdmes megemelni 127 mb-ra (alapból 64)

service restart memcached
apt install php-memcached
apt-get install php-pear php-dev zlib1g-dev
pecl channel-update pecl.php.net
pecl install memcache

Php.ini-be fel kell venni: extension=memcache.so majd újra kell indítani az fpm php-t.

WordPress plugin-ből érdemes telepíteni az alábbit:

Memcached Object Cache

Így majd kapunk értesítést a wordpres-sen belül, ha esetleg új verzió lenne. Sikeres telepítés után kézzel kell átmásolni a object-cache.php fájlt a /wp-content/plugins/memcached könyvtárból a wp-content könyvtárba. Majd felvenni a WP_CACHE_KEY_SALT változót a wp-config.php-be (a plugin leáírsa – readme.txt – alapján)

Ha működik a dolog, akkor a Query monitor Overview fülén tudjuk majd ellenőrizni:

Ha ezzel mind megvagyunk nincs más dolgunk, csak a wordpress oldalon is körülnézni egy kicsit. Itt nem érdemes kézzel matatni a dolgokban, nagyszerű plugin-ek vannak, amik megteszik ezeket helyettünk. Én az alábbiakra tettem le a voksom:

Query Monitor – hogy lásd mi történik

Memcached Object Cache – a php objektumok memcached-ben történő tárolásához

WP Rocket – a legenerált oldalak gyorsítása, és további optimalizálások (css, js minify, stb.)

Smush – kép tömörítés és konverzió webp formátumra (és igény esetén átméretezés adott limitre)

Ha mindent jól csináltunk, akkor egy viszonylag gyenge szerveren (Intel Pentium Processor E6700 és 1 Gb memória), az alábbit kellene látunk egy Elementor által generált oldal esetén.

Ui: eredetileg egy oldalbetöltés 3s volt…

Svn pre-commit hook and conflict markers

Előfordul néha, hogy a nagy lelkesedésben conflict makereket tartalmazó fájlt commitolnak a fejlesztők a repository-ba. Ez nem túl gyakori hiba, de azért tud kellemetlen lenni. Keresgettem egy kicsit, de nem találtam nekem tetsző script-et, ezért írtam egyet.

 

SVNLOOK=/usr/bin/svnlook
for x in `$SVNLOOK changed "$REPOS" -t "$TXN"`; do
 if [ "$updated_file" == true ]; then
    mimetype=`$SVNLOOK propget "$REPOS" svn:mime-type -t "$TXN" "${x}" 2>/dev/null`
    #ignore binary files
    if [ -z ${mimetype} ]; then
      if $SVNLOOK cat -t "$TXN" "$REPOS" "${x}" | grep -qE '^+?(<<<<<<<|>>>>>>>)'; then
        echo "Commited conflict marker detected, commit rejected!" 1>&2 && exit 1
      fi
    fi
    updated_file=false
    continue
 else
    if [ "$x" = "U" ]; then
      updated_file=true
    fi
 fi
done
set -e

Postfix + google apps

Google apps-ban van lehetőség SMTP Relay szerver engedélyezésére. Ez akkor jó, ha például olyan helyről szeretnénk levelet küldeni, ami nem rendelkezik Google Apps felhasználóval, például szerverekről.

Ezt a Google Apps adminisztrátori felületén lehet megtenni:

Google Apps -> Settings for Gmail -> Advanced Settings -> General Settings

SMTP relay service

Itt érdemes bekapcsolni az alábbi két opciót:

Only accept mail from the specified IP addresses – csak megadott helyekről fogadjon el leveleket

Allowed senders: Any addresses (not recommended) – onnan viszont bármilyen címről

 

Be is állítottam mindent, de a google SMTP szervere folyamatosan eldobálta a levelet, mert valamiért a postfix mindig csak a szerver nevét (pl. root@server) rakta bele a feladó mezőbe, amit a google annak ellenére sem szeret, hogy beállítottuk, hogy szeresse…

A végső megoldást az alábbi hack jelentette:

A /etc/postfix könyvtár alá létrehoztam egy sender_canonical nevű fájlt, aminek a tartalma:

/^(.*@).*$/     ${1}server.voji.hu

Módosítottam továbbá a /etc/postfix/main.cf-et:

sender_canonical_maps = regexp:/etc/postfix/sender_canonical
relayhost = smtp-relay.gmail.com:25

Ezek után már csak ki kellett generálni a sender_canonical-hoz tartozó .db fájlt:

postmap sender_canonical

valamint újrarúgni a postfix-et:

sudo postfix reload

 

És már csak egy gyors teszt volt hátra:

echo "Test mail from postfix" | mail -s "Postfix test" voji@voji.hu

 

Mindeközben a /var/log/mail.log fájlban:

Sep 10 14:44:20 server postfix/smtp[11752]: 98D866567C3: to=<voji@voji.hu>, relay=smtp-relay.gmail.com[173.194.65.28]:25, delay=0.7, delays=0.34/0/0.26/0.09, dsn=2.0.0, status=sent (250 2.0.0 OK 1410353060 q15sm45749wij.3 – gsmtp)

Sep 10 14:44:20 adsrv2 postfix/qmgr[11744]: 98D866567C3: removed


Tadaaam.

 

Ui: azt, hogy a postfix által küldött levelek normális feladóval rendelkezzenek biztos el lehet érni ennél kultúráltabb módon  is, de egyenlőre ennél jobb megoldást nem találtam (pedig próbálkoztam midnenféle myorigin = /etc/mailname-el és társaival is)

 

 

Selenium headless test

A selenium egy zseniális eszköz, én személy szerint nem csak tesztelésre, hanem folyamat automatizálásra is egyre többet használom. Néha egyszerűen x nélkül szeretném használni, hogy csinálja meg amit szeretnék, a többi dolog nem is érdekel.

Ehhez az alábbi dolgok szükségesek:

  • firefox (apt-get install firefox)
  • java (apt-get install default-jre)
  • selenium, és selenium RC (lásd később)
  • egy két csomag, hogy fusson a firefox x nélkül (apt-get -y install xvfb x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic libstdc++5 xserver-xorg-core xauth dbus-x11)

Első lépésként bármilyen gépen el kell készíteni magát a teszt esetet. Ehhez a firefox alá fel kell telepíteni a selenium plugint, amiben a record-al felvehetjük amit csinálunk, majd menthetjük. Fontos, hogy nekünk nem csak egy teszt esetre (test case), hanem egy test suite-ra is szükségünk lesz. Tehát először mentsük a tesztesetet (File – Save Test Case) majd a hozzá tartozó Test Sutie-ot is (File – Save Test Suite).

Ezek után irány a linux, ahol az alábbi script-el tudjuk elrúgni a tesztet:

#!/bin/sh
Xvfb -fp /usr/share/fonts/X11/misc/ :22 -screen 0 1024x768x16 2>&1 &
export DISPLAY=:22
java -jar selenium-server-standalone-2.42.2.jar -htmlSuite "*firefox" "http://192.168.2.1" "rrestart_suite.html" "results.html"

A fenti példában:

  • “http://192.168.2.1” – az oldal címe, amint a tesztesetet le fogja futtatni
  • “rrestart_suite.html” – a test suite neve
  • “results.html” – ebbe a fájlba kerülnek naplózásra futási eredmények

Egyébként a seleniumot meg lehet hajtani java programból is, ami egy sokkal érdekesebb téma(ez által lehet pl. excel adatforrás alapú tömeges tesztelést végezni). Ha lesz időm, talán arról is készül majd egy rövid cikk.

Oracle 11g 64 bit telepítése ubuntu 12.04 64 bit alá

Az Oracle céget és piacvezető alkalmazásukat elég jól jellemzi, hogy az ubuntu és minden más normális linux disztribúció támogatása kimerül abban, hogy tedd redhat-ra mert az a supportált. Oracle adatbázis miatt redhat-et telepíteni pedig több mint nevetséges.

Az ubuntura történő telepítés nem is olyan bonyolult, csak rá kell jönni a telepítő (és a borzasztó oracle telepítést végző script halom) működésére.

A telepítő két dolgot csinál valójában:

  1. kimásolja az oracle fájlokat
  2. sok make fájlal, és elképzelhetetlenül sok (és értelmetlen) változó segítségével lefordítja a bináris dolgokat

Az első lépésen viszonylag könnyen felül lehet emelkedni, a neten megvan hozzá minden, én csak kigyűjtöttem egy helyre.

Kell egy kevés dependencia, hogy egyáltalán elinduljon a telepítés:

sudo apt-get install ksh less lesstif2 lesstif2-dev lib32z1 libaio1 libaio-dev \
libc6-dev libc6-dev-i386 libc6-i386 libelf-dev libltdl-dev libmotif4 \
libodbcinstq4-1 libodbcinstq4-1:i386 libpth-dev libpthread-stubs0 \
libpthread-stubs0-dev lsb-cxx make openssh-server pdksh rlwrap rpm \
sysstat unixodbc unixodbc-dev unzip x11-utils zlibc gcc-multilib \
ia32-libs libstdc++5 libstdc++5:i386

Egy két extra link, hogy minden ott legyen, ahol a telepítő keresi:

sudo ln -s /usr/bin/basename /bin/basename
sudo ln -sf /bin/bash /bin/sh
sudo ln -s /usr/bin/rpm /bin/rpm
sudo ln -s /usr/bin/awk /bin/awk
sudo mkdir /usr/lib64
sudo ln -s /usr/lib/x86_64-linux-gnu/libc_nonshared.a /usr/lib64/
sudo ln -s /usr/lib/x86_64-linux-gnu/libpthread_nonshared.a /usr/lib64/
sudo ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib64/
sudo ln -s /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib64
sudo ln -s /usr/lib/i386-linux-gnu/libpthread_nonshared.a /usr/lib/libpthread_nonshared.a
sudo ln -s /bin/lib/libgcc_s.so.1 /lib/libgcc_s.so
sudo ln -s /usr/lib/libstdc++.so.6.0.13 /usr/lib/libstdc++.so.5

Egy user, és pár group a telepítőnek, és az oracle példánynak:

 sudo groupadd oinstall
sudo groupadd dba
sudo groupadd nobody
sudo useradd -m oracle -g oinstall -G dba
sudo passwd oracle

Kell még egy pár kernel paraméter:

sudo nano /etc/sysctl.conf

Ide az alábbi dolgokat kell felvenni:

kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000

Ha a módosításokkal megvagyunk, olvastassuk fel újra a kernelparamétereket:

sudo /sbin/sysctl -p

A limits-eket is érdemes módosítani:

sudo nano /etc/security/limits.conf

ide fel kell még venni az alábbi sorokat:

* soft nproc 2047
* hard nproc 16384
* soft nofile 1024
* hard nofile 65536

És kell még egy ál-redhat release is, hogy a telepítő megnyugodjon:

sudo nano /etc/redhat-release

A fájl tartalma pedig:

Red Hat Enterprise Linux AS release 3 (Taroon)

Ha mindent default módon telepítünk, akkor érdemes még felvenni, az alábbi környezeti változókat, hogy az életünk könnyebb legyen már a telepítés alatt is:

#oracle exports
export ORACLE_BASE=/home/oracle
export ORACLE_HOME=$ORACLE_BASE/app/oracle/product/11.2.0/dbhome_1
export ORACLE_SID=orcl11
export PATH=$PATH:$ORACLE_HOME/bin

Ha ezzel megvagyunk, akkor jöhet a telepítő kitömörítése, és indítása (oracle userként).

xhost +
sudo su oracle
~/oracle_install/runInstaller

A fájlok másolása ha nem rontottunk el semmit, akkor hiba nélkül megtörténik, az érdekes rész ezután jön. Amikor elkezd fordítani az oracle, jó eséllyel látunk majd egy két hibát. Gondolom meg kell indokolni Oracle-nál, hogy mire kell azt a nagyon sok support költséget fizetni (hogy nem normális telepítő írására, az biztos). A hibák az alábbi főbb problémákra vezethetőek vissza:

  1. Ubuntu alatt a gcc picit szigorúbban fordít, és meg kell enyhíteni a lelkét, amin a „-Wl,–no-as-needed” paraéterpáros általában szokott segíteni.
  2. Hiányoznak a fordításhoz referenciák, amit a gcc általában –l(lib) formában kap meg.

Itt fontos megjegyezni, hogy a –lagtsh az valójában libagtsh.so-t jelent, azt érdemes keresni. Másik hasznos utasítás az nm parancs, aminek a segítségével megnézhetjük, hogy egy adott függvény, amit épp a make nem talál, milyen so fájlokban van benne. Pl:

nm -A $ORACLE_HOME/lib/*.so | grep procr_get_ctx

Ahol U van, ott az so fájl használja a szolgáltatást, ahol T ott implementálva van.

A neten sok problémára van megoldás, de nem mindre (én kettőre nem találtam). A tapasztalatom szerint ilyen esetekben érdemesebb picit beleásni a dolgokba, és megérteni, mit és miért csinálunk, mert az az esetek nagy részében célravezetőbb mint mindenféle misztikus sed-et, és egyéb utasításokat kiadni, hátha valami működik.

Az részletes fordítás alatt jelentkező (make) hibákat az alábbi módon érdemes nézni:

tail -f $ORACLE_HOME/install/make.log

Vegyük sorra, hogy nálam milyen problémák adódtak, és mi volt a megoldásuk:

– libagtsh.so: undefined reference to `nnfyboot’ in make: rdbms/lib/dg4odbc]

Ez egy elég ravasz hiba, a probléma az, hogy nincs még meg az a fájl, ami a fordításhoz szükséges. A megoldást az internet szállítja: fordítsunk magunknak egyet:

ln -s $ORACLE_HOME/lib/libclient11.a $ORACLE_HOME/lib/libagtsh.a
$ORACLE_HOME/bin/genagtsh $ORACLE_HOME/lib/libagtsh.so 1.0

 

– libnnz11.so: could not read symbols: Invalid operation /sysman/lib/ins_emagent.mk

Kis keresgetés után lehet látni, hogy a hívás a $ORACLE_HOME/sysman/lib/ins_emagent.mk fájlból indul, és egy olyan szolgáltatásra hivatkozik, ami a libnnz11.so-ben van benne. Ezt pótoljuk oly módon, hogy a dependenciát is kapja meg meg a gcc:

$ORACLE_HOME/sysman/lib/ins_emagent.mk

régi:

$(MK_EMAGENT_NMECTL)

új:

$(MK_EMAGENT_NMECTL) -lnnz11

– genorasdksh: Failed to link liborasdk.so.11.1

Szintén egy dependencia probléma, amikor a teljes oracle sdk-t próbálja lefordítani, akkor nagyon sok dolgot nem talál hirtelen. A megoldás hasonló az előző esethez, a megnézzük a szolgáltatásokat, azonnal feltűnik, hogy a libagtsh.so és a  liborasdkbase.so hiányzik neki nagyon. Értessük meg vele:

$ORACLE_HOME/bin/genorasdksh

Régi:

OLIBS="$LCLIENT $LSQL $LVSN $LNETWORK $LCLIENT \
$LCOMMON $LGENERIC $LMM $XAONDY $LNETWORK $LCLIENT $LCOMMON \
$LGENERIC $LTRACE $LNNET_ON $LSKGXP"

Új:

OLIBS="$LCLIENT $LSQL $LVSN $LNETWORK $LCLIENT \
$LCOMMON $LGENERIC $LMM $XAONDY $LNETWORK $LCLIENT $LCOMMON \
$LGENERIC $LTRACE $LNNET_ON $LSKGXP -lagtsh -lorasdkbase"

– getcrshome – libhashgen11 missing reference

Itt ha megnézzük, akkor az a szolgáltatás amit keres, megtalálható az .so fájlban, ami meg is van adva. Itt a hiányzó extra paraméter a gond. Kis keresgetés után erre is rá lehet találni. A megoldás:

$ORACLE_HOME/srvm/lib/env_srvm.mk

Régi:

LDOBJSZ=-m64

Új:

LDOBJSZ=-m64 -Wl,--no-as-needed

És láss csodát, hiba nélkül működik az oracle ubuntun. Szerencsére csak az oracle build script-jeit láttam, a forrását nem, de ha azt is olyanok írták, mint ezeket a scripteket, akkor jobb is ez így…

Ubuntu és a lányok

Azt hiszem fontos mérföldkőhöz érkezett a világ. Kedves húgom laptopja ismét feladta a harcot, és megállt. Ez önmagában még nem mérföldkő, és nem is újdonság, általában ilyenkor kerülök én a képbe két facebook chat között…

Kértem kölcsön laptopot, azon viszont ubuntu volt. Gondolkoztam, megint lesz egy hétvége szívás, windows installer, dvd írás, serial beírás (kézzel ugye), driverek letöltése, frissítés, és minden ezzel járó dolog. Hogy aztán egy év múlva a windows és a hibás felhasználói szokások miatt  annyira elamortizálódjon az egész, hogy újra lehessen kezdeni az egész telepítési hercehurcát előröl.

Azt mondtam nem. Marad az ubuntu, és meglátjuk mi lesz.

A várakozásaimmal ellentétben, nem az történt, hogy  telepítenem kell a windowst.

Az átlag felhasználónak ugyanis nincsenek speciális elvárásai. Menjen a böngésző, legyen skype, hang, képfelvétel, és ezekre már mind van ingyenes, merem állítani a default windows programoknál jobb alternatíva. Gondoljunk csak a gimp-re, audacity-re és társaira (és ezeket kellene összehasonlítani a paint-el és a windows sound recorderével?). És ezek a programok bár vannak windowsra, rendszerint gyorsabbak, jobban működnek linux alatt, mert először arra voltak, és ott mindeni ezeket használja, míg windows alatt van aki fizet ilyesmiért pár dollárt, és eloszlik a tömeg. A microsoft pedig magasról tesz rá milyen a hangfelvevő. Vesz fel hangot? Igen. Ezzel vége a meetingnek, lehet menni pénzt költeni, de az meg úgyis az office-ből jön…

Persze van még egy fontos elvárás. Alapvető dolgokkal ne kelljen szívni. Sajnos ez egy picit még beárnyékolja az idilli képet. A dolgok egészen jól mentek,  pár dolog viszont okozhat csak alapvető ismeretekkel rendelkező felhasználónak álmatlan éjszakákat.

Az első a felhasználó jelszavának a megváltoztatása volt grafikus felületen. Megcsináltam, a process kifagyott, és a jelszó természetesen nem változott meg. Ez terminállal és a passwd utasítással gyorsan orvosolható probléma, de nem egy átlag user-nek (aki nem tudja, hogy van terminál, és passwd). Azért ilyen hibákkal ritkán találkozni más operációs rendszeren.

Probléma volt még, hogy alapból a chrome-ban nincs flash. Jó, az hogy alapból nincs, az nem akkora baj, de nem is lehet engedélyezni. A megoldás egy apt-get, és utána kézzel egy symlink létrehozása a google chrome plugins könyvtárába… A flash használatát egy átlag felhasználó elvárná, ellenben véleményem szerint egy ilyen művelet nem várható el tőle…

Szintén problémába ütköztem a a Cheese nevű videó felvevő programmal kapcsolatban. Elindult, rányomott az ember a felvételre, és erre a kedves program szó nélkül kilépett. Megint terminál, először valami jackd daemon hiányzott. Hát jó, telepítettem egyet. Aztán megint kifagyott ezúttal valami gstreamer hiányzott (volt is róla nyitott ubuntu hibajegy). Azt is telepítettem. Persze azt, hogy “mi”, és hogy “hiányzott” a program egy akkora dump-al közölte, hogy more-ba kellett csövezni a kimenetet (és igen, az errort is külön). Ez több mint ciki, vannak akik még 2013-ban sem hallottak a hibakezelésről, hibaüzenetekről, felhasználói interakcióról, meg ilyesmikről…

Félreértés ne essen, az ubuntu továbbra is szuper, és amit csinálnak az jó irány. Biztos vagyok benne, hogy az idő múlásával egyre szélesebb rétegeket fog meghódítani.

Ellenben fontos azt látni, hogy ha az első találkozás egy operációs rendszerrel ilyen, az sokakat elrémíthet a folytatástól. Nem is tudom, hogy mi lett volna, ha tényleg tesztelem is a dolgot, nem csak próbálom használni. Azért a fő szoftverbeszerzési csatornáról nem lenne rossz, ha olyan szoftverek jönnének, amik működnek is. Főleg ha az embernek nincs a közelben rokona, aki megoldja az váratlanul felmerülő problémákat…  🙂

 

Ubuntu – utf8 hu locale

Ha szeretnénk ékezetes karaktereket látni (beleértve a nagyon bonyolult ő betűt is) akkor az alábbiakat kell tenni:

1. felvenni a locale beállításokat a támogatott locale beállítások közé:

echo ‘hu_HU.UTF-8 UTF-8’ | sudo tee -a /var/lib/locales/supported.d/hu

2. újra generálni a locale fájlokat

sudo dpkg-reconfigure locales

3. beállítani ezt defaultnak:

sudo nano /etc/default/locale

Ebbe kell beírni az alábbi két sort:

LANG=hu_HU.UTF-8
LC_ALL=hu_HU.UTF-8

4. puty-al is megértetni, hogy itt bizony utf-8 lesz

Window – Translation – Recieved data ssumed to -> UTF-8

Tadamm…