
Sugeng rawuh, Habr! Aku Artem Karamyshev, kepala tim administrasi sistem . Kita duwe akeh peluncuran produk anyar sajrone taun kepungkur. We wanted kanggo mesthekake yen layanan API gampang keukur, fault-tolerant, lan siap kanggo wutah kanthi cepet ing mbukak pangguna. Platform kita diimplementasikake ing OpenStack, lan aku pengin menehi pitutur marang kowe apa masalah toleransi kesalahan komponen sing kudu diatasi kanggo entuk sistem toleransi kesalahan. Aku mikir iki bakal menarik kanggo wong-wong sing uga ngembangake produk ing OpenStack.
Toleransi kesalahan sakabèhé saka platform kasusun saka daya tahan komponen. Dadi, kita bakal ngliwati kabeh level sing kita nemtokake risiko lan nutup.
Versi video crita iki, sumber utama yaiku laporan ing konferensi Uptime dina 4, diatur dening , sampeyan bisa ndeleng .
Ketahanan arsitektur fisik
Bagian umum awan MCS saiki adhedhasar rong pusat data Tier III, ing antarane ana serat peteng dhewe, dilindhungi undhang-undhang ing tingkat fisik kanthi rute sing beda-beda, kanthi throughput 200 Gbit / s. Tier III nyedhiyakake tingkat toleransi kesalahan sing dibutuhake kanggo infrastruktur fisik.
Serat peteng dilindhungi undhang-undhang ing tingkat fisik lan logis. Proses reservasi saluran kasebut terus-terusan, ana masalah, lan kita terus nambah komunikasi antarane pusat data.
Contone, durung suwe, nalika nggarap sumur cedhak salah sawijining pusat data, excavator nyuwil pipa, lan ing jero pipa iki ana kabel optik utama lan serep. Saluran komunikasi fault-tolerant karo pusat data dadi rawan ing sawijining titik, ing sumur. Mulane, kita wis ilang bagean saka infrastruktur. Kita nggawe kesimpulan lan njupuk sawetara tumindak, kalebu nginstal optik tambahan ing sumur jejer.
Ing pusat data ana titik ngarsane panyedhiya komunikasi sing kita nyebarake prefiks liwat BGP. Kanggo saben arah jaringan, metrik sing paling apik dipilih, sing ngidini klien sing beda-beda diwenehake kanthi kualitas sambungan sing paling apik. Yen komunikasi liwat siji panyedhiya mudhun, kita mbangun maneh rute liwat panyedhiya sing kasedhiya.
Yen panyedhiya gagal, kita kanthi otomatis ngalih menyang sing sabanjure. Yen gagal salah sawijining pusat data, kita duwe salinan pangilon saka layanan kita ing pusat data kapindho, sing njupuk kabeh beban.

Ketahanan infrastruktur fisik
Apa sing digunakake kanggo toleransi kesalahan tingkat aplikasi
Layanan kita dibangun ing sawetara komponen opensource.
ExaBGP iku layanan sing nindakake sawetara fungsi nggunakake protokol nuntun dinamis basis BGP. Kita aktif nggunakake aplikasi kasebut kanggo ngiklanake alamat IP sing wis diwènèhi putih kanggo pangguna ngakses API.
HAProxy punika imbangan dhuwur-muatan sing ngijini sampeyan kanggo ngatur aturan imbangan lalu lintas fleksibel banget ing tingkat beda saka model OSI. Kita digunakake kanggo ngimbangi ing ngarep kabeh layanan: database, makelar pesen, layanan API, layanan web, proyek internal kita - kabeh ana ing mburi HAProxy.
aplikasi API - aplikasi web sing ditulis nganggo python, sing pangguna ngatur infrastruktur lan layanane.
Aplikasi buruh (Sabanjure mung buruh) - ing layanan OpenStack, iki minangka daemon infrastruktur sing ngidini sampeyan nyiarake perintah API menyang infrastruktur kasebut. Contone, nggawe disk ana ing buruh, lan panjalukan nggawe ana ing API aplikasi.
Arsitektur Aplikasi OpenStack Standar
Umume layanan sing dikembangake kanggo OpenStack nyoba ngetutake paradigma siji. A layanan biasane kasusun saka 2 bagean: API lan buruh (pelaksana backend). Minangka aturan, API minangka aplikasi WSGI ing python, sing diluncurake minangka proses independen (daemon), utawa nggunakake server web Nginx utawa Apache sing wis siap. API ngolah panjaluk pangguna lan menehi instruksi luwih lanjut menyang aplikasi pekerja kanggo dieksekusi. Transfer kasebut nggunakake makelar pesen, biasane RabbitMQ, sing liyane ora didukung. Nalika pesen tekan makelar, diproses dening para pekerja lan, yen perlu, bali tanggapan.
Paradigma iki kalebu titik-titik kegagalan umum sing terisolasi: RabbitMQ lan database. Nanging RabbitMQ diisolasi ing siji layanan lan, ing teori, bisa dadi individu kanggo saben layanan. Dadi ing MCS kita misahake layanan kasebut sabisa-bisa; kanggo saben proyek individu kita nggawe database sing kapisah, RabbitMQ sing kapisah. Pendekatan iki apik amarga yen ana kacilakan ing sawetara titik sing rawan, ora kabeh layanan rusak, nanging mung bagean kasebut.
Jumlah aplikasi pegawe ora winates, supaya API bisa gampang skala horisontal konco balancers kanggo nambah kinerja lan toleransi fault.
Sawetara layanan mbutuhake koordinasi ing layanan nalika operasi sekuensial rumit dumadi ing antarane API lan buruh. Ing kasus iki, pusat koordinasi siji digunakake, sistem kluster kayata Redis, Memcache, etcd, sing ngidini siji buruh marang liyane sing tugas iki diutus kanggo wong ("monggo ora njupuk"). Kita nggunakake etc. Minangka aturan, buruh aktif komunikasi karo database, nulis lan maca informasi saka ing kono. Kita nggunakake mariadb minangka basis data, sing dumunung ing kluster multimaster.
Layanan tunggal klasik iki diatur kanthi cara sing umum ditampa kanggo OpenStack. Bisa dianggep minangka sistem tertutup, sing cara skala lan toleransi kesalahan cukup jelas. Contone, kanggo toleransi fault API, iku cukup kanggo sijine balancer ing ngarepe. Pekerja skala digayuh kanthi nambah jumlahe.
Titik lemah ing kabeh skema yaiku RabbitMQ lan MariaDB. Arsitèkturé pantes artikel kapisah. Ing artikel iki aku arep fokus ing toleransi fault API.

Arsitektur Aplikasi Openstack. Balancing lan toleransi fault saka platform maya
Nggawe HAProxy balancer fault-tolerant nggunakake ExaBGP
Kanggo nggawe API kita bisa diukur, cepet lan tahan kesalahan, kita sijine load balancer ing ngarepe. Kita milih HAProxy. Ing mratelakake panemume, wis kabeh ciri sing perlu kanggo tugas kita: imbangan ing sawetara tingkat OSI, antarmuka Manajemen, keluwesan lan kaukur, nomer akeh cara wawas, support kanggo tabel sesi.
Masalah pisanan sing kudu ditanggulangi yaiku toleransi kesalahan saka balancer kasebut. Mung nginstal balancer uga nggawe titik gagal: balancer break lan layanan crash. Kanggo nyegah kedadeyan kasebut, kita nggunakake HAProxy bebarengan karo ExaBGP.
ExaBGP ngidini sampeyan ngleksanakake mekanisme kanggo mriksa kahanan layanan. Kita nggunakake mekanisme iki kanggo mriksa fungsi HAProxy lan, yen ana masalah, mateni layanan HAProxy saka BGP.
Skema ExaBGP+HAProxy
- Kita nginstal piranti lunak sing dibutuhake, ExaBGP lan HAProxy, ing telung server.
- Kita nggawe antarmuka loopback ing saben server.
- Ing kabeh telung server, kita nemtokake alamat IP putih sing padha menyang antarmuka iki.
- Alamat IP putih diiklanake menyang Internet liwat ExaBGP.
Toleransi kesalahan digayuh kanthi ngiklanake alamat IP sing padha saka kabeh telung server. Saka sudut pandang jaringan, alamat sing padha bisa diakses saka telung hop sabanjure. Router ndeleng telung rute sing padha, milih prioritas sing paling dhuwur adhedhasar metrik dhewe (iki biasane pilihan sing padha), lan lalu lintas mung menyang salah sawijining server.
Yen ana masalah karo operasi HAProxy utawa kegagalan server, ExaBGP mandheg ngumumake rute kasebut, lan lalu lintas kanthi lancar pindhah menyang server liyane.
Mangkono, kita entuk toleransi kesalahan saka balancer.

Toleransi kesalahan HAProxy balancers
Skema kasebut dadi ora sampurna: kita sinau babagan cadangan HAProxy, nanging ora sinau babagan nyebarake beban ing layanan kasebut. Mulane, kita nggedhekake skema iki sethithik: kita pindhah menyang keseimbangan antarane sawetara alamat IP putih.
Balancing adhedhasar DNS plus BGP
Masalah imbangan beban kanggo HAProxy kita tetep ora dirampungake. Nanging, bisa ditanggulangi kanthi gampang, kaya sing ditindakake ing kene.
Kanggo ngimbangi telung server sampeyan butuh 3 alamat IP putih lan DNS lawas sing apik. Saben alamat kasebut ditemtokake ing antarmuka loopback saben HAProxy lan diiklanake menyang Internet.
Ing OpenStack, kanggo ngatur sumber daya, direktori layanan digunakake, sing nemtokake API endpoint saka layanan tartamtu. Ing direktori iki kita ndhaptar jeneng domain - public.infra.mail.ru, sing ditanggulangi liwat DNS kanthi telung alamat IP sing beda. Akibaté, kita entuk distribusi beban ing antarane telung alamat liwat DNS.
Nanging wiwit nalika ngumumake alamat IP putih, kita ora ngontrol prioritas pilihan server, iki durung ngimbangi. Biasane, mung siji server sing bakal dipilih adhedhasar senioritas alamat IP, lan loro liyane bakal nganggur amarga ora ana metrik sing ditemtokake ing BGP.
Kita miwiti ngirim rute liwat ExaBGP kanthi metrik sing beda. Saben penyeimbang ngiklanake kabeh telung alamat IP putih, nanging salah sijine, sing utama kanggo penyeimbang iki, diiklanake kanthi metrik minimal. Dadi, nalika kabeh telung balancer lagi operasi, telpon menyang alamat IP pisanan pindhah menyang balancer pisanan, nelpon kanggo kaloro kanggo kaloro, lan nelpon kanggo katelu kanggo katelu.
Apa sing kedadeyan nalika salah sijine penyeimbang tiba? Yen ana balancer gagal, alamat utama isih diiklanake saka loro liyane, lan lalu lintas disebarake ing antarane. Mangkono, kita menehi pangguna sawetara alamat IP bebarengan liwat DNS. Kanthi ngimbangi DNS lan metrik sing beda, kita entuk distribusi beban sing rata ing kabeh telung balancer. Lan ing wektu sing padha kita ora kelangan toleransi fault.

Balancing HAProxy adhedhasar DNS + BGP
Interaksi antarane ExaBGP lan HAProxy
Dadi, kita ngetrapake toleransi kesalahan yen server ninggalake, adhedhasar mungkasi pengumuman rute. Nanging HAProxy bisa mati amarga alasan liyane saka kegagalan server: kesalahan administrasi, kegagalan ing layanan kasebut. Kita uga pengin mbusak balancer sing rusak saka beban ing kasus kasebut, lan kita butuh mekanisme sing beda.
Mula, ngembangake skema sadurunge, kita ngetrapake denyut jantung ing antarane ExaBGP lan HAProxy. Iki minangka implementasine piranti lunak saka interaksi antarane ExaBGP lan HAProxy, nalika ExaBGP nggunakake skrip khusus kanggo mriksa status aplikasi.
Kanggo nindakake iki, sampeyan kudu ngatur pemeriksa kesehatan ing konfigurasi ExaBGP, sing bisa mriksa status HAProxy. Ing kasus kita, kita ngatur backend kesehatan ing HAProxy, lan saka sisih ExaBGP kita mriksa kanthi panjalukan GET sing prasaja. Yen woro-woro mandheg kedadeyan, mula HAProxy kemungkinan ora bisa digunakake lan ora perlu ngiklanake.

Pemeriksaan Kesehatan HAProxy
HAProxy Peers: sinkronisasi sesi
Sabanjure sing kudu ditindakake yaiku nyinkronake sesi. Nalika nggarap balancers sing disebarake, angel ngatur panyimpenan informasi babagan sesi klien. Nanging HAProxy minangka salah sawijining sawetara penyeimbang sing bisa nindakake iki amarga fungsi Peers - kemampuan kanggo mindhah tabel sesi ing antarane proses HAProxy sing beda.
Ana macem-macem cara balancing: sing prasaja kayata , lan ditambahi, nalika sesi klien dieling-eling, lan saben wektu dheweke rampung ing server sing padha kaya sadurunge. We wanted kanggo ngleksanakake pilihan kapindho.
HAProxy nggunakake meja kelet kanggo nyimpen sesi klien mekanisme iki. Dheweke nyimpen alamat IP asli klien, alamat target sing dipilih (backend) lan sawetara informasi layanan. Biasane, tabel kelet digunakake kanggo nyimpen pasangan sumber-IP + tujuan-IP, kang utamané migunani kanggo aplikasi sing ora bisa nransfer konteks sesi pangguna nalika ngalih menyang balancer liyane, Contone, ing mode wawas RoundRobin.
Yen meja kelet diwulangake kanggo mindhah antarane pangolahan HAProxy sing beda-beda (antarane keseimbangane), penyeimbang kita bakal bisa nggarap siji meja blumbang. Iki bakal nggawe bisa ngalih jaringan klien kanthi lancar yen salah sijine penyeimbang gagal; nggarap sesi klien bakal terus ing backend sing padha sing dipilih sadurunge.
Kanggo operasi sing tepat, masalah alamat IP sumber saka balancer saka sesi kasebut kudu dirampungake. Ing kasus kita, iki minangka alamat dinamis ing antarmuka loopback.
Karya sing bener saka kanca-kanca mung bisa ditindakake ing kahanan tartamtu. Tegese, wektu entek TCP kudu cukup gedhe utawa ngoper kudu cukup cepet supaya sesi TCP ora duwe wektu kanggo mungkasi. Nanging, ngidini kanggo ngoper mulus.
Ing IaaS kita duwe layanan sing dibangun nggunakake teknologi sing padha. Iki , sing diarani Octavia. Iki adhedhasar rong proses HAProxy lan wiwitane kalebu dhukungan kanggo kanca-kanca. Dheweke wis mbuktekake awake dhewe apik banget ing layanan iki.
Gambar kasebut kanthi skematis nuduhake gerakan tabel peer ing antarane telung conto HAProxy, konfigurasi diusulake babagan carane bisa dikonfigurasi:

HAProxy Peers (sinkronisasi sesi)
Yen sampeyan ngleksanakake skema sing padha, operasi kasebut kudu diuji kanthi teliti. Iku ora kasunyatan sing bakal bisa ing cara sing padha 100% wektu. Nanging paling sampeyan ora bakal kelangan tabel kelet nalika sampeyan kudu ngelingi IP sumber klien.
Watesan jumlah panjalukan simultan saka klien sing padha
Layanan apa wae sing kasedhiya kanggo umum, kalebu API kita, bisa tundhuk panjaluk longsor. Alasan kanggo wong-wong mau bisa beda-beda, saka kesalahan pangguna nganti serangan sing ditarget. Kita sacara periodik DDoSed dening alamat IP. Klien asring nggawe kesalahan ing skrip lan menehi mini-DDoSs.
Siji cara utawa liyane, proteksi tambahan kudu diwenehake. Solusi sing jelas yaiku mbatesi jumlah panjaluk API lan ora mbuwang wektu CPU ngolah panjaluk sing ala.
Kanggo ngleksanakake watesan kuwi, kita nggunakake watesan tarif, diatur ing basis saka HAProxy, nggunakake tabel kelet padha. Nyetel watesan cukup prasaja lan ngidini sampeyan mbatesi pangguna kanthi jumlah panjaluk menyang API. Algoritma ngelingi IP sumber saka ngendi panjalukan digawe lan mbatesi jumlah panjalukan simultan saka siji pangguna. Mesthi, kita ngetung profil beban API rata-rata kanggo saben layanan lan nyetel watesan ≈ 10 kaping nilai iki. Kita terus ngawasi kahanan kasebut kanthi rapet lan tetep driji ing pulsa.
Apa iki katon kaya ing laku? Kita duwe pelanggan sing nggunakake API autoscaling kita kabeh wektu. Dheweke nggawe kira-kira rong nganti telung atus mesin virtual ing wayah esuk lan mbusak ing wayah sore. Kanggo OpenStack, nggawe mesin virtual, uga nganggo layanan PaaS, mbutuhake paling ora 1000 panjalukan API, amarga interaksi antarane layanan uga dumadi liwat API.
Transfer tugas kasebut nyebabake beban sing cukup gedhe. Kita ngevaluasi beban iki, nglumpukake puncak saben dina, nambah kaping sepuluh, lan iki dadi watesan tarif. Kita tetep driji ing pulsa. Kita kerep ndeleng bot lan scanner sing nyoba kanggo ndeleng apa kita duwe script CGA sing bisa mbukak, kita aktif Cut mau.
Cara nganyari basis kode sampeyan tanpa diweruhi pangguna
Kita uga ngleksanakake toleransi fault ing tingkat pangolahan penyebaran kode. Bisa uga ana gangguan nalika diluncurake, nanging pengaruhe ing kasedhiyan layanan bisa diminimalisir.
Kita terus-terusan nganyari layanan lan kudu mesthekake yen basis kode dianyari tanpa mengaruhi pangguna. Kita bisa ngatasi masalah iki kanthi nggunakake kapabilitas manajemen HAProxy lan implementasine Graceful Shutdown ing layanan kita.
Kanggo ngatasi masalah iki, perlu kanggo mesthekake kontrol balancer lan "bener" mati layanan:
- Ing kasus HAProxy, kontrol ditindakake liwat file stats, sing sejatine minangka soket lan ditetepake ing konfigurasi HAProxy. Sampeyan bisa ngirim printah menyang liwat stdio. Nanging alat kontrol konfigurasi utama kita ansible, supaya duwe modul dibangun ing ngatur HAProxy. Sing digunakake kanthi aktif.
- Umume layanan API lan Mesin ndhukung teknologi mateni sing apik: nalika mateni, dheweke ngenteni tugas saiki rampung, dadi panyuwunan http utawa sawetara tugas layanan. Bab sing padha karo buruh. Dheweke ngerti kabeh tugas sing ditindakake lan rampung yen wis rampung kabeh.
Thanks kanggo rong titik kasebut, algoritma aman kanggo penyebaran kita katon kaya iki.
- Pangembang nglumpukake paket kode anyar (kanggo kita iki RPM), nguji ing lingkungan dev, nguji ing panggung, lan ninggalake ing repositori panggung.
- Pangembang nyetel tugas kanggo penyebaran kanthi katrangan sing paling rinci babagan "artefak": versi paket anyar, deskripsi fungsi anyar lan rincian liyane babagan penyebaran yen perlu.
- Administrator sistem miwiti nganyari. Bukak playbook Ansible, sing banjur nindakake ing ngisor iki:
- Njupuk paket saka gudang panggung lan digunakake kanggo nganyari versi paket ing gudang produk.
- Compiles dhaftar backends saka layanan dianyari.
- Mateni layanan pisanan sing dianyari ing HAProxy lan ngenteni proses rampung. Thanks kanggo shutdown sing apik, kita yakin manawa kabeh panjaluk klien saiki bakal rampung kanthi sukses.
- Sawise API lan buruh rampung mandheg, lan HAProxy dipateni, kode kasebut dianyari.
- Ansible mlaku layanan.
- Kanggo saben layanan, "pegangan" tartamtu ditarik, sing nindakake tes unit ing sawetara tes kunci sing wis ditemtokake. A mriksa dhasar saka kode anyar njupuk Panggonan.
- Yen ora ana kesalahan ing langkah sadurunge, backend diaktifake.
- Ayo pindhah menyang backend sabanjuré.
- Sawise kabeh backend dianyari, tes fungsional diluncurake. Yen ora ana, mula pangembang ndeleng fungsi anyar sing digawe.
Iki ngrampungake panyebaran.

Siklus nganyari layanan
Skema iki ora bakal bisa digunakake yen kita ora duwe siji aturan. Kita ndhukung versi lawas lan anyar ing perang. Ing advance, ing tataran pangembangan piranti lunak wis glethakaken mudhun sanajan ana owah-owahan ing database layanan, padha ora bakal break kode sadurungé. Akibaté, basis kode dianyari kanthi bertahap.
kesimpulan
Nuduhake pikirane dhewe babagan arsitektur WEB sing tahan kesalahan, aku pengin maneh nyathet poin-poin penting:
- toleransi fault fisik;
- toleransi kesalahan jaringan (balancer, BGP);
- toleransi fault saka piranti lunak digunakake lan dikembangaké.
Uptime stabil kabeh!
Source: www.habr.com
