3scale/apisonator

View on GitHub
docs/benchmark.md

Summary

Maintainability
Test Coverage
# Benchmarking the performance

Apisonator is designed to process a lot of requests quickly and sometimes minor changes or changes in the underlying libraries results in significant performance degradation.

Due to differences in the underlying hardware, a fixed numbers can't be given. Always compare performance with and without your changes.

Another thing to keep in mind is that a local redis has a significantly lower latency than a remote one. So a real world setup benchmark will be much more valuable. For example locally the `sync` mode will be very much comparable to `async`. But in reality `sync` is much slower at present.

## Check worker performance locally

Run the following rake task with `CONFIG_REDIS_ASYNC=false` or `CONFIG_REDIS_ASYNC=true` depending on which mode your changes affected.

```
CONFIG_REDIS_ASYNC=true CONFIG_QUEUES_MASTER_NAME=localhost:6379/5 CONFIG_REDIS_PROXY=localhost:6379/6 time -- bundle exec rake --backtrace  bench[worker/worker_bench.rb]
```

## Check listerner performance locally

### Obtain existing keys and metric

This is useful if you later want to compare performed requests to the reported requests in porta.
Alternatively you can generate fake entries into apisonator database.

Open porta, choose a provider and get the keys through the UI.

You can use also use porta rails console.
```ruby
Account.all.pluck :org_name, :id
Account.find(2).provider_key
Account.find(2).services.first.id
Account.find(2).services.first.cinstances.take.user_key
```

To ensure the provider data is synced in apisonator, run this in porta repo:
```
PROVIDER_ID=2445584351329 bundle exec rake backend:storage:rewrite
```

### Create fake keys and metric

This approach is quicker and doesn't require porta to be running.

With ruby
```
export CONFIG_REDIS_ASYNC=false
bundle exec ruby -Ilib/ -r3scale/backend.rb <<EOF
  ThreeScale::Backend::Service.save!(provider_key: 'pk', id: '1')
  ThreeScale::Backend::Application.save(service_id: '1', id: '1', state: :active)
  ThreeScale::Backend::Application.save_id_by_key('1', 'uk', '1')
  ThreeScale::Backend::Metric.save(service_id: '1', id: '1', name: 'hits')
EOF
```

Or API:
```
curl -X PUT -u system_app:password http://localhost:3001/internal/services/1 -d '{"service": { "id": "1", "provider_key": "pk" }}'
curl -X PUT -u system_app:password http://localhost:3001/internal/services/1/applications/1 -d '{"application": { "state": "active" }}'
curl -X PUT -u system_app:password http://localhost:3001/internal/services/1/applications/1/key/uk
curl -X PUT -u system_app:password http://localhost:3001/internal/services/1/metrics/1 -d '{"metric": { "name": "hits" }}'
```

Note that the api user and password need to match your actual passwords from local apisonator environment or from the `backend-internal-api` secret in the OpenShift project.

### Run many requests with hey

This is an example command using the fake data above. You need to adjust for real keys in porta.

```
hey -z 1h -c 60 "http://localhost:3001/transactions/authrep.xml?provider_key=pk&service_id=1&user_key=uk&usage%5Bhits%5D=1"
```

## running long stress test inside OCP

Obtain proper keys or create them as described above. Then run a pod like this one in the OpenShift cluster.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: backend-hey-0
spec:
  restartPolicy: Never
  containers:
    - name: hey
      image: williamyeh/hey:latest
      args:
      - "-z"
      - 12h
      - "-c"
      - "60"
      - "http://backend-listener-internal/transactions/authrep.xml?provider_key=pYH6zoa2HlaWt0nj6QDg9Y0WTVjqyo&service_id=2555418011440&user_key=301e82fc483319fe89d7bb06e80b181a&usage%5Bhits%5D=1"
```