Ini mungkin pertanyaan konyol tapi saya dan beberapa teman telah membahas keterbatasan potensial TCP. Kami memiliki aplikasi yang akan mendengarkan klien (pikirkan gateway) dan rutekan semua data klien yang terhubung melalui satu penerbit kafka yang terhubung ke satu topik.
Salah satu teman saya mengatakan bahwa TCP akan menjadi masalah bagi gateway ini karena akan membuat koneksi baru untuk setiap pesan yang dikirim (bukan kafka tetapi protokol transportasi yang mendasarinya sendiri adalah masalahnya), membutuhkan port baru setiap kali. Pada tingkat kita akan mengirim pesan klien ini (gigabytes), kafka akan kehabisan port untuk membaca ??
Saya telah melakukan pengembangan selama beberapa tahun dan belum pernah mendengar ini sebelumnya dan ingin mendapatkan pemahaman tingkat yang lebih rendah (yang saya pikir saya miliki) tentang cara kerja TCP. Pemahaman saya adalah bahwa ketika Anda membuat koneksi TCP, koneksi itu tetap terbuka sampai waktunya habis oleh aplikasi atau ditutup secara paksa oleh server atau klien. Data yang dikirim melalui koneksi ini adalah stream dan tidak akan membuka / menutup koneksi baru terlepas dari 3 V (volume, kecepatan, variasi).
Sejauh port pergi, satu port digunakan untuk penyiaran dan port deskriptor file internal adalah sesuatu yang dikelola aplikasi untuk baca / tulis klien individu. Saya tidak pernah mengerti TCP untuk membuat koneksi baru untuk setiap paket yang ditulisnya.
Saya minta maaf sebelumnya jika pertanyaan ini tidak langsung dan atau terlalu kabur. Saya benar-benar bingung dan berharap seseorang dapat memberikan lebih banyak konteks untuk apa yang dikatakan rekan saya?
sumber
SO_REUSEADDR
untuk menutup soket lebih cepat, meningkatkan jangkauan port sementara dll. Selain ituTCP_FASTOPEN
dan beberapa toggle tingkat OS dapat digunakan untuk mengatasi keterbatasan TCP yang terkenal lainnya. Either way, tidak ada gunanya membahas keterbatasan TCP ketika Anda bahkan tidak memiliki beban kerja untuk menguji.Jawaban:
Temanmu sangat bingung. TCP adalah protokol berorientasi aliran. Ia tidak memiliki gagasan tentang pesan. Tentu saja, ia menggunakan paket-paket pada layer IP, tetapi untuk aplikasi ini adalah detail implementasi. TCP menyisipkan batas paket di mana masuk akal untuk melakukannya, dan tidak harus satu kali per
write()
atausend()
. Demikian pula, ini menggabungkan paket berturut-turut jika Anda menerima lebih dari satu di antara panggilan keread()
ataurecv()
.Tidak perlu dikatakan, desain yang berorientasi pada aliran ini akan sepenuhnya tidak dapat digunakan jika setiap pengiriman membuat koneksi baru. Jadi, satu-satunya cara untuk membuat koneksi baru adalah dengan menutup dan membuka kembali koneksi secara manual.
(Dalam praktiknya, sebagian besar protokol yang dibangun di atas TCP memiliki sesuatu yang menyerupai pesan, seperti permintaan dan tanggapan HTTP. Tetapi TCP tidak tahu atau tidak peduli dengan struktur hal-hal seperti itu.)
Mungkin saja teman Anda memikirkan UDP, yang memang memiliki pesan, tetapi juga tanpa koneksi. Sebagian besar implementasi soket memungkinkan Anda untuk "menghubungkan" soket UDP ke host jarak jauh, tetapi ini hanya cara mudah untuk menghindari keharusan berulang kali menentukan alamat IP dan port. Sebenarnya tidak melakukan apa pun di tingkat jaringan. Namun demikian, Anda dapat secara manual melacak rekan yang Anda ajak bicara di bawah UDP. Tetapi jika Anda melakukan itu, maka memutuskan apa yang dianggap sebagai "koneksi" adalah masalah Anda, bukan OS. Jika Anda ingin membangun kembali "koneksi" pada setiap pesan, Anda bisa melakukannya. Namun, itu mungkin bukan ide yang bagus.
sumber
Dari perspektif TCP, tidak ada klien atau server (klien / server adalah konsep aplikasi yang di luar topik di sini). TCP membuat koneksi antara peer, dan kedua peer dapat mengirim dan menerima koneksi sampai peer lain menutupnya, atau time out karena tidak aktif.
Apa yang mungkin membingungkan situasinya adalah bahwa beberapa aplikasi, misalnya browser, akan membuka banyak koneksi untuk secara bersamaan memuat hal-hal seperti elemen halaman web.
TCP tidak membuka koneksi baru untuk setiap segmen yang dikirim, tetapi aplikasi dapat membuka beberapa koneksi TCP. Juga, ketika koneksi TCP ditutup, port TCP yang digunakan dalam koneksi dibebaskan, dan tersedia untuk digunakan lagi. Jawaban ini memberikan beberapa informasi, dan itu mengarahkan Anda ke RFC untuk TCP.
sumber
Tidak, TCP tidak perlu membuka koneksi baru untuk setiap paket yang dikirim.
Anda dapat mengirim banyak paket melalui koneksi persisten HTTP , di mana:
Terlampir adalah gambar yang menunjukkan perbedaan antara beberapa koneksi (banyak koneksi dibuat untuk mengirim satu objek per koneksi) dan koneksi persisten (satu koneksi dibuat dan beberapa objek dikirim ke sana):
Sumber: https://www.vcloudnine.de/how-to-dramatically-improve-website-load-times/
sumber
Interpretasi Anda tentang cara kerja TCP benar.
Adapun apa kata teman Anda, saya melihat dua kemungkinan di sini:
Anda salah memahami teman Anda, yang merujuk pada batasan lapisan aplikasi yang mengakibatkan setiap pesan dikirim melalui koneksi baru (dan ini tidak selalu tidak biasa; mungkin atau mungkin tidak mungkin untuk memutuskan perilaku ini, tergantung pada perangkat lunak apa tumpukan Anda menggunakan);
Temanmu salah.
sumber
Seperti yang ditunjukkan orang lain, TCP benar-benar memungkinkan koneksi tetap terbuka untuk jumlah waktu berapa pun, bertukar sejumlah "pesan" di kedua arah selama waktu itu. Yang mengatakan, pada akhirnya terserah aplikasi (baik klien dan server) untuk menentukan apakah kemampuan itu digunakan.
Untuk menggunakan kembali koneksi TCP (soket) yang ada, aplikasi klien harus tetap membuka soket itu dan menggunakannya ketika perlu menulis lebih banyak data. Jika klien tidak melakukan ini, melainkan membuang soket lama dan membuka soket baru setiap kali diperlukan, maka memang akan memaksa koneksi baru yang dapat menyebabkan masalah sumber daya pada klien atau server jika dilakukan cukup sering untuk menghabiskan salah satu kumpulan koneksi TCP stack.
Demikian juga, server harus cukup pintar untuk menjaga agar soket tetap terbuka di sisinya dan menunggu lebih banyak data. Seperti halnya klien, ia memiliki opsi untuk menutup soket di mana klien yang toleran terhadap kesalahan yang ingin mengirim lebih banyak data tidak akan memiliki pilihan selain membuka soket baru, yang mengarah ke masalah yang sama.
Akhirnya, seperti yang telah disebutkan orang lain, TCP berorientasi pada aliran. Tidak ada pembingkaian apa pun. Hanya karena satu rekan menulis data dengan cara tertentu (mis. Panggilan tulis 1 1024 byte diikuti oleh 2 panggilan tulis 256 byte), itu tidak menjamin bahwa rekan lain akan membacanya dalam potongan ukuran yang sama (misalnya mungkin mendapatkan semua 1536 byte dalam satu panggilan baca). Jadi, jika Anda mengirim banyak "pesan" melalui soket TCP mentah, Anda harus menyediakan protokol pembingkaian Anda sendiri untuk menggambarkan pesan yang berbeda. Walaupun pasti ada cara sederhana untuk melakukan ini, umumnya keliru karena ada banyak protokol yang dibangun di atas TCP untuk mengatasi masalah ini. Untuk diskusi lebih lanjut, lihat ini: https://blog.stephencleary.com/2009/04/message-framing.html
sumber
Saya pikir teman Anda berbicara tentang HTTP, bukan TCP.
HTTP pada awalnya adalah protokol stateless: setiap permintaan HTTP akan menggunakan koneksi TCP yang terpisah. Inilah sebabnya kami membutuhkan cookie (atau yang serupa) untuk mengimplementasikan sesi.
sumber
Anda telah menyebutkan "koneksi tunggal dan memerlukan port baru setiap kali", dan saya akan menafsirkan karena Anda memiliki banyak klien menggunakan teknik PAT dalam lingkungan jaringan yang sama untuk terhubung ke server di luar organisasi Anda. PAT akan memiliki batas 65535 (batas sesi TCP pada Alamat IPv4). Jika itu benar, Anda memiliki batasnya.
Apakah TCP membuka koneksi baru untuk setiap paket yang dikirim? TIDAK, tidak selama sesi TCP valid. dan ...
sumber
Saya suka halaman wikipedia yang luar biasa pada TCP . Itu jelas menunjukkan apa yang terjadi dengan nomor port. Ini, secara kebetulan, juga berisi bab bermanfaat tentang penggunaan sumber daya:
Singkatnya, TCP menggunakan satu sumber daya yang sangat terbatas, yang merupakan jumlah port pada klien (yang dibatasi oleh ukuran bidang port pada header TCP, 16 bit).
Jadi, TCP adalah mampu kehabisan port, jika klien membuka banyak koneksi TCP secara paralel tanpa menutup mereka. Masalahnya hanya terjadi di sisi klien, dan tidak masalah jika koneksi dengan alamat IP server yang sama atau berbeda atau port server.
Dalam pengaturan Anda, Anda tampaknya memiliki satu aplikasi yang menerima banyak permintaan klien ( inibisa berupa permintaan TCP individual, karena mungkin klien Anda menggunakan ini untuk mencatat beberapa peristiwa ke aplikasi Anda dan tidak menahan saluran TCP terbuka antara), dan membuat permintaan internal baru ke broker Kafka Anda (yang sangat mudah bisa berupa koneksi TCP individual jika Anda memilih untuk mengimplementasikannya seperti ini). Dalam hal ini, hambatan (dalam hal sumber daya, bukan kinerja) akan terjadi jika Anda berhasil mendapatkan sejumlah besar permintaan pada saat yang sama dari klien Anda (tidak ada masalah bagi Anda, karena di sisi server Anda hanya perlu satu port untuk semuanya), dan Anda membuka sejumlah besar permintaan penerusan ke Kafka Anda, dan Kafka tidak dapat memprosesnya dengan cukup cepat, berakhir dengan Anda memiliki lebih dari 16 bit koneksi yang terbuka secara bersamaan.
Anda adalah hakim sendiri di sini; periksa aplikasi Anda dan cobalah untuk mencari tahu apakah Anda terhubung ke Kafka dengan permintaan terpisah setiap kali (mungkin melalui beberapa proksi REST API). Jika Anda melakukannya, dan Anda memiliki banyak klien, maka Anda tentu dalam bahaya.
Jika Anda hanya memiliki sedikit klien, kurang dari 65k-ish, dan / atau Anda menyimpan satu koneksi ke browser Kafka Anda, maka Anda akan baik-baik saja.
sumber