TL;DR
The F5 BigPipe LTM uses HTTP/0.9 to send its HTTP monitoring requests by default. Wildfly 9.0 does not like this; moving to a monitor request of HTTP/1.1 fixed the problem.
Caution: LTM 10.2.x and 11.x do not append a CR/LF to the end unless you are using Basic Authentication. This is contrary to previous behavior. SOL2167: Constructing HTTP requests for use with the HTTP or HTTPS application health monitor (requires registration)
This information is current as of September, 2015. For potential updates please see: SOL3224: HTTP health checks may fail even though the node is responding correctly (registration required).
Background
Upon upgrading to Wildfly 9 from an existing JBoss installation, the existing http
monitor on the F5 LTM ceased to work; it marked the hosts in the pool down
despite their being active when tested outside of the LTM.
Solution
- The root cause is that Wildfly does not like the
HTTP/0.9
request. -
Per the HTTP/1.1 specification, a request consists of a:
1 2 3 4 |
VERB URL SPEC\r\n HEADERS\r\n \r\n |
Note the trailing
\r\n
; this is important. Without it the server will wait on the client to complete the request until the request times out.
- The set of headers which the solution sends are almost assuredly overkill. However, it’s working, and they should not hurt anything except as noted below:
Header | Notes |
---|---|
Host: | Specifies an empty host; this might be better expressed as the name or address of the LTM. This was included as a ‘Cargo Cult’ parameter; the examples from F5 include the header. In my opinion it should be populated *or* left out. |
Accept: text/html | This specifies to the server that we can accept text/html and assumes that the backend is able to send that. If the backend does not send text/html then either the proper MIME type needs to be specified *or* *.* sent which allows any sort of data. The LTM does the equivalent of a grep looking for the string specified in the recv . |
Connection: close | This specifies that the server needs to close the connection rather than keeping it alive for re-use.
HTTP/1.1 specifies that connections are persistent by [default](http://tools.ietf.org/html/rfc7230#section-6.3). If you do not *explicitly* close the connection it will remain open, tying up connections on the backend. The amount of time it remains open is variable — the spec does not dictate how long it is to remain open. It may be closed at either end *or* [either end can add this header to either the request or response](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10). Once received, the connection should not be considered persistent. |
- The text of the monitor:
1 2 3 4 5 6 7 8 |
bp>monitor pubsjs_mon list monitor pubsjs_mon { defaults from http partition PARTITION recv "RECEIVED_DATA" send "GET /PATH_TO_CHECK HTTP/1.1\r\nHost: \r\nAccept: text/html\r\nConnection: close\r\n\r\n" } |
Note the
send
; prior to LTM 10.2.x a trailing\r\n
would be appended. This is no longer the case. Within the send the entire request is specified, including headers. An “empty” line is appended at the end.
recv
specifies the string for which to grep
the response. If the string is not within the response or if the request times out then the check failed.