2008-08-07 24 views

Trả lời

16

Một etag là một chuỗi tùy ý mà máy chủ gửi cho máy khách mà khách hàng sẽ gửi lại cho máy chủ vào lần tiếp theo tệp được yêu cầu.

Dấu thập phân phải được tính trên máy chủ dựa trên tệp. Sắp xếp như một tổng kiểm tra, nhưng bạn có thể không muốn kiểm tra tất cả các tệp gửi đi.

server    client 

     <------------- request file foo 

file foo etag: "xyz" --------> 

     <------------- request file foo 
         etag: "xyz" (what the server just sent) 

(the etag is the same, so the server can send a 304) 

Tôi đã tạo chuỗi ở định dạng "số inode/datestamp/kích thước tệp". Vì vậy, nếu một tập tin được thay đổi trên máy chủ sau khi nó đã được phục vụ cho khách hàng, etag mới được tạo lại sẽ không khớp nếu khách hàng yêu cầu lại nó.

 
char *mketag(char *s, struct stat *sb) 
{ 
    sprintf(s, "%d/%d/%d", sb->st_ino, sb->st_mtime, sb->st_size); 
    return s; 
} 
+2

Nếu mtime là thời gian tệp được thay đổi lần cuối, thì mục đích kích thước và inode là gì? – Steve

+0

Trong trường hợp của tôi, đó là vì nó là một con đường tính toán từ một chương trình CGI. Bạn nói đúng rằng trong trường hợp của một con đường trực tiếp mà các mtime có lẽ sẽ là đủ. Vì chi phí chủ yếu là stat(), bạn không phải trả thêm phí để bao gồm inode và size, có thể bảo vệ khỏi trường hợp (không chắc chắn), nơi quản trị viên giả mạo có thể cập nhật tệp và chạm vào tệp đó mtime ban đầu. –

+0

@MarkHarrison, tại sao bạn cần báo giá kép xung quanh etag? Nó là một phần bắt buộc của cú pháp? – Pacerier

6

Từ http://developer.yahoo.com/performance/rules.html#etags:

Theo mặc định, cả Apache và IIS nhúng dữ liệu trong ETag làm giảm đáng kể tỷ lệ cược của bài kiểm tra tính hợp lệ thành công trên các trang web với nhiều máy chủ.

...

Nếu bạn không tận dụng mô hình xác thực linh hoạt mà ETags cung cấp, tốt hơn hết là chỉ xóa toàn bộ ETAG.

17

Miễn là nó thay đổi bất cứ khi nào thay đổi biểu diễn tài nguyên, cách bạn tạo nó hoàn toàn tùy thuộc vào bạn.

Bạn nên cố gắng tạo ra nó trong một cách mà bổ sung:

  1. không yêu cầu bạn phải tái tính toán nó trên mỗi GET có điều kiện, và
  2. không thay đổi nếu nội dung nguồn hasn 't đã thay đổi

Sử dụng băm nội dung có thể khiến bạn thất bại ở vị trí số 1 nếu bạn không lưu trữ băm được tính cùng với tệp.

Sử dụng số inode có thể khiến bạn thất bại ở # 2 nếu bạn sắp xếp lại hệ thống tệp hoặc bạn phân phối nội dung từ nhiều máy chủ.

Một cơ chế có thể hoạt động là sử dụng nội dung hoàn toàn phụ thuộc như băm SHA-1 hoặc chuỗi phiên bản, được tính và lưu trữ một lần bất cứ khi nào nội dung tài nguyên của bạn thay đổi.

0

Tôi khuyên bạn không nên sử dụng chúng và thay vào đó hãy sử dụng các tiêu đề được sửa đổi lần cuối.

Askapache có một bài viết hữu ích về điều này. (Như họ làm khá nhiều tất cả mọi thứ có vẻ như!)

http://www.askapache.com/htaccess/apache-speed-etags.html

+1

liên kết askapache bị hỏng – bskinnersf

+0

Hmm, đó là một sự xấu hổ, hy vọng họ sẽ trở lại ngay sau khi trang web là một lời khuyên vàng! –

+0

Liên kết đã được sao lưu ngay bây giờ. –

2

Làm thế nào để tạo ra các etag apache mặc định trong bash

for file in *; do printf "%x-%x-%x\t$file\n" `stat -c%i $file` `stat -c%s $file` $((`stat -c%Y $file`*1000000)) ; done 

Ngay cả khi tôi đang tìm kiếm một cái gì đó giống hệt như các etag (trình duyệt yêu cầu một tập tin chỉ khi nó đã thay đổi trên máy chủ), nó không bao giờ làm việc và tôi đã kết thúc bằng cách sử dụng một thủ thuật GET (thêm một dấu thời gian như là một đối số nhận được vào các tập tin js).

1

Tôi đã sử dụng Adler-32 làm trình rút gọn liên kết html. Tôi không chắc đây có phải là một ý hay hay không, nhưng cho đến nay, tôi đã không chú ý đến bất kỳ bản sao nào. Nó có thể hoạt động như một bộ tạo etag. Và nó sẽ nhanh hơn sau đó cố gắng băm bằng cách sử dụng một chương trình mã hóa như sha, nhưng tôi havent xác minh điều này. Mã tôi sử dụng là:

shortlink = str(hex(zlib.adler32(link)+(2**32-1)/2))[2:-1]