Varnish故障排除¶
有时,Varnish会行为不端,或者更确切地说,会按照您告诉它的方式运行,但不一定是您希望它运行的方式。为了让您了解正在发生的事情,您可以查看以下几个地方。 Varnishlog , /var/log/syslog
, /var/log/messages
都是瓦尼什可能会留下线索的好地方。本节将指导您完成Varnish的基本故障排除。
当Varnish不能启动时¶
有时瓦尼什启动不起来。有太多可能的原因导致Varnish无法在您的计算机上启动。我们已经看到了从错误的权限到 /dev/null
到阻塞端口的其他进程。
在调试模式下启动Varnish以查看正在进行的操作。
尝试使用与其他方法相同的参数启动Varnish,但是 -d
添加了。这将为您提供一些关于正在发生的事情的更多信息。让我们看看当其他东西在它的端口上侦听时,Varnish会有什么反应。::
# varnishd -n foo -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:8080 -d
storage_malloc: max size 1024 MB.
Using old SHMFILE
Platform: Linux,2.6.32-21-generic,i686,-smalloc,-hcritbit
200 193
-----------------------------
Varnish Cache CLI.
-----------------------------
Type 'help' for command list.
Type 'quit' to close CLI session.
Type 'start' to launch worker process.
现在,Varnish正在运行,但只有主进程在运行,在调试模式下,缓存不会启动。现在您在控制台上。您可以通过发出“Start”命令来指示主进程启动缓存。用法:
start
bind(): Address already in use
300 22
Could not open sockets
现在我们的问题来了。还有一些东西被绑定到Varnish的HTTP端口。如果这还不管用,试着 strace
或 truss
或者来IRC上找我们。
Varnish正在崩溃-恐慌¶
当Varnish破产时,子进程崩溃。大多数崩溃都是通过我们在Varnish源代码中包含的许多一致性检查中的一个来捕获的。当Varnish命中其中之一时,缓存进程将以受控的方式使自身崩溃,从而在母进程中留下良好的堆栈跟踪。
您可以通过键入以下命令来检查任何紧急消息 panic.show
在CLI中。::
panic.show
Last panic at: Tue, 15 Mar 2011 13:09:05 GMT
Assert error in ESI_Deliver(), cache_esi_deliver.c line 354:
Condition(i == Z_OK || i == Z_STREAM_END) not true.
thread = (cache-worker)
ident = Linux,2.6.32-28-generic,x86_64,-sfile,-smalloc,-hcritbit,epoll
Backtrace:
0x42cbe8: pan_ic+b8
0x41f778: ESI_Deliver+438
0x42f838: RES_WriteObj+248
0x416a70: cnt_deliver+230
0x4178fd: CNT_Session+31d
(..)
崩溃可能是由于配置错误或错误造成的。如果您怀疑这是一个错误,您可以在错误报告中使用输出,请参阅上面介绍章节中的“故障票证”部分。
Varnish崩溃-堆栈溢出¶
抛开错误不谈,最有可能导致崩溃的原因是堆栈溢出,这就是为什么我们添加了一个启发式方法,当崩溃看起来像是由一个错误引起时,我们会添加一个注释。在本例中,紧急消息包含如下内容::
Signal 11 (Segmentation fault) received at 0x7f631f1b2f98 si_code 1
THIS PROBABLY IS A STACK OVERFLOW - check thread_pool_stack parameter
作为第一个措施,请遵循以下建议,并检查当您将128K添加到任何值时是否仍会发生崩溃 thread_pool_stack
参数并重新启动Varnish。
如果Varnish不再与更大的 thread_pool_stack
参数,那么它不是错误(至少最有可能是这样)。
Varnish正在崩溃-分段故障¶
有时,BUG逃脱了一致性检查,Varnish受到分段错误的打击。当子进程发生这种情况时,它将被记录,核心被转储,子进程再次启动。
内核转储通常是由于Varnish中的错误造成的。然而,为了调试段错误,开发人员需要您提供大量数据。
确保您安装了带有调试符号的Varnish。
检查您的操作系统写入核心文件的位置,并确保您确实获得了这些文件。例如,在Linux上,了解
/proc/sys/kernel/core_pattern
从 core(5) 曼佩奇。确保在启动varnishd的父Shell中允许核心转储。简而言之,这将是:
ulimit -c unlimited但如果Varnish是从初始脚本开始的,则需要进行调整,或者在使用system d的情况下,
LimitCORE=infinity
在服务的[Service]]
单元文件的一节。
一旦你有了核心, cd
放到Varnish的工作目录中(由 -n
参数,其缺省值为 $PREFIX/var/varnish/$HOSTNAME
使用 $PREFIX
作为安装前缀,通常 /usr/local
,用来打开芯子 gdb
并发出命令 bt
以获取导致段错误的线程的堆栈跟踪。
下安装的Varnish的基本调试会话 /usr/local
可能如下所示::
$ cd /usr/local/var/varnish/`uname -n`/
$ gdb /usr/local/sbin/varnishd core
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
[...]
Core was generated by `/usr/local/sbin/varnishd -a 127.0.0.1:8080 -b 127.0.0.1:8080'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7f7749ea3700 (LWP 31258))]
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f775132342a in __GI_abort () at abort.c:89
#2 0x000000000045939f in pan_ic (func=0x7f77439fb811 "VCL", file=0x7f77439fb74c "", line=0,
cond=0x7f7740098130 "PANIC: deliberately!", kind=VAS_VCL) at cache/cache_panic.c:839
#3 0x0000000000518cb1 in VAS_Fail (func=0x7f77439fb811 "VCL", file=0x7f77439fb74c "", line=0,
cond=0x7f7740098130 "PANIC: deliberately!", kind=VAS_VCL) at vas.c:51
#4 0x00007f77439fa6e9 in vmod_panic (ctx=0x7f7749ea2068, str=0x7f7749ea2018) at vmod_vtc.c:109
#5 0x00007f77449fa5b8 in VGC_function_vcl_recv (ctx=0x7f7749ea2068) at vgc.c:1957
#6 0x0000000000491261 in vcl_call_method (wrk=0x7f7749ea2dd0, req=0x7f7740096020, bo=0x0,
specific=0x0, method=2, func=0x7f77449fa550 <VGC_function_vcl_recv>) at cache/cache_vrt_vcl.c:462
#7 0x0000000000493025 in VCL_recv_method (vcl=0x7f775083f340, wrk=0x7f7749ea2dd0, req=0x7f7740096020,
bo=0x0, specific=0x0) at ../../include/tbl/vcl_returns.h:192
#8 0x0000000000462979 in cnt_recv (wrk=0x7f7749ea2dd0, req=0x7f7740096020) at cache/cache_req_fsm.c:880
#9 0x0000000000461553 in CNT_Request (req=0x7f7740096020) at ../../include/tbl/steps.h:36
#10 0x00000000004a7fc6 in HTTP1_Session (wrk=0x7f7749ea2dd0, req=0x7f7740096020)
at http1/cache_http1_fsm.c:417
#11 0x00000000004a72c3 in http1_req (wrk=0x7f7749ea2dd0, arg=0x7f7740096020)
at http1/cache_http1_fsm.c:86
#12 0x0000000000496bb6 in Pool_Work_Thread (pp=0x7f774980e140, wrk=0x7f7749ea2dd0)
at cache/cache_wrk.c:406
#13 0x00000000004963e3 in WRK_Thread (qp=0x7f774980e140, stacksize=57344, thread_workspace=2048)
at cache/cache_wrk.c:144
#14 0x000000000049610b in pool_thread (priv=0x7f774880ec80) at cache/cache_wrk.c:439
#15 0x00007f77516954a4 in start_thread (arg=0x7f7749ea3700) at pthread_create.c:456
#16 0x00007f77513d7d0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
Varnish给我上师冥想¶
首先在中找到相关的日志条目 Varnishlog 。这可能会给你一个线索。自.以来 Varnishlog 记录了大量数据,可能很难追踪到条目。您可以设置 Varnishlog 要记录所有503错误,请发出以下命令:
$ varnishlog -q 'RespStatus == 503' -g request
如果错误发生在不久前,事务可能仍在共享内存日志段中。为了得到 Varnishlog 要处理整个共享内存日志,只需添加‘-d’参数::
$ varnishlog -d -q 'RespStatus == 503' -g request
请参阅 VSL-查询 和 Varnishlog 有关进一步过滤功能的详细说明和各种选项的说明的手册页。
Varnish不缓存¶
看见 实现高打击率 。