Skip to content

How To Use

matthew hawthorne edited this page Jun 9, 2013 · 9 revisions

Running zuul-simple-webapp

zuul-simple-webapp is an example web application that shows a few simple use cases of zuul-core.

The best way to understand it is to load it into your environment, run it, modify it, then run it again to notice the changes.

On a Mac or unix-like environment, cd into the zuul-simple-webapp directory and run this command:

gradle jettyRun -Dzuul.script.root=`pwd`/src/main/filters

After compilation you will see a message like this:

> Building > :zuul-simple-webapp:jettyRun > Running at http://localhost:8080//

By default zuul-simple-webapp uses apache.org as the origin. You can verify this by accessing http://localhost:8080 in a browser.

Examining zuul-simple-webapp

You see that we passed the zuul.script.root property to zuul-simple-webapp in order to make it work.

zuul-simple-webapp/src/main/filters is a standard layout for Zuul Filters, containing preProcess, routing, and postProcess directories for each primary Filter type, respectively.

Here is the sequence of Filter execution:

  1. DebugFilter executes (since the DynamicBooleanProperty routingDebug defaults to true) and enables Zuul route and request debugging:
Object run() {
    RequestContext ctx = RequestContext.getCurrentContext()
    ctx.setDebugRouting(true)
    ctx.setDebugRequest(true)
    return null;
}
  1. PreDecorationFilter sets the origin host (via RequestContext.html.setRouteHost() and adds a Cache-Control header to pass along (via RequestContext.html.addZuulRequestHeader()
Object run() {
    RequestContext ctx = RequestContext.getCurrentContext()

    // sets origin
    ctx.setRouteHost(new URL("http://apache.org/"));

    // sets custom header to send to the origin
    ctx.addOriginRequestHeader("cache-control", "max-age=3600");
}
  1. DebugRequestFilter executes with type pre and filterOrder 10000.

shouldFilter() evaluates to true (since [Debug.debugRequest()](http://netflix.github.io/zuul/javadoc/zuul-core/com/netflix/zuul/context/Debug.html#debugRequest(\)) was set to true by [DebugFilter][]:

boolean shouldFilter() {
    return Debug.debugRequest()
}

run() adds request debug information via [Debug.addRequestDebug()](http://netflix.github.io/zuul/javadoc/zuul-core/com/netflix/zuul/context/Debug.html#addRequestDebug(java.lang.String\))

Object run() {
    HttpServletRequest req = RequestContext.currentContext.request as HttpServletRequest

    Debug.addRequestDebug("REQUEST:: " + req.getScheme() + " " + req.getRemoteAddr() + ":" + req.getRemotePort())
    Debug.addRequestDebug("REQUEST:: > " + req.getMethod() + " " + req.getRequestURI() + " " + req.getProtocol())
    
   // and so on
}

4. SimpleHostRoutingFilter executes with filterOrder 100.

shouldFilter evaluates to true since the routeHost was set by PreDecorationFilter and sendZuulResponse defaults to true:

boolean shouldFilter() {
    return RequestContext.currentContext.getRouteHost() != null && RequestContext.currentContext.sendZuulResponse()
}

5. SendResponseFilter executes with type post and filterOrder 1000.

shouldFilter evaluates to true since zuulResponseHeaders, responseDataStream and responseBody were set by SimpleHostRoutingFilter.

boolean shouldFilter() {
    return !RequestContext.currentContext.getZuulResponseHeaders().isEmpty() ||
            RequestContext.currentContext.getResponseDataStream() != null ||
            RequestContext.currentContext.responseBody != null
}

run copies the origin response into Zuul's response - gruesome details omitted for brevity:

Object run() {
    addResponseHeaders()
    writeResponse()
}

6. StatsFilter executes with type post and filterOrder 2000.

shouldFilter is hardcoded to true as we always want to log the stats if they exist.

run logs the routing and request stats to stout:

Object run() {
    dumpRoutingDebug()
    dumpRequestDebug()
}

Debug Logging

Verbose debug logging for Zuul is enabled by default.

Lines that begin with ZUUL_DEBUG show diagnostics about Zuul itself - typically details on running Filters and modifying the RequestContext:

ZUUL_DEBUG::Filter pre 5 PreDecorationFilter
ZUUL_DEBUG::Filter {PreDecorationFilter TYPE:pre ORDER:5} Execution time = 12ms
ZUUL_DEBUG::{PreDecorationFilter} added originResponseHeaders=[com.netflix.util.Pair@64edca63]
ZUUL_DEBUG::{PreDecorationFilter} added routeHost=http://apache.org/
ZUUL_DEBUG::Filter pre 10000 DebugRequest
ZUUL_DEBUG::Filter {DebugRequest TYPE:pre ORDER:10000} Execution time = 36ms
ZUUL_DEBUG::Invoking {route} type filters
ZUUL_DEBUG::Filter route 100 SimpleHostRoutingFilter
ZUUL_DEBUG::Filter {SimpleHostRoutingFilter TYPE:route ORDER:100} Execution time = 251ms
ZUUL_DEBUG::{SimpleHostRoutingFilter} added responseStatusCode=304
ZUUL_DEBUG::{SimpleHostRoutingFilter} added hostZuulResponse=HTTP/1.1 304 Not Modified [Date: Sun, 09 Jun 2013 02:09:19 GMT, Server: Apache/2.4.4 (Unix) mod_wsgi/3.4 Python/2.7.3 OpenSSL/1.0.0g, Connection: Keep-Alive, Keep-Alive: timeout=5, max=100, ETag: "90a0-4deae5495ba47", Expires: Sun, 09 Jun 2013 03:09:19 GMT, Cache-Control: max-age=3600]
ZUUL_DEBUG::{SimpleHostRoutingFilter} added zuulResponseHeaders=[com.netflix.util.Pair@28aa2b8a, com.netflix.util.Pair@efa5136, com.netflix.util.Pair@1615a33c, com.netflix.util.Pair@c8b48f6b, com.netflix.util.Pair@2bbdebb3]
ZUUL_DEBUG::{SimpleHostRoutingFilter} added zuulRequestHeaders={}
ZUUL_DEBUG::{SimpleHostRoutingFilter} added responseGZipped=false
ZUUL_DEBUG::Invoking {post} type filters
ZUUL_DEBUG::Filter post 1000 SendResponseFilter
ZUUL_DEBUG::Filter {SendResponseFilter TYPE:post ORDER:1000} Execution time = 22ms
ZUUL_DEBUG::Filter post 2000 Stats

Lines that begin with REQUEST_DEBUG show information about HTTP requests and responses: REQUEST is the incoming request to Zuul, ZUUL is the request that Zuul forwards to the origin, ORIGIN_RESPONSE is the response from the origin, and OUTBOUND is the outgoing response from Zuul back to the client.

Below you will see debug logging for the initial GET request to the "/" resource:

REQUEST_DEBUG::REQUEST:: http 0:0:0:0:0:0:0:1:51254
REQUEST_DEBUG::REQUEST:: > GET / HTTP/1.1
REQUEST_DEBUG::REQUEST:: > Host:localhost:8080
REQUEST_DEBUG::REQUEST:: > Connection:keep-alive
REQUEST_DEBUG::REQUEST:: > Cache-Control:max-age=0
REQUEST_DEBUG::REQUEST:: > Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
REQUEST_DEBUG::REQUEST:: > User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31
REQUEST_DEBUG::REQUEST:: > DNT:1
REQUEST_DEBUG::REQUEST:: > Accept-Encoding:gzip,deflate,sdch
REQUEST_DEBUG::REQUEST:: > Accept-Language:en-US,en;q=0.8
REQUEST_DEBUG::REQUEST:: > Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
REQUEST_DEBUG::REQUEST:: > If-None-Match:"90a0-4deae5495ba47"
REQUEST_DEBUG::REQUEST:: > If-Modified-Since:Sun, 09 Jun 2013 01:10:31 GMT
REQUEST_DEBUG::REQUEST:: > 
REQUEST_DEBUG::ZUUL:: host=http://apache.org/
REQUEST_DEBUG::ZUUL::> Host  localhost:8080
REQUEST_DEBUG::ZUUL::> Connection  keep-alive
REQUEST_DEBUG::ZUUL::> Cache-Control  max-age=0
REQUEST_DEBUG::ZUUL::> Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
REQUEST_DEBUG::ZUUL::> User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31
REQUEST_DEBUG::ZUUL::> DNT  1
REQUEST_DEBUG::ZUUL::> Accept-Language  en-US,en;q=0.8
REQUEST_DEBUG::ZUUL::> Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.3
REQUEST_DEBUG::ZUUL::> If-None-Match  "90a0-4deae5495ba47"
REQUEST_DEBUG::ZUUL::> If-Modified-Since  Sun, 09 Jun 2013 01:10:31 GMT
REQUEST_DEBUG::ZUUL:: > GET  /?null HTTP/1.1
REQUEST_DEBUG::ZUUL::>
REQUEST_DEBUG::ORIGIN_RESPONSE:: > Date, Sun, 09 Jun 2013 02:09:19 GMT
REQUEST_DEBUG::ORIGIN_RESPONSE:: > Keep-Alive, timeout=5, max=100
REQUEST_DEBUG::ORIGIN_RESPONSE:: > ETag, "90a0-4deae5495ba47"
REQUEST_DEBUG::ORIGIN_RESPONSE:: > Expires, Sun, 09 Jun 2013 03:09:19 GMT
REQUEST_DEBUG::ORIGIN_RESPONSE:: > Cache-Control, max-age=3600
REQUEST_DEBUG::OUTBOUND: >  Date:Sun, 09 Jun 2013 02:09:19 GMT
REQUEST_DEBUG::OUTBOUND: >  Keep-Alive:timeout=5, max=100
REQUEST_DEBUG::OUTBOUND: >  ETag:"90a0-4deae5495ba47"
REQUEST_DEBUG::OUTBOUND: >  Expires:Sun, 09 Jun 2013 03:09:19 GMT
REQUEST_DEBUG::OUTBOUND: >  Cache-Control:max-age=3600

Running zuul-netflix-webapp

Clone this wiki locally