Feb 26 2010
nginx triki
Tiem, kas tankā – Nginx ir webserveris, līdzīgi kā Apache, Microsoft IIS, Lighttpd utt, bet krietni ātrāks par iepriekšminētajiem un kas pietiekami būtiski – Nginx var darīt arī ko krietni vairāk, nekā parasts webserveris. Bet par to mazliet vēlāk.
Iesākumā gribu pieminēt interesantu lietu, ka lai arī Nginx principā ir zināms pietiekami sen, taču patieso uzvaras gājienu uzsāka pagājušā gadā – http://royal.pingdom.com/2010/01/22/internet-2009-in-numbers/ – popularitātes pieagums par 384.4% ir gana iespaidīgs.
Mana personīgā pieredze ar Nginx ir visai pozitīva. Iepriekšējais favorīts Lighttpd ir nolikts maliņā, kopš tika konstatēts, ka php fast-cgi režīmā uz lighta darbinās 5-10x lēnāk, nekā uz nginx. Nemaz jau nerunājot par visiem pārējiem bonusiem.
Labi, pietiek muldēt, jāķeras pie lietas:)
Bet lieta sekojoša – kādu brīdi atpakaļ gribējās pamēģināt tādu lietu, kā Amazon s3, jeb statisku failu hostēšanu kaut kur citur, nav pat obligāti šis s3, tā vietā varētu būt jebkas cits. Pamatojums? Trafiks. Tieši uz šiem statiskajiem failiem (img, css, js) tas saskrien visvairāk. Amazon tādā ziņā ir labs, ka mani faili tiek izmētāti pa visu pasauli uz n-tajiem serveriem un klients to dabū no sev tuvākā, ātrākā. Mīnuss – tas tomēr ir maksas pasākums. Lai arī ļoti minimālas maksas, taču maksas.
Domāts, darīts – piereģistrējos s3, sakopēju savus failus, salieku webā src=amazon, bet kaut kā nav īsti smuki – visādi sveši url figurē, plus tas viss salīdzinoši notiek diezgan lēni.
Un šajā brīdī atcerējos par nginx un tā iespējām:
location /s3redirect {
rewrite ^/(s3redirect)/(.*)$ /s3/$2 break;
proxy_pass http://alxf1lv.s3.amazonaws.com;
proxy_redirect off;
proxy_set_header Host alxf1lv.s3.amazonaws.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Un vualā – lapā varu atbrīvoties no amazon linkiem, tā vietā lietojot it kā lokālu folderi /s3redirect. Rewrite paredzēts tam, lai pārrakstītu s3redirect par s3, jo tieši tādā folderī mani dati stāv uz amazon servera. Bet otra problēma saglabājas – lēnums. Jo katrs pieprasījums vienalga brien uz amazon. Galarezultātā pat sanāk lēnāk, nekā pa tiešo, jo pieprasījums vēl iziet lokālo stadiju:) Nu ko, turpinam rakt un pieslēdzam cache:
location /s3proxy {
rewrite ^/(s3proxy)/(.*)$ /s3/$2 break;
proxy_pass http://alxf1lv.s3.amazonaws.com;
proxy_redirect off;
proxy_set_header Host alxf1lv.s3.amazonaws.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_key backend$request_uri;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout invalid_header;
}
+
html {
..........
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=one:180m max_size=500m;
}
Vēlamais efekts panākts – faili stāv uz amazon, taču servējas jau no lokālā dzelža, kas gan, protams, izklausās stulbi, jo faili jau sākotnēji var stāvēt lokāli, taču domājot plašāk, paveras pietiekami plašas scalability iespējas.
Jāteic gan, ka es neapstājos pie sasniegtā:) Ideja “a kā būtu servēt no atmiņas” realizējās šādā nginx konfigurācijā:
location /s3 {
set $memcached_key $uri;
memcached_pass 127.0.0.1:11211;
error_page 404 = @fetch;
}
location @fetch {
proxy_pass http://alxf1lv.s3.amazonaws.com;
proxy_redirect off;
proxy_set_header Host alxf1lv.s3.amazonaws.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache one;
proxy_cache_key backend$request_uri;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout invalid_header;
}
+
html{
.................
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=one:180m max_size=500m;
}
Jeb cilvēciskākā valodā – fails tiek servēts no memcache, ja tur nav – no proxy un ja nav arī tur – no amazon:) Jā, sviestaini, un jā, diez vai es to reāli izmantošu, bet kā neliels ieskats nginx iespējās, domāju, diezgan ok:)
Testi (100 secīgi pieprasījumi 73Kb lielam failam):
Pa tiešo no amazon s3 62.5762 sec Redirect 63.1520 sec Redirect + proxy 1.071 sec Redirect+ proxy + memcache 0.1760 sec
secinājumus varat izdarīt paši:)
Jāpiebilst gan, ka šādā konfigurācijā memcache māk tikai lasīt – dati pirms tam kaut kādā veidā tur ir jādabū iekšā. PHP piemērs par šo tēmu – kaut vai šeit beigās. Bet, jebkurā gadījumā, tas ir pietiekami būtisks mīnuss.
Bet varētu šo problēmu atrisināt arī savādāk – ar viena cita nginx moduļa palīdzību – NginxHttpMemcModule, kurš memcache māk arī rakstīt.
Šis vien ir ko vērts http://wiki.nginx.org/images/0/0e/Absolut_nginx.jpg