Connection management in HTTP/1.x

This translation is incomplete. Please help translate this article from English

การจัดการการเชื่อมต่อเป็นหัวข้อสำคัญใน HTTP: การเปิดและรักษาการเชื่อมต่อส่วนใหญ่มีผลต่อประสิทธิภาพของเว็บไซต์และแอปพลิเคชันเว็บ ใน HTTP / 1.x มีหลายโมเดล: การเชื่อมต่อสั้น ๆ , การเชื่อมต่อแบบถาวรและHTTP pipelining

HTTP ส่วนใหญ่อาศัย TCP สำหรับโปรโตคอลการขนส่งโดยให้การเชื่อมต่อระหว่างไคลเอนต์และเซิร์ฟเวอร์ ในวัยเด็ก HTTP ใช้แบบจำลองเดียวเพื่อจัดการการเชื่อมต่อดังกล่าว การเชื่อมต่อเหล่านี้มีอายุการใช้งานสั้น: การเชื่อมต่อใหม่ที่สร้างขึ้นทุกครั้งที่จำเป็นต้องส่งคำขอและจะปิดเมื่อได้รับคำตอบ

โมเดลที่เรียบง่ายนี้มีข้อ จำกัด ด้านประสิทธิภาพโดยธรรมชาติ: การเปิดการเชื่อมต่อ TCP แต่ละครั้งเป็นการดำเนินการที่ใช้ทรัพยากรมาก ต้องแลกเปลี่ยนข้อความหลายข้อความระหว่างไคลเอนต์และเซิร์ฟเวอร์ เวลาในการตอบสนองของเครือข่ายและแบนด์วิดท์มีผลต่อประสิทธิภาพเมื่อคำขอต้องการส่ง หน้าเว็บสมัยใหม่ต้องการคำขอจำนวนมาก (ตั้งแต่หนึ่งโหลขึ้นไป) เพื่อให้บริการข้อมูลตามจำนวนที่ต้องการซึ่งพิสูจน์ได้ว่ารุ่นก่อนหน้านี้ไม่มีประสิทธิภาพ

รุ่นใหม่กว่าสองรุ่นถูกสร้างขึ้นใน HTTP / 1.1 โมเดลการเชื่อมต่อแบบต่อเนื่องช่วยให้การเชื่อมต่อเปิดระหว่างคำขอที่ต่อเนื่องลดเวลาที่ต้องใช้ในการเปิดการเชื่อมต่อใหม่ รูปแบบการไปป์ไลน์ HTTP ก้าวไปอีกขั้นด้วยการส่งคำขอต่อเนื่องหลายรายการโดยไม่ต้องรอคำตอบช่วยลดเวลาแฝงในเครือข่ายได้มาก

Compares the performance of the three HTTP/1.x connection models: short-lived connections, persistent connections, and HTTP pipelining.

HTTP / 2 เพิ่มโมเดลเพิ่มเติมสำหรับการจัดการการเชื่อมต่อ

It's important point to note that connection management in HTTP applies to the connection between two consecutive nodes, which is hop-by-hop and not end-to-end. The model used in connections between a client and its first proxy may differ from the model between a proxy and the destination server (or any intermediate proxies). The HTTP headers involved in defining the connection model, like Connection and Keep-Alive, are hop-by-hop headers with their values able to be changed by intermediary nodes.

A related topic is the concept of HTTP connection upgrades, wherein an HTTP/1.1 connection is upgraded to a different protocol, such as TLS/1.0, WebSocket, or even HTTP/2 in cleartext. This protocol upgrade mechanism is documented in more detail elsewhere.

Short-lived connections

The original model of HTTP, and the default one in HTTP/1.0, is short-lived connections. Each HTTP request is completed on its own connection; this means a TCP handshake happens before each HTTP request, and these are serialized.

The TCP handshake itself is time-consuming, but a TCP connection adapts to its load, becoming more efficient with more sustained (or warm) connections. Short-lived connections do not make use of this efficiency feature of TCP, and performance degrades from optimum by persisting to transmit over a new, cold connection.

This model is the default model used in HTTP/1.0 (if there is no Connection header, or if its value is set to close). In HTTP/1.1, this model is only used when the Connection header is sent with a value of close.

Unless dealing with a very old system, which doesn't support a persistent connection, there is no compelling reason to use this model.

Persistent connections

Short-lived connections have two major hitches: the time taken to establish a new connection is significant, and performance of the underlying TCP connection gets better only when this connection has been in use for some time (warm connection). To ease these problems, the concept of a persistent connection has been designed, even prior to HTTP/1.1. Alternatively this may be called a keep-alive connection.

A persistent connection is one which remains open for a period of time, and can be reused for several requests, saving the need for a new TCP handshake, and utilizing TCP's performance enhancing capabilities. This connection will not stay open forever: idle connections are closed after some time (a server may use the Keep-Alive header to specify a minimum time the connection should be kept open).

Persistent connections also have drawbacks; even when idling they consume server resources, and under heavy load, DoS attacks can be conducted. In such cases, using non-persistent connections, which are closed as soon as they are idle, can provide better performance.

HTTP/1.0 connections are not persistent by default. Setting Connection to anything other than close, usually retry-after, will make them persistent.

In HTTP/1.1, persistence is the default, and the header is no longer needed (but it is often added as a defensive measure against cases requiring a fallback to HTTP/1.0).

HTTP pipelining

HTTP pipelining is not activated by default in modern browsers:

  • Buggy proxies are still common and these lead to strange and erratic behaviors that Web developers cannot foresee and diagnose easily.
  • Pipelining is complex to implement correctly: the size of the resource being transferred, the effective RTT that will be used, as well as the effective bandwidth, have a direct incidence on the improvement provided by the pipeline. Without knowing these, important messages may be delayed behind unimportant ones. The notion of important even evolves during page layout! HTTP pipelining therefore brings a marginal improvement in most cases only.
  • Pipelining is subject to the HOL problem.

For these reasons, pipelining has been superseded by a better algorithm, multiplexing, that is used by HTTP/2.

By default, HTTP requests are issued sequentially. The next request is only issued once the response to the current request has been received. As they are affected by network latencies and bandwidth limitations, this can result in significant delay before the next request is seen by the server.

Pipelining is the process to send successive requests, over the same persistent connection, without waiting for the answer. This avoids latency of the connection. Theoretically, performance could also be improved if two HTTP requests were to be packed into the same TCP message. The typical MSS (Maximum Segment Size), is big enough to contain several simple requests, although the demand in size of HTTP requests continues to grow.

Not all types of HTTP requests can be pipelined: only idempotent methods, that is GET, HEAD, PUT and DELETE, can be replayed safely: should a failure happen, the pipeline content can simply be repeated.

Today, every HTTP/1.1-compliant proxy and server should support pipelining, though many have limitations in practice: a significant reason no modern browser activates this feature by default.

Domain sharding

Unless you have a very specific immediate need, don't use this deprecated technique; switch to HTTP/2 instead. In HTTP/2, domain sharding is no longer useful: the HTTP/2 connection is able to handle parallel unprioritized requests very well. Domain sharding is even detrimental to performance. Most HTTP/2 implementations use a technique called connection coalescing to revert eventual domain sharding.

As an HTTP/1.x connection is serializing requests, even without any ordering, it can't be optimal without large enough available bandwidth. As a solution, browsers open several connections to each domain, sending parallel requests. Default was once 2 to 3 connections, but this has now increased to a more common use of 6 parallel connections. There is a risk of triggering DoS protection on the server side if attempting more than this number.

หากเซิร์ฟเวอร์ต้องการให้เว็บไซต์หรือแอปพลิเคชันตอบสนองเร็วขึ้นเซิร์ฟเวอร์อาจบังคับให้เปิดการเชื่อมต่อเพิ่มเติม ตัวอย่างเช่นแทนที่จะมีทรัพยากรทั้งหมดในโดเมนเดียวกันพูดก็อาจแบ่งมากกว่าหลายโดเมน,www.example.com , , แต่ละโดเมนเหล่านี้แก้ไขไปยังเซิร์ฟเวอร์เดียวกันและเว็บเบราว์เซอร์จะเปิดการเชื่อมต่อ 6 รายการให้กับแต่ละโดเมน(ในตัวอย่างของเราเพิ่มการเชื่อมต่อเป็น 18) เทคนิคนี้เรียกว่าsharding โดเมนwww1.example.comwww2.example.comwww3.example.com

สรุป

การจัดการการเชื่อมต่อที่ได้รับการปรับปรุงช่วยเพิ่มประสิทธิภาพใน HTTP ได้มาก ด้วย HTTP / 1.1 หรือ HTTP / 1.0 การใช้การเชื่อมต่อแบบต่อเนื่องอย่างน้อยก็จนกว่าจะไม่มีการใช้งานจะนำไปสู่ประสิทธิภาพที่ดีที่สุด อย่างไรก็ตามความล้มเหลวของการวางท่อนำไปสู่การออกแบบรูปแบบการจัดการการเชื่อมต่อที่เหนือกว่าซึ่งรวมอยู่ใน HTTP / 2