Skip to content

Dashboard

HTTP/2 - Những câu hỏi thường gặp

Created by Admin

HTTP/2 được phát triển dựa trên SPDY, là một phiên bản hiện đại, tiên tiến hơn của giao thức HTTP cũ. Sau đây là câu trả lời cho những câu hỏi phổ biến nhất là HTTP/2.

Nội dung

Câu hỏi chung

  • Tại sao phải sửa đổi HTTP?
  • Ai đã tạo ra HTTP/2?
  • Mối quan hệ với SPDY là gì?
  • HTTP/2.0 hay HTTP/2?
  • Sự khác biệt chính với HTTP/1.x là gì?
  • Tại sao lại là HTTP/2 nhị phân?
  • Vì sao HTTP/2 được multiplex?
  • Tại sao chỉ có một kết nối TCP?
  • Lợi ích của Server Push là gì?
  • Tại sao chúng ta cần nén header?
  • Tại sao là HPACK?
  • HTTP/2 có thể làm cho cookie (hoặc các header khác) tốt hơn không?
  • Còn những người dùng HTTP không có trình duyệt thì sao?
  • HTTP/2 có yêu cầu mã hóa không?
  • HTTP/2 làm gì để cải thiện bảo mật?
  • Tôi có thể sử dụng HTTP/2 bây giờ không?
  • HTTP/2 sẽ thay thế HTTP/1.x?
  • Sẽ có một HTTP/3?

Câu hỏi về Implementation

  • Tại sao các quy tắc lại xung quanh Tính liên tục của HEADERS frame?
  • Kích thước trạng thái HPACK tối thiểu hoặc tối đa là bao nhiêu?
  • Làm cách nào để tránh giữ trạng thái HPACK?
  • Tại sao có single compression/ flow-control context?
  • Tại sao có biểu tượng EOS trong HPACK?
  • Tôi có thể triển khai HTTP/2 mà không cần HTTP/1.1 không?
  • Ví dụ về mức độ ưu tiên trong Section 5.3.2 có sai không?
  • Tôi có cần TCP_NODELAY cho các kết nối HTTP/2 không?

Câu hỏi về Deployment

  • Làm cách nào để gỡ lỗi HTTP/2 nếu nó được mã hóa?
  • Làm cách nào để sử dụng HTTP/2 server push?

Câu hỏi chung

Tại sao phải sửa đổi HTTP?

HTTP/1.1 đã phục vụ tốt cho Web trong hơn 15 năm, nhưng nó đang bắt đầu có những hạn chế. 

Việc tải một trang Web tốn nhiều tài nguyên hơn bao giờ hết và việc tải tất cả các nội dung là rất khó. Bởi vì HTTP thực tế chỉ cho phép một request trên mỗi kết nối TCP.

Trước đây, các trình duyệt đã sử dụng nhiều kết nối TCP để đưa ra các yêu cầu song song. Tuy nhiên, nếu quá nhiều kết nối được sử dụng, nó có thể phản tác dụng. Ví dụ, kiểm soát tắc nghẽn TCP bị vô hiệu hóa, dẫn đến tắc nghẽn làm ảnh hưởng đến hiệu suất và mạng. Về cơ bản, việc có quá nhiều kết nối là không cân bằng. Bởi vì các trình duyệt đang chiếm nhiều hơn phần tài nguyên mạng của chúng.

Đồng thời, số lượng lớn các request có nghĩa là rất nhiều dữ liệu trùng lặp “on the wire”.

Cả hai yếu tố này có nghĩa là nếu quá nhiều request HTTP/1.1 được thực hiện, nó sẽ ảnh hưởng đến hiệu suất.

Điều này đã đưa ngành CNTT đến mục tiêu mới. Nó được coi là Best practice để thực hiện những việc như spriting, data: inlining, phân miền và kết nối. Các bản hack này là dấu hiệu của các vấn đề tiềm ẩn trong chính giao thức và gây ra một số vấn đề khi được sử dụng.

Ai đã tạo ra HTTP/2?

HTTP/2 được phát triển bởi IETF’s HTTP Working Group, nhóm duy trì giao thức HTTP. Nó bao gồm một số người triển khai HTTP, người dùng, nhà khai thác mạng và chuyên gia HTTP.

Mặc dù danh sách gửi thư của chúng ta được lưu trữ trên trang W3C. Đây không phải là một nỗ lực của W3C. Tuy nhiên, Tim Berners-Lee và W3C TAG luôn được cập nhật về tiến độ của WG.

Một số lượng lớn người đã đóng góp vào nỗ lực này. Những người tham gia tích cực nhất bao gồm các kỹ sư từ Firefox, Chrome, Twitter, Microsoft’s HTTP stack, Curl và Akamai. Cũng như một số người triển khai HTTP bằng các ngôn ngữ như Python , Ruby và NodeJS.

Mối quan hệ với SPDY là gì?

HTTP/2 lần đầu tiên được thảo luận khi SPDY đang thu hút sự chú ý của những người triển khai (như Mozilla và nginx). Khi đó, nó cũng đang cho thấy những cải tiến đáng kể so với HTTP/1.x.

Sau khi đề xuất và lựa chọn, SPDY / 2 đã được chọn làm cơ sở cho HTTP/2. Kể từ đó, đã có một số thay đổi, dựa trên thảo luận trong Working group và phản hồi từ những người thực hiện.

Trong suốt quá trình, các nhà phát triển cốt lõi của SPDY đã tham gia vào việc phát triển HTTP/2. Trong đó bao gồm cả Mike Belshe và Roberto Peon.

Vào tháng 2 năm 2015, Google đã công bố kế hoạch loại bỏ hỗ trợ cho SPDY để chuyển sang HTTP/2.

Nó là HTTP/2.0 hay HTTP/2?

Working group đã quyết định loại bỏ phiên bản nhỏ (“.0”) vì nó đã gây ra nhiều nhầm lẫn trong HTTP/1.x.

Nói cách khác, phiên bản HTTP chỉ cho biết khả năng tương thích của wire, không phải bộ tính năng hoặc “marketing”.

Sự khác biệt chính so với HTTP/1.x?

Ở cấp độ cao, HTTP/2:

  • là dạng nhị phân, thay vì dạng văn bản
  • được multiplex hoàn toàn, thay vì được sắp xếp và blocking
  • có thể sử dụng một kết nối cho song song
  • sử dụng nén header để giảm chi phí
  • cho phép server chủ động “đẩy” response vào client cache

Tại sao lại là HTTP/2 nhị phân?

Các giao thức nhị phân phân tích cú pháp hiệu quả hơn, nhỏ gọn hơn “on the wire “. Và quan trọng nhất, chúng ít bị lỗi hơn so với các giao thức văn bản như HTTP/1.x. Sở dĩ vì chúng thường có một số khả năng để “trợ giúp ” những thứ như xử lý khoảng trắng, viết hoa, kết thúc dòng, dòng trống, v.v.

Ví dụ, HTTP/1.1 xác định bốn cách khác nhau để phân tích cú pháp một tin nhắn. Trong khi đó, HTTP/2 chỉ có một đường dẫn mã.

Tuy không thể sử dụng HTTP/2 thông qua telnet, nhưng chúng ta đã có một số công cụ hỗ trợ, chẳng hạn như plugin Wireshark.

Tại sao HTTP/2 được multiplex?

HTTP/1.x có một vấn đề được gọi là “head-of-line blocking”. Tức là chỉ một request được thực hiện trên một kết nối tại một thời điểm.

HTTP/1.1 đã cố gắng khắc phục điều này bằng pipelining, nhưng nó không giải quyết được hoàn toàn sự cố. Cụ thể, một response lớn hoặc chậm vẫn có thể chặn những response sau nó. Ngoài ra, pipelining rất khó triển khai. Sở dĩ vì nhiều trung gian và server không xử lý nó chính xác.

Điều này buộc client phải sử dụng một số phương pháp heuristics (thường là phỏng đoán). Để xác định yêu cầu đặt kết nối nào với nguồn gốc khi nào. Vì một trang thường tải gấp 10 lần (hoặc nhiều hơn) số lượng kết nối có sẵn. Từ đó có thể ảnh hưởng nghiêm trọng đến hiệu suất, thường dẫn đến rất nhiều request bị chặn.

Multiplexing giải quyết những vấn đề này bằng cách cho phép nhiều request và response được thực hiện cùng một lúc. Thậm chí có thể xen kẽ các phần của một tin nhắn với một tin nhắn khác trên dây.

Đổi lại, client chỉ sử dụng một kết nối cho mỗi điểm gốc để tải một trang.

Vì sao chỉ có một kết nối TCP?

Với HTTP/1, các trình duyệt mở từ 4 đến 8 kết nối cho mỗi tên miền. Vì nhiều trang web sử dụng nhiều nguồn gốc, một lần tải trang sẽ mở ra đến hơn 30 kết nối.

Một ứng dụng mở quá nhiều kết nối cùng lúc phá vỡ nhiều giả định mà TCP đã được xây dựng. Vì mỗi kết nối sẽ bắt đầu một loạt dữ liệu trong response, các bộ đệm trong mạng sẽ bị tràn. Từ đó gây ra sự tắc nghẽn và truyền lại.

Ngoài ra, việc sử dụng quá nhiều kết nối sẽ độc quyền tài nguyên mạng, “đánh cắp” chúng từ các ứng dụng khác hoạt động tốt hơn (ví dụ: VoIP).

Lợi ích của Server Push là gì?

Khi trình duyệt request một trang, server sẽ gửi HTML trong response. Sau đó, trình duyệt phân tích cú pháp HTML và đưa ra request cho tất cả các nội dung trước khi bắt đầu gửi JavaScript, hình ảnh và CSS.

Server Push cho phép server tránh được sự chậm trễ này bằng cách “đẩy” các response mà nó cho rằng client sẽ cần vào bộ nhớ cache của nó.

Tuy nhiên, nếu Pushing response được sử dụng không đúng cách, nó có thể gây hại cho hiệu suất. Sử dụng đúng Server Push là một lĩnh vực cần được thử nghiệm và nghiên cứu liên tục.

Tại sao chúng ta cần nén header?

Patrick McManus từ Mozilla đã trả lời câu hỏi này bằng cách tính toán ảnh hưởng của header đối với tải trang trung bình.

Nếu bạn giả định rằng một trang có khoảng 80 nội dung (điều này khá phổ biến trong Web ngày nay). Mỗi request có 1400 byte header, thì cần ít nhất 7-8 các chuyến đi vòng để đưa các header ra “on the wire”. Đó là không tính thời gian response. Tức là đó chỉ là thời gian để đưa chúng ra khỏi client.

Điều này là do cơ chế TCP’s Slow Start. Cơ chế này phân chia packet trên các kết nối mới dựa trên số lượng packet đã được thừa nhận. Do đó giới hạn số lượng packet có thể được gửi trong một vài chuyến đầu tiên.

Ngay cả việc nén nhẹ trên các header cũng cho phép những request đó đi vào wire chỉ trong một chuyến. Thậm chí có thể là trong một packet.

Lợi ích này rất đáng kể, đặc biệt là khi bạn xem xét tác động đối với các mobile client. Vốn thường thấy round-trip latency lên đến vài trăm mili giây, ngay cả trong điều kiện tốt.

HTTP/2

Tại sao là HPACK?

SPDY/2 đề xuất sử dụng GZIP context duy nhất theo mỗi hướng để nén header.

Từ đó, một cuộc tấn công lớn đã chống lại việc sử dụng nén luồng (như GZIP) bên trong mã hóa, đó là CRIME.

Với CRIME, kẻ tấn công có thể đưa dữ liệu vào luồng được mã hóa để “thăm dò” plaintext và khôi phục nó. Vì đây là Web, JavaScript làm cho điều này có thể thực hiện được. Đồng thời, cũng đã có các minh chứng về việc khôi phục cookie và mã thông báo xác thực. Bằng cách sử dụng CRIME cho các tài nguyên HTTP được bảo vệ bởi TLS.

Do đó, chúng ta không thể sử dụng tính năng nén GZIP. Chúng tôi đã tạo một lược đồ nén header mới, cụ thể hoạt động ở mức độ chi tiết thô. HTTP header thường không thay đổi giữa các mesage, nên điều này vẫn mang lại hiệu quả nén hợp lý và an toàn hơn nhiều.

Nỗ lực này đã được dùng để thực hiện một bản sửa đổi của giao thức wire. Tức là cách HTTP header, phương thức, v.v. được đưa vào “wire”, không thay đổi ngữ nghĩa của HTTP.

Đó là bởi vì HTTP được sử dụng rất rộng rãi. Nếu chúng ta sử dụng phiên bản HTTP này để giới thiệu một cơ chế trạng thái mới. Hoặc thay đổi các phương pháp cốt lõi, giao thức mới sẽ không tương thích với Web hiện có .

Đặc biệt, chúng ta muốn có thể dịch từ HTTP/1 sang HTTP/2 và ngược lại mà không bị mất thông tin. Nếu chúng ta bắt đầu “cleaning up” các header, chúng ta sẽ gặp vấn đề về khả năng tương tác với hầu hết các trang Web hiện có.

Như vậy sẽ tạo ra xung đột chống lại việc áp dụng giao thức mới.

HTTP Working group chịu trách nhiệm về tất cả HTTP, không chỉ HTTP/2. Do đó, chúng ta có thể làm việc trên các cơ chế mới không phụ thuộc vào phiên bản. Miễn là chúng tương thích ngược với Web hiện có.

Còn những người dùng HTTP không có trình duyệt thì sao?

Các ứng dụng không phải là trình duyệt cũng có thể sử dụng HTTP/2, nếu chúng đã sử dụng HTTP.

HTTP/2 có các đặc điểm hiệu suất tốt cho “API” HTTP. Vì các API không cần phải xem xét những thứ như chi phí yêu cầu trong thiết kế của chúng.

Phải nói rằng, trọng tâm chính của các cải tiến mà chúng tôi đang xem xét là các trường hợp sử dụng trình duyệt điển hình. Vì đây là trường hợp sử dụng cốt lõi cho giao thức.

HTTP/2 có yêu cầu mã hóa không?

Không. Sau khi thảo luận, Working group không đồng thuận về việc yêu cầu sử dụng mã hóa (ví dụ: TLS) cho giao thức mới.

Tuy nhiên, một số triển khai chỉ hỗ trợ HTTP/2 khi nó được sử dụng qua kết nối được mã hóa. Đồng thời, hiện không có trình duyệt nào hỗ trợ HTTP/2 không được mã hóa.

HTTP/2 làm gì để cải thiện bảo mật?

HTTP/2 xác định cấu hình TLS được yêu cầu; điều này bao gồm phiên bản, ciphersuite blacklist, và các tiện ích mở rộng được sử dụng.

Ngoài ra còn có thảo luận về các cơ chế bổ sung. Chẳng hạn như sử dụng TLS cho các URL HTTP://

Tôi có thể sử dụng HTTP/2 bây giờ không?

Trong các trình duyệt, HTTP/2 được hỗ trợ bởi Edge, Safari, Firefox và Chrome mới nhất. Các trình duyệt khác dựa trên Blink cũng sẽ hỗ trợ HTTP/2 (ví dụ: Opera và Yandex). Xem caniuse để biết thêm chi tiết.

Ngoài ra còn có một số server (bao gồm hỗ trợ beta từ Akamai, các trang web chính của Google và Twitter) và một số implementation Mã nguồn mở mà bạn có thể triển khai và thử nghiệm.

Xem implementation list để biết thêm chi tiết.

HTTP/2 sẽ thay thế HTTP/1.x?

Mục tiêu của Working group là thay thế các sử dụng điển hình của HTTP/1.x bằng  HTTP/2. Tuy nhiên, do cách mọi người triển khai proxy và server, HTTP/1.x có thể vẫn được sử dụng trong một thời gian khá dài.

Sẽ có một HTTP/3?

Nếu cơ chế thương lượng được giới thiệu bởi HTTP/2 hoạt động tốt, thì có thể hỗ trợ các phiên bản HTTP mới dễ dàng hơn nhiều so với trước đây.

Các câu hỏi về Implementation

Tại sao các quy tắc lại xoay xung quanh Tính liên tục của HEADERS frames?

Continuation (tính liên tục) tồn tại khi một giá trị (ví dụ: Set-Cookie) vượt quá 16KiB – 1. Có nghĩa là nó không thể vừa với frame. Cách ít lỗi nhất để giải quyết vấn đề này là yêu cầu tất cả dữ liệu header phải ở trong các back-to-back frame. Điều này sẽ giúp việc giải mã và quản lý bộ đệm dễ dàng hơn.

Kích thước HPACK state tối thiểu hoặc tối đa là bao nhiêu?

Người nhận luôn kiểm soát lượng bộ nhớ được sử dụng trong HPACK. Và có thể đặt nó ở mức tối thiểu bằng 0, với mức tối đa liên quan đến số nguyên tối đa có thể biểu diễn trong khung SETTINGS, hiện tại là 2 ^ 32 – 1.

Làm cách nào để tránh giữ HPACK state?

Gửi kích thước state vào khung SETTINGS (SETTINGS_HEADER_TABLE_SIZE) về 0. Sau đó RST tất cả các luồng cho đến khi nhận được khung SETTINGS với bộ bit ACK.

Tại sao có một single compression/ flow-control context duy nhất?

Câu trả lời là: Vì sự đơn giản.

Các đề xuất ban đầu có các nhóm luồng chia sẻ context, kiểm soát luồng, v.v. Mặc dù mang lại lợi ích cho proxy (và trải nghiệm của người dùng), nhưng sẽ thêm phức tạp. Chúng tôi sẽ bắt đầu với điều đơn giản, xem nó lỗi như thế nào. Và sau đó giải quyết lỗi (nếu có) trong một bản sửa đổi giao thức trong tương lai.

Tại sao có biểu tượng EOS trong HPACK?

Mã hóa huffman của HPACK, vì lý do hiệu quả và bảo mật của CPU, đệm các chuỗi được mã hóa huffman vào ranh giới byte tiếp theo. Có thể có từ 0-7 bit đệm cần thiết cho bất kỳ chuỗi cụ thể nào.

Nếu giải mã huffman được xem xét một cách riêng biệt, thì bất kỳ ký hiệu nào dài hơn phần đệm bắt buộc sẽ hoạt động. Tuy nhiên, thiết kế của HPACK cho phép so sánh từng byte các chuỗi được mã hóa huffman. Bằng cách yêu cầu các bit của ký hiệu EOS được sử dụng để đệm, người dùng có thể so sánh từng byte của các chuỗi được mã hóa huffman để xác định sự bình đẳng. Điều này có nghĩa là nhiều header có thể được giải thích mà không bị giải mã huffman.

Tôi có thể triển khai HTTP/2 mà không cần triển khai HTTP/1.1 không?

Có. 

Đối với HTTP/2 qua TLS (h2), nếu bạn không triển khai định danh ALPN http1.1, thì bạn sẽ không cần hỗ trợ bất kỳ tính năng HTTP/1.1 nào.

Đối với HTTP/2 qua TCP (h2c), bạn cần thực hiện yêu cầu nâng cấp ban đầu.

h2c-only client sẽ cần tạo request OPTIONS cho “*” hoặc HEAD cho “/”, khá an toàn và dễ xây dựng. Client muốn triển khai HTTP/2 chỉ sẽ cần coi các response HTTP/1.1 không có mã trạng thái 101 là lỗi.

h2c-only server có thể chấp nhận request chứa trường header Nâng cấp với response 101 cố định. Request không có token h2c có thể bị từ chối với mã trạng thái 505 (Phiên bản HTTP không được hỗ trợ) có chứa trường header Nâng cấp. Server không muốn xử lý phản hồi HTTP/1.1 sẽ từ chối stream 1 với mã lỗi REFUSED_STREAM ngay sau khi gửi preface để khuyến khích client thử lại request qua kết nối HTTP/2 được nâng cấp.

Ví dụ về mức độ ưu tiên trong Section 5.3.2 có sai không?

Không. Stream B có trọng số 4, stream C có trọng số 12. Để xác định tỷ lệ tài nguyên sẵn có mà mỗi stream này nhận được, hãy tính tổng tất cả các trọng số (16) và chia trọng lượng của từng stream cho tổng trọng lượng. Do đó, stream B nhận được một phần tư tài nguyên có sẵn. Và stream C nhận được ba phần tư. Do đó, stream B lý tưởng nhận được một phần ba tài nguyên được phân bổ cho stream C.

Tôi có cần TCP_NODELAY cho các kết nối HTTP/2 của mình không?

Có. Ngay cả đối với client-side implementation chỉ tải xuống nhiều dữ liệu bằng cách sử dụng một luồng duy nhất. Khi đó một số packet vẫn cần thiết để gửi lại theo hướng ngược lại để đạt được tốc độ truyền tối đa. Nếu không có bộ TCP_NODELAY (vẫn cho phép thuật toán Nagle), các packet gửi đi có thể bị giữ lại một thời gian để cho phép chúng hợp nhất với một packet tiếp theo.

Ví dụ một packet nói với packet khác rằng có nhiều cửa sổ hơn để gửi dữ liệu, việc trì hoãn gửi trong nhiều mili giây (hoặc hơn) có thể gây ảnh hưởng nghiêm trọng đến các kết nối tốc độ cao.

Các câu hỏi về Deployment

Làm cách nào để gỡ lỗi HTTP/2 nếu nó được mã hóa?

Cách dễ nhất là sử dụng tính năng NSS keylogging kết hợp với plugin Wireshark (có trong các bản phát triển gần đây). Nó hoạt động với cả Firefox và Chrome.

Làm cách nào để sử dụng HTTP/2 server push?

HTTP/2 server push cho phép server cung cấp nội dung cho client mà không cần chờ request. Điều này cải thiện thời gian truy xuất tài nguyên, đặc biệt đối với các kết nối với sản phẩm có độ trễ băng thông lớn. 

Pushing các tài nguyên khác nhau dựa trên nội dung của một request có thể là không khôn ngoan. Hiện tại, các trình duyệt chỉ sử dụng các request được push nếu chúng sẽ đưa ra một request phù hợp (xem Phần 4 của RFC 7234).
Một số cache không tôn trọng các biến thể trong tất cả các trường request header, ngay cả khi chúng được liệt kê trong trường header Vary. Để tối đa hóa khả năng tài nguyên được push sẽ được chấp nhận, tốt nhất nên tránh thương lượng nội dung. Thương lượng nội dung dựa trên trường header accept-encoding được lưu trữ rộng rãi trong cache. Tuy nhiên các trường header khác có thể không được hỗ trợ tốt.

Theo HTTP/2.

Source: https://vietnix.vn/http-2/