Project

General

Profile

[Solved] Listen Queue overflow, hangs lighttpd; sonewconn

Added by aaminoff over 6 years ago

We have an odd problem where the system runs out of listen queues, causing lighttpd 1.4.45 running on FreeBSD 11.1-RELEASE-p1 to stop serving requests. (It happens to be on port 59 for an internal purpose). The load on this system is very predictable: every 2 minutes a cron job on each of about 50 machines fetches 2 small files over HTTPS from this server using curl. Why then does this problem only happen occasionally, after several hours of running normally? Is some resource being consumed/leaked/not freed that we are not seeing? This may be a FreeBSD problem not a lighttpd problem.

Normally, requests are handled and the request queue is clear:

# netstat -L4an
Current listen queue sizes (qlen/incqlen/maxqlen)
Proto Listen                           Local Address
tcp4  0/0/2048                         *.59

but once in a while, for some reason the queue fills up. We see messages like:

sonewconn: pcb 0xfffff80018f401d0: Listen queue overflow: 3073 already in queue awaiting acceptance (1 occurrences)

And netstat -L4an shows

tcp4  3073/0/2048                      *.59

and netstat -Aan shows 3073 connections to port 59. Depending on exactly when we run netstat -Aan, the state of those 3073 may be CLOSE_WAIT or CLOSED.

The system we see this problem on is running FreeBSD 11.1-RELEASE-p1. lighttpd is installed from pkg version 1.4.45_1. This problem did not happen under FreeBSD 10.3-RELEASE-p3, with packages upgraded as of about 2016-05. It does happen if we stay on FreeBSD 10.3-RELEASE-p3, but run a pkg upgrade.

We bumped up sysctl settings and the queue length in lighttpd.conf to try to give the system room to process the backlog, but that does not appear to help.

sysctl.conf:

kern.maxfiles=1046393       # [ values copied from FreeBSD 10.3 ]
kern.maxfilesperproc=941751
kern.ipc.somaxconn=4096     # [ up from default 128 ]
kern.ipc.soacceptqueue=4096

lighttpd.conf:

server.listen-backlog = 2048
server.max-fds = 2048
server.event-handler = "poll" # [ changed from default freebsd-kqueue in a failed attempt to fix the problem ]

I can show the whole lighttpd.conf in a separate post.


Replies (6)

RE: Listen Queue overflow, hangs lighttpd; sonewconn - Added by aaminoff over 6 years ago

I redacted some info because I do not want to talk about the internal purpose this is for.

var.log_root    = "/ldisk/thehost/lighttpd-log" 
var.server_root = "/ldisk/thehost/thename" 
var.state_dir   = "/var/run" 
var.home_dir    = "/var/spool/lighttpd" 
server.port = 59
server.use-ipv6 = "disable" 
server.username  = "www" 
server.groupname = "www" 
server.core-files = "disable" 
server.document-root = "/ldisk/thehost/thename" 
server.tag = "lighttpd-nber-thehost" 
server.pid-file = state_dir + "/lighttpd.pid" 
server.errorlog             = log_root + "/error.log" 
include "/usr/local/etc/lighttpd/conf.d/access_log.conf" 
debug.log-request-handling        = "disable" 
debug.log-request-header-on-error = "enable" 
debug.log-timeouts                 = "enable" 
server.event-handler = "poll" 
server.network-backend = "sendfile" 
server.listen-backlog = 2048
server.max-fds = 2048
server.stat-cache-engine = "disable" 
server.max-connections = 1024
server.max-keep-alive-idle = 2
server.max-keep-alive-requests = 2
server.max-request-size = 64
server.max-read-idle = 20
server.max-write-idle = 60
index-file.names += (
  "index.xhtml", "index.html", "index.htm", "default.htm", "index.php" 
)
  server.range-requests = "disable" 
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi", ".scgi" )
include "/usr/local/etc/lighttpd/conf.d/mime.conf" 
server.modules += ( "mod_access", "mod_auth", "mod_status" )
include "/ldisk/thehost/etc/access.conf" 
status.status-url          = "/server-status" 
status.config-url          = "/server-config" 
status.statistics-url      = "/server-statistics" 
status.enable-sort         = "enable" 

auth.backend               = "htpasswd" 
auth.backend.htpasswd.userfile = "/ldisk/thehost/etc/htpasswd" 
auth.require = ( "" =>
                   (
                     "method"  => "basic",
                     "realm"   => "redacted",
                     "require" => "user=nber" 
                   )
                 )
server.follow-symlink = "disable" 
ssl.engine = "enable" 
ssl.pemfile = "/thepath/cert/nber-server-2017.pem" 
ssl.use-sslv2 = "disable" 
ssl.use-sslv3 = "disable" 
ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
ssl.honor-cipher-order = "enable" 

RE: Listen Queue overflow, hangs lighttpd; sonewconn - Added by gstrauss over 6 years ago

When the issue occurs, have you queried /server-status? Or do you query and save /server-status at any interval to check that lighttpd is processing requests and closing connections?

As you said, this may not be lighttpd, but here are some settings to reduce lighttpd resource usage that you may want to try (after you look in the documentation to see what each one does):

server.bsd-accept-filter = "disable" 
server.network-backend = "writev" 
ssl.read-ahead = "disable" 
server.max-keep-alive-requests = 0

In versions before lighttpd 1.4.46, the httpready filter was enabled by default in FreeBSD. In lighttpd 1.4.46, it will be disabled by default. You should first try server.bsd-accept-filter = "disable" to see if that fixes your issue. See also https://github.com/lighttpd/lighttpd1.4/pull/65

RE: Listen Queue overflow, hangs lighttpd; sonewconn - Added by gstrauss over 6 years ago

For the log, you said you already tried server.event-handler = "poll". For more details, see 12440e89 as this will be fixed in lighttpd 1.4.46

RE: Listen Queue overflow, hangs lighttpd; sonewconn - Added by aaminoff over 6 years ago

Thanks for those helpful suggestions. I have made the config changes you recommend and we will see what happens.

RE: Listen Queue overflow, hangs lighttpd; sonewconn - Added by aaminoff over 6 years ago

After making those recommended config changes we have not seen the problem for 4 days (vs several times per day before). So I am pretty confident this is solved. Thank you for your help.

RE: [Solved] Listen Queue overflow, hangs lighttpd; sonewconn - Added by gstrauss over 6 years ago

Thanks for the update. Do you know which (one or more) of the following made the difference?

server.event-handler = "poll" 
server.bsd-accept-filter = "disable" 
server.network-backend = "writev" 
ssl.read-ahead = "disable" 
server.max-keep-alive-requests = 0

Until lighttpd 1.4.46, you should use server.event-handler = "poll" instead of "kqueue", and you probably want server.bsd-accept-filter = "disable" unless you know what the enabled behavior is and really want it. Setting server.network-backend = "writev" is fine, but "freebsd-sendfile" is preferred on FreeBSD, but only if it works for you. ssl.read-ahead = "disable" is intended for low-memory systems, and you should prefer to use keepalive rather than disabling keepalive, so avoid server.max-keep-alive-requests = 0 unless that is what you really intend.

    (1-6/6)