Use Cases
Service Discovery
Convox makes it easy to build microservice architectures by enabling easy communication between services and applications whether they are closely related, unrelated, on the same rack, on different racks, and even access the raw nodes behind the load balancer if required.
Building a loosely coupled architecture relies on your different services being able to interrogate and discover, independently, where other services that they may need are deployed, without having to have specific IP addresses and ports defined. In a cloud-centric world, these are transient and cannot be relied upon.
Previously, you may have had to set up a Zookeeper or Consul instance and configured all or your internal services to report and interrogate with them. Convox provides Service Discovery oppportunities out of the box without relying on yet another service to maintain!
If you would like to make a service accessible only to other services on the same Rack, see Internal Services.
To Discover Services in the Same App
You can link services in the same app using the links section of convox.yml.
Example
services:
web:
port: 3000
worker:
links:
- web
This would set an WEB_URL
environment variable on the worker
service pointing at the load balancer for the web
service. No matter where or how many web
service instances are deployed, the worker
instances will be able to access them via the load balancer.
To Discover Services/Apps on the Same Rack
Convox sets up internal DNS on a Rack such that the following hostname format will resolve to a specific service:
[service].[app].[rack].convox
The Rack’s name is available as the environment variable RACK
.
Example
$ curl https://api.auth.$RACK.convox
This hostname would resolve to the load balancer of the api
service of the auth
app on the current Rack. Using naming conventions like this allow for effective auto-discovery with no overhead.
To Discover Services/Apps on Different Racks
Use convox services
to find the load balancer hostname of a given service and set an environment variable with the resulting hostname.
Example
$ convox services -a auth -r acme/utility
SERVICE DOMAIN PORTS
api auth-api.router.us-east-1.convox.site 80:3000 443:3000
You can then extract the load balancer URL to inject into any other service you require…
$ AUTH_URL="$(convox services -a docs -r acme/test | sed -n 2p | awk '{print $2}')"
$ convox env set AUTH_URL=$AUTH_URL -a frontend -r acme/production
This would set an AUTH_URL
environment variable on the frontend
app on the acme/production
Rack to point at the load balancer for the api
service on the auth
app on the acme/utility
Rack.
To Discover every Instance of a Service
You can interrogate the Convox API to retrieve the raw endpoints of the current container instances of a service or app. The API will return JSON to describe the running processes for an app.
Example
$ convox api get /apps/nodejs/processes
[
{
"app": "nodejs",
"command": "",
"cpu": 0,
"host": "10.0.2.10",
"id": "3485248b1d18",
"image": "xxx.dkr.ecr.us-east-1.amazonaws.com/xxx:web.BIYKGJLHGIV",
"instance": "i-092941b05e75008ff",
"memory": 0,
"name": "web",
"ports": [
"47889:3000"
],
"release": "RLEUTDHBBKD",
"started": "2019-09-25T09:32:51Z",
"status": "running"
},
{
"app": "nodejs",
"command": "",
"cpu": 0,
"host": "10.0.3.87",
"id": "8db3b9378db0",
"image": "xxx.dkr.ecr.us-east-1.amazonaws.com/xxx:web.BIYKGJLHGIV",
"instance": "i-02cf094037d64f5e5",
"memory": 0,
"name": "web",
"ports": [
"32768:3000"
],
"release": "RLEUTDHBBKD",
"started": "2019-09-03T11:10:31Z",
"status": "running"
}
]
We can use awesome tools like jq
to parse the json and pull out the information we need, for instance to find all the web
services running in the nodejs
app we can do something like this:
$ convox api get /apps/nodejs/processes | jq '.[] | if .name == "web" then {node: .host, port: .ports[] | split(":")[0]} else "" end | join(":")'
"10.0.3.87:32768"
"10.0.2.10:47889"