Bagi mereka yang tidak tahu: LAppS - Lua Application Server , hampir seperti nginx atau apache, tetapi hanya untuk protokol WebSocket, bukan HTTP.
HTTP di dalamnya hanya didukung pada tingkat permintaan Upgrade.
LAppS awalnya diasah untuk beban tinggi dan skalabilitas vertikal, dan hari ini telah mencapai puncak kemampuannya pada perangkat keras saya (well, hampir, Anda dapat mengoptimalkan lebih lanjut, tetapi itu akan menjadi kerja yang panjang dan sulit).
Yang paling penting, LAppS dalam hal kinerja tumpukan WebSocket telah melampaui perpustakaan uWebSockets, yang diposisikan sebagai implementasi WebSocket tercepat.
Tertarik silakan di bawah kucing.
Sudah beberapa bulan sejak artikel LAppS terakhir saya, artikel itu tidak membangkitkan minat. Saya harap artikel ini sepertinya lebih menarik bagi orang Khabrovit. LAppS selama ini telah membuat jalur yang agak sulit ke versi 0.7.0, ditumbuhi fungsi dan telah berkembang dalam hal kinerja (yang dijanjikan sebelumnya).
Salah satu fitur yang muncul: modul yang dapat dimuat dengan implementasi bagian klien dari protokol WebSocket, - cws.
Berkat modul ini, saya akhirnya bisa memeras semuanya dari komputer di rumah saya dan memuat LAppS secara nyata.
Pengujian sebelumnya dilakukan dengan menggunakan klien ebs dari pustaka websocketpp (rincian lebih lanjut dapat ditemukan di halaman proyek github), yang tidak hanya lambat, tetapi juga sulit untuk diparalelkan. Pengujian dilakukan secara sederhana: sekelompok klien mulai, hasil dari masing-masing klien dikumpulkan menggunakan awk, dan aritmatika sederhana menghasilkan hasil kinerja. Hasilnya adalah sebagai berikut:
Server | Jumlah pelanggan | Server RPS | RPS per pelanggan | payload (byte) |
---|
LAppS 0.7.0 | 240 | 84997 | 354.154 | 128 |
uWebSockets (terbaru) | 240 | 74172.7 | 309.053 | 128 |
LAppS 0.7.0 | 240 | 83627.4 | 348.447 | 512 |
uWebSockets (terbaru) | 240 | 71024.4 | 295.935 | 512 |
LAppS 0.7.0 | 240 | 79270.1 | 330.292 | 1024 |
uWebSockets (terbaru) | 240 | 66499.8 | 277.083 | 1024 |
LAppS 0.7.0 | 240 | 51621 | 215.087 | 8192 |
uWebSockets (terbaru) | 240 | 45341.6 | 188.924 | 8192 |
Dalam tes ini, juga dalam jumlah paket berikutnya, pada kenyataannya, itu dua kali lebih tinggi. pengukuran dilakukan pada on_message dan dalam metode on_message klien, sebuah paket baru dengan ukuran yang sama dikirimkan. Yaitu permintaan klien dan respons server adalah ukuran yang sama, dan jika Anda mempertimbangkan jumlah lalu lintas yang diproses oleh server, Anda perlu menggandakan hasil RPS dengan mengalikan dengan muatan dan mengabaikan header, Anda bisa mendapatkan perkiraan jumlah lalu lintas dalam byte.
Jelas, dengan operasi simultan dari 240 proses klien, LAppS sendiri (seperti uWebSockets) tidak memiliki banyak sumber daya CPU yang tersisa.
Saya melihat beberapa implementasi klien untuk WebSocket di bawah Lua, dan sayangnya saya tidak menemukan modul yang sederhana dan cukup produktif yang dengannya saya dapat memuat LAppS dengan benar. Karena itu, seperti biasa sepeda Anda lakukan.
Modul ini memiliki antarmuka yang cukup sederhana dan meniru perilaku browser WebSocket API
Contoh sederhana cara bekerja dengan modul ini (layanan untuk menerima transaksi dengan BitMEX):
Teks tersembunyibitmex={} bitmex.__index=bitmex bitmex.init=function() end - bitmex.run=function()
Saya segera memperingatkan Anda, modul hanya muncul hari ini dan tidak diuji dengan baik.
Untuk pengujian, saya menulis layanan sederhana untuk LAppS dan menyebutnya tolok ukur bersahaja yang sama.
Layanan ini pada awalnya menciptakan 100 koneksi ke server gema WebSocket (tidak peduli yang mana), dan jika koneksi berhasil, ia mengirim pesan 1kb. Saat menerima pesan dari server, ia mengirimnya kembali.
Komputer rumah saya: Intelยฎ Core (TM) i7-7700 CPU @ 3.60GHz, microcode 0x5e
Memori: DIMM DDR4 Synchronous Unbuffered (Tidak Terdaftar) 2400 MHz (0,4 ns), Kingston KHX2400C15 / 16G
Semua pengujian dilakukan di localhost ini.
Konfigurasi gema layanan dalam LAppS:
"echo": { "auto_start": true, "instances": 2, "internal": false, "max_inbound_message_size": 16777216, "preload": null, "protocol": "raw", "request_target": "/echo" }
Parameter instance memerlukan LAppS untuk memulai dua layanan gema paralel.
Konfigurasi patok layanan (klien):
"benchmark" : { "auto_start" : true, "instances": 4, "internal": true, "preload" : [ "cws", "time" ] }
Pada awal 4 contoh benchmark layanan dibuat
Hasil dengan TLS diaktifkan
Server | Jumlah pelanggan | Server RPS | RPS per pelanggan | payload (byte) |
---|
LAppS 0.7.0-Hulu | 400 | 257828 | 644.57 | 1024 |
nginx & lua-resty-websocket 4 pekerja | 400 | 33788 | 84.47 | 1024 |
websocketpp | 400 | 9789.52 | 24.47 | 1024 |
uWebSockets gagal sejauh ini untuk menguji - jabat tangan TLS bersumpah pada SSLv3 (klien saya menggunakan TLSv1.2 dan terpotong di libreSSL SSLv3 yang saya gunakan).
Hasil tanpa TLS
Server | Jumlah pelanggan | Server RPS | RPS per pelanggan | payload (byte) |
---|
LAppS 0.7.0-hulu | 400 | 439700 | 1099.25 | 1024 |
uWebSockets-hulu | 400 | 247549 | 618.87 | 1024 |
Mengapa dalam pos "setengah juta" pesan, dan dalam tes 257828? Karena ada dua kali lebih banyak pesan (seperti yang dijelaskan di atas).
uWebsockets, menunjukkan hasil yang tidak menyenangkan dalam tes ini, hanya karena ia bekerja pada core 1, versi multi-threaded dari uWebSockets dari repositori proyek tidak benar-benar berfungsi, dan ketika TLS dinyalakan, ia memiliki perlombaan data di tumpukan OpenSSL.
Jika Anda membayangkan bahwa uWebSockets berfungsi dengan baik pada 2 core (seperti 2 layanan gema LAppS), maka dapat secara kondisional mematikan 495098 RPS (cukup gandakan hasil dari tabel).
Tetapi Anda perlu mempertimbangkan bahwa server gema ( uWebSockets ) tidak melakukan apa-apa dengan data yang diterima, tetapi segera mengirimkannya kembali. LAppS meneruskan data ke tumpukan Lua yang sesuai dengan layanan.
Apa yang Baru di LAppS
- Modul otentikasi PAM pam_auth
- Modul antrian pesan: mqr - untuk bertukar pesan antar layanan dalam server LAppS yang sama (untuk pertukaran multi-server, Anda perlu menggunakan sesuatu yang sudah ada, misalnya: RabbitMQ, mosquitto, dll)
- Koneksi jaringan ACL
Semua ini dapat ditemukan di halaman wiki proyek.
Nah, untuk camilan, untuk para pecinta, apa sebenarnya yang dilakukan LAppS selama pengujian ini.
Tanpa TLS
Teks tersembunyi iptables. 4.98% lapps [ip_tables] [k] ipt_do_table 3.80% lapps [kernel.vmlinux] [.] syscall_return_via_sysret Lua 3.52% lapps libluajit-5.1.so.2.0.5 [.] lj_str_new WebSocket 1.96% lapps lapps [.] WSStreamProcessing::WSStreamServerParser::parse 1.88% lapps [kernel.vmlinux] [k] copy_user_enhanced_fast_string 1.81% lapps [kernel.vmlinux] [k] __fget 1.61% lapps [kernel.vmlinux] [k] tcp_ack 1.49% lapps [kernel.vmlinux] [k] _raw_spin_lock_irqsave 1.48% lapps [kernel.vmlinux] [k] sys_epoll_ctl 1.45% lapps [xt_tcpudp] [k] tcp_mt LAppS 1.35% lapps lapps [.] LAppS::IOWorker<false, true>::execute 1.28% lapps lapps [.] cws_eventloop ... 1.27% lapps [nf_conntrack] [k] __nf_conntrack_find_get.isra.11 1.14% lapps [kernel.vmlinux] [k] __inet_lookup_established 1.14% lapps libluajit-5.1.so.2.0.5 [.] lj_BC_TGETS C++ 1.01% lapps lapps [.] LAppS::Application<false, true, (abstract::Application::Protocol)0>::execute ... 0.98% lapps [kernel.vmlinux] [k] ep_send_events_proc 0.98% lapps [kernel.vmlinux] [k] tcp_recvmsg 0.96% lapps libc-2.26.so [.] __memmove_avx_unaligned_erms 0.93% lapps libc-2.26.so [.] malloc 0.92% lapps [kernel.vmlinux] [k] tcp_transmit_skb 0.88% lapps [kernel.vmlinux] [k] sock_poll 0.85% lapps [nf_conntrack] [k] nf_conntrack_in 0.83% lapps [nf_conntrack] [k] tcp_packet 0.79% lapps [kernel.vmlinux] [k] do_syscall_64 0.78% lapps [kernel.vmlinux] [k] ___slab_alloc 0.78% lapps [kernel.vmlinux] [k] _raw_spin_lock_bh 0.73% lapps libc-2.26.so [.] _int_free 0.69% lapps [kernel.vmlinux] [k] __slab_free 0.66% lapps libcryptopp.so.5.6.5 [.] CryptoPP::Rijndael::Base::UncheckedSetKey 0.66% lapps [kernel.vmlinux] [k] tcp_write_xmit 0.65% lapps [kernel.vmlinux] [k] sock_def_readable 0.65% lapps [kernel.vmlinux] [k] tcp_sendmsg_locked 0.64% lapps libc-2.26.so [.] vfprintf ( - bemchmark) 0.64% lapps lapps [.] LAppS::ClientWebSocket::send ... 0.64% lapps [kernel.vmlinux] [k] tcp_v4_rcv 0.63% lapps [kernel.vmlinux] [k] __alloc_skb 0.61% lapps lapps [.] std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release 0.61% lapps [kernel.vmlinux] [k] _raw_spin_lock 0.60% lapps libc-2.26.so [.] __memset_avx2_unaligned_erms 0.60% lapps [kernel.vmlinux] [k] kmem_cache_alloc_node 0.59% lapps libluajit-5.1.so.2.0.5 [.] lj_tab_get 0.59% lapps [kernel.vmlinux] [k] __local_bh_enable_ip 0.58% lapps [kernel.vmlinux] [k] __dev_queue_xmit 0.57% lapps [kernel.vmlinux] [k] nf_hook_slow 0.55% lapps [kernel.vmlinux] [k] ep_poll_callback 0.55% lapps [kernel.vmlinux] [k] skb_release_data 0.54% lapps [kernel.vmlinux] [k] native_queued_spin_lock_slowpath 0.54% lapps libc-2.26.so [.] cfree@GLIBC_2.2.5 0.53% lapps [kernel.vmlinux] [k] ip_finish_output2 0.49% lapps libluajit-5.1.so.2.0.5 [.] lj_BC_RET 0.49% lapps libc-2.26.so [.] __strlen_avx2 0.48% lapps [kernel.vmlinux] [k] _raw_spin_unlock_irqrestore
Kami akan menemukan 10 perbedaan saat bekerja dengan TLS
Teks tersembunyi 3.73% lapps [kernel.vmlinux] [k] syscall_return_via_sysret 3.49% lapps libcrypto.so.43.0.1 [.] gcm_ghash_clmul 3.42% lapps libcrypto.so.43.0.1 [.] aesni_ctr32_encrypt_blocks 2.74% lapps [ip_tables] [k] ipt_do_table 2.17% lapps libluajit-5.1.so.2.0.5 [.] lj_str_new 1.41% lapps libpthread-2.26.so [.] __pthread_mutex_lock 1.34% lapps libssl.so.45.0.1 [.] tls1_enc 1.32% lapps [kernel.vmlinux] [k] __fget 1.16% lapps libcrypto.so.43.0.1 [.] getrn 1.06% lapps libc-2.26.so [.] __memmove_avx_unaligned_erms 1.06% lapps lapps [.] WSStreamProcessing::WSStreamServerParser::parse 1.05% lapps [kernel.vmlinux] [k] tcp_ack 1.02% lapps [kernel.vmlinux] [k] copy_user_enhanced_fast_string 1.02% lapps [nf_conntrack] [k] __nf_conntrack_find_get.isra.11 0.98% lapps lapps [.] cws_eventloop 0.98% lapps [kernel.vmlinux] [k] native_queued_spin_lock_slowpath 0.93% lapps libcrypto.so.43.0.1 [.] aead_aes_gcm_open 0.92% lapps lapps [.] LAppS::IOWorker<true, true>::execute 0.91% lapps [kernel.vmlinux] [k] tcp_recvmsg 0.89% lapps [kernel.vmlinux] [k] sys_epoll_ctl 0.88% lapps libcrypto.so.43.0.1 [.] aead_aes_gcm_seal 0.84% lapps [kernel.vmlinux] [k] do_syscall_64 0.82% lapps [kernel.vmlinux] [k] __inet_lookup_established 0.82% lapps [kernel.vmlinux] [k] tcp_transmit_skb 0.79% lapps libpthread-2.26.so [.] __pthread_mutex_unlock_usercnt 0.77% lapps [kernel.vmlinux] [k] _raw_spin_lock_irqsave 0.76% lapps [xt_tcpudp] [k] tcp_mt 0.71% lapps libcrypto.so.43.0.1 [.] aesni_encrypt 0.70% lapps [kernel.vmlinux] [k] _raw_spin_lock 0.67% lapps [kernel.vmlinux] [k] ep_send_events_proc 0.66% lapps libcrypto.so.43.0.1 [.] ERR_clear_error 0.63% lapps [kernel.vmlinux] [k] sock_def_readable 0.62% lapps lapps [.] LAppS::Application<true, true, (abstract::Application::Protocol)0>::execute 0.61% lapps libc-2.26.so [.] malloc 0.61% lapps [nf_conntrack] [k] nf_conntrack_in 0.58% lapps libssl.so.45.0.1 [.] ssl3_read_bytes 0.58% lapps libluajit-5.1.so.2.0.5 [.] lj_BC_TGETS 0.57% lapps [kernel.vmlinux] [k] tcp_write_xmit 0.56% lapps libssl.so.45.0.1 [.] do_ssl3_write 0.55% lapps [kernel.vmlinux] [k] __netif_receive_skb_core 0.54% lapps [kernel.vmlinux] [k] ___slab_alloc 0.54% lapps libc-2.26.so [.] __memset_avx2_unaligned_erms 0.51% lapps [kernel.vmlinux] [k] _raw_spin_lock_bh 0.51% lapps libcrypto.so.43.0.1 [.] gcm_gmult_clmul 0.51% lapps [kernel.vmlinux] [k] sock_poll 0.48% lapps [nf_conntrack] [k] tcp_packet 0.48% lapps libc-2.26.so [.] cfree@GLIBC_2.2.5 0.48% lapps libssl.so.45.0.1 [.] SSL_read 0.46% lapps [kernel.vmlinux] [k] copy_user_generic_unrolled 0.45% lapps [kernel.vmlinux] [k] tcp_sendmsg_locked 0.45% lapps lapps [.] LAppS::ClientWebSocket::send 0.44% lapps libc-2.26.so [.] _int_free 0.44% lapps libssl.so.45.0.1 [.] ssl3_read_internal 0.43% lapps [kernel.vmlinux] [k] futex_wake 0.42% lapps libluajit-5.1.so.2.0.5 [.] lj_tab_get 0.42% lapps libc-2.26.so [.] vfprintf 0.41% lapps [kernel.vmlinux] [k] tcp_v4_rcv