Skip to content

Commit

Permalink
example: add choastesting example
Browse files Browse the repository at this point in the history
  • Loading branch information
cboudereau committed Jun 10, 2024
1 parent c635a68 commit 0065888
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/chaostesting/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.cache
Binary file added examples/chaostesting/0-client-toxics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/chaostesting/0-server-toxics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/chaostesting/1-client-no-toxics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/chaostesting/1-server-no-toxics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions examples/chaostesting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Chaos testing with toxiproxy

This setup uses toxiproxy as a middleware between client and database to simulate latency, bandwidth and variation problems at TCP level.

The client service uses toxiproxy service as a sybase database which integrates toxic issues and forward tcp packets to the database service (sybase server).

Prometheus
[dashboard](http://localhost:9090/graph?g0.expr=rate(client%5B1m%5D)&g0.tab=0&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h&g1.expr=sybase_test_table_insert&g1.tab=0&g1.stacked=0&g1.show_exemplars=0&g1.range_input=1h) is used to analyze metrics from statsd:

The ``client`` is a counter from the client point of view while ``sybase_test_table_insert`` is a timer from the server point of view.

## Example without Toxics (direct)
![Client counter without toxics](./1-client-no-toxics.png)
![Server rates without toxics](./1-server-no-toxics.png)

## Example with Toxics
We can see that the that from the client point of view the rate is lower than before (1rps > 0.04rps).
![Client counter with toxics](./0-client-toxics.png)
![Server rates with toxics](./0-server-toxics.png)

## Tools

### Toxiproxy

[Project Page](https://github.com/Shopify/toxiproxy)

### Prometheus

[Dashboard](http://localhost:9090/graph?g0.expr=rate(client%5B1m%5D)&g0.tab=0&g0.stacked=0&g0.show_exemplars=0&g0.range_input=1h&g1.expr=sybase_test_table_insert&g1.tab=0&g1.stacked=0&g1.show_exemplars=0&g1.range_input=1h)
27 changes: 27 additions & 0 deletions examples/chaostesting/client/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use TESTDB
go

set statistics time ON

/* Tradeoff : measure delay with datetime (no support for ticks nor timestamp nor true stopwatch, precision is 1/300 second). Ok to measure high latencies ie : > 1s */
declare @s datetime
select @s = GETUTCDATE()

insert into dbo.TEST_TABLE(TEST_FIELD1) values ('1')
insert into dbo.TEST_TABLE(TEST_FIELD1) values ('1')
insert into dbo.TEST_TABLE(TEST_FIELD1) values ('1')
insert into dbo.TEST_TABLE(TEST_FIELD1) values ('1')
insert into dbo.TEST_TABLE(TEST_FIELD1) values ('1')

declare @e datetime
select @e = GETUTCDATE()

declare @t integer
select @t = DATEDIFF(MILLISECOND, @s, @e)

declare @msg varchar(255)
select @msg = "sybase.test_table.insert:" + convert(varchar, @t) + "|ms"
exec sp_sendmsg "statsd", 8125, @msg
select @msg as metric, count(*) as total from dbo.TEST_TABLE

go
12 changes: 12 additions & 0 deletions examples/chaostesting/client/schedule.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh
. /opt/sap/SYBASE.sh

set -u

while true
do
echo running $1
isql -Usa -S${SERVER}:5000 -P${SA_PASSWORD} -D${DATABASE} -i $1
echo -n "client:1|c" >/dev/udp/statsd/8125
sleep 1
done
74 changes: 74 additions & 0 deletions examples/chaostesting/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
version: '3.8'

services:
prometheus:
image: prom/prometheus:v2.41.0
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- 9090:9090
networks:
- bridge

statsd:
image: prom/statsd-exporter:v0.23.0
command: "--statsd.listen-udp=:8125 --web.listen-address=:9102 --log.level=debug"
networks:
- bridge
depends_on:
- prometheus

database:
image: superbeeeeeee/docker-sybase
pull_policy: always
environment:
- DATABASE=TESTDB
- SA_PASSWORD=Sybase1234
volumes:
- ./database/:/docker-entrypoint-initdb.d/
networks:
- bridge
healthcheck:
test: healthcheck
interval: 10s
retries: 10

client:
image: superbeeeeeee/docker-sybase
pull_policy: always
entrypoint: ["/schedule.sh", "/data.sql"]
environment:
- DATABASE=TESTDB
- SA_PASSWORD=Sybase1234
- SERVER=database
volumes:
- ./client/schedule.sh:/schedule.sh:ro
- ./client/data.sql:/data.sql:ro
networks:
- bridge
depends_on:
database:
condition: service_healthy
statsd:
condition: service_started
toxiproxy:
condition: service_started

toxiproxy:
image: shopify/toxiproxy
networks:
- bridge
toxiproxy-config:
image: shopify/toxiproxy
entrypoint: >
sh -c "/go/bin/toxiproxy-cli -h toxiproxy:8474 create database --listen 0.0.0.0:5000 --upstream database:5000;
/go/bin/toxiproxy-cli -h toxiproxy:8474 toxic add -t latency -a latency=2000 database;
/go/bin/toxiproxy-cli -h toxiproxy:8474 toxic add -t bandwidth -a rate=1 database;
/go/bin/toxiproxy-cli -h toxiproxy:8474 toxic add -t slicer -a average_size=1000 -a size_variation=900 -a delay=10000 database;"
networks:
- bridge
depends_on:
- toxiproxy

networks:
bridge:
2 changes: 2 additions & 0 deletions examples/chaostesting/database/0-allow_sp_sendmsg.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sp_configure 'allow sendmsg', 1
go
18 changes: 18 additions & 0 deletions examples/chaostesting/database/1-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use TESTDB
go
CREATE TABLE dbo.TEST_TABLE (
IDROW numeric(18,0) IDENTITY NOT NULL,
TEST_FIELD1 char(4) NOT NULL,
)
LOCK DATAROWS
WITH exp_row_size = 0, reservepagegap = 0, identity_gap = 500, DML_LOGGING = FULL
ON [default]
GO
CREATE NONCLUSTERED INDEX I1_TEST_TABLE
ON dbo.TEST_TABLE(TEST_FIELD1)
ON [default]
GO
CREATE UNIQUE NONCLUSTERED INDEX UI_TEST_TABLE
ON dbo.TEST_TABLE(IDROW)
ON [default]
GO
Binary file added examples/chaostesting/docker-compose.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions examples/chaostesting/graphviz.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# https://github.com/pmsipilot/docker-compose-viz
# https://github.com/pmsipilot/docker-compose-viz#usage
docker run --rm -it --name dcv -v $(pwd):/input pmsipilot/docker-compose-viz render -m image compose.yml --no-volumes --no-networks --horizontal --force
23 changes: 23 additions & 0 deletions examples/chaostesting/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.

external_labels:
monitor: 'prometheus-monitor'

scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'

# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s

static_configs:
- targets: ['localhost:9090']

- job_name: 'statsd-exporter'

# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s

static_configs:
- targets: ['statsd:9102']

0 comments on commit 0065888

Please sign in to comment.