-
Notifications
You must be signed in to change notification settings - Fork 110
Add save and load route table feature to nats-client #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
domdom82
merged 2 commits into
cloudfoundry:develop
from
domdom82:nats_client_save_load_routes
Oct 31, 2022
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# NATS Client | ||
|
||
## What is it? | ||
|
||
Gorouter is loosely coupled with user apps via the NATS message bus. They share common subjects like `router.register` and `router.unregister` where apps publish their routes | ||
while gorouter subscribes to them. | ||
|
||
If developers want to debug a certain scenario, usually they have to set up applications and NATS in such a way that it reproduces | ||
the scenario inside gorouter. This can be cumbersome and tedious, as one has to fully deploy Cloud Foundry, push the apps, scale them up | ||
and then maybe tweak NATS or the IaaS provider to reproduce a network error or other issues. | ||
|
||
To mitigate this problem, `nats_client` was created. It has the following features: | ||
|
||
- Subscribe to NATS subjects and stream them to the shell to see what's received by gorouter | ||
- Publish messages to NATS subjects to inject events such as `router.register` and `router.unregister` | ||
- Save the current route table of a gorouter to a json file. The file may then be inspected and / or changed | ||
- Load a previously saved route table into gorouter via NATS | ||
|
||
## Where is it? | ||
|
||
After you have deployed `routing` you will find two files on a `gorouter` VM: | ||
- `/var/vcap/packages/routing_utils/bin/nats_client` (the actual NATS client binary) | ||
- `/var/vcap/jobs/gorouter/bin/nats_client` (a wrapper script calling the binary with the gorouter's config file) | ||
|
||
## How to use it | ||
Show the usage help by running: | ||
```shell | ||
/var/vcap/jobs/gorouter/bin/nats_client --help | ||
|
||
Usage: | ||
/var/vcap/jobs/gorouter/bin/nats_client [COMMAND] | ||
|
||
COMMANDS: | ||
sub [SUBJECT] [MESSAGE] | ||
(Default) Streams NATS messages from server with provided SUBJECT. Default SUBJECT is 'router.*' | ||
Example: /var/vcap/jobs/gorouter/bin/nats_client sub 'router.*' | ||
|
||
pub [SUBJECT] [MESSAGE] | ||
Publish the provided message JSON to SUBJECT subscription. SUBJECT and MESSAGE are required | ||
Example: /var/vcap/jobs/gorouter/bin/nats_client pub router.register '{"host":"172.217.6.68","port":80,"uris":["bar.example.com"]}' | ||
|
||
save <FILE> | ||
Save this gorouter's route table to a json file. | ||
Example: /var/vcap/jobs/gorouter/bin/nats_client save routes.json' | ||
|
||
load <FILE> | ||
Load routes from a json file into this gorouter. | ||
Example: /var/vcap/jobs/gorouter/bin/nats_client load routes.json' | ||
``` | ||
|
||
### Streaming NATS Messages | ||
By default, `nats_client` will subscribe to `router.*` subjects: | ||
```shell | ||
/var/vcap/jobs/gorouter/bin/nats_client | ||
|
||
Subscribing to router.* | ||
new message with subject: router.register | ||
{"uris":["some-app.cf.mydomain.com"],"host":"10.1.3.7","port":3000,"tags":null,"private_instance_id":"abea5c4c-4c91-4827-7156-2e9496512903"} | ||
new message with subject: router.register | ||
{"uris":["another-app.cf.mydomain.com","*.another-app.cf.my-domain.com"],"host":"10.1.1.73","port":8083,"tls_port":8083,"tags":null,"private_instance_id":"efcc4e10-f705-423c-6ec4-b25e9d4fa327","server_cert_domain_san":"another-app.cf.my-domain.com"} | ||
(...) | ||
``` | ||
|
||
### Publishing NATS Messages | ||
You may use the `nats_client` to publish messages such as `router.register` to simulate a CF app starting up: | ||
```shell | ||
/var/vcap/jobs/gorouter/bin/nats_client pub router.register '{"host":"httpstat.us","tls_port":443,"server_cert_domain_san":"httpstat.us", "uris":["httpstat.us"]}' | ||
|
||
Publishing message to router.register | ||
Done | ||
``` | ||
|
||
You can then test the new route and see if the backend can be reached using: | ||
```shell | ||
curl http://localhost:8081/200 -H "Host: httpstat.us" | ||
200 OK% | ||
``` | ||
(the above example assumes you have gorouter running locally without TLS) | ||
|
||
|
||
### Saving the Route Table to Disk | ||
The `save` command will allow you to store the current route able as a json file. | ||
```shell | ||
/var/vcap/jobs/gorouter/bin/nats_client save routes.json | ||
|
||
Saving route table to routes.json | ||
Done | ||
``` | ||
You can then view and edit the route table to your needs. | ||
|
||
### Loading a Route Table from Disk | ||
Once you have prepared a route table json file you can load it using the `load` command | ||
```shell | ||
/var/vcap/jobs/gorouter/bin/nats_client load routes.json | ||
|
||
Loading route table from routes.json | ||
Done | ||
``` | ||
The routes will not be loaded directly but the contents of `routes.json` will be transformed into `router.register` messages and published to gorouter via NATS in order. | ||
|
||
**NOTICE:** | ||
*Be aware that non-TLS routes that don't get refreshed continuously will be pruned again.* | ||
|
||
## When to use it | ||
There are many scenarios where you may use `nats_client` to debug gorouter issues: | ||
- Debug retries of failing endpoints | ||
- Test different kinds of backend errors (e.g. dial timeout, TLS handshake issues, app misbehaving etc.) | ||
- Debug load balancing algorithms | ||
- Set up large deployments with hundreds of apps and thousands of routes, without having to actually deploy all of them | ||
- Simulate outages where large numbers of backends no longer respond (e.g. AZ outages) | ||
- Simulate NATS outages where apps have moved elsewhere but gorouter didn't get the proper `router.unregister` message | ||
- etc. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
gorouter.yml | ||
routes.json | ||
nats_client |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.