From 40ab5f92681199b75c614db4531e6d9034bca470 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Wed, 16 Oct 2024 14:09:39 -0700 Subject: [PATCH 01/12] Add port sharing support to PlatformBenchmarks on Linux --- .../TechEmpower/PlatformBenchmarks/Program.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs index 58238dbe2..b379841f5 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs @@ -2,10 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; using Microsoft.Extensions.Configuration; #if DATABASE using Npgsql; @@ -106,6 +109,32 @@ public static IWebHost BuildWebHost(string[] args) if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { options.UnsafePreferInlineScheduling = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS") == "1"; + + // Allow multiple processes bind to the same port. This also "works" on Windows in that it will + // prevent address in use errors and hand off to another process if no others are available, + // but it wouldn't round-robin new connections between processes like it will on Linux. + options.CreateBoundListenSocket = endpoint => + { + if (endpoint is not IPEndPoint ip) + { + return SocketTransportOptions.CreateDefaultBoundListenSocket(endpoint); + } + + // Normally, we'd call CreateDefaultBoundListenSocket for the IPEndpoint too, but we need + // to set ReuseAddress before calling bind, and CreateDefaultBoundListenSocket calls bind. + var listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + + // Kestrel expects IPv6Any to bind to both IPv6 and IPv4 + if (ip.Address.Equals(IPAddress.IPv6Any)) + { + listenSocket.DualMode = true; + } + + listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + listenSocket.Bind(ip); + + return listenSocket; + }; } }); From 7c4a6edfc94be21bc28cf786880bc547bf18ef53 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Wed, 16 Oct 2024 14:12:04 -0700 Subject: [PATCH 02/12] Add port sharing support to Minimal benchmarks on Linux --- .../TechEmpower/Minimal/Program.cs | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/Minimal/Program.cs b/src/BenchmarksApps/TechEmpower/Minimal/Program.cs index 287f7a035..05d3b7b8c 100644 --- a/src/BenchmarksApps/TechEmpower/Minimal/Program.cs +++ b/src/BenchmarksApps/TechEmpower/Minimal/Program.cs @@ -5,6 +5,10 @@ using Minimal; using Minimal.Database; using Minimal.Models; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; +using System.Net.Sockets; +using System.Net; +using System.Runtime.InteropServices; var builder = WebApplication.CreateBuilder(args); @@ -13,9 +17,41 @@ builder.WebHost.ConfigureKestrel(options => { - options.AllowSynchronousIO = true; + options.AllowSynchronousIO = true; }); +// Allow multiple processes bind to the same port. This also "works" on Windows in that it will +// prevent address in use errors and hand off to another process if no others are available, +// but it wouldn't round-robin new connections between processes like it will on Linux. +if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) +{ + builder.WebHost.UseSockets(options => + { + options.CreateBoundListenSocket = endpoint => + { + if (endpoint is not IPEndPoint ip) + { + return SocketTransportOptions.CreateDefaultBoundListenSocket(endpoint); + } + + // Normally, we'd call CreateDefaultBoundListenSocket for the IPEndpoint too, but we need + // to set ReuseAddress before calling bind, and CreateDefaultBoundListenSocket calls bind. + var listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + + // Kestrel expects IPv6Any to bind to both IPv6 and IPv4 + if (ip.Address.Equals(IPAddress.IPv6Any)) + { + listenSocket.DualMode = true; + } + + listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + listenSocket.Bind(ip); + + return listenSocket; + }; + }); +} + // Load custom configuration var appSettings = new AppSettings(); builder.Configuration.Bind(appSettings); @@ -40,7 +76,8 @@ var createFortunesTemplate = RazorSlice.ResolveSliceFactory>("/Templates/Fortunes.cshtml"); var htmlEncoder = CreateHtmlEncoder(); -app.MapGet("/fortunes", async (HttpContext context, Db db) => { +app.MapGet("/fortunes", async (HttpContext context, Db db) => +{ var fortunes = await db.LoadFortunesRows(); var template = (RazorSliceHttpResult>)createFortunesTemplate(fortunes); template.HtmlEncoder = htmlEncoder; From f399ad5e8420f717eda0bf3dce8348a015a13f02 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 14:45:17 -0700 Subject: [PATCH 03/12] Add dockerfile --- src/BenchmarksApps/TechEmpower/dockerfile | 15 +++++++++++++++ src/BenchmarksApps/TechEmpower/startprocess.sh | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 src/BenchmarksApps/TechEmpower/dockerfile create mode 100755 src/BenchmarksApps/TechEmpower/startprocess.sh diff --git a/src/BenchmarksApps/TechEmpower/dockerfile b/src/BenchmarksApps/TechEmpower/dockerfile new file mode 100644 index 000000000..b403e17f0 --- /dev/null +++ b/src/BenchmarksApps/TechEmpower/dockerfile @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +WORKDIR /app +COPY src/Platform . +COPY startprocess.sh out +RUN dotnet publish -c Release -o out /p:DatabaseProvider=Npgsql + +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime +ENV URLS http://+:8080 + +WORKDIR /app +COPY --from=build /app/out ./ + +EXPOSE 8080 + +CMD ./startprocess.sh diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh new file mode 100755 index 000000000..084dda6ca --- /dev/null +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -0,0 +1,4 @@ +dotnet Platform.dll +dotnet Platform.dll +dotnet Platform.dll +dotnet Platform.dll From c944e6d19ac14e396062eca80efa6885404f1a9d Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 15:24:01 -0700 Subject: [PATCH 04/12] Start multiple processes --- .dockerignore | 3 +++ .../PlatformBenchmarks/PlatformBenchmarks.csproj | 2 +- src/BenchmarksApps/TechEmpower/dockerfile | 10 +++++----- src/BenchmarksApps/TechEmpower/startprocess.sh | 10 ++++++---- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.dockerignore b/.dockerignore index da193f387..78e7fc0af 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,5 @@ .git* .dockerignore +# Ignore all built assets +**/[b|B]in/ +**/[O|o]bj/ diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj index 119e04f60..8e4a8b2d0 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj @@ -1,7 +1,7 @@  - net7.0;net8.0 + net7.0;net8.0;net9.0 Exe true true diff --git a/src/BenchmarksApps/TechEmpower/dockerfile b/src/BenchmarksApps/TechEmpower/dockerfile index b403e17f0..0664c548d 100644 --- a/src/BenchmarksApps/TechEmpower/dockerfile +++ b/src/BenchmarksApps/TechEmpower/dockerfile @@ -1,15 +1,15 @@ FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /app -COPY src/Platform . -COPY startprocess.sh out -RUN dotnet publish -c Release -o out /p:DatabaseProvider=Npgsql +COPY . . +RUN dotnet publish ./src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj -c Release -o out -f net9.0 +COPY ./src/BenchmarksApps/TechEmpower/startprocess.sh out FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime -ENV URLS http://+:8080 +ENV URLS=http://+:8080 WORKDIR /app COPY --from=build /app/out ./ EXPOSE 8080 -CMD ./startprocess.sh +CMD ["./startprocess.sh"] diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index 084dda6ca..dda2f454b 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,4 +1,6 @@ -dotnet Platform.dll -dotnet Platform.dll -dotnet Platform.dll -dotnet Platform.dll +#!/bin/bash + +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll From 6a48c968768130408578fe815c792bda9f1c6ff9 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 15:51:49 -0700 Subject: [PATCH 05/12] Support database --- src/BenchmarksApps/TechEmpower/dockerfile-db | 15 +++++ .../TechEmpower/te.benchmarks.yml | 66 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/BenchmarksApps/TechEmpower/dockerfile-db create mode 100644 src/BenchmarksApps/TechEmpower/te.benchmarks.yml diff --git a/src/BenchmarksApps/TechEmpower/dockerfile-db b/src/BenchmarksApps/TechEmpower/dockerfile-db new file mode 100644 index 000000000..258547129 --- /dev/null +++ b/src/BenchmarksApps/TechEmpower/dockerfile-db @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +WORKDIR /app +COPY . . +RUN dotnet publish ./src/BenchmarksApps/TechEmpower/PlatformBenchmarks/PlatformBenchmarks.csproj -c Release -o out -f net9.0 /p:IsDatabase=true +COPY ./src/BenchmarksApps/TechEmpower/startprocess.sh out + +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime +ENV URLS=http://+:8080 + +WORKDIR /app +COPY --from=build /app/out ./ + +EXPOSE 8080 + +CMD ["./startprocess.sh"] diff --git a/src/BenchmarksApps/TechEmpower/te.benchmarks.yml b/src/BenchmarksApps/TechEmpower/te.benchmarks.yml new file mode 100644 index 000000000..2b17f6709 --- /dev/null +++ b/src/BenchmarksApps/TechEmpower/te.benchmarks.yml @@ -0,0 +1,66 @@ +imports: + - https://raw.githubusercontent.com/dotnet/crank/main/src/Microsoft.Crank.Jobs.Wrk/wrk.yml + - https://raw.githubusercontent.com/dotnet/crank/main/src/Microsoft.Crank.Jobs.Bombardier/bombardier.yml + - https://github.com/aspnet/Benchmarks/blob/main/scenarios/aspnet.profiles.yml?raw=true + +jobs: + + aspnetcore: + source: + repository: https://github.com/aspnet/Benchmarks + branchOrCommit: main + dockerFile: src/BenchmarksApps/TechEmpower/dockerfile + dockerImageName: aspnetcore_reuse + dockerContextDirectory: ./ + readyStateText: Application started + arguments: --add-host="tfb-database:{{databaseServer}}" + noClean: true + + postgresql: + source: + repository: https://github.com/TechEmpower/FrameworkBenchmarks.git + branchOrCommit: master + dockerFile: toolset/databases/postgres/postgres.dockerfile + dockerImageName: postgres_te + dockerContextDirectory: toolset/databases/postgres + readyStateText: ready to accept connections + noClean: true + +scenarios: + +# ASP.NET Core (Platform) + plaintext_aspnetcore: + application: + job: aspnetcore + load: + job: wrk + variables: + presetHeaders: plaintext + path: /plaintext + pipeline: 16 + serverPort: 8080 + + json_aspnetcore: + application: + job: aspnetcore + load: + job: wrk + variables: + presetHeaders: json + path: /json + serverPort: 8080 + + fortunes_aspnetcore: + db: + job: postgresql + application: + job: aspnetcore + source: + dockerFile: src/BenchmarksApps/TechEmpower/dockerfile-db + dockerImageName: aspnetcore_reuse_db + load: + job: wrk + variables: + presetHeaders: html + path: /fortunes + serverPort: 8080 From 85f7ebd98ff5e544b2ab58aa6adfdb9e17084cc6 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:23:18 -0700 Subject: [PATCH 06/12] cgroups --- src/BenchmarksApps/TechEmpower/startprocess.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index dda2f454b..419bd71af 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,6 +1,13 @@ #!/bin/bash -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll +cgcreate -g cpu,cpuset:/cpugroup1 +cgcreate -g cpu,cpuset:/cpugroup2 + +cgset -r cpuset.cpus=0-27 /cpugroup1 +cgset -r cpuset.cpus=28-55 /cpugroup2 + +cgexec -g cpu:/cpugroup1 dotnet ./PlatformBenchmarks.dll & +cgexec -g cpu:/cpugroup2 dotnet ./PlatformBenchmarks.dll + +cgdelete -g cpu:/cpugroup1 +cgdelete -g cpu:/cpugroup2 From cd290114a0ee8a98b59a19ca1b47d93dea297896 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:26:20 -0700 Subject: [PATCH 07/12] install cgroups --- src/BenchmarksApps/TechEmpower/startprocess.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index 419bd71af..89a3bf83e 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Install dependencies +apt-get update \ + && apt-get install -y --no-install-recommends \ + cgroup-tools + cgcreate -g cpu,cpuset:/cpugroup1 cgcreate -g cpu,cpuset:/cpugroup2 From 720342e48fae86b4e8d8f9364c2a8465509e86a8 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:30:42 -0700 Subject: [PATCH 08/12] Use two processes --- src/BenchmarksApps/TechEmpower/startprocess.sh | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index 89a3bf83e..8a19babc8 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Install dependencies -apt-get update \ - && apt-get install -y --no-install-recommends \ - cgroup-tools - -cgcreate -g cpu,cpuset:/cpugroup1 -cgcreate -g cpu,cpuset:/cpugroup2 - -cgset -r cpuset.cpus=0-27 /cpugroup1 -cgset -r cpuset.cpus=28-55 /cpugroup2 - -cgexec -g cpu:/cpugroup1 dotnet ./PlatformBenchmarks.dll & -cgexec -g cpu:/cpugroup2 dotnet ./PlatformBenchmarks.dll - -cgdelete -g cpu:/cpugroup1 -cgdelete -g cpu:/cpugroup2 +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll From 8568fa8a2ccb3140cd18b6b4b48b81b592ab1111 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:35:04 -0700 Subject: [PATCH 09/12] one process --- src/BenchmarksApps/TechEmpower/startprocess.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index 8a19babc8..ecddd0c25 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,4 +1,3 @@ #!/bin/bash -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll +dotnet ./PlatformBenchmarks.dll \ No newline at end of file From 6cf930d2e66afc3bb93219380611444df135e023 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:38:05 -0700 Subject: [PATCH 10/12] ten processes --- src/BenchmarksApps/TechEmpower/startprocess.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index ecddd0c25..d0c25ff51 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,3 +1,12 @@ #!/bin/bash -dotnet ./PlatformBenchmarks.dll \ No newline at end of file +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll & +dotnet ./PlatformBenchmarks.dll From 6743d1857105d69b09516fdecdeb24fd9e467d2b Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 16 Oct 2024 16:59:37 -0700 Subject: [PATCH 11/12] three processes --- src/BenchmarksApps/TechEmpower/startprocess.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index d0c25ff51..f663c9839 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -2,11 +2,5 @@ dotnet ./PlatformBenchmarks.dll & dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll +dotnet ./PlatformBenchmarks.dll + From 291fb815e3816f9115b4c5863029330a58103488 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Fri, 25 Oct 2024 11:33:57 -0700 Subject: [PATCH 12/12] cgroups --- src/BenchmarksApps/TechEmpower/startprocess.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/BenchmarksApps/TechEmpower/startprocess.sh b/src/BenchmarksApps/TechEmpower/startprocess.sh index f663c9839..6577ea8ea 100755 --- a/src/BenchmarksApps/TechEmpower/startprocess.sh +++ b/src/BenchmarksApps/TechEmpower/startprocess.sh @@ -1,6 +1,18 @@ #!/bin/bash -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll & -dotnet ./PlatformBenchmarks.dll +# Install dependencies +apt-get update \ + && apt-get install -y --no-install-recommends \ + cgroup-tools +cgcreate -g cpu,cpuset:/cpugroup1 +cgcreate -g cpu,cpuset:/cpugroup2 + +cgset -r cpuset.cpus=0-5 /cpugroup1 +cgset -r cpuset.cpus=6-12 /cpugroup2 + +cgexec -g cpu:/cpugroup1 dotnet ./PlatformBenchmarks.dll & +cgexec -g cpu:/cpugroup2 dotnet ./PlatformBenchmarks.dll + +cgdelete -g cpu:/cpugroup1 +cgdelete -g cpu:/cpugroup2