(Go)Router

Page last updated: June 30, 2015

The router routes traffic coming into Cloud Foundry to the appropriate component: usually, Cloud Controller or a running application on a DEA node. The router is implemented in Go. Implementing a custom router in Go gives the router full control over every connection, which makes it easier to support WebSockets and other types of traffic (for example, via HTTP CONNECT). A single process contains all routing logic, removing unnecessary latency.

Refer to the following instructions for help getting started with the gorouter in a standalone environment.

Setup

$ git clone https://github.com/cloudfoundry/gorouter.git
$ cd gorouter
$ git submodule update --init
$ ./bin/go install router/router
$ gem install nats

Start

# Start NATS server in daemon mode
$ nats-server -d

# Start gorouter
$ ./bin/router

Usage

Gorouter receives route updates via NATS. By default, routes that have not been updated in two minutes are pruned. Therefore, to maintain an active route, ensure that the route is updated at least every two minutes. The format of these route updates is as follows:

{
  "host": "127.0.0.1",
  "port": 4567,
  "uris": [
    "my_first_url.vcap.me",
    "my_second_url.vcap.me"
  ],
  "tags": {
    "another_key": "another_value",
    "some_key": "some_value"
  }
}

Such a message can be sent to both the router.register subject to register URIs, and to the router.unregister subject to unregister URIs, respectively.

$ nohup ruby -rsinatra -e 'get("/") { "Hello!" }' &
$ nats-pub 'router.register' '{"host":"127.0.0.1","port":4567,
    "uris":["my_first_url.vcap.me","my_second_url.vcap.me"],
    "tags":{"another_key":"another_value","some_key":"some_value"}}'
Published [router.register] : '{"host":"127.0.0.1","port":4567,
    "uris":["my_first_url.vcap.me","my_second_url.vcap.me"],
    "tags":{"another_key":"another_value","some_key":"some_value"}}'
$ curl my_first_url.vcap.me:8080
Hello!

Instrumentation

Gorouter provides /varz and /healthz http endpoints for monitoring.

The /routes endpoint returns the entire routing table as JSON. Each route has an associated array of host:port entries.

All of the endpoints require http basic authentication, credentials for which you can acquire through NATS. You can explicitly set the port, user and password (pass is the config attribute) in the gorouter.yml config file status section.

status:
  port: 8080
  user: some_user
  pass: some_password

Example interaction with curl:

$ curl -vvv "http://someuser:[email protected]:8080/routes"
* About to connect() to 127.0.0.1 port 8080 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'someuser'
> GET /routes HTTP/1.1
> Authorization: Basic c29tZXVzZXI6c29tZXBhc3M=
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: 127.0.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Mon, 25 Mar 2013 20:31:27 GMT
< Transfer-Encoding: chunked
<
{"0295dd314aaf582f201e655cbd74ade5.cloudfoundry.me":["127.0.0.1:34567"],
"03e316d6aa375d1dc1153700da5f1798.cloudfoundry.me":["127.0.0.1:34568"]}