Prestasi aplikasi rangkaian Linux. pengenalan

Aplikasi web kini digunakan di mana-mana, dan antara semua protokol pengangkutan, HTTP menduduki bahagian terbesar. Apabila mengkaji nuansa pembangunan aplikasi web, kebanyakan orang memberi sedikit perhatian kepada sistem pengendalian di mana aplikasi ini sebenarnya berjalan. Pemisahan pembangunan (Dev) dan operasi (Ops) hanya memburukkan keadaan. Tetapi dengan kebangkitan budaya DevOps, pembangun menjadi bertanggungjawab untuk menjalankan aplikasi mereka dalam awan, jadi sangat berguna untuk mereka membiasakan diri dengan bahagian belakang sistem pengendalian. Ini amat berguna jika anda cuba menggunakan sistem untuk beribu-ribu atau berpuluh-puluh ribu sambungan serentak.

Had dalam perkhidmatan web sangat serupa dengan yang terdapat dalam aplikasi lain. Sama ada pengimbang beban atau pelayan pangkalan data, semua aplikasi ini mempunyai masalah yang sama dalam persekitaran berprestasi tinggi. Memahami batasan asas ini dan cara mengatasinya secara umum akan membantu anda menilai prestasi dan kebolehskalaan aplikasi web anda.

Saya menulis siri artikel ini sebagai jawapan kepada soalan daripada pembangun muda yang ingin menjadi arkitek sistem yang berpengetahuan tinggi. Adalah mustahil untuk memahami dengan jelas teknik pengoptimuman aplikasi Linux tanpa menyelami asas cara ia berfungsi pada peringkat sistem pengendalian. Walaupun terdapat banyak jenis aplikasi, dalam siri ini saya ingin meneroka aplikasi berasaskan web dan bukannya aplikasi desktop seperti pelayar atau penyunting teks. Bahan ini bertujuan untuk pembangun dan arkitek yang ingin memahami cara program Linux atau Unix berfungsi dan cara menyusunnya untuk prestasi tinggi.

Linux adalah bilik server sistem pengendalian, dan selalunya aplikasi anda dijalankan pada OS ini. Walaupun saya menyebut "Linux", kebanyakan masa anda boleh menganggap bahawa saya maksudkan semua sistem pengendalian seperti Unix secara umum. Walau bagaimanapun, saya belum menguji kod yang disertakan pada sistem lain. Jadi, jika anda berminat dengan FreeBSD atau OpenBSD, keputusan anda mungkin berbeza-beza. Apabila saya mencuba sesuatu yang khusus Linux, saya menunjukkannya.

Walaupun anda boleh menggunakan pengetahuan ini untuk membina apl dari awal dan ia akan dioptimumkan dengan sempurna, sebaiknya jangan berbuat demikian. Jika anda menulis pelayan web baharu dalam C atau C++ untuk aplikasi perniagaan organisasi anda, ini mungkin hari terakhir anda bekerja. Walau bagaimanapun, mengetahui struktur aplikasi ini akan membantu dalam memilih program sedia ada. Anda akan dapat membandingkan sistem berasaskan proses dengan sistem berasaskan benang serta sistem berasaskan peristiwa. Anda akan memahami dan menghargai mengapa Nginx berprestasi lebih baik daripada Apache httpd, mengapa aplikasi Python berasaskan Tornado boleh memberi perkhidmatan kepada lebih ramai pengguna berbanding dengan aplikasi Python berasaskan Django.

ZeroHTTPd: Alat Pembelajaran

ZeroHTTPd ialah pelayan web yang saya tulis dari awal dalam C sebagai alat pengajaran. Ia tidak mempunyai kebergantungan luaran, termasuk akses kepada Redis. Kami menjalankan prosedur Redis kami sendiri. Lihat di bawah untuk butiran lanjut.

Walaupun kita boleh membincangkan teori dengan panjang lebar, tidak ada yang lebih baik daripada menulis kod, menjalankannya, dan membandingkan semua seni bina pelayan antara satu sama lain. Ini adalah kaedah yang paling jelas. Oleh itu, kami akan menulis pelayan web ZeroHTTPd yang mudah menggunakan setiap model: berasaskan proses, berasaskan benang dan berasaskan peristiwa. Mari lihat setiap pelayan ini dan lihat prestasinya berbanding antara satu sama lain. ZeroHTTPd dilaksanakan dalam satu fail C. Pelayan berasaskan acara termasuk uthash, pelaksanaan jadual cincang yang hebat yang terdapat dalam satu fail pengepala. Dalam kes lain, tiada kebergantungan, supaya tidak merumitkan projek.

Terdapat banyak ulasan dalam kod untuk membantu anda memahami. Sebagai pelayan web mudah dalam beberapa baris kod, ZeroHTTPd juga merupakan rangka kerja minimum untuk pembangunan web. Ia mempunyai kefungsian terhad, tetapi mampu menyediakan fail statik dan halaman "dinamik" yang sangat mudah. Saya harus mengatakan bahawa ZeroHTTPd bagus untuk mempelajari cara mencipta aplikasi Linux berprestasi tinggi. Pada umumnya, kebanyakan perkhidmatan web menunggu permintaan, menyemaknya dan memprosesnya. Inilah yang akan dilakukan oleh ZeroHTTPd. Ini adalah alat untuk belajar, bukan pengeluaran. Ia tidak hebat dalam pengendalian ralat dan tidak mungkin membanggakan amalan keselamatan terbaik (oh ya, saya pernah menggunakannya strcpy) atau helah bijak bahasa C. Tetapi saya harap ia berfungsi dengan baik.

Prestasi aplikasi rangkaian Linux. pengenalan
Halaman utama ZeroHTTPd. Ia boleh mengeluarkan jenis fail yang berbeza termasuk imej

Permohonan Buku Pelawat

Aplikasi web moden biasanya tidak terhad kepada fail statik. Mereka mempunyai interaksi yang kompleks dengan pelbagai pangkalan data, cache, dsb. Jadi kami akan mencipta aplikasi web ringkas yang dipanggil "Buku Pelawat" di mana pelawat meninggalkan entri di bawah nama mereka. Buku pelawat menyimpan entri yang ditinggalkan lebih awal. Terdapat juga kaunter pelawat di bahagian bawah halaman.

Prestasi aplikasi rangkaian Linux. pengenalan
Aplikasi web "Buku Pelawat" ZeroHTTPd

Kaunter pelawat dan entri buku tetamu disimpan dalam Redis. Untuk komunikasi dengan Redis, prosedur sendiri dilaksanakan; mereka tidak bergantung pada perpustakaan luaran. Saya bukan peminat besar untuk melancarkan kod homebrew apabila terdapat penyelesaian yang tersedia secara umum dan diuji dengan baik. Tetapi tujuan ZeroHTTPd adalah untuk mengkaji prestasi Linux dan akses kepada perkhidmatan luaran, sambil menyediakan permintaan HTTP mempunyai kesan prestasi yang serius. Kami mesti mengawal sepenuhnya komunikasi dengan Redis dalam setiap seni bina pelayan kami. Dalam sesetengah seni bina kami menggunakan panggilan menyekat, dalam yang lain kami menggunakan prosedur berasaskan acara. Menggunakan pustaka klien Redis luaran tidak akan menyediakan kawalan ini. Selain itu, pelanggan Redis kecil kami hanya melaksanakan beberapa fungsi (mendapat, menetapkan dan menambah kunci; mendapatkan dan menambahkan pada tatasusunan). Di samping itu, protokol Redis sangat elegan dan mudah. Anda tidak perlu mengajarnya secara khusus. Hakikat bahawa protokol melakukan semua kerja dalam kira-kira seratus baris kod menunjukkan sejauh mana ia difikirkan dengan baik.

Rajah berikut menunjukkan perkara yang dilakukan oleh aplikasi apabila permintaan pelanggan (pelayar). /guestbookURL.

Prestasi aplikasi rangkaian Linux. pengenalan
Cara aplikasi buku tetamu berfungsi

Apabila halaman buku tetamu perlu dikeluarkan, terdapat satu panggilan ke sistem fail untuk membaca templat ke dalam memori dan tiga panggilan rangkaian ke Redis. Fail templat mengandungi kebanyakan kandungan HTML untuk halaman dalam tangkapan skrin di atas. Terdapat juga pemegang tempat khas untuk bahagian dinamik kandungan: siaran dan kaunter pelawat. Kami menerimanya daripada Redis, memasukkannya ke dalam halaman dan menyediakan pelanggan dengan kandungan yang lengkap. Panggilan ketiga kepada Redis boleh dielakkan kerana Redis mengembalikan nilai kunci baharu apabila dinaikkan. Walau bagaimanapun, untuk pelayan kami, yang mempunyai seni bina berasaskan acara tak segerak, banyak panggilan rangkaian adalah ujian yang baik untuk tujuan pembelajaran. Jadi kami membuang nilai pulangan Redis bagi bilangan pelawat dan menanyakannya dengan panggilan berasingan.

Seni bina pelayan ZeroHTTPd

Kami sedang membina tujuh versi ZeroHTTPd dengan fungsi yang sama tetapi seni bina berbeza:

  • berulang
  • Pelayan fork (satu proses kanak-kanak setiap permintaan)
  • Pelayan pra-fork (pra-fork proses)
  • Pelayan dengan urutan pelaksanaan (satu utas setiap permintaan)
  • Pelayan dengan penciptaan pra-benang
  • Berasaskan seni bina poll()
  • Berasaskan seni bina epoll

Kami mengukur prestasi setiap seni bina dengan memuatkan pelayan dengan permintaan HTTP. Tetapi apabila membandingkan seni bina yang sangat selari, bilangan pertanyaan meningkat. Kami menguji tiga kali dan mengira purata.

Metodologi ujian

Prestasi aplikasi rangkaian Linux. pengenalan
Persediaan ujian beban ZeroHTTPd

Adalah penting apabila menjalankan ujian, semua komponen tidak berjalan pada mesin yang sama. Dalam kes ini, OS dikenakan overhed penjadualan tambahan kerana komponen bersaing untuk CPU. Mengukur overhed sistem pengendalian bagi setiap seni bina pelayan yang dipilih ialah salah satu matlamat terpenting latihan ini. Menambah lebih banyak pembolehubah akan memudaratkan proses. Oleh itu, tetapan dalam gambar di atas berfungsi dengan baik.

Apakah yang dilakukan oleh setiap pelayan ini?

  • load.unixism.net: Di sinilah kami berlari ab, utiliti Penanda Aras Apache. Ia menjana beban yang diperlukan untuk menguji seni bina pelayan kami.
  • nginx.unixism.net: Kadangkala kita mahu menjalankan lebih daripada satu contoh program pelayan. Untuk melakukan ini, pelayan Nginx dengan tetapan yang sesuai berfungsi sebagai pengimbang beban ab kepada proses pelayan kami.
  • zerohttpd.unixism.net: Di sini kami menjalankan program pelayan kami pada tujuh seni bina yang berbeza, satu demi satu.
  • redis.unixism.net: Pelayan ini menjalankan daemon Redis, tempat entri buku tetamu dan kaunter pelawat disimpan.

Semua pelayan berjalan pada teras pemproses yang sama. Ideanya adalah untuk menilai prestasi maksimum setiap seni bina. Memandangkan semua program pelayan diuji pada perkakasan yang sama, ini adalah garis dasar untuk perbandingan. Persediaan ujian saya terdiri daripada pelayan maya yang disewa daripada Digital Ocean.

Apa yang kita ukur?

Anda boleh mengukur penunjuk yang berbeza. Kami menilai prestasi setiap seni bina dalam konfigurasi tertentu dengan memuatkan pelayan dengan permintaan pada tahap selari yang berbeza: beban meningkat daripada 20 hingga 15 pengguna serentak.

Keputusan ujian

Carta berikut menunjukkan prestasi pelayan pada seni bina yang berbeza pada tahap selari yang berbeza. Paksi-y ialah bilangan permintaan sesaat, paksi-x ialah sambungan selari.

Prestasi aplikasi rangkaian Linux. pengenalan

Prestasi aplikasi rangkaian Linux. pengenalan

Prestasi aplikasi rangkaian Linux. pengenalan

Di bawah adalah jadual dengan keputusan.

permintaan sesaat

paralelisme
berulang
garpu
pra-garpu
penstriman
pra-penstriman
pengundian
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
penyebaran besar
2138

5000
-
penyebaran besar
1600
1100
2519
-
2235

8000
-
-
1200
penyebaran besar
2451
-
2100

10
-
-
penyebaran besar
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Daripada graf dan jadual dapat dilihat bahawa melebihi 8000 permintaan serentak, kami hanya mempunyai dua pemain lagi: pra-garpu dan epoll. Apabila beban meningkat, pelayan berasaskan tinjauan pendapat berprestasi lebih teruk daripada pelayan penstriman. Seni bina pra-penciptaan benang adalah pesaing yang layak untuk dinilai, bukti betapa baiknya kernel Linux menjadualkan sejumlah besar benang.

Kod Sumber ZeroHTTPd

Kod Sumber ZeroHTTPd di sini. Terdapat direktori berasingan untuk setiap seni bina.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking ─ ─ ─ ─ ─ ─ benang │ ├── utama.c ├── 04_prethreading │ ├── main.c ├── 05_poll │ ├── main.c ├── 06_epoll │ └── Make.c ─ public ─ ├ ├ fail.c ├ ├── indeks .html │ └── tux . png └── templat └── buku pelawat └── index.html

Selain tujuh direktori untuk semua seni bina, terdapat dua lagi dalam direktori peringkat teratas: awam dan templat. Yang pertama mengandungi fail index.html dan imej daripada tangkapan skrin pertama. Anda boleh meletakkan fail dan folder lain di sana, dan ZeroHTTPd harus menyediakan fail statik tersebut tanpa sebarang masalah. Jika laluan dalam penyemak imbas sepadan dengan laluan dalam folder awam, maka ZeroHTTPd mencari fail index.html dalam direktori ini. Kandungan untuk buku tetamu dijana secara dinamik. Ia hanya mempunyai halaman utama dan kandungannya adalah berdasarkan fail 'templates/guestbook/index.html'. ZeroHTTPd dengan mudah menambah halaman dinamik untuk sambungan. Ideanya ialah pengguna boleh menambah templat pada direktori ini dan melanjutkan ZeroHTTPd mengikut keperluan.

Untuk membina kesemua tujuh pelayan, jalankan make all daripada direktori peringkat atas - dan semua binaan akan muncul dalam direktori ini. Fail boleh laku mencari direktori awam dan templat dalam direktori dari mana ia dilancarkan.

API Linux

Anda tidak perlu mahir dalam API Linux untuk memahami maklumat dalam siri artikel ini. Walau bagaimanapun, saya mengesyorkan membaca lebih lanjut mengenai topik ini; terdapat banyak sumber rujukan di Internet. Walaupun kami akan menyentuh beberapa kategori API Linux, tumpuan kami akan tertumpu pada proses, urutan, peristiwa dan susunan rangkaian. Selain buku dan artikel tentang API Linux, saya juga mengesyorkan membaca mana untuk panggilan sistem dan fungsi perpustakaan yang digunakan.

Prestasi dan Kebolehskalaan

Satu nota tentang prestasi dan kebolehskalaan. Secara teorinya, tidak ada hubungan antara mereka. Anda boleh mempunyai perkhidmatan web yang berfungsi dengan baik, dengan masa tindak balas beberapa milisaat, tetapi ia tidak berskala sama sekali. Begitu juga, mungkin terdapat aplikasi web berprestasi buruk yang mengambil masa beberapa saat untuk bertindak balas, tetapi ia berskala berpuluh-puluh untuk mengendalikan berpuluh-puluh ribu pengguna serentak. Walau bagaimanapun, gabungan prestasi tinggi dan kebolehskalaan adalah gabungan yang sangat berkuasa. Aplikasi berprestasi tinggi biasanya menggunakan sumber secara berjimat-cermat dan dengan itu memberi perkhidmatan kepada lebih ramai pengguna serentak pada pelayan dengan cekap, mengurangkan kos.

Tugas CPU dan I/O

Akhir sekali, dalam pengkomputeran sentiasa terdapat dua jenis tugas yang mungkin: untuk I/O dan CPU. Menerima permintaan melalui Internet (rangkaian I/O), menyampaikan fail (rangkaian dan cakera I/O), berkomunikasi dengan pangkalan data (rangkaian dan cakera I/O) adalah semua aktiviti I/O. Sesetengah pertanyaan pangkalan data boleh menjadi sedikit intensif CPU (menyisih, purata sejuta hasil, dll.). Kebanyakan aplikasi web dihadkan oleh I/O maksimum yang mungkin, dan pemproses jarang digunakan pada kapasiti penuh. Apabila anda melihat bahawa beberapa tugas I/O menggunakan banyak CPU, kemungkinan besar ia adalah tanda seni bina aplikasi yang lemah. Ini boleh bermakna bahawa sumber CPU dibazirkan pada pengurusan proses dan penukaran konteks - dan ini tidak berguna sepenuhnya. Jika anda melakukan sesuatu seperti pemprosesan imej, penukaran fail audio atau pembelajaran mesin, maka aplikasi itu memerlukan sumber CPU yang berkuasa. Tetapi untuk kebanyakan aplikasi ini tidak berlaku.

Ketahui lebih lanjut tentang seni bina pelayan

  1. Bahagian I: Seni Bina Berulang
  2. Bahagian II. Pelayan garpu
  3. Bahagian III. Pelayan pra-garpu
  4. Bahagian IV. Pelayan dengan urutan pelaksanaan
  5. Bahagian V. Pelayan pra-benang
  6. Bahagian VI. Seni bina berasaskan Pol
  7. Bahagian VII. seni bina berasaskan epoll

Sumber: www.habr.com

Tambah komen