Pagganap ng application ng Linux network. Panimula

Ginagamit na ngayon ang mga web application sa lahat ng dako, at sa lahat ng transport protocol, sinasakop ng HTTP ang lion's share. Kapag pinag-aaralan ang mga nuances ng pagbuo ng web application, ang karamihan sa mga tao ay nagbibigay ng napakakaunting pansin sa operating system kung saan aktwal na tumatakbo ang mga application na ito. Ang paghihiwalay ng development (Dev) at operations (Ops) ay nagpalala lang sa sitwasyon. Ngunit sa pag-usbong ng kultura ng DevOps, nagiging responsable ang mga developer sa pagpapatakbo ng kanilang mga application sa cloud, kaya lubhang kapaki-pakinabang para sa kanila na maging lubos na pamilyar sa backend ng operating system. Ito ay lalong kapaki-pakinabang kung sinusubukan mong mag-deploy ng system para sa libu-libo o sampu-sampung libong magkakasabay na koneksyon.

Ang mga limitasyon sa mga serbisyo sa web ay halos kapareho sa mga nasa iba pang mga application. Maging ito ay mga tagabalanse ng pag-load o mga server ng database, lahat ng mga application na ito ay may mga katulad na problema sa isang kapaligiran na may mataas na pagganap. Ang pag-unawa sa mga pangunahing limitasyong ito at kung paano malalampasan ang mga ito sa pangkalahatan ay makakatulong sa iyong suriin ang pagganap at scalability ng iyong mga web application.

Sinusulat ko ang seryeng ito ng mga artikulo bilang tugon sa mga tanong ng mga batang developer na gustong maging mga arkitekto ng system na may mahusay na kaalaman. Imposibleng malinaw na maunawaan ang mga diskarte sa pag-optimize ng application ng Linux nang hindi sumisid sa mga pangunahing kaalaman kung paano gumagana ang mga ito sa antas ng operating system. Bagama't maraming uri ng mga application, sa seryeng ito gusto kong tuklasin ang mga web-based na application kaysa sa mga desktop application gaya ng browser o text editor. Ang materyal na ito ay inilaan para sa mga developer at arkitekto na gustong maunawaan kung paano gumagana ang mga programa ng Linux o Unix at kung paano ayusin ang mga ito para sa mataas na pagganap.

Ang Linux ay silid ng server operating system, at kadalasan ang iyong mga application ay tumatakbo sa OS na ito. Bagama't sinasabi ko ang "Linux", kadalasan ay maaari mong ligtas na ipagpalagay na ang ibig kong sabihin ay lahat ng mga operating system na katulad ng Unix sa pangkalahatan. Gayunpaman, hindi ko pa nasubukan ang kasamang code sa ibang mga system. Kaya, kung interesado ka sa FreeBSD o OpenBSD, maaaring mag-iba ang iyong mga resulta. Kapag sinubukan ko ang isang bagay na partikular sa Linux, itinuturo ko ito.

Bagama't magagamit mo ang kaalamang ito upang bumuo ng isang app mula sa simula at ito ay ganap na ma-optimize, pinakamahusay na huwag gawin iyon. Kung magsulat ka ng bagong web server sa C o C++ para sa application ng negosyo ng iyong organisasyon, maaaring ito na ang iyong huling araw sa trabaho. Gayunpaman, ang pag-alam sa istruktura ng mga application na ito ay makakatulong sa pagpili ng mga umiiral na programa. Magagawa mong ihambing ang mga system na nakabatay sa proseso sa mga system na nakabatay sa thread pati na rin ang mga nakabatay sa kaganapan. Mauunawaan at pahalagahan mo kung bakit mas mahusay ang pagganap ng Nginx kaysa sa Apache httpd, kung bakit ang isang Tornado based Python application ay maaaring maghatid ng mas maraming user kumpara sa isang Django based Python application.

ZeroHTTPd: Learning Tool

ZeroHTTPd ay isang web server na sinulat ko mula sa simula sa C bilang isang tool sa pagtuturo. Wala itong mga panlabas na dependency, kabilang ang pag-access sa Redis. Nagpapatakbo kami ng aming sariling mga pamamaraan ng Redis. Tingnan sa ibaba para sa higit pang mga detalye.

Bagama't maaari nating talakayin ang teorya nang mahaba, walang mas mahusay kaysa sa pagsulat ng code, pagpapatakbo nito, at paghahambing ng lahat ng mga arkitektura ng server sa bawat isa. Ito ang pinaka-halatang paraan. Samakatuwid, magsusulat kami ng simpleng ZeroHTTPd web server gamit ang bawat modelo: batay sa proseso, batay sa thread, at batay sa kaganapan. Tingnan natin ang bawat isa sa mga server na ito at tingnan kung paano gumaganap ang mga ito kumpara sa isa't isa. Ang ZeroHTTPd ay ipinatupad sa isang C file. Kasama sa server na nakabatay sa kaganapan uthash, isang mahusay na pagpapatupad ng hash table na nasa iisang header file. Sa ibang mga kaso, walang mga dependency, upang hindi kumplikado ang proyekto.

Mayroong maraming mga komento sa code upang matulungan kang maunawaan. Bilang isang simpleng web server sa ilang linya ng code, ang ZeroHTTPd ay isa ring minimal na framework para sa web development. Ito ay may limitadong pag-andar, ngunit may kakayahang maghatid ng mga static na file at napakasimpleng "dynamic" na mga pahina. Kailangan kong sabihin na ang ZeroHTTPd ay mabuti para sa pag-aaral kung paano lumikha ng mataas na pagganap ng mga aplikasyon ng Linux. Sa pangkalahatan, karamihan sa mga serbisyo sa web ay naghihintay para sa mga kahilingan, suriin ang mga ito at iproseso ang mga ito. Ito mismo ang gagawin ng ZeroHTTPd. Ito ay isang tool para sa pag-aaral, hindi produksyon. Hindi ito mahusay sa paghawak ng error at malamang na hindi ipagmalaki ang pinakamahusay na mga kasanayan sa seguridad (oh yeah, ginamit ko strcpy) o ang matatalinong panlilinlang ng wikang C. Ngunit umaasa ako na ginagawa nito nang maayos ang trabaho nito.

Pagganap ng application ng Linux network. Panimula
ZeroHTTPd home page. Maaari itong mag-output ng iba't ibang uri ng file kabilang ang mga imahe

Application ng Guest Book

Ang mga modernong web application ay karaniwang hindi limitado sa mga static na file. Mayroon silang mga kumplikadong pakikipag-ugnayan sa iba't ibang mga database, cache, atbp. Kaya gagawa kami ng isang simpleng web application na tinatawag na "Guest Book" kung saan ang mga bisita ay nag-iiwan ng mga entry sa ilalim ng kanilang mga pangalan. Nag-iimbak ang guest book ng mga entry na naiwan kanina. Mayroon ding visitor counter sa ibaba ng page.

Pagganap ng application ng Linux network. Panimula
Web application na "Guest Book" ZeroHTTPd

Ang counter ng bisita at mga entry sa guest book ay naka-imbak sa Redis. Para sa mga komunikasyon sa Redis, ang mga sariling pamamaraan ay ipinatupad; hindi sila nakadepende sa panlabas na aklatan. Hindi ako isang malaking tagahanga ng paglulunsad ng homebrew code kapag may magagamit sa publiko at mahusay na nasubok na mga solusyon. Ngunit ang layunin ng ZeroHTTPd ay pag-aralan ang pagganap ng Linux at pag-access sa mga panlabas na serbisyo, habang ang paghahatid ng mga kahilingan sa HTTP ay may malubhang epekto sa pagganap. Dapat naming ganap na kontrolin ang mga komunikasyon sa Redis sa bawat isa sa aming mga arkitektura ng server. Sa ilang mga arkitektura gumagamit kami ng pagharang ng mga tawag, sa iba naman ay gumagamit kami ng mga pamamaraang batay sa kaganapan. Ang paggamit ng panlabas na Redis client library ay hindi magbibigay ng kontrol na ito. Bilang karagdagan, ang aming maliit na kliyente ng Redis ay gumaganap lamang ng ilang mga function (pagkuha, pagtatakda at pagdaragdag ng isang susi; pagkuha at pagdaragdag sa isang array). Bilang karagdagan, ang Redis protocol ay napaka-elegante at simple. Hindi mo na kailangang espesyal na ituro ito. Ang mismong katotohanan na ginagawa ng protocol ang lahat ng gawain sa halos isang daang linya ng code ay nagpapakita kung gaano ito pinag-isipan.

Ipinapakita ng sumusunod na figure kung ano ang ginagawa ng application kapag humiling ang kliyente (browser). /guestbookURL.

Pagganap ng application ng Linux network. Panimula
Paano gumagana ang application ng guest book

Kapag kailangang magbigay ng page ng guest book, mayroong isang tawag sa file system para basahin ang template sa memorya at tatlong tawag sa network sa Redis. Ang template file ay naglalaman ng karamihan sa HTML na nilalaman para sa pahina sa screenshot sa itaas. Mayroon ding mga espesyal na placeholder para sa dynamic na bahagi ng nilalaman: mga post at counter ng bisita. Natanggap namin ang mga ito mula sa Redis, ipasok ang mga ito sa pahina at binibigyan ang kliyente ng ganap na nabuong nilalaman. Maaaring iwasan ang ikatlong tawag sa Redis dahil ibinabalik ng Redis ang bagong halaga ng key kapag nadagdagan. Gayunpaman, para sa aming server na may asynchronous na arkitektura na nakabatay sa kaganapan, maraming mga tawag sa network ay isang magandang pagsubok para sa mga layunin ng pag-aaral. Kaya itinatapon namin ang halaga ng pagbabalik ng Redis tungkol sa bilang ng mga bisita at itatanong ito sa isang hiwalay na tawag.

Mga arkitektura ng server ZeroHTTPd

Bumubuo kami ng pitong bersyon ng ZeroHTTPd na may parehong functionality ngunit magkaibang mga arkitektura:

  • umuulit
  • Fork server (isang proseso ng bata bawat kahilingan)
  • Pre-fork server (pre-fork ng mga proseso)
  • Server na may mga execution thread (isang thread bawat kahilingan)
  • Server na may pre-thread na paggawa
  • Batay sa arkitektura poll()
  • Batay sa arkitektura epoll

Sinusukat namin ang pagganap ng bawat arkitektura sa pamamagitan ng pag-load sa server ng mga kahilingan sa HTTP. Ngunit kapag naghahambing ng lubos na magkatulad na mga arkitektura, ang bilang ng mga query ay tumataas. Tatlong beses kaming sumubok at kinakalkula ang average.

Pamamaraan ng pagsubok

Pagganap ng application ng Linux network. Panimula
ZeroHTTPd load testing setup

Mahalaga na kapag nagpapatakbo ng mga pagsubok, ang lahat ng mga bahagi ay hindi tumatakbo sa parehong makina. Sa kasong ito, ang OS ay nagkakaroon ng karagdagang pag-iiskedyul ng overhead habang ang mga bahagi ay nakikipagkumpitensya para sa CPU. Ang pagsukat sa overhead ng operating system ng bawat isa sa mga napiling arkitektura ng server ay isa sa pinakamahalagang layunin ng pagsasanay na ito. Ang pagdaragdag ng higit pang mga variable ay magiging masama sa proseso. Samakatuwid, pinakamahusay na gumagana ang setting sa larawan sa itaas.

Ano ang ginagawa ng bawat isa sa mga server na ito?

  • load.unixism.net: Dito tayo tumatakbo ab, Apache Benchmark na utility. Binubuo nito ang pag-load na kinakailangan upang subukan ang aming mga arkitektura ng server.
  • nginx.unixism.net: Minsan gusto naming magpatakbo ng higit sa isang instance ng isang server program. Upang gawin ito, gumagana ang Nginx server na may naaangkop na mga setting bilang isang load balancer na nagmumula ab sa aming mga proseso ng server.
  • zerohttpd.unixism.net: Dito pinapatakbo namin ang aming mga server program sa pitong magkakaibang arkitektura, nang paisa-isa.
  • redis.unixism.net: Ang server na ito ay nagpapatakbo ng Redis daemon, kung saan nakaimbak ang mga entry sa guestbook at mga bisitang counter.

Ang lahat ng mga server ay tumatakbo sa parehong core ng processor. Ang ideya ay suriin ang pinakamataas na pagganap ng bawat arkitektura. Dahil ang lahat ng mga programa ng server ay nasubok sa parehong hardware, ito ay isang baseline para sa paghahambing. Ang aking test setup ay binubuo ng mga virtual server na nirentahan mula sa Digital Ocean.

Ano ang ating sinusukat?

Maaari mong sukatin ang iba't ibang mga tagapagpahiwatig. Sinusuri namin ang pagganap ng bawat arkitektura sa isang partikular na configuration sa pamamagitan ng pag-load sa mga server ng mga kahilingan sa iba't ibang antas ng parallelism: ang pag-load ay lumalaki mula 20 hanggang 15 kasabay na mga user.

Mga resulta ng pagsubok

Ipinapakita ng sumusunod na tsart ang pagganap ng mga server sa iba't ibang mga arkitektura sa iba't ibang antas ng paralelismo. Ang y-axis ay ang bilang ng mga kahilingan sa bawat segundo, ang x-axis ay parallel na koneksyon.

Pagganap ng application ng Linux network. Panimula

Pagganap ng application ng Linux network. Panimula

Pagganap ng application ng Linux network. Panimula

Nasa ibaba ang isang talahanayan na may mga resulta.

mga kahilingan sa bawat segundo

pagkakasundo
umuulit
tinidor
paunang tinidor
streaming
pre-streaming
presinto
epoll

20
7
112
2100
1800
2250
1900
2050

50
7
190
2200
1700
2200
2000
2000

100
7
245
2200
1700
2200
2150
2100

200
7
330
2300
1750
2300
2200
2100

300
-
380
2200
1800
2400
2250
2150

400
-
410
2200
1750
2600
2000
2000

500
-
440
2300
1850
2700
1900
2212

600
-
460
2400
1800
2500
1700
2519

700
-
460
2400
1600
2490
1550
2607

800
-
460
2400
1600
2540
1400
2553

900
-
460
2300
1600
2472
1200
2567

1000
-
475
2300
1700
2485
1150
2439

1500
-
490
2400
1550
2620
900
2479

2000
-
350
2400
1400
2396
550
2200

2500
-
280
2100
1300
2453
490
2262

3000
-
280
1900
1250
2502
malawak na pagkalat
2138

5000
-
malawak na pagkalat
1600
1100
2519
-
2235

8000
-
-
1200
malawak na pagkalat
2451
-
2100

10
-
-
malawak na pagkalat
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Mula sa graph at talahanayan, makikita na higit sa 8000 sabay-sabay na kahilingan mayroon na lang tayong dalawang manlalaro na natitira: pre-fork at epoll. Habang tumataas ang load, mas malala ang performance ng isang server na nakabatay sa poll kaysa sa streaming. Ang arkitektura ng thread-pre-creation ay isang karapat-dapat na kakumpitensya na mag-epoll, isang testamento sa kung gaano kahusay ang pag-iskedyul ng Linux kernel ng malaking bilang ng mga thread.

ZeroHTTPd Source Code

ZeroHTTPd Source Code dito. Mayroong isang hiwalay na direktoryo para sa bawat arkitektura.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking ─ ─ ─ ─ ─ ─ . threading │ ├── main.c ├── 04_prethreading │ ├── main.c ├── 05_poll │ ├── main.c ├── 06_epoll │ └─── Main.c ─ ├── index .html │ └── tux . png └── mga template └── guestbook └── index.html

Bilang karagdagan sa pitong direktoryo para sa lahat ng mga arkitektura, may dalawa pa sa nangungunang antas na direktoryo: pampubliko at mga template. Ang una ay naglalaman ng index.html file at ang larawan mula sa unang screenshot. Maaari kang maglagay ng iba pang mga file at folder doon, at dapat ihatid ng ZeroHTTPd ang mga static na file na iyon nang walang anumang problema. Kung ang path sa browser ay tumutugma sa path sa pampublikong folder, hahanapin ng ZeroHTTPd ang index.html file sa direktoryong ito. Ang nilalaman para sa guest book ay dynamic na nabuo. Mayroon lamang itong home page, at ang nilalaman nito ay batay sa file na 'templates/guestbook/index.html'. Ang ZeroHTTPd ay madaling nagdaragdag ng mga dynamic na pahina para sa extension. Ang ideya ay ang mga user ay maaaring magdagdag ng mga template sa direktoryo na ito at palawigin ang ZeroHTTPd kung kinakailangan.

Upang bumuo ng lahat ng pitong server, tumakbo make all mula sa nangungunang antas na direktoryo - at lahat ng mga build ay lalabas sa direktoryong ito. Hinahanap ng mga executable na file ang mga direktoryo ng publiko at mga template sa direktoryo kung saan sila inilunsad.

Linux API

Hindi mo kailangang maging bihasa sa Linux API para maunawaan ang impormasyon sa serye ng artikulong ito. Gayunpaman, inirerekumenda ko ang pagbabasa ng higit pa sa paksang ito; maraming mga mapagkukunan ng sanggunian sa Internet. Bagama't tatalakayin namin ang ilang kategorya ng mga Linux API, ang aming pagtuon ay pangunahin sa mga proseso, thread, kaganapan, at network stack. Bilang karagdagan sa mga libro at artikulo tungkol sa Linux API, inirerekomenda ko rin ang pagbabasa ng mana para sa mga system call at mga function ng library na ginamit.

Pagganap at Scalability

Isang tala tungkol sa pagganap at scalability. Sa teorya, walang koneksyon sa pagitan nila. Maaari kang magkaroon ng serbisyo sa web na gumagana nang napakahusay, na may oras ng pagtugon na ilang millisecond, ngunit hindi ito nasusukat. Gayundin, maaaring mayroong hindi mahusay na gumaganap na web application na tumatagal ng ilang segundo upang tumugon, ngunit ito ay sumusukat ng sampu upang mahawakan ang libu-libong kasabay na mga user. Gayunpaman, ang kumbinasyon ng mataas na pagganap at scalability ay isang napakalakas na kumbinasyon. Ang mga application na may mataas na pagganap ay karaniwang gumagamit ng mga mapagkukunan nang matipid at sa gayon ay mahusay na nagsisilbi sa mas maraming kasabay na mga gumagamit sa server, na binabawasan ang mga gastos.

Mga gawain ng CPU at I/O

Sa wakas, sa pag-compute ay palaging may dalawang posibleng uri ng mga gawain: para sa I/O at CPU. Ang pagtanggap ng mga kahilingan sa Internet (network I/O), paghahatid ng mga file (network at disk I/O), pakikipag-ugnayan sa database (network at disk I/O) ay lahat ng aktibidad ng I/O. Ang ilang mga query sa database ay maaaring medyo masinsinang CPU (pag-uuri, pag-average ng isang milyong resulta, atbp.). Karamihan sa mga web application ay nililimitahan ng maximum na posibleng I/O, at ang processor ay bihirang ginagamit sa buong kapasidad. Kapag nakita mo na ang ilang gawain sa I/O ay gumagamit ng maraming CPU, malamang na ito ay tanda ng hindi magandang arkitektura ng application. Ito ay maaaring mangahulugan na ang mga mapagkukunan ng CPU ay nasasayang sa pamamahala ng proseso at paglipat ng konteksto - at hindi ito lubos na kapaki-pakinabang. Kung gumagawa ka ng isang bagay tulad ng pagpoproseso ng imahe, pag-convert ng audio file, o pag-aaral ng makina, kung gayon ang application ay nangangailangan ng malakas na mapagkukunan ng CPU. Ngunit para sa karamihan ng mga aplikasyon hindi ito ang kaso.

Matuto nang higit pa tungkol sa mga arkitektura ng server

  1. Bahagi I: Paulit-ulit na Arkitektura
  2. Bahagi II. Mga server ng tinidor
  3. Bahagi III. Mga pre-fork server
  4. Bahagi IV. Mga server na may mga thread ng pagpapatupad
  5. Bahagi V. Mga pre-threaded na server
  6. Bahagi VI. Arkitekturang nakabatay sa Pol
  7. Bahagi VII. arkitektura na nakabatay sa epoll

Pinagmulan: www.habr.com

Magdagdag ng komento