- Restarting in the background
- Viewing logs
- Scaling up the application
- Looking at resource usage
- Scaling workers on a single node
- Adding more workers
- Accessing internal services
- Measuring latency under load
- Let's draw hasty conclusions
Restarting in the background
- Many flags and commands of Compose are modeled after those of
Start the app in the background with the
docker-compose up -d
Check that our app is running with the
docker-compose ps also shows the ports exposed by the application.
docker-compose logscommand works like
View all logs since container creation and exit when done:
Stream container logs, starting at the last 10 lines for each container:
docker-compose logs --tail 10 --follow
^Q to pause/resume log output.
Scaling up the application
Our goal is to make that performance graph go up (without changing a line of code!)
Before trying to scale the application, we'll figure out if we need more resources (CPU, RAM...)
For that, we will use good old UNIX tools on our Docker node
Looking at resource usage
- Let's look at CPU, memory, and I/O usage
topto see CPU and memory usage (you should see idle cycles)
vmstat 1to see I/O usage (si/so/bi/bo)
(the 4 numbers should be almost zero, except
We have available resources.
- How can we use them?
Scaling workers on a single node
- Docker Compose supports scaling
- Let's scale
workerand see what happens!
Start one more
docker-compose up -d --scale worker=2
Look at the performance graph (it should show a x2 improvement)
Look at the aggregated logs of our containers (
worker_2should show up)
Look at the impact on CPU load with e.g. top (it should be negligible)
Adding more workers
- Great, let's add more workers and call it a day, then!
Start eight more
docker-compose up -d --scale worker=10
Look at the performance graph: does it show a x10 improvement?
Look at the aggregated logs of our containers
Look at the impact on CPU load and memory usage
You should have seen a 3x speed bump (not 10x)
Adding workers didn't result in linear improvement
Something else is slowing us down
... But what?
The code doesn't have instrumentation
Let's use state-of-the-art HTTP performance analysis!
(i.e. good old tools like
Accessing internal services
hasherare exposed on ports 8001 and 8002
This is declared in the Compose file:
... rng: build: rng ports: - "8001:80" hasher: build: hasher ports: - "8002:80" ...
Measuring latency under load
We will use
Check the latency of
httping -c 3 localhost:8001
Check the latency of
httping -c 3 localhost:8002
rng has a much higher latency than
Let's draw hasty conclusions
The bottleneck seems to be
What if we don't have enough entropy and can't generate enough random numbers?
We need to scale out the
rngservice on multiple machines!
Note: this is a fiction! We have enough entropy. But we need a pretext to scale out.
(In fact, the code of
/dev/urandom, which never runs out of entropy...
...and is just as good as