problem s Apache22 na FreeBSD 6.1 a Accept Filter
Dan Lukes
dan at obluda.cz
Tue Jul 25 11:45:24 CEST 2006
Miroslav Lachman wrote:
> Ten problem neni jen pri signalu USR1, ale i pri HUP, tedy klasickem
> reloadu (vim, ze uz jsi tu minimalne jednou psal, ze jsi mel s USR1
> problemy, kdy apache pak uz nenabehnul a ze s HUP je to jistejsi)
No, to uz se do jiste miry vysvetlilo, to byla chyba v kodu OpenSSL a
od te doby, co jsem na vsech 4.x instaloval novejsi OpenSSL z portu tak
to prestalo. Ale je pravda, ze stejne gracefull restart nepouzivam ...
> Bohuzel nevim, jak overit, jestli ten filtr funguje, nebo ne.
Hm, pripoustim, ze to bez debuggeru neumim zjistit take - a s
debuggerem je to, s ohledem na komplikovany kod Apache take netrivialni
zalezitost.
Mozna by to slo zjistit s necim, co by monitorovalo, jake systemove
volani aplikace pouzila, jake predala parametry a co dostala zpatky -
potrebujeme videt co vrati prvni 'read' po akceptaci noveho spojeni.
Mozna existuje nejaky jednoduchy zpusob, jak zjistit, co je na socketu
aktivni za filtry, ale ja ho neznam.
> jako takovy bezi, to mam vyzkousene, ale krome trochy teorie z manualu o
> ACCEPT FILTERu nevim jak presne to funguje a tudiz co zjistovat a hlavne
> jak to zjistovat.
To muzu vysvetlit - aplikace cekajici na spojeni vola 'listen()'. Tim
zada TCP stack, aby pro ni prijimal prichozi TCP spojeni. Kdyz takove
spojeni prichazi, probehne standardni TCP hanshaking
(SYN->;SYN+ACK<-;ACK->), ktery probiha pod kontrolou jadra a TCP stacku
- bez ucasti aplikace. Jakmile je takto TCP spojeni ustaveno, je
zarazeno do fronty novych prichozich spojeni - odkud si tuto informaci
muze aplikace vyzvednout volanim accept(). Pak uz, pod rizenim aplikace,
probiha cteni "uzivatelskych" dat (obvykle volanim read() ).
Filtr umoznuje rict, ze ten handshaking probihajici v rezii jadra je
delsi a komplikovanejsi a odsunout tak okamzik, kdy spojeni a cteni dat
prechazi od jadra pod kontrolu aplikace. HTTP filtr napriklad zpusobuje,
ze jadro povazuje spojeni za "predatelne navazane" teprve v okamziku,
kdy z protejsi strany dorazil kompletni HTTP request (nebo kdyz filtr
dojde k zaveru, ze se o HTTP request vubec nejedna). Teprve v te chvili
zaradi spojeni do fronty a teprve v teto chvili si jej aplikace muze
accept()em vyzvednout. Prvni read() pak uz muze precist rovnou cely
pozadavek. Bez filtru by mohlo byt treba mnoho readu - v zavislosti na
tom, jak klient data pozadavku posila.
Cele to ma pouze vykonovy duvod - systemova volani maji relativne
velkou rezii. Kazdy usetreny read() se na zatizenem stroji pocita. A je
to pritom v aplikaci snadno pouzitelne, protoze krome zadosti o aktivaci
filtru neni treba delat v aplikaci zadnou zmenu.
> Je klidne mozne, ze je to jen hlaska v logu a o zadny skutecny problem,
> ktery by jakkoliv omezoval funkcnost Apache nejde.
Z vyse uvedeneho plyne, ze dokonce i kdyby ten filtr aktivni nebyl, tak
nejde o funkcni omezeni - jen vykonove. Aplikace, s vyjimkou tech tri
radek, ktere filtr aktivuji, je napsana uplne stejne, jako by zadny
filtr neexistoval - jinymi slovy - aplikace nepocita (a slusna aplikace
nikdy pocitat nebude) s tim, ze urcita data dostane "v kuse" - i tak ma
a musi mit implementovany kod, ktery pocita s tim, ze cokoliv co cte
muze prijit ve vice nez jednom readu (i kdyby to byly jen dva byte). Je
prijemne plus (vykonostni) pokud to prijde najednou, ale nic se nedeje,
pokud filtr "nezabere" a aplikace si data musi slozit sama.
Dan
P.S. Ten druhy "hotovy" filtr v systemu (accf_data) povazuje spojeni za
predatelne dokoncene ve chvili, kdy prijde prvni byte uzivatelskych dat.
More information about the Users-l
mailing list