squid第16章 除錯和故障處理
16.1 一些通用問題
在討論通用debug前,我先提起一些經常發生的問題。
16.1.1 "Failed to make swap directory"
Failed to make swap directory /var/spool/cache: (13) Permission denied
這點發生在你執行squid -z,並且squid的使用者ID沒有對/var/spool目錄的寫許可權的時候。記住假如以root來啟動squid,並且沒有增加cache_effective_user行,那麼squid預設以nobody使用者執行。解決方法很簡單:
# chown nobody:nobody /var/spool
16.1.2 "Address already in use"
commBind: Cannot bind socket FD 10 to *:3128: Address already in use
這個訊息出現在bind()系統呼叫失敗時,因為請求埠已經被其他應用程式所開啟。通常,若已有一個squid在執行,而又試圖啟動第2個squid例項,就會發生這種情況。假如你見到這個錯誤訊息,請使用ps來觀察是否squid已經在執行。
Squid使用SO_REUSEADDR socket選項,以便bind()呼叫總能成功,即使仍有一些殘餘的socket位於TIME_WAIT狀態。若該訊息出現,儘管squid沒有在運 行,但你的作業系統可能在處理這個問題上有bug。重啟作業系統是解決問題的一個方法。
另一個可能性是埠(例如3128)當前已被其他應用程式使用。假如你懷疑這點,就可使用lsof程式來發現哪個應用正在該埠上偵聽。FreeBSD使用者能使用sockstat代替。
16.1.3 "Could not determine fully qualified hostname"
FATAL: Could not determine fully qualified hostname. Please set 'visible_hostname'
假如squid不能識別它自己的完整可驗證域名,就會報這個錯。如下是squid使用的演算法:
- 1) 假如你將squid的HTTP埠繫結在指定的介面地址上,squid試圖對該地址執行反向DNS查詢。假如成功,查詢答案就被用上。
- 2) Squid呼叫gethostname( )函式,然後使用 gethostbyname( )函式,試著解析其IP地址。假如成功,squid使用後者函式返回的官方主機名串。
假如以上2項技術都不能工作,squid以前面提到的致命錯誤訊息退出。在該情形下,必須使用visible_hostname指令來告訴squid它的主機名。例如:
visible_hostname my.host.name
16.1.4 "DNS name lookup tests failed"
預設情況下,squid在啟動前執行一些DNS查詢。這點確保你的DNS伺服器可到達,並且執行正確。假如測試失敗,可在cache.log或syslog裡見到如下訊息:
FATAL: ipcache_init: DNS name lookup tests failed
假如你在內網裡使用squid,squid可能不能查詢到它的標準主機名列表。可使用dns_testnames指令來指定你自己的主機名。只要接受到響應,squid就會認為DNS測試成功。
假如你想完全跳過DNS測試,簡單的在啟動squid時,使用-D命令列選項:
% squid -D ...
16.1.5 "Illegal character in hostname"
urlParse: Illegal character in hostname 'super_bikes.tripod.com'
預設情況下,squid檢查URL的主機名部分的字元,假如它發現了非標準的字元,squid會抱怨。參考RFC 1034和1035,名字必須由字母A-Z,數字0-9,以及短橫線(-)組成。下劃線(_)是最有問題的字元之一。
Squid驗證主機名是因為,在某些情形下,DNS對畸形字元的解析會很困難。例如:
% host super_bikes.tripod.com
super_bikes.tripod.com has address 209.202.196.70
% ping super_bikes.tripod.com
ping: cannot resolve super_bikes.tripod.com: Unknown server error
Squid事先檢查主機名,這好過於以後返回Unknown server error訊息。然後它會告訴使用者主機名包含畸形字元。
某些DNS解析器確實能處理下劃線和其他非標準字元。假如你想讓squid不檢查主機名,請在執行./configure時,使用—disable -hostname-checks選項。假如你允許下劃線作為唯一的例外,那麼使用—enable-underscores選項。
16.1.6 "Running out of filedescriptors"
WARNING! Your cache is running out of filedescriptors
上述訊息出現在squid用完了所有可用檔案描述符時。假如這點發生在正常條件下,就有必要增加核心的檔案描述符限制,並且重新編譯squid。請見3.3.1章。
假如squid成為了拒絕服務攻擊的目標,那也會見到這條訊息。某些人可能有意或無意的,同時對squid傳送成百上千條請求。在這種情形下,可以增加一條包過濾規則,阻止來自惡意地址的TCP進入連線。假如攻擊是分散式的,或使用假冒源地址,就很難阻止它們。
轉發迴圈(見10.2章)也可能耗盡squid的所有檔案描述符,但僅僅發生在squid不能檢測到死迴圈時。Via頭部包含了某個請求遍歷過的所 有代理的主機名。squid在頭部裡查詢它自己的主機名,假如發現了,就報告這個迴圈。假如因為某些理由,Via頭部從外出或進入HTTP請求裡過濾掉 了,squid就不能檢測到迴圈。在該情形下,所有檔案描述符被迴圈遍歷squid的同一請求迅速耗完。
16.1.7 "icmpRecv: Connection refused"
假如pinger程式沒有正確的安裝,可見到下列訊息:
icmpRecv: recv: (61) Connection refused
不過看起來更象是因為沒有開啟ICMP socket的許可權,pinger立刻退出了。因為該程序未在執行,當squid試圖與它會話時,會接受到I/O錯誤。為了解決該問題,請到原始碼目錄以root執行:
# make install-pinger
假如成功,你可見到pinger程式有下列檔案屬主和許可設定:
# ls -l /usr/local/squid/libexec/pinger
-rws--x--x 1 root squid 140728 Sep 16 19:58 /usr/local/squid/libexec/pinger
16.1.8 在執行一段時間後,Squid變慢了
看起來更象squid與其他程序,或與它自己,在競爭系統中的記憶體。當squid程序的記憶體不再充足時,作業系統被迫從交換空間進行記憶體讀寫。這對squid的效能有強烈影響。
為了證實這個想法,請使用top和ps等工具檢查squid的程序大小。也檢查squid自己的頁面錯誤計數器,見14.2.1.24章的描述。一旦你已確認記憶體耗費是問題所在,請執行下列步驟來減少squid的記憶體使用:
- 1. 減少cache_mem值,見附錄B。
- 2. 關掉記憶體池,用該選項:
memory_pools off
- 3. 通過降低一個或多個cache目錄的size,減少磁碟cache大小。
16.1.9 除錯訪問控制
假如訪問控制不能正確工作,如下是一些有用幫助。編輯squid.conf檔案,設定debug_options行如下:
debug_options ALL,1 33,2
然後,重配置squid:
% squid -k reconfigure
現在,對每個客戶端請求以及每個響應,squid都寫一條訊息到cache.log。該訊息包含了請求方式,URI,是否請求/響應被允許或拒絕,以及與之匹配的最後ACL的名字。例如:
2003/09/29 20:22:05| The request
GET http://images.slashdot.org:80/topics/topicprivacy.gif is ALLOWED,
because it matched 'localhost'
2003/09/29 20:22:05| The reply for
GET http://images.slashdot.org/topics/topicprivacy.gif is ALLOWED,
because it matched 'all'
知道ACL的名字,並非總能知道相應的http_access行,但也相當接近了。假如必要,可以複製acl行,並給予它們唯一的名字,以便給定的ACL名字僅僅出現在一個http_access規則裡。
16.2 通過cache.log進行除錯
從13.1章已瞭解到,cache.log包含了不同的操作訊息,squid認為這些訊息足夠重要,從而告訴了你。我們也將這些作為debug訊息 考慮。可以使用debug_options指令來控制出現在cache.log裡的訊息的冗長度。通過增加debug等級,可以見到更詳細的訊息,有助於 理解squid正在做什麼。例如:
debug_options ALL,1 11,3 20,3
在squid原始碼裡的每個debug訊息有2個數字特徵:1個節和1個等級。節範圍從0到100,等級範圍從0到10。通常來說,節號對應著源代 碼的組成成分。換句話說,在單一原始檔裡的所有訊息,有相同的節號。在某些情形下,多個檔案使用同一debug節,這意味著某個原始檔變得太大,從而被拆 分成多個小塊。
每個原始檔的頂部有一行,用於指示debug節。它看起來如此:
* DEBUG: section 9 File Transfer Protocol (FTP)
我不指望你通過檢視原始檔來查詢節號,所有相關資訊定義在表16-1裡。
Table 16-1. Debugging section numbers for the debug_options directive
Number | Description | Source file(s) |
0 | Client Database | client_db.c |
1 | Startup and Main Loop | main.c |
2 | Unlink Daemon | unlinkd.c |
3 | Configuration File Parsing | cache_cf.c |
4 | Error Generation | errorpage.c |
5 | Socket Functions | comm.c |
5 | Socket Functions | comm_select.c |
6 | Disk I/O Routines | disk.c |
7 | Multicast | multicast.c |
8 | Swap File Bitmap | filemap.c |
9 | File Transfer Protocol (FTP) | ftp.c |
10 | Gopher | gopher.c |
11 | Hypertext Transfer Protocol (HTTP) | http.c |
12 | Internet Cache Protocol | icp_v2.c |
12 | Internet Cache Protocol | icp_v3.c |
13 | High Level Memory Pool Management | mem.c |
14 | IP Cache | ipcache.c |
15 | Neighbor Routines | neighbors.c |
16 | Cache Manager Objects | cache_manager.c |
17 | Request Forwarding | forward.c |
18 | Cache Manager Statistics | stat.c |
19 | Store Memory Primitives | stmem.c |
20 | Storage Manager | store.c |
20 | Storage Manager Client-Side Interface | store_client.c |
20 | Storage Manager Heap-Based Replacement | repl/heap/store_heap_replacement.c |
20 | Storage Manager Logging Functions | store_log.c |
20 | Storage Manager MD5 Cache Keys | store_key_md5.c |
20 | Storage Manager Swapfile Metadata | store_swapmeta.c |
20 | Storage Manager Swapin Functions | store_swapin.c |
20 | Storage Manager Swapout Functions | store_swapout.c |
20 | Store Rebuild Routines | store_rebuild.c |
21 | Misc Functions | tools.c |
22 | Refresh Calculation | refresh.c |
23 | URL Parsing | url.c |
24 | WAIS Relay | wais.c |
25 | MIME Parsing | mime.c |
26 | Secure Sockets Layer Proxy | ssl.c |
27 | Cache Announcer | send-announce.c |
28 | Access Control | acl.c |
29 | Authenticator | auth/basic/auth_basic.c |
29 | Authenticator | auth/digest/auth_digest.c |
29 | Authenticator | authenticate.c |
29 | NTLM Authenticator | auth/ntlm/auth_ntlm.c |
30 | Ident (RFC 1413) | ident.c |
31 | Hypertext Caching Protocol | htcp.c |
32 | Asynchronous Disk I/O | fs/aufs/async_io.c |
33 | Client-Side Routines | client_side.c |
34 | Dnsserver Interface | dns.c |
35 | FQDN Cache | fqdncache.c |
37 | ICMP Routines | icmp.c |
38 | Network Measurement Database | net_db.c |
39 | Cache Array Routing Protocol | carp.c |
40 | Referer Logging | referer.c |
40 | User-Agent Logging | useragent.c |
41 | Event Processing | event.c |
42 | ICMP Pinger Program | pinger.c |
43 | AIOPS | fs/aufs/aiops.c |
44 | Peer Selection Algorithm | peer_select.c |
45 | Callback Data Registry | cbdata.c |
45 | Callback Data Registry | leakfinder.c |
46 | Access Log | access_log.c |
47 | Store COSS Directory Routines | fs/coss/store_dir_coss.c |
47 | Store Directory Routines | fs/aufs/store_dir_aufs.c |
47 | Store Directory Routines | fs/diskd/store_dir_diskd.c |
47 | Store Directory Routines | fs/null/store_null.c |
47 | Store Directory Routines | fs/ufs/store_dir_ufs.c |
47 | Store Directory Routines | store_dir.c |
48 | Persistent Connections | pconn.c |
49 | SNMP Interface | snmp_agent.c |
49 | SNMP Support | snmp_core.c |
50 | Log File Handling | logfile.c |
51 | File Descriptor Functions | fd.c |
52 | URN Parsing | urn.c |
53 | AS Number Handling | asn.c |
54 | Interprocess Communication | ipc.c |
55 | HTTP Header | HttpHeader.c |
56 | HTTP Message Body | HttpBody.c |
57 | HTTP Status-Line | HttpStatusLine.c |
58 | HTTP Reply (Response) | HttpReply.c |
59 | Auto-Growing Memory Buffer with printf | MemBuf.c |
60 | Packer: A Uniform Interface to Store Like Modules | Packer.c |
61 | Redirector | redirect.c |
62 | Generic Histogram | StatHist.c |
63 | Low Level Memory Pool Management | MemPool.c |
64 | HTTP Range Header | HttpHdrRange.c |
65 | HTTP Cache Control Header | HttpHdrCc.c |
66 | HTTP Header Tools | HttpHeaderTools.c |
67 | String | String.c |
68 | HTTP Content-Range Header | HttpHdrContRange.c |
69 | HTTP Header: Extension Field | HttpHdrExtField.c |
70 | Cache Digest | CacheDigest.c |
71 | Store Digest Manager | store_digest.c |
72 | Peer Digest Routines | peer_digest.c |
73 | HTTP Request | HttpRequest.c |
74 | HTTP Message | HttpMsg.c |
75 | WHOIS Protocol | whois.c |
76 | Internal Squid Object handling | internal.c |
77 | Delay Pools | delay_pools.c |
78 | DNS Lookups; interacts with lib/rfc1035.c | dns_internal.c |
79 | Squid-Side DISKD I/O Functions | fs/diskd/store_io_diskd.c |
79 | Storage Manager COSS Interface | fs/coss/store_io_coss.c |
79 | Storage Manager UFS Interface | fs/ufs/store_io_ufs.c |
80 | WCCP Support | wccp.c |
82 | External ACL | external_acl.c |
83 | SSL Accelerator Support | ssl_support.c |
84 | Helper Process Maintenance | helper.c |
debug等級這樣分配:重要訊息有較低值,非重要訊息有較高值。0等級是非常重要的訊息,10等級是相對不緊要的訊息。另外,關於等級其實並沒有嚴格的嚮導或要求。開發者通常自由選擇適應的debug等級。
debug_options指令決定哪個訊息出現在cache.log,它的語法是:
debug_options section,level section,level ...
預設設定是ALL,1,這意味著squid會將所有等級是0或1的debug訊息打印出來。假如希望cache.log裡出現更少的debug訊息,可設定debug_options為ALL,0。
假如想觀察某個元件的其他debug資訊,簡單的將相應的節號和等級增加到debug_options列表的末端。例如,如下行對FTP服務端程式碼增加了等級5的debug:
debug_options ALL,1 9,5
如同其他配置指令一樣,可以改變debug_options,然後給squid傳送重置訊號:
% squid -k reconfigure
注意debug_options引數是按順序處理的,後來的值會覆蓋先前的值。假如使用ALL關鍵字,這點尤其要注意。考慮如下示例:
debug_options 9,5 20,9 4,2 ALL,1
在該情形下,最後的值覆蓋了所有先前的設定,因為ALL,1對所有節設定了debug等級為1。
選擇合適的debug節號和等級有時非常困難,尤其是對squid新手而言。許多更詳細的debug訊息僅對squid開發者和熟悉原始碼的使用者有 意義。無經驗的squid使用者會發現許多debug訊息無意義和不可理解。進一步的說,假如squid相對忙的話,你可能對某個特殊請求或事件進行獨立 debug有困難。假如你能一次用一個請求來測試squid,那麼高的debug等級通常更有用。
若以高debug等級來執行squid較長時間,需要特別謹慎。假如squid繁忙,cache.log增長非常快,並可能最終耗盡它的分割槽的剩餘 空間。假如這點發生,squid以致命訊息退出。另一個關注點是效能可能下降明顯。因為有大量的debug訊息,squid要耗費許多CPU資源來格式化 和列印字串。將所有debug訊息寫往cache.log,也浪費了大量的磁碟頻寬。
16.3 Coredump,斷點,和堆疊跟蹤
假如不幸,squid可能在執行時遭遇致命錯誤。這型別的錯誤來自3個風格:斷點,匯流排錯誤,和異常分片。
斷點是原始碼裡的正常檢測。它是一個工具,被開發者用來確認在處理某事情前,相應的條件總為真。假如條件為假,程式退出並建立一個core檔案,以便開發者能分析形勢。如下是個典型的示例:
int some_array[100];
void
some_func(int idx)
{
...
assert(idx < 100);
some_array[idx]++;
...
}
這裡,斷點確保陣列索引的值位於陣列範圍內。假如去訪問大於或等於100的陣列元素,就會遇到錯誤。假如不知何故,idx的值不小於100,程式執行時會列印如下訊息:
assertion failed: filename.c:123: "idx < 100"
假如這點發生在squid上,就可在cache.log裡見到"assertion failed"訊息。另外,作業系統會建立一個core檔案,這對事後分析有用。在本節結尾,我會解釋如何去處理core檔案。
匯流排錯誤是:由於處理器檢測到其總線上的異常條件,會引發機器語言指令執行時致命失敗。當處理器試圖操作非連續的記憶體地址時,通常會發生這種錯誤。在64位處理器系統上可能更容易見到匯流排錯誤,例如Alpha和某些SPARC CPU。幸運的是,它們容易修復。
異常分片錯誤不幸的更常見,且有時難以修復。SEGV通常發生在程序試圖訪問無效記憶體區域時(可能是個NULL指標,或超出程序空間之外的記憶體地址)。當bug原因和SEGV影響在不同時間呈現時,它們特別難於捕獲到。
Squid預設捕獲匯流排錯誤和異常分片,當它們發生時,squid試圖執行一個clean shutdown(清理關閉)。可在cache.log裡見到類似的語句:
FATAL: Received Bus Error...dying.
2003/09/29 23:18:01| storeDirWriteCleanLogs: Starting...
大多數情形下,squid能夠寫swap.state檔案的clean版本。在退出前,squid呼叫abort()函式來建立core檔案。core檔案可以幫助你或其他開發者來捕獲和修復bug。
在錯誤發生時馬上建立core檔案,而不是先呼叫clean shutdown過程,這樣更利於除錯。使用-C命令列選項,可以告訴squid不去捕獲匯流排錯誤和異常分片:
% squid -C ...
注意某些作業系統使用檔名core,而另外一些優先考慮程序名(例如squid.core)。一旦找到core檔案,請使用偵錯程式來進行堆疊跟 蹤。gdb是GNU偵錯程式--GNU C編譯器的配套工具。假如沒有gdb,可試著執行dbx或adb代替。如下顯示如何使用gdb來進行堆疊跟蹤:
% gdb /usr/local/squid/sbin/squid /path/to/squid.core
...
Core was generated by 'squid'.
Program terminated with signal 6, Abort trap.
...
然後,敲入where來列印堆疊軌跡:
(gdb) where
#0 0x28168b54 in kill ( ) from /usr/lib/libc.so.4
#1 0x281aa0ce in abort ( ) from /usr/lib/libc.so.4
#2 0x80a2316 in death (sig=10) at tools.c:301
#3 0xbfbfffac in ?? ( )
#4 0x80abe0a in storeDiskdSend (mtype=4, sd=0x82101e0, id=1214000,
sio=0x9e90a10, size=4096, offset=-1, shm_offset=0)
at diskd/store_io_diskd.c:485
#5 0x80ab726 in storeDiskdWrite (SD=0x82101e0, sio=0x9e90a10,
buf=0x13e94000 "...", size=4096, offset=-1, free_func=0)
at diskd/store_io_diskd.c:251
#6 0x809d2fb in storeWrite (sio=0x9e90a10, buf=0x13e94000 "...",
size=4096, offset=-1, free_func=0) at store_io.c:89
#7 0x80a1c2d in storeSwapOut (e=0xc5a7800) at store_swapout.c:259
#8 0x809b667 in storeAppend (e=0xc5a7800, buf=0x810f9a0 "...", len=57344)
at store.c:533
#9 0x807873b in httpReadReply (fd=134, data=0xc343590) at http.c:642
#10 0x806492f in comm_poll (msec=10) at comm_select.c:445
#11 0x8084404 in main (argc=2, argv=0xbfbffa8c) at main.c:742
#12 0x804a465 in _start ( )
你可見到,堆疊軌跡列印了每個函式的名字,它的引數,以及原始碼檔名和行數。當捕獲bug時,這些資訊特別有用。然而在某些情形下,這些還不夠。可能要求你在偵錯程式裡執行其他命令,例如列印來自某個函式的變數的值:
(gdb) frame 4
#4 0x80abe0a in storeDiskdSend (mtype=4, sd=0x82101e0, id=1214000,
sio=0x9e90a10, size=4096, offset=-1, shm_offset=0)
at diskd/store_io_diskd.c:485
485 x = msgsnd(diskdinfo->smsgid, &M,
msg_snd_rcv_sz, IPC_NOWAIT);
(gdb) set print pretty
(gdb) print M
$2 = {
mtype = 4,
id = 1214000,
seq_no = 7203103,
callback_data = 0x9e90a10,
size = 4096,
offset = -1,
status = -1,
shm_offset = 0
}
在報告了某個bug後,請保留core檔案一些天,可能還需要從它獲取其他資訊。
16.3.1 不能找到core檔案?
core檔案寫在程序的當前目錄。squid在啟動時預設不改變其當前目錄。這樣你的core檔案(如果有的話),會寫在啟動squid的目錄。假 如檔案系統沒有足夠的自由空間,或程序屬主沒有對該目錄的寫許可權,就無法產生core檔案。可以使用coredump_dir指令來讓squid使用指定 的coredump目錄--位於其他地方的有充足自由空間和完全許可權的目錄。
程序資源限制也會阻止產生core檔案。程序限制引數之一是coredump檔案的大小。大部分作業系統預設設定這個值為"無限"。在當前 shell裡使用limits或ulimit命令,可以檢查當前限制。然而請注意,你的shell的限制可能不同於squid的程序限制,特別是當 squid隨系統啟動而自動啟動時。假如懷疑程序限制阻止了core檔案的產生,試試這樣:
csh% limit coredumpsize unlimited
csh% squid -NCd1
在FreeBSD上,某個sysctl引數控制了作業系統對呼叫了setuid()或setgid()函式的程序,是否產生core檔案。假如以root啟動,squid會用到這些函式。這樣為了得到coredump,必須告訴核心建立core檔案,用這個命令:
# sysctl kern.sugid_coredump=1
請見sysctl.conf的manpage,關於在系統啟動時如何自動設定變數的資訊。
16.4 重現問題
有時候可能遇到這樣的問題:某個請求,或原始伺服器看起來不能與squid協調工作。可以使用下面的技術來確定問題在於squid,客戶端,或原始伺服器。技巧就是捕獲HTTP請求,然後用不同的方法響應它,直到你驗證了問題。
捕獲HTTP請求意味著獲取除了URL外的更多資訊,包括請求方式,HTTP版本號,和所有請求頭部。捕獲請求的一個方法是,短期啟用squid的完整debug模式。在squid主機上,敲入:
% squid -kdebug
然後,到web瀏覽器上釋出請求。squid幾乎會立刻接受到請求。在若干秒後,回到squid主機,併發布同樣的命令:
% squid -kdebug
現在cache.log檔案包含了上述客戶端的請求。假如squid繁忙,cache.log會包含大量的請求,所以你必須查詢它。它看起來如下:
2003/09/29 10:37:40| parseHttpRequest: Method is 'GET'
2003/09/29 10:37:40| parseHttpRequest: URI is 'http://squidbook.org/'
2003/09/29 10:37:40| parseHttpRequest: Client HTTP version 1.1.
2003/09/29 10:37:40| parseHttpRequest: req_hdr = {
User-Agent: Mozilla/5.0 (compatible; Konqueror/3)
Pragma: no-cache
Cache-control: no-cache
Accept: text/*, image/jpeg, image/png, image/*, */*
Accept-Encoding: x-gzip, gzip, identity
Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5
Accept-Language: en
Host: squidbook.org
注意squid把首行元素分開列印,必須手工組合它們如下:
GET http://squidbook.org/ HTTP/1.1
捕獲完整請求的另一個方法是使用工具例如netcat或socket (http://www.jnickelsen.de/socket/ )。啟動socket程式偵聽在某個埠,然後配置瀏覽器使用該埠作為代理地址。當再次發起請求時,socket打印出HTTP請求:
% socket -s 8080
GET http://squidbook.org/ HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; Konqueror/3)
Pragma: no-cache
Cache-control: no-cache
Accept: text/*, image/jpeg, image/png, image/*, */*
Accept-Encoding: x-gzip, gzip, identity
Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5
Accept-Language: en
Host: squidbook.org
最後,還可以使用網路包分析工具例如tcpdump或ethereal。使用tcpdump捕獲到一些包後,可以使用tcpshow來檢視它們:
# tcpdump -w tcpdump.log -c 10 -s 1500 port 80
# tcpshow -noHostNames -noPortNames < tcpdump.log | less
...
Packet 4.
TIME: 08:39:29.593051 (0.000627)
LINK: 00:90:27:16:AA:75 -> 00:00:24:C0:0D:25 type=IP
IP: 10.0.0.21 -> 206.168.0.6 hlen=20 TOS=00 dgramlen=304 id=4B29
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=15DC
TCP: port 2074 -> 80 seq=0481728885 ack=4107144217
hlen=32 (data=252) UAPRSF=011000 wnd=57920 cksum=EB38 urg=0
DATA: GET / HTTP/1.0.
Host: www.ircache.net.
Accept: text/html, text/plain, application/pdf, application/
postscript, text/sgml, */*;q=0.01.
Accept-Encoding: gzip, compress.
Accept-Language: en.
Negotiate: trans.
User-Agent: Lynx/2.8.1rel.2 libwww-FM/2.14.
注意tcpshow按資料裡的新行字元為週期來進行列印。
一旦捕獲到了某個請求,就將它存到檔案。然後可以使用netcat或socket來讓它重新通過squid:
% socket squidhost 3128 < request | less
假如響應看起來正常,問題可能在於使用者代理。否則,可以改變不同事情來孤立問題。例如,假如你看到一些古怪的HTTP頭部,那就從請求裡刪除它們, 然後再試一次。讓請求直接到達原始伺服器,而不是經過squid,這樣做也可除錯。方法就是從請求裡刪除http://host.name/,並將請求發 送到原始伺服器:
% cat request
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; Konqueror/3)
Pragma: no-cache
Cache-control: no-cache
Accept: text/*, image/jpeg, image/png, image/*, */*
Accept-Encoding: x-gzip, gzip, identity
Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5
Accept-Language: en
Host: squidbook.org
% socket squidbook.org 80 < request | less
以這種方式使用HTTP時,請參考RFC 2616和Oreilly的HTTP:The Definitive Guide這本書。
16.5 報告Bug
假如你的squid版本已經有幾個月未更新了,在報告bug前你應該更新它。因為其他人可能也注意了同樣的bug,並且它已被修復。
假如你發現了squid的合理bug,請將它填入到squid的bug跟蹤資料庫:http://www.squid-cache.org/bugs/ 。 它當前是個"bugzilla"資料庫,需要你建立一個帳號。當bug被squid開發者處理了時,你會接到更新通知。
當報告bug時,確認包含下列資訊:
- 1) Squid版本號。假如bug發生在不止一個版本上,就也要寫上其他版本號。
- 2) 作業系統名字和版本。
- 3) bug每次都發生,還是偶爾發生。
- 4) 所發生事情的精確描述。類似於"它不能工作","請求失敗"之類的語句,本質上對bug修復者無用。記得要非常詳細。
- 5) 對斷點,匯流排錯誤,或異常分片的堆疊跟蹤。
記住squid開發者通常是無報酬的義務勞動,所以要有耐心。嚴重bug比小問題享有更高的解決優先順序。
譯後序
當譯完本書最後一章時,心頭襲來深深的寂寞。
在計算機領域,國內外技術水平差之甚遠,部分原因歸咎於語言的差異。
某種技術在國外流行若干年後,才有相應的中文文件出現。
沒有文件,技術人員無法起步;而不規範的發行文件,更是誤導了一批又一批的初學者。
本書的作者Duane Wessels是位大師級的人物,除了精湛的技術外,他寫的本書文筆通暢,脈絡清晰,絲毫不晦澀。
若對研究Squid抱著嚴肅的態度,那麼請認真的拜讀原著。
而我所能做的,只是按照我自己的理解,把原著譯成中文。
好的軟體只是解決了某一方面的問題,而真正可貴的,是開源的精神。
在開源的世界裡,可以體會到現實中所沒有的無私與奉獻。
相關推薦
squid第16章 除錯和故障處理
16.1 一些通用問題 在討論通用debug前,我先提起一些經常發生的問題。 16.1.1 "Failed to make swap directory" Failed to make swap director
第7章中斷和中斷處理
7.6 中斷上下文 當執行一箇中斷處理程式時,核心處於中斷上下文中。程序上下文是一種核心所處的操作模式,此時核心代表程序執行——例如,執行系統呼叫或允許核心執行緒。在程序上下文中,可以通過current巨集關聯當前程序。此外,因為程序是以程序上下文的形式連線到核心中的,因此
【Linxu核心設計與實現】-第7章 中斷和中斷處理
第7章 中斷和中斷處理 作業系統的核心任務之一-對連線上的硬體進行管理(硬碟、鍵盤、滑鼠等)。要想管理這些硬體,就需要可以和他們進行通訊。硬體的反應要遠遠慢於CPU,輪詢會耗費大量CPU資源,顯然不
第六章,文本處理工具和正則表達式
文本處理工具 vim 正則表達式 更多筆記點擊查看Linux學習從入門到打死也不放棄,完全筆記整理(持續更新)http://blog.51cto.com/13683480/2095439筆記整理起始時間:2018年4月7日14:15:07 本章內容:各種文本工具來查看、分析、統計文本cat,tac
第 16 章 C 預處理器和 C 庫(條件編譯)
struct FN getc con ade 定義 輸入 lap pla 1 /*-------------------------------------- 2 names_st.h -- names_st 結構的頭文件 3 --------------
第 16 章 C 預處理器和 C 庫(可變參數:stdarg.h)
args rar 分享 預處理 close aps code 可變 use 1 /*------------------------------------------------- 2 varargs.c -- use variable number of
第六章樹和二叉樹--樹和森林-計算機17級 7-2 家譜處理 (30 分)
7-2 家譜處理 (30 分) 人類學研究對於家族很感興趣,於是研究人員蒐集了一些家族的家譜進行研究。實驗中,使用計算機處理家譜。為了實現這個目的,研究人員將家譜轉換為文字檔案。下面為家譜文字檔案的例項: John Robert Frank And
資料庫系統概論(第九章: 關係查詢處理和查詢優化)
第9章 關係查詢處理和查詢優化 查詢優化分類 : 代數優化:指關係代數表示式的優化 物理優化:指存取路徑和底層操作演算法的選擇9.1 關係資料庫系統的查詢處理 9.1.1 查詢處理步驟 ※關係資料庫管
第16章 string類和標準模板庫
本章內容包括: 標準C++ string類 模板auto_ptr,unique_ptr和shared_ptr 標準模板庫(STL) 容器類 迭代類 函式物件(functor) STL演算法 模板initializer_list 16.1 s
通用關鍵點和描述符——learning opencv3第16章翻譯 二
中間光流部分省略了,可以直接看中文版一 與跟蹤,物件檢測和一些相關主題的兩個基本概念是關鍵點和描述符。我們的第一個任務是瞭解這者,以及它們之間的差異。 在最高抽象層次上,關鍵點是影象的一小部分,應該或者至少是獨一無二的,我們認為可能將其能夠定位在另一個相關影象中。描述符
構建之法 第五章 團隊和流程
ini 之前 組織 第五章 團隊 mod 交互 然而 逆轉 典型的團隊開發模式和流程,完全是新的內容;涉及到更多的術語和有意思的策略性東西 1.團隊模式【我比較認可的】 主治醫師模式 由首席程序員(相當於首席醫生)負責整個工程,周圍人員各司其職,配合支持中心人物的工作;
第2章 GNS3和PacketTracer網絡模擬器(1)_GNS3概述
下載 功能 安裝位置 ges images 項目目錄 捕獲 png 編寫 1. 安裝和配置GNS3 1.1 GNS3概述 (1)GNS3是一款具有圖形化界面,可運行在多平臺(包括Windows、Linux、Mac OS等)上面的網絡虛擬軟件。 (2)可以在虛擬環境中運行Ci
第2章 GNS3和PacketTracer網絡模擬器(3)_搭建Packet tracer實驗環境
router images conf address 3.2 發送 style 廣域網 eric 3. Packet tracer實驗環境 3.1 設置網絡拓撲圖 (1)配置路由器局域網和廣域網接口,如上圖(可雙擊相應的圖標,然後在命令行或圖形界面上進行IP地址等配置)
第五章 團隊和流程隨筆
步驟 但是 位置 產品 地理位置 開始 如果 軟件 流程 軟件團隊的模式: 主治醫師模式、明星模式、社區模式、業余劇團模式、秘密團隊、特工團隊、交響樂團模式、爵士樂模式、功能團隊模式、官僚模式。 瀑布模型的特點: 強調階段的順序性和依賴性,即下一個階段的開始必須以上一個階段
深入理解計算機系統 第三章大略和第五章大略
$0 一個 編譯 存儲器 系統 32位 做了 ++i 擴展 這2章總結的很少,主要是覺得沒那麽重要。 1.2個操作數的指令,第二個操作數通常是目的操作數:movb a b,move a to b,而add a b,b+=a,指令分為指令類,如mov類:movb,movw,m
Python核心編程第八章--條件和循環
ext ads uid ldh eal ann jca cer 條件 html5%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%AA%8C%E8%AF%81%E4%B8%8A%E4%
第五章 團隊和流程
成員 指揮 規模 聊天 局限性 功能 其他 分析 混沌 團隊有一致的集體目標,團隊要一起完成這目標。一個團隊的成員不一定要同時工作,例如接力賽跑。 團隊成員有各自的分工,互相依賴合作,共同完成任務。 軟件團隊有各種形式,適用於不同的人員和需求。基於直覺形成的團隊模式未必是最
accp8.0轉換教材第10章Ajax和jQuery理解與練習
put else win send jquery實現 servlet ews window 8.0 C/S (Client/Server)結構,即大家熟知的客戶機和服務器結構。 B/S(Browser/Server)結構即瀏覽器和服務器結構。 認識ajax 、XMLHttp
構建之法(第五章 團隊和流程)
功能 實用 運用 驗證 的人 秘密 開發 個性化 社區 第五章主要講了典型的軟件團隊模式和開發流程。以及我們也將討論團隊模式和開發效率之間的一些關系。 1.非團隊和團隊 團隊的主要特點: 1) 團隊有一致的集體目標,團隊要一起完成這個目標。一個團