Squid調試和故障處理


http://blog.zhdata.com/tag/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很陌生,請先花時間閱讀Simon                Tatham寫的”How to Report Bugs Effectively” (http://www.chiark.greenend.org.uk/~sgtatham/bugs.html )。

當報告bug時,確認包含下列信息:

  • 1) Squid版本號。假如bug發生在不止一個版本上,就也要寫上其他版本號。
  • 2) 操作系統名字和版本。
  • 3) bug每次都發生,還是偶爾發生。
  • 4) 所發生事情的精確描述。類似於”它不能工作”,”請求失敗”之類的語句,本質上對bug修復者無用。記得要非常詳細。
  • 5) 對斷點,總線錯誤,或異常分片的堆棧跟蹤。

記住squid開發者通常是無報酬的義務勞動,所以要有耐心。嚴重bug比小問題享有更高的解決優先級。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM