Apakah TCP membuka koneksi baru untuk setiap paket yang dikirim?

15

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?

pengguna0000001
sumber
13
Saya pikir Anda telah salah mengerti apa yang dikatakan teman Anda. TCP tidak melakukan hal seperti itu, tetapi ada kemungkinan bahwa klien tertentu akan membuat koneksi TCP baru untuk setiap pesan yang ingin diteruskan.
hobbs
13
TCP tidak mungkin membuka koneksi baru untuk setiap paket karena membutuhkan beberapa paket untuk membuka koneksi baru. Dan itu tidak bisa membuka koneksi baru untuk setiap pesan karena TCP tidak memiliki konsep pesan. Temanmu sangat bingung. Hal yang paling penting untuk dipahami tentang TCP, konsep yang paling mendasar, adalah bahwa TCP adalah protokol byte stream.
David Schwartz
1
Argumen teman Anda tidak selalu salah - jika Anda tidak menggunakan kembali port melalui level aplikasi tetap hidup atau ada terlalu banyak klien, sistem Anda mungkin kehabisan port sesaat. Ada beberapa cara untuk mengatasi masalah itu: menggunakan SO_REUSEADDRuntuk menutup soket lebih cepat, meningkatkan jangkauan port sementara dll. Selain itu TCP_FASTOPENdan 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.
user1643723

Jawaban:

22

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 ??

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 ke read()atau recv().

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.

Kevin
sumber
9

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.

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.

Data yang dikirim melalui koneksi ini adalah stream dan tidak akan membuka / menutup koneksi baru terlepas dari 3 V (volume, kecepatan, variasi).

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.

Ron Maupin
sumber
2
Padahal dalam TCP ada satu mitra yang memprakarsai koneksi (sering disebut "klien") dan yang lainnya (sering disebut "server"). Tentu saja, setelah koneksi dibuat, perbedaan ini tidak penting lagi.
Paŭlo Ebermann
2
@ PaŭloEbermann, tidak ada dalam TCP RFC tentang klien atau server. Konsep klien / server adalah konsep aplikasi. Apa yang menjadi topik di sini adalah protokol pada atau di bawah OSI layer-4, dan tidak ada klien atau server dalam protokol tersebut. Bahkan, apa yang Anda anggap sebagai klien (yang membuka koneksi TCP) mungkin, sebenarnya, menjadi server aplikasi. Kami memiliki server yang melakukan koneksi TCP ke klien untuk melakukan hal-hal seperti pemeriksaan dan pembaruan keamanan.
Ron Maupin
7

Tidak, TCP tidak perlu membuka koneksi baru untuk setiap paket yang dikirim.

Anda dapat mengirim banyak paket melalui koneksi persisten HTTP , di mana:

... satu koneksi TCP untuk mengirim dan menerima beberapa permintaan / tanggapan HTTP [digunakan], sebagai lawan dari membuka koneksi baru untuk setiap pasangan permintaan / respons tunggal.

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):

Koneksi Ganda vs Koneksi Tetap

Sumber: https://www.vcloudnine.de/how-to-dramatically-improve-website-load-times/


sumber
7
Jawaban ini sepertinya lapisan yang membingungkan. Permintaan / respons HTTP jarang berupa satu paket.
Barmar
2
Belum lagi setiap "open" sebenarnya 3 panah (syn, synack, ack), dan setiap "close" adalah 4 lainnya (fin, ack 2x server dan klien), jadi jika benar-benar ada koneksi per paket, overhead akan bertambah dengan cepat.
htmlcoderexe
5

Interpretasi Anda tentang cara kerja TCP benar.

Adapun apa kata teman Anda, saya melihat dua kemungkinan di sini:

  1. 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);

  2. Temanmu salah.

Lightness Races with Monica
sumber
5

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

Scot
sumber
2

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.

reinierpost
sumber
0

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 ...

Halo
sumber
0

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:

Penggunaan sumber daya

Sebagian besar implementasi mengalokasikan entri dalam tabel yang memetakan sesi untuk proses sistem operasi yang berjalan. Karena paket TCP tidak termasuk pengidentifikasi sesi, kedua titik akhir mengidentifikasi sesi menggunakan alamat dan port klien. Setiap kali paket diterima, implementasi TCP harus melakukan pencarian pada tabel ini untuk menemukan proses tujuan. Setiap entri dalam tabel dikenal sebagai Blok Kontrol Transmisi atau TCB. Ini berisi informasi tentang titik akhir (IP dan port), status koneksi, menjalankan data tentang paket yang dipertukarkan dan buffer untuk mengirim dan menerima data.

Jumlah sesi di sisi server hanya dibatasi oleh memori dan dapat bertambah ketika koneksi baru tiba, tetapi klien harus mengalokasikan port acak sebelum mengirim SYN pertama ke server. Port ini tetap dialokasikan selama seluruh percakapan, dan secara efektif membatasi jumlah koneksi keluar dari masing-masing alamat IP klien. Jika suatu aplikasi gagal untuk menutup koneksi yang tidak dibutuhkan dengan benar, klien dapat kehabisan sumber daya dan menjadi tidak dapat membuat koneksi TCP baru, bahkan dari aplikasi lain.

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.

AnoE
sumber