5 changed files with 177 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
rsyslog.pid |
||||
@ -0,0 +1,31 @@ |
|||||
|
package itix |
||||
|
|
||||
|
import scala.concurrent.duration._ |
||||
|
|
||||
|
import io.gatling.core.Predef._ |
||||
|
import io.gatling.http.Predef._ |
||||
|
import io.gatling.jdbc.Predef._ |
||||
|
|
||||
|
class Apicast1kPOST extends Simulation { |
||||
|
|
||||
|
val httpProtocol = http |
||||
|
.baseURL("http://localhost:8080") |
||||
|
.inferHtmlResources() |
||||
|
.acceptHeader("*/*") |
||||
|
.contentTypeHeader("application/x-www-form-urlencoded") |
||||
|
.userAgentHeader("curl/7.54.0") |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
val scn = scenario("Apicast1kPOST") |
||||
|
.repeat(1000) { |
||||
|
exec(http("POST-1k") |
||||
|
.post("/?user_key=secret") |
||||
|
.formParam("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "") |
||||
|
.check(status.is(200))) |
||||
|
} |
||||
|
|
||||
|
setUp(scn.inject(rampUsers(200) over(5 seconds))).protocols(httpProtocol) |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
# Performance Testing |
||||
|
|
||||
|
## Setup |
||||
|
|
||||
|
- Download and install [gatling](http://gatling.io/). |
||||
|
- Edit `apicast/conf/nginx.conf` to set `worker_connections` to a much reasonable setting for a development machine |
||||
|
- Launch a development apicast with the following parameters: |
||||
|
``` |
||||
|
export APICAST_LOG_LEVEL=crit |
||||
|
export THREESCALE_CONFIG_FILE=config.json |
||||
|
sudo sysctl -w kern.maxfiles=65536 |
||||
|
sudo sysctl -w kern.maxfilesperproc=65536 |
||||
|
sudo launchctl limit maxfiles 65536 65536 |
||||
|
ulimit -n 65536 |
||||
|
bin/apicast -i 3600 -m on -w 8 &> apicast.log |
||||
|
``` |
||||
|
|
||||
|
**WARNING:** On MacOS, you have to run apicast **as root** to be able to push up |
||||
|
the maximum number of open files (`ulimit -n`). |
||||
|
|
||||
|
- Install and run a rsyslog server: |
||||
|
``` |
||||
|
sudo brew install rsyslog |
||||
|
/usr/local/Cellar/rsyslog/*/sbin/rsyslogd -4 -n -f rsyslog.conf -i "$PWD/rsyslog.pid" |
||||
|
``` |
||||
|
|
||||
|
## Recording a scenario (OPTIONAL) |
||||
|
|
||||
|
Gatling scenario are available in the [performance-testing directory](performance-testing). |
||||
|
However, you can record your own by : |
||||
|
|
||||
|
- Launcing the recorder and starting a recording |
||||
|
- Doing a test request through the gatling proxy |
||||
|
``` |
||||
|
export http_proxy=http://localhost:8000 |
||||
|
curl "http://localhost:8080/?user_key=secret" -D - -X POST -d "data" |
||||
|
``` |
||||
|
|
||||
|
Then, you can customize the scenario to loop over the request you recorded and |
||||
|
add virtual users. |
||||
|
|
||||
|
## Running a scenario against the vanilla apicast |
||||
|
|
||||
|
Run the gatling scenario: |
||||
|
``` |
||||
|
gatling.sh -sf . -s itix.Apicast1kPOST |
||||
|
``` |
||||
|
|
||||
|
## Running a scenario against the apicast with the logging module |
||||
|
|
||||
|
Then, re-start apicast with the following environment: |
||||
|
``` |
||||
|
export APICAST_MODULE=custom/verbose |
||||
|
export SYSLOG_HOST=127.0.0.1.xip.io |
||||
|
export SYSLOG_PORT=1601 |
||||
|
export SYSLOG_PROTO=tcp |
||||
|
export SYSLOG_PERIODIC_FLUSH=5 |
||||
|
export SYSLOG_FLUSH_LIMIT=10240 |
||||
|
``` |
||||
|
|
||||
|
Run the gatling scenario: |
||||
|
``` |
||||
|
gatling.sh -sf . -s itix.Apicast1kPOST |
||||
|
``` |
||||
|
|
||||
|
Check that you have exactly 200000 lines in both `apicast.log`: |
||||
|
- the one created by the apicast server |
||||
|
- the one created by the rsyslog server |
||||
|
|
||||
|
``` |
||||
|
$ wc -l apicast.log |
||||
|
200000 apicast.log |
||||
|
``` |
||||
|
|
||||
|
## Reference |
||||
|
|
||||
|
- https://www.digitalocean.com/community/tutorials/how-to-optimize-nginx-configuration |
||||
|
- http://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/ |
||||
|
- http://gatling.io/docs/current/general/simulation_setup/#injection |
||||
|
- http://gatling.io/docs/current/cheat-sheet/ |
||||
|
- https://superuser.com/a/867865 |
||||
@ -0,0 +1,56 @@ |
|||||
|
{ |
||||
|
"id": 1234567890987, |
||||
|
"provider_key": "provider-key", |
||||
|
"services": [ |
||||
|
{ |
||||
|
"id": 654321, |
||||
|
"backend_version": "1", |
||||
|
"backend_authentication_type": "service_token", |
||||
|
"backend_authentication_value": "service-token-1234567890", |
||||
|
"proxy": { |
||||
|
"api_backend": "http://127.0.0.1:8081", |
||||
|
"auth_app_key": "app_key", |
||||
|
"auth_app_id": "app_id", |
||||
|
"auth_user_key": "user_key", |
||||
|
"credentials_location": "query", |
||||
|
"error_auth_failed": "Authentication failed", |
||||
|
"error_auth_missing": "Authentication parameters missing", |
||||
|
"error_status_auth_failed": 403, |
||||
|
"error_headers_auth_failed": "text/plain; charset=us-ascii", |
||||
|
"error_status_auth_missing": 403, |
||||
|
"error_headers_auth_missing": "text/plain; charset=us-ascii", |
||||
|
"error_no_match": "No Mapping Rule matched", |
||||
|
"error_status_no_match": 404, |
||||
|
"error_headers_no_match": "text/plain; charset=us-ascii", |
||||
|
"secret_token": "Shared_secret_sent_from_proxy_to_API_backend", |
||||
|
"hostname_rewrite": null, |
||||
|
"oauth_login_url": null, |
||||
|
"hosts": [ |
||||
|
"localhost" |
||||
|
], |
||||
|
"backend": { |
||||
|
"endpoint": "http://127.0.0.1:8081", |
||||
|
"host": "backend" |
||||
|
}, |
||||
|
"proxy_rules": [ |
||||
|
{ |
||||
|
"http_method": "GET", |
||||
|
"pattern": "/", |
||||
|
"metric_system_name": "hits", |
||||
|
"delta": 1, |
||||
|
"parameters": [], |
||||
|
"querystring_parameters": {} |
||||
|
}, |
||||
|
{ |
||||
|
"http_method": "POST", |
||||
|
"pattern": "/", |
||||
|
"metric_system_name": "hits", |
||||
|
"delta": 1, |
||||
|
"parameters": [], |
||||
|
"querystring_parameters": {} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
module(load="imtcp") |
||||
|
|
||||
|
ruleset(name="remote1"){ |
||||
|
action(type="omfile" file="/tmp/apicast.log") |
||||
|
} |
||||
|
|
||||
|
|
||||
|
input(type="imtcp" port="1601" ruleset="remote1" RateLimit.Interval="0" RateLimit.Burst="1000000000") |
||||
Loading…
Reference in new issue