GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Menangani Sudden Burst di Koneksi HTTPS Baru?

Solusi 1:

Terima kasih @MichaelHampton atas bantuan Anda.

Saya menemukan solusi untuk masalah saya, dan mudah-mudahan dapat membantu orang lain (terutama jika Anda menggunakan Java).

Saya telah mendengar banyak saran untuk meningkatkan nofiles untuk mengizinkan lebih banyak koneksi, tetapi saya ingin memulai dengan menegaskan kembali bahwa masalahnya bukan karena server tidak dapat membuat lebih banyak koneksi, tetapi server tidak dapat membuat koneksi dengan cukup cepat dan memutuskan koneksi.

Upaya pertama saya untuk mengatasi masalah ini adalah dengan menambah antrean koneksi melalui net.ipv4.tcp_max_syn_backlog , net.core.somaxconn dan lagi di konfigurasi server aplikasi jika perlu. Untuk vertx ini adalah server.setAcceptBacklog(...); . Hal ini mengakibatkan menerima lebih banyak koneksi dalam antrean, tetapi tidak mempercepat pembuatan koneksi. Dari sudut pandang klien yang menghubungkan, mereka tidak lagi mengatur ulang koneksi karena luapan, membuat koneksi hanya membutuhkan waktu lebih lama. Karena alasan ini, menambah antrean koneksi bukanlah solusi nyata dan hanya menukar satu masalah dengan masalah lainnya.

Mencoba mempersempit di mana dalam proses koneksi hambatannya, saya mencoba tolok ukur yang sama dengan HTTP alih-alih HTTPS dan menemukan bahwa masalahnya hilang sepenuhnya. Masalah khusus saya adalah dengan TLS Handshake itu sendiri dan kemampuan server untuk memuaskannya.

Dengan menggali lebih dalam aplikasi saya sendiri, saya menemukan bahwa mengganti SSLHandler default Java dengan yang asli (OpenSSL) sangat meningkatkan kecepatan koneksi melalui HTTPS.

Berikut adalah perubahan yang saya buat untuk aplikasi khusus saya (menggunakan Vertx 3.9.1).

  1. Tambahkan dependensi netty-tcnative
<!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-tcnative</artifactId>
    <version>2.0.31.Final</version>
    <classifier>osx-x86_64</classifier>
    <scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-tcnative</artifactId>
    <version>2.0.31.Final</version>
    <classifier>linux-x86_64-fedora</classifier>
    <scope>compile</scope>
</dependency>

Ketergantungan pertama adalah untuk osx untuk menguji saat runtime. Yang kedua adalah untuk centos linux saat dikompilasi. linux-x86_64 tersedia juga untuk rasa lainnya. Saya mencoba menggunakan boringssl karena openssl tidak mendukung ALPN tetapi setelah berjam-jam saya tidak dapat membuatnya berfungsi, jadi saya memutuskan untuk hidup tanpa http2 untuk saat ini. Dengan sebagian besar koneksi hanya mengirim 1-2 permintaan kecil sebelum memutuskan sambungan, ini sebenarnya bukan masalah bagi saya. Jika Anda bisa menggunakan boringssl sebaliknya, itu mungkin lebih disukai.

  1. Karena saya tidak menggunakan ketergantungan versi uber. Saya perlu menginstal dependensi os untuk centos. Ini telah ditambahkan ke Dockerfile
RUN yum -y install openssl
RUN yum -y install apr
  1. Untuk memberi tahu server vertx agar menggunakan OpenSSL alih-alih versi Java, setel opsi OpenSSL di server (meskipun hanya objek default)
httpServerOptions.setOpenSslEngineOptions(new OpenSSLEngineOptions());
  1. Akhirnya, di skrip run saya, saya menambahkan io.netty.handler.ssl.openssl.useTasks=true pilihan ke Jawa. Ini memberi tahu penangan ssl untuk menggunakan tugas saat menangani permintaan sehingga tidak memblokir.
java -Dio.netty.handler.ssl.openssl.useTasks=true -jar /app/application.jar

Setelah perubahan ini, saya dapat membuat koneksi lebih cepat dengan lebih sedikit overhead. Apa yang memakan waktu puluhan detik sebelumnya dan mengakibatkan seringnya reset koneksi sekarang membutuhkan 1-2 detik tanpa reset. Bisa jadi lebih baik, tetapi peningkatan besar dari tempat saya sebelumnya.

Solusi 2:

Perbaikan yang bagus!.

Jadi sepertinya lapisan SSL, tentu harus melakukan lebih banyak pemrosesan, dalam hal jabat tangan jaringan, dan transformasi kripto yang memakan sumber daya. Kecuali jika SSL Anda dapat memindahkan beberapa pemrosesan ke perangkat keras, SSL pasti dapat menambah beban pada server Anda, dan seperti yang Anda ketahui, tidak semua pustaka SSL dibuat sama!.

Masalah-masalah ini adalah kandidat yang bagus untuk proxy balik ujung depan. Ini idealnya dapat ditempatkan sebelum aplikasi Anda, dan menangani semua koneksi SSL ke klien, lalu melakukan http ke backend Anda.

Aplikasi asli Anda memiliki sedikit hal yang harus dilakukan, karena proksi terbalik ujung depan Anda dapat menyerap semua pekerjaan SSL, dan manajemen koneksi tcp.

Apache dan NGNIX dapat melakukan ini, dan memiliki beberapa opsi untuk menyeimbangkan beban koneksi tersebut ke server backend yang memuat paling sedikit.

Anda akan menemukan bahwa NGNIX dapat melakukan terminasi SSL jauh lebih cepat daripada java, dan bahkan jika java bisa, Anda mendistribusikan pemrosesan manajemen koneksi ke seluruh mesin, sehingga mengurangi beban (memori/cpu/disk io) di server back end Anda. Anda mendapatkan efek samping dengan membuat konfigurasi bagian belakang menjadi lebih sederhana.

Kelemahannya adalah Anda menggunakan http antara proxy dan aplikasi Anda, yang di beberapa lingkungan yang sangat aman tidak diinginkan.

Semoga Sukses!


Linux
  1. Cara memaksa Apache untuk menggunakan HTTPS

  2. Cara Install JBoss AS 7 dengan SSL di Linux (Aktifkan HTTPS SSL di JBoss)

  3. Bagaimana cara mengatur nick default untuk koneksi irssi baru?

  1. Alihkan ke HTTPS

  2. Bagaimana Menangani Switch Dalam Script Shell?

  3. Cara mengamankan koneksi dengan sertifikat SSL/TLS

  1. Cara Mengarahkan HTTP ke HTTPS di Nginx

  2. Cara Mengaktifkan Protokol HTTPS dengan Apache 2 di Ubuntu 20.04

  3. bagaimana cara memaksa hanya menerima koneksi ssl di vsftpd?