Skip to content

Commit

Permalink
enhance Sample36 by UnixDomainSocket
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel.mash committed Dec 8, 2018
1 parent 16e9c70 commit aaf22a9
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 6 deletions.
64 changes: 64 additions & 0 deletions SQLite3/Samples/36 - Simple REST Benchmark/README.md
@@ -0,0 +1,64 @@
# Simple mORMot server for REST benchmark

## Socket based server

- compile and run RESTBenchmark
- test it with browser:
- http://localhost:8888/root/abc
- http://localhost:8888/root/xyz
- test it with Apache Bench
```
ab -n 10000 -c 1000 http://localhost:8888/root/abc
```

## Keep alive
By default mROMot HTTP server runs in KeepAlive mode.

To disable KeepAlive run `RESTBenchmark` with secont parameter `false`
```
./RESTBenchmark 8888 false
```

Disabling KeepAlive make sence in case mORMotserver is behind the reverse proxy.
In this case reverse proxy cares about KeepAlive connection pool and mormot can
operate with fixed thread pool size.

## Unix Domain Socket (Linux)

### When to use
In case mORMot is behind a local reverse proxy on the environment with a
huge number of incoming connection it's make sence to use a UDS to minimize
unnecessary TCP handshakes between mORMot and reverse proxy.

To emulate such environment on the syntetic test we can disable keep alive
in RESTBEnchmark by passing `false` to then second parameter
```
./RESTBenchmark unix false
./RESTBenchmark 8888 false
```

### How to run

- compile program and run with `unix` parameter
```
./RESTBenchmark unix
```

Benchmark will listen on Unix Domain Socket `/tmp/rest-bench.socket`

- test it with curl
```
curl --unix-socket /tmp/rest-bench.socket http://localhost/root/abc
```

- setup nginx as a reverse proxy
```
sudo ln -s "$(pwd)/mormot-rest-nginx.conf" /etc/nginx/sites-available
sudo ln -s /etc/nginx/sites-available/mormot-rest-nginx.conf /etc/nginx/sites-enabled
sudo nginx -s reload
```

- test it using ab (or better - wrk)
```
wrk http://localhost:8888/root/abc
```
35 changes: 30 additions & 5 deletions SQLite3/Samples/36 - Simple REST Benchmark/RESTBenchmark.dpr
Expand Up @@ -8,13 +8,15 @@ program RESTBenchmark;
- ab -n 1000 -c 100 http://localhost:8888/root/xyz
for bandwidth measure (returns some ORM query as 77KB of JSON)
}

{$ifndef UNIX}
{$APPTYPE CONSOLE}
{$endif}

uses
{$I SynDprUses.inc} // use FastMM4 on older Delphi, or set FPC threads
SysUtils,
SynCommons, // framework core
SynCrtSock, // direct access to HTTP server
SynLog, // logging features
mORMot, // RESTful server & ORM
mORMotSQLite3, // SQLite3 engine as ORM core
Expand Down Expand Up @@ -99,7 +101,7 @@ begin
ctxt.Returns(s);
end;

procedure DoTest;
procedure DoTest(const url: AnsiString; keepAlive: boolean);
var
aRestServer: TSQLRestServerDB;
aHttpServer: TSQLHttpServer;
Expand All @@ -114,10 +116,15 @@ begin
aServices := TMyServices.Create(aRestServer);
try
// serve aRestServer data over HTTP
aHttpServer := TSQLHttpServer.Create('8888',[aRestServer]);
aHttpServer := TSQLHttpServer.Create(url,[aRestServer]);
if not keepAlive and (aHttpServer.HttpServer is THttpServer) then
THttpServer(aHttpServer.HttpServer).ServerKeepAliveTimeOut := 0;
try
aHttpServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries
writeln('Background server is running.'#10);
write('Background server is running on ', url, ' keepAlive ');
if (keepAlive) then
writeLn('is enabled') else
writeLn('is disabled');
write('Press [Enter] to close the server.');
readln;
finally
Expand All @@ -131,12 +138,30 @@ begin
end;
end;

const
UNIX_SOCK_PATH = '/tmp/rest-bench.socket';

var
url: AnsiString;
keepAlive: boolean;

begin
// set logging abilities
SQLite3Log.Family.Level := LOG_VERBOSE;
//SQLite3Log.Family.EchoToConsole := LOG_VERBOSE;
SQLite3Log.Family.PerThreadLog := ptIdentifiedInOnFile;
DoTest;
SQLite3Log.Family.NoFile := true; // do not create log files for benchmark
{$ifdef UNIX}
if (ParamCount>0) and (ParamStr(1)='unix') then begin
url := 'unix:' + UNIX_SOCK_PATH;
if FileExists(UNIX_SOCK_PATH) then
DeleteFile(UNIX_SOCK_PATH); // remove socket file
end else
{$endif}
url := '8888';
if (ParamCount>1) and (ParamStr(2)='false') then
keepAlive := false else
keepAlive := true;
DoTest(url, keepAlive);
end.

Expand Up @@ -7,7 +7,6 @@
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<UseDefaultCompilerOptions Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
Expand Down
59 changes: 59 additions & 0 deletions SQLite3/Samples/36 - Simple REST Benchmark/mormot-rest-nginx.conf
@@ -0,0 +1,59 @@
upstream mormot-uds {
server unix:/tmp/rest-bench.socket;
keepalive 32;
}

upstream mormot-sock {
server localhost:8888;
keepalive 32;
}

server {
listen 8889;

server_name localhost;

access_log /dev/null;
# prevent nginx version exposing in Server header
server_tokens off;

proxy_set_header Host $host;
# Tell upstream real IP address of client
proxy_set_header X-Real-IP $realip_remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Do not rewrite a URL while pass it to upstream
proxy_redirect off;
# Let's upstream handle errors
proxy_intercept_errors on;
tcp_nodelay on;

# proxy all requests to the beckend
location / {
proxy_pass http://mormot-sock;
}
}

server {
listen 8887;

server_name localhost;

access_log /dev/null;
# prevent nginx version exposing in Server header
server_tokens off;

proxy_set_header Host $host;
# Tell upstream real IP address of client
proxy_set_header X-Real-IP $realip_remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Do not rewrite a URL while pass it to upstream
proxy_redirect off;
# Let's upstream handle errors
proxy_intercept_errors on;
tcp_nodelay on;

# proxy all requests to the beckend
location / {
proxy_pass http://mormot-uds;
}
}

0 comments on commit aaf22a9

Please sign in to comment.