Netramesh - solusi mesh layanan ringan

Saat kami beralih dari aplikasi monolitik ke arsitektur layanan mikro, kami menghadapi tantangan baru.

Dalam aplikasi monolitik, biasanya cukup mudah untuk menentukan di bagian sistem mana kesalahan terjadi. Kemungkinan besar, masalahnya ada pada kode monolit itu sendiri, atau pada database. Namun ketika kami mulai mencari masalah dalam arsitektur layanan mikro, semuanya tidak lagi terlihat jelas. Kita perlu menemukan seluruh jalur yang diambil permintaan dari awal hingga akhir dan memilihnya dari ratusan layanan mikro. Selain itu, banyak dari mereka juga memiliki fasilitas penyimpanan sendiri, yang juga dapat menyebabkan kesalahan logika, serta masalah kinerja dan toleransi kesalahan.

Netramesh - solusi mesh layanan ringan

Saya telah lama mencari alat yang dapat membantu mengatasi masalah seperti itu (saya menulis tentang ini di HabrΓ©: 1, 2), namun pada akhirnya saya membuat solusi open source sendiri. Pada artikel ini saya berbicara tentang manfaat pendekatan service mesh dan berbagi alat baru untuk implementasinya.

Penelusuran terdistribusi adalah solusi umum untuk masalah menemukan kesalahan dalam sistem terdistribusi. Tetapi bagaimana jika pendekatan pengumpulan informasi tentang interaksi jaringan ini belum diterapkan dalam sistem, atau, lebih buruk lagi, sebagian sistem sudah berfungsi dengan baik, tetapi sebagian lagi tidak, karena belum ditambahkan ke layanan lama. ? Untuk mengetahui secara pasti akar penyebab suatu masalah, diperlukan gambaran lengkap tentang apa yang terjadi pada sistem. Sangat penting untuk memahami layanan mikro mana yang terlibat dalam jalur utama bisnis yang penting.

Di sini pendekatan mesh layanan dapat membantu kami, yang akan menangani semua mesin untuk mengumpulkan informasi jaringan pada tingkat yang lebih rendah daripada layanan itu sendiri yang beroperasi. Pendekatan ini memungkinkan kami mencegat semua lalu lintas dan menganalisisnya dengan cepat. Selain itu, aplikasi bahkan tidak perlu mengetahui apa pun tentangnya.

Pendekatan jaring layanan

Ide utama dari pendekatan mesh layanan adalah untuk menambahkan lapisan infrastruktur lain melalui jaringan, yang memungkinkan kita melakukan apa pun dengan interaksi antar layanan. Sebagian besar implementasi bekerja sebagai berikut: wadah sespan tambahan dengan proksi transparan ditambahkan ke setiap layanan mikro, yang melaluinya semua lalu lintas masuk dan keluar layanan dilewatkan. Dan di sinilah kita dapat melakukan penyeimbangan klien, menerapkan kebijakan keamanan, menerapkan pembatasan jumlah permintaan, dan mengumpulkan informasi penting tentang interaksi layanan dalam produksi.

Netramesh - solusi mesh layanan ringan

Solusi

Sudah ada beberapa implementasi dari pendekatan ini: Istio ΠΈ linkerd2. Mereka menyediakan banyak fitur di luar kotak. Namun pada saat yang sama, terdapat pengeluaran sumber daya yang besar. Selain itu, semakin besar cluster tempat sistem beroperasi, semakin banyak sumber daya yang dibutuhkan untuk memelihara infrastruktur baru. Di Avito, kami mengoperasikan cluster kubernetes yang berisi ribuan instance layanan (dan jumlahnya terus bertambah pesat). Dalam implementasinya saat ini, Istio menggunakan ~300Mb RAM per mesin virtual layanan. Karena banyaknya kemungkinan, penyeimbangan transparan juga memengaruhi waktu respons layanan secara keseluruhan (hingga 10 ms).

Hasilnya, kami melihat kemampuan apa yang kami butuhkan saat ini, dan memutuskan bahwa alasan utama mengapa kami mulai menerapkan solusi tersebut adalah kemampuan untuk mengumpulkan informasi penelusuran dari seluruh sistem secara transparan. Kami juga ingin memiliki kendali atas interaksi layanan dan melakukan berbagai manipulasi dengan header yang ditransfer antar layanan.

Hasilnya, kami mengambil keputusan:β€Š Netramesh.

Netramesh

Netramesh adalah solusi mesh layanan ringan dengan kemampuan untuk menskalakan tanpa batas, berapa pun jumlah layanan dalam sistem.

Sasaran utama dari solusi baru ini adalah overhead sumber daya yang rendah dan kinerja yang tinggi. Di antara fitur-fitur utamanya, kami langsung ingin dapat mengirimkan rentang penelusuran secara transparan ke sistem Jaeger kami.

Saat ini, sebagian besar solusi cloud diterapkan di Golang. Dan tentu saja ada alasannya. Menulis aplikasi jaringan di Golang yang bekerja secara asinkron dengan I/O dan menskalakan seluruh inti sesuai kebutuhan sangatlah mudah dan cukup sederhana. Dan yang juga sangat penting, performanya cukup untuk mengatasi masalah ini. Itu sebabnya kami juga memilih Golang.

Performa

Kami telah memfokuskan upaya kami untuk mencapai produktivitas maksimum. Untuk solusi yang diterapkan di samping setiap contoh layanan, diperlukan konsumsi RAM dan waktu CPU yang kecil. Dan, tentu saja, penundaan responsnya juga harus kecil.

Mari kita lihat hasil apa yang kita dapatkan.

RAM

Netramesh menggunakan ~10Mb tanpa lalu lintas dan maksimum 50Mb dengan beban hingga 10000 RPS per instans.

Proksi utusan Istio selalu menggunakan ~300Mb di cluster kami dengan ribuan instance. Hal ini tidak memungkinkannya untuk diperluas ke seluruh cluster.

Netramesh - solusi mesh layanan ringan

Netramesh - solusi mesh layanan ringan

Dengan Netramesh kami mendapat pengurangan konsumsi memori ~10x.

CPU

Penggunaan CPU relatif sama saat dimuat. Itu tergantung pada jumlah permintaan per satuan waktu ke sespan. Nilai pada 3000 permintaan per detik pada puncaknya:

Netramesh - solusi mesh layanan ringan

Netramesh - solusi mesh layanan ringan

Ada satu poin penting lagi: Netramesh - solusi tanpa bidang kendali dan tanpa beban tidak menghabiskan waktu CPU. Dengan Istio, sidecar selalu memperbarui titik akhir layanan. Hasilnya, kita bisa melihat gambar ini tanpa memuat:

Netramesh - solusi mesh layanan ringan

Kami menggunakan HTTP/1 untuk komunikasi antar layanan. Peningkatan waktu respons Istio saat melakukan proxy melalui utusan mencapai 5-10 ms, yang mana merupakan jumlah yang cukup banyak untuk layanan yang siap merespons dalam hitungan milidetik. Dengan Netramesh kali ini mengalami penurunan menjadi 0.5-2ms.

Skalabilitas

Sejumlah kecil sumber daya yang dikonsumsi oleh setiap proxy memungkinkan untuk menempatkannya di samping setiap layanan. Netramesh sengaja dibuat tanpa komponen bidang kendali untuk menjaga setiap sespan tetap ringan. Seringkali dalam solusi mesh layanan, bidang kontrol mendistribusikan informasi penemuan layanan ke setiap sidecar. Bersamaan dengan itu muncul informasi tentang batas waktu dan pengaturan keseimbangan. Semua ini memungkinkan Anda melakukan banyak hal berguna, tetapi sayangnya, ukurannya membengkak.

Penemuan layanan

Netramesh - solusi mesh layanan ringan

Netramesh tidak menambahkan mekanisme tambahan apa pun untuk penemuan layanan. Semua lalu lintas diproksi secara transparan melalui netra sespan.

Netramesh mendukung protokol aplikasi HTTP/1. Untuk mendefinisikannya, daftar port yang dapat dikonfigurasi digunakan. Biasanya, sistem memiliki beberapa port yang melaluinya komunikasi HTTP terjadi. Misalnya, kami menggunakan 80, 8890, 8080 untuk interaksi antara layanan dan permintaan eksternal. Dalam hal ini, mereka dapat diatur menggunakan variabel lingkungan NETRA_HTTP_PORTS.

Jika Anda menggunakan Kubernetes sebagai orkestrator dan mekanisme entitas Layanannya untuk komunikasi intra-cluster antar layanan, maka mekanismenya akan tetap sama. Pertama, layanan mikro memperoleh alamat IP layanan menggunakan kube-dns dan membuka koneksi baru ke sana. Koneksi ini pertama kali dibuat dengan netra-sidecar lokal dan semua paket TCP awalnya tiba di netra. Selanjutnya, netra-sidecar membuat koneksi dengan tujuan awal. NAT pada pod IP pada node tetap sama persis dengan tanpa netra.

Pelacakan terdistribusi dan penerusan konteks

Netramesh menyediakan fungsionalitas yang diperlukan untuk mengirim rentang penelusuran tentang interaksi HTTP. Netra-sidecar mengurai protokol HTTP, mengukur penundaan permintaan, dan mengekstrak informasi yang diperlukan dari header HTTP. Pada akhirnya, kami mendapatkan semua jejak dalam satu sistem Jaeger. Untuk konfigurasi yang lebih detail, Anda juga dapat menggunakan variabel lingkungan yang disediakan oleh perpustakaan resmi perpustakaan jaeger pergi.

Netramesh - solusi mesh layanan ringan

Netramesh - solusi mesh layanan ringan

Tapi ada masalah. Sampai layanan menghasilkan dan mengirimkan header uber khusus, kami tidak akan melihat rentang penelusuran yang terhubung dalam sistem. Dan inilah yang kita butuhkan untuk segera menemukan penyebab masalahnya. Di sini sekali lagi Netramesh punya solusinya. Proksi membaca header HTTP dan, jika tidak berisi id jejak uber, buatlah header. Netramesh juga menyimpan informasi tentang permintaan masuk dan keluar di sespan dan mencocokkannya dengan memperkayanya dengan header permintaan keluar yang diperlukan. Yang perlu Anda lakukan dalam layanan ini hanyalah mengirim satu header saja X-Request-Id, yang dapat dikonfigurasi menggunakan variabel lingkungan NETRA_HTTP_REQUEST_ID_HEADER_NAME. Untuk mengontrol ukuran konteks di Netramesh, Anda dapat mengatur variabel lingkungan berikut: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (waktu penyimpanan konteks) dan NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (frekuensi pembersihan konteks).

Dimungkinkan juga untuk menggabungkan beberapa jalur di sistem Anda dengan menandainya dengan token sesi khusus. Netra memungkinkan Anda untuk menginstal HTTP_HEADER_TAG_MAP untuk mengubah header HTTP menjadi tag rentang penelusuran yang sesuai. Ini bisa sangat berguna untuk pengujian. Setelah lulus uji fungsional, Anda dapat melihat bagian sistem mana yang terpengaruh dengan memfilter berdasarkan kunci sesi yang sesuai.

Menentukan Sumber Permintaan

Untuk menentukan dari mana permintaan itu berasal, Anda dapat menggunakan fungsi menambahkan header secara otomatis dengan sumbernya. Menggunakan variabel lingkungan NETRA_HTTP_X_SOURCE_HEADER_NAME Anda dapat menentukan nama header yang akan diinstal secara otomatis. Dengan menggunakan NETRA_HTTP_X_SOURCE_VALUE Anda dapat mengatur nilai header X-Source yang akan ditetapkan untuk semua permintaan keluar.

Hal ini memungkinkan distribusi header yang berguna ini didistribusikan secara merata ke seluruh jaringan. Kemudian Anda dapat menggunakannya di layanan dan menambahkannya ke log dan metrik.

Perutean lalu lintas dan internal Netramesh

Netramesh terdiri dari dua komponen utama. Yang pertama, netra-init, menetapkan aturan jaringan untuk mencegat lalu lintas. Dia menggunakan aturan pengalihan iptables untuk mencegat seluruh atau sebagian lalu lintas dengan sespan, yang merupakan komponen utama kedua Netramesh. Anda dapat mengonfigurasi port mana yang perlu dicegat untuk sesi TCP masuk dan keluar: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Alat ini juga memiliki fitur menarik - perutean probabilistik. Jika Anda menggunakan Netramesh secara eksklusif untuk mengumpulkan rentang penelusuran, maka di lingkungan produksi Anda dapat menghemat sumber daya dan mengaktifkan perutean probabilistik menggunakan variabel NETRA_INBOUND_PROBABILITY ΠΈ NETRA_OUTBOUND_PROBABILITY (dari 0 hingga 1). Nilai defaultnya adalah 1 (semua lalu lintas disadap).

Setelah intersepsi berhasil, netra sespan menerima koneksi baru dan menggunakannya SO_ORIGINAL_DST opsi soket untuk mendapatkan tujuan awal. Netra kemudian membuka koneksi baru ke alamat IP asli dan menjalin komunikasi TCP dua arah antara para pihak, mendengarkan semua lalu lintas yang lewat. Jika port didefinisikan sebagai HTTP, Netra mencoba menguraikan dan melacaknya. Jika penguraian HTTP gagal, Netra kembali ke TCP dan secara transparan memproksi byte tersebut.

Membangun grafik ketergantungan

Setelah menerima sejumlah besar informasi penelusuran di Jaeger, saya ingin mendapatkan grafik interaksi lengkap dalam sistem. Namun jika sistem Anda cukup terisi dan miliaran rentang penelusuran terakumulasi setiap hari, menggabungkannya menjadi bukan tugas yang mudah. Ada cara resmi untuk melakukan ini: ketergantungan percikan. Namun, diperlukan waktu berjam-jam untuk membuat grafik lengkap dan memaksa Anda mengunduh seluruh kumpulan data dari Jaeger selama XNUMX jam terakhir.

Jika Anda menggunakan Elasticsearch untuk menyimpan rentang penelusuran, Anda dapat menggunakannya utilitas Golang sederhana, yang akan membuat grafik yang sama dalam hitungan menit menggunakan fitur dan kemampuan Elasticsearch.

Netramesh - solusi mesh layanan ringan

Cara menggunakan Netramesh

Netra dapat dengan mudah ditambahkan ke layanan apa pun yang menjalankan orkestrator mana pun. Anda dapat melihat contohnya di sini.

Saat ini, Netra tidak memiliki kemampuan untuk mengimplementasikan sidecar ke layanan secara otomatis, namun ada rencana untuk mengimplementasikannya.

Masa depan Netramesh

tujuan utama Netramesh adalah untuk mencapai biaya sumber daya minimal dan kinerja tinggi, memberikan kemampuan dasar untuk observasi dan pengendalian komunikasi antar layanan.

Ke depannya, Netramesh akan mendukung protokol lapisan aplikasi lain selain HTTP. Perutean L7 akan tersedia dalam waktu dekat.

Gunakan Netramesh jika Anda mengalami masalah serupa dan kirimkan pertanyaan dan saran kepada kami.

Sumber: www.habr.com

Tambah komentar