Sistem RPC Benchmark (dan Inverted Json)


Perbandingan berbagai alat (RabbitMQ, Crossbar.io, Nats.io, Nginx, dll.) Untuk mengatur RPC antara layanan microser.

Penggunaan memori


Penggunaan CPU


Tes multi-prosesor



Artikel diperbarui 2019-12-15

Ringkasan . Implementasi panggilan RPC sinkron melalui sistem MQ klasik tidak efektif - ini memberikan penurunan kinerja dan efek samping yang perlu secara manual luka (atau dengan alat tambahan).
Inverted Json adalah server tugas ringan yang memungkinkan Anda untuk melakukan panggilan RPC sinkron "jujur" (klien dan server terhubung melalui Inverted Json untuk mengirim informasi), yang memastikan kinerja tinggi (7 kali lebih cepat dari RabbitMQ), dan komunikasi terjadi melalui http , yang memungkinkan Anda untuk menggunakan alat http apa pun, bahkan menggulung dari konsol.

1. Tes


Semua alat dibagi menjadi 3 kelompok:
  • "Sambungan langsung" - ketika klien menangani pekerja secara langsung, dalam proyek-proyek dengan sejumlah besar pekerja / layanan itu adalah yang paling sulit untuk dikonfigurasikan, ia membutuhkan "klien cerdas", yaitu saat menelepon, klien harus memiliki informasi tentang bagaimana dan ke mana harus mengirim permintaan (atau proxy lokal tambahan diperlukan), sebagai aturan itu menghasilkan beban paling sedikit di jaringan.
  • โ€œKoneksi proxyโ€ - varian dengan titik masuk tunggal, klien sederhana, tetapi pada saat yang sama kesulitan tetap ada di sisi pekerja / serial - meneruskan dan mengalokasikan port, mendaftarkan alamat untuk proxy, pengaturan firewall yang lebih rumit, alat tambahan sering digunakan untuk mengelola seluruh tambak ini .
  • "Koneksi terbalik" - satu titik masuk untuk klien dan pekerja (dapat dianggap sebagai ESB), pengaturan jaringan yang paling sederhana.
  • Memori dan penggunaan prosesor diambil dari `docker stats`
  • Dalam tes "2-core", server dan klien dengan firewall dibagi menjadi beberapa core untuk mengurangi pengaruh satu sama lain, oleh karena itu server dibatasi hingga 2 core melalui tasket (uji multi-core tanpa batasan)
Beberapa pemikiran tentang patokan di bawah ini.

2. MQ atau RPC


Meskipun kedua metode komunikasi ini berbeda, terkadang yang pertama digunakan alih-alih yang kedua dan sebaliknya.
Jika Anda mencoba menguraikan batas, kapan menggunakan apa, Anda bisa mendapatkan sesuatu seperti ini:
  • RPC (panggilan prosedur sinkron) - ketika klien membutuhkan respons segera (dalam waktu singkat), ketika pekerja perlu menjawab sementara klien menunggu jawaban, dan jika klien telah pergi (dengan batas waktu), jawaban ini tidak lagi diperlukan (inilah sebabnya Anda tidak perlu menyimpan โ€œ request โ€, seperti yang sering dilakukan dalam sistem MQ).
    Misalnya, ketika Anda membuat kueri dalam database - Anda melakukan RPC, Anda tidak akan ingin menggunakan MQ untuk ini.
  • MQ (panggilan prosedur tidak sinkron) - ketika jawabannya tidak diperlukan (segera), ketika Anda hanya perlu menyelesaikan beberapa jenis tugas pada akhirnya atau hanya mentransfer data.
    Misalnya, untuk mengirim surat, Anda dapat mengirim tugas melalui MQ

3. RPC melalui RabbitMQ


RabbitMQ sering digunakan untuk mengatur RPC, tetapi seperti sistem MQ serupa, ia menciptakan overhead tambahan, itulah sebabnya penggunaannya tidak terlalu produktif.

Jika Anda menggunakan "antrian" untuk RPC, maka Anda perlu membersihkan saluran, karena jika pekerja telah jatuh selama beberapa waktu, maka setelah memulai kembali itu bisa mendapatkan banyak tugas yang tidak relevan, karena klien mengirim permintaan selama ini dan, di samping itu, sia-sia menunggu jawaban. pekerja itu tidak aktif. Secara total, pekerja akan menerima tugas bahkan jika klien pergi sebelumnya, sama dengan klien, jika saluran klien tidak dihitung, maka ia mungkin akan tersumbat dengan jawaban yang tidak diterima dari pekerja, meskipun dalam RabbitMQ dimungkinkan untuk menutup saluran klien, tetapi pada saat yang sama kinerja akan berkurang secara dramatis.

Anda juga perlu melakukan pekerja babi untuk mengetahui apakah dia masih hidup.
Selain itu, sumber daya dihabiskan untuk bekerja dengan saluran, ketika dalam sistem RPC data hanya dikirim ke pekerja dan sebaliknya.

4. Json terbalik


Ada banyak sistem MQ yang berbeda, tetapi tidak banyak Server Pekerjaan (RPC) seperti Gearman / Crossbar.io adalah pilihan yang sangat kecil, sehingga pengembang sering mengambil sistem MQ untuk RPC.
Oleh karena itu, Inverted JSON (iJson) dibuat - server proxy dengan antarmuka http tempat klien dan pekerja terhubung sebagai klien jaringan: [klien] -> [Inverted Json] <- [pekerja], ditulis dalam C / C ++, menggunakan epoll, mesin negara untuk perutean, pengaliran streaming json, irisan bukannya string *, dll. cara untuk kinerja yang lebih baik.

Keuntungan dari JSON Terbalik dibandingkan RabbitMQ:
  • Tidak perlu membersihkan saluran klien dan pekerja dari pesan yang tidak diterima
  • Tidak perlu melakukan ping pekerja, klien akan menerima kesalahan segera jika pekerja terputus (dengan koneksi keepalive)
  • Api yang lebih mudah - hanya permintaan http (sebagai aturan, sudah didukung oleh semua bahasa dan kerangka kerja)
  • Bekerja lebih cepat dan lebih sedikit menggunakan memori
  • Cara yang lebih mudah untuk mengirim perintah ke pekerja tertentu (misalnya, jika ada beberapa pekerja dalam antrian, tetapi Anda perlu bekerja dengan satu pekerja tertentu)

Informasi Json Terbalik Lainnya
  • Kemampuan untuk mentransfer data biner (bukan hanya json, seperti namanya)
  • Tidak perlu menentukan id jika pekerja terhubung sebagai tetap hidup, Inverted Json hanya menghubungkan klien dan pekerja secara langsung.
  • Kemampuan untuk "berlangganan" ke beberapa perintah (saluran), berlangganan ke suatu pola (misalnya perintah / *) tanpa kehilangan kinerja.
  • Gambar Docker hanya 2,6 MB (versi ramping)
  • Kernel Inverted Json hanya ~ 1400 baris kode (v0.3), lebih sedikit kode - lebih sedikit bug;)
  • Inverted JSON tidak mengubah tubuh permintaan (tubuh), tetapi mengirimkannya apa adanya.


5. Coba Json Terbalik dalam 3 menit


Anda dapat mencoba Inverted Json sekarang jika Anda memiliki Docker dan curl :


Deskripsi dari gambar:
1) Meluncurkan gambar buruh pelabuhan dari Inverted Json pada port 8001, --log 47 log permintaan masuk, dll .:
$ docker run -it -p 8001:8001 lega911/ijson --log 47 

2) Daftarkan pekerja untuk tugas "kalk / jumlah", dan tunggu tugas, ketik permintaan "dapatkan", yaitu - dapatkan tugas:
 $ curl localhost/calc/sum -H 'type: get' 

3) Klien membuat permintaan RPC calc / sum:
 $ curl localhost/calc/sum -d '{"id": 15, "data": "2+3"}' 

4) Pekerja menerima tugas `{" id ": 15," data ":" 2 + 3 "}` - data tidak berubah, sekarang Anda harus mengirim hasilnya ke id yang sama, ketik permintaan "hasil":
 $ curl localhost -H 'type: result' -d '{"id": 15, "result": 5}' 

... dan klien mendapatkan hasilnya seperti `{"id": 15, "result": 5}`

5.1. Jsonrpc


JsonRPC 2 tidak didukung, tetapi ada beberapa dasar, misalnya, klien dapat mengirim permintaan seperti (url / rpc / panggilan):
 {"jsonrpc": "2.0", "method": "calc/sum", "params": [42, 23], "id": 1} 
terima kesalahan seperti:
 {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": null} 
Namun, jika ada permintaan, maka dukungan JsonRPC dapat ditingkatkan.

5.2. Contoh klien dan pekerja Python


 # client.py import requests print(requests.post('http://127.0.0.1:8001/test/command', json={'id': 1, 'params': 'Hello'}).json()) # worker.py import requests while True: req = requests.post('http://127.0.0.1:8001/test/command', headers={'type': 'get'}).json() response = { 'id': req['id'], 'result': req['params'] + ' world!' } requests.post('http://127.0.0.1:8001/', json=response, headers={'type': 'result'}) 

Dan di sini Anda dapat menemukan contoh dalam "mode pekerja", yang lebih produktif dan ringkas.

6. Beberapa pemikiran tentang hasil benchmark


  • Crossbar.io : didasarkan pada python, jadi tidak begitu cepat dan tidak dapat menggunakan banyak core karena GIL.
  • RabbitMQ : RPC di atas MQ, yang membebankan biaya tambahan. Penurunan kinerja yang cepat dengan peningkatan beban (tidak tercermin dalam tes).
  • Nat : bukan yang buruk, meskipun lebih rendah dari Inverted Json, seperti RPC melalui MQ juga akan memiliki masalah yang sama.
  • Inverted Json : mencapai batas jaringan (mis. Meluncurkan beberapa salinan tes pada core yang berbeda tidak memberikan hasil total yang lebih baik), menunjukkan penggunaan memori dan prosesor yang paling efisien dibandingkan kinerja.
  • Nginx : ketika proxy-pass, kinerja turun dengan cepat jika mode keep-hidup tidak dihidupkan (dimatikan secara default), karena fakta bahwa linux tidak memungkinkan membuka / menutup banyak soket dalam waktu singkat (ini tidak tercermin dalam tes).
  • Traefik : sangat rakus, menggunakan 600% CPU pada puncaknya, lebih rendah dari nginx dalam kecepatan
  • uvloop (di bawah asyncio) - memberikan kinerja yang sangat baik, karena kebanyakan ditulis dalam C / C ++, untuk RPC lebih disukai daripada ZeroMQ
  • ZeroMQ - pekerja itu sendiri ditulis dalam Python, jadi itu berlari ke kernel, meskipun tes multiprosesor mengkonsumsi lebih dari 100% CPU, ini disebabkan oleh fakta bahwa zeromq itu sendiri ditulis dalam C / C ++ tanpa penangkapan GIL. Ini memberikan kinerja yang hebat, tetapi di sisi lain, jika pekerja tidak hanya + b, setiap komplikasi akan menyebabkan penurunan yang signifikan dalam RPC, karena akan mencapai inti lebih awal.
  • ZeroRPC : dinyatakan sebagai pembungkus ringan di atas ZeroMQ, pada kenyataannya, 95% dari kinerja dari ZeroMQ hilang, tampaknya tidak begitu ringan.
  • GRPC : opsi untuk python menghasilkan banyak kode python boilerplate, mis. Prosesornya ternyata berat dan cepat bersandar pada CPU, untuk bahasa yang dikompilasi mungkin tidak ada masalah seperti itu.
  • Tes 2-core dan multi-core, dalam multi-core beberapa indikator menurun, karena Anda harus bersaing untuk sumber daya CPU dengan kode tes klien, di sisi lain, beberapa tes memberikan kinerja yang hebat, misalnya Traefik, yang memakan CPU 600%


7. Kesimpulan


Jika Anda memiliki perusahaan besar dan banyak karyawan, maka Anda dapat membiarkan diri Anda untuk mendukung berbagai alat kompleks untuk mengatur koneksi langsung antara layanan microser, yang dapat memberikan komunikasi yang efektif.
Dan untuk perusahaan kecil dan pemula, di mana tim kecil perlu menyelesaikan masalah dari berbagai bidang, Inverted Json dapat menghemat waktu dan sumber daya.

Untuk pengembangan Inverted Json, rencana mencakup dukungan untuk pubsub, kubernetes, dan ide menarik lainnya.
Jika Anda tertarik dengan proyek ini atau hanya ingin membantu penulis, Anda dapat memberi tanda bintang pada proyek github , terima kasih.

PS:


  • Butuh lebih banyak waktu untuk membuat artikel ini termasuk tes daripada membuat Inverted Json sendiri
  • Prototipe Json terbalik juga ditulis dalam 1. python + asyncio + uvloop, 2. di GoLang
  • Tes ditinjau oleh para ahli yang berbeda.
  • "Irisan bukan string" - dalam kebanyakan kasus ketika mem-parsing http / json data tidak disalin ke string, tetapi tautan ke data sumber digunakan, dengan demikian, tidak ada alokasi dan penyalinan memori yang tidak perlu.
  • Jika Anda akan menguji - jangan menggunakan permintaan dengan python, ini sangat lambat, lebih baik daripada pycurl, pembungkus ini digunakan dalam pengujian.
  • Patokannya ada di sini
  • Sumber di sini

Source: https://habr.com/ru/post/id466263/


All Articles