Add basis of web application benchmarks
This commit is contained in:
Родитель
36291cdb7a
Коммит
b56b47bc8d
|
@ -3,6 +3,7 @@
|
|||
|
||||
# Measured benchmark results
|
||||
microbenchmarks/results.json
|
||||
webapps/results.json
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
*.Dockerfile
|
||||
run.ps1
|
||||
results.json
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"requestPath": "/hello.php"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
echo "Hello World!";
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
cp hello.php $1
|
|
@ -0,0 +1,3 @@
|
|||
FROM httpd:2.4.43
|
||||
|
||||
CMD ["bash"]
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace peachpie.Server
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var host = WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>()
|
||||
.UseUrls("http://*:80/")
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
|
||||
class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, IHostEnvironment env)
|
||||
{
|
||||
app.UsePhp(new PhpRequestOptions(scriptAssemblyName: "peachpie"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<Import Project="Version.props" Sdk="Peachpie.NET.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Peachpie.AspNetCore.Web" Version="$(PeachpieVersion)" />
|
||||
<ProjectReference Include="..\Website\Website.msbuildproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Peachpie.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyName>peachpie</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**/*.php" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Website", "Website\Website.msbuildproj", "{A271793F-72BF-429D-9EC8-83C03559CBD6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{AF5D53C1-32B5-473F-9229-817608068701}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|x64.Build.0 = Debug|x64
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Debug|x86.Build.0 = Debug|x86
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|x64.ActiveCfg = Release|x64
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|x64.Build.0 = Release|x64
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|x86.ActiveCfg = Release|x86
|
||||
{A271793F-72BF-429D-9EC8-83C03559CBD6}.Release|x86.Build.0 = Release|x86
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|x64.Build.0 = Debug|x64
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Debug|x86.Build.0 = Debug|x86
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|x64.ActiveCfg = Release|x64
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|x64.Build.0 = Release|x64
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|x86.ActiveCfg = Release|x86
|
||||
{AF5D53C1-32B5-473F-9229-817608068701}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,99 @@
|
|||
param (
|
||||
[string] $serverDockerFilter='server-*',
|
||||
[string] $appFilter='*',
|
||||
[int] $seconds=30,
|
||||
[int] $concurrency=20,
|
||||
[string] $outputFile='results.json'
|
||||
)
|
||||
|
||||
# Maximum theoretical number of requests to run (in practice it's limited by time instead)
|
||||
$maxRequests = 10000000
|
||||
|
||||
# Common helper variables for consistent naming of images and containers
|
||||
$network = "appbenchmarks"
|
||||
$clientContainer = "${network}-client"
|
||||
$serverContainer = "${network}-server"
|
||||
$clientTag = "${clientContainer}:latest"
|
||||
|
||||
# Helper function to create a reasonably named tag for the generated image
|
||||
function Get-ServerTagName {
|
||||
param ($serverDockerFile, $appDir)
|
||||
$serverName = $serverDockerFile.Basename.ToLower()
|
||||
$appName = $appDir.Name.ToLower()
|
||||
return "appbenchmarks-${serverName}-app-${appName}:latest"
|
||||
}
|
||||
|
||||
# Helper function for parsing text information using Regex
|
||||
function Select-Regex {
|
||||
param ([string]$subject, [string]$pattern)
|
||||
$m = $subject | Select-String -pattern $pattern
|
||||
return $m.Matches[0].Groups[1].Value
|
||||
}
|
||||
|
||||
# Gather *.Dockerfile files of servers according to the filter
|
||||
$serverDockerFiles = Get-ChildItem . -Filter $serverDockerFilter | Where-Object {$_.Name -like "server-*.Dockerfile"}
|
||||
|
||||
# Gather all the directories of all the apps to benchmark
|
||||
$appDirs = Get-ChildItem ./apps -Filter $appFilter
|
||||
|
||||
# Generate all the docker images, one for each pair of server and app
|
||||
Foreach ($serverDockerFile in $serverDockerFiles) {
|
||||
Foreach ($appDir in $appDirs) {
|
||||
$tag = Get-ServerTagName $serverDockerFile $appDir
|
||||
& docker build --tag $tag --file $serverDockerFile --build-arg app=$appDir .
|
||||
}
|
||||
}
|
||||
|
||||
# Generate the docker image for the benchmark client
|
||||
& docker build --tag $clientTag --file ./client.Dockerfile .
|
||||
|
||||
# Create the network to enable communication between the containers
|
||||
& docker network create $network
|
||||
|
||||
# Run all the apps, benchmark them and gather the results
|
||||
$results = @{}
|
||||
Foreach ($serverDockerFile in $serverDockerFiles) {
|
||||
$results[$serverDockerFile.Basename] = @{}
|
||||
Foreach ($appDir in $appDirs) {
|
||||
# Run the given container in the network
|
||||
$tag = Get-ServerTagName $serverDockerFile $appDir
|
||||
& docker run --name $serverContainer --network $network --detach --rm $tag
|
||||
|
||||
# Run the client container in the network
|
||||
& docker run --name $clientContainer --network $network --detach --rm --tty $clientTag
|
||||
|
||||
# Compose the URL to run the benchmarks on
|
||||
$appDirFullPath = $appDir.Fullname
|
||||
$benchmarkConfig = Get-Content "${appDirFullPath}/benchmarkConfig.json" | ConvertFrom-Json
|
||||
$requestPath = $benchmarkConfig.requestPath
|
||||
$url = "http://${serverContainer}${requestPath}"
|
||||
|
||||
# Wait for the server to start
|
||||
Start-Sleep -s 10
|
||||
|
||||
# Warm-up server (the client is reused to prevent from cooling it down due to reset)
|
||||
& docker exec $clientContainer ab -t $seconds -c $concurrency -n $maxRequests $url
|
||||
|
||||
# Run the benchmarks and obtain the results
|
||||
$abOutput = (& docker exec $clientContainer ab -t $seconds -c $concurrency -n $maxRequests $url) | Out-String
|
||||
|
||||
# Gather the results from the Apache Bench output
|
||||
$results[$serverDockerFile.Basename][$appDir.Name] = @{
|
||||
concurrency = $concurrency;
|
||||
time_ms = $seconds * 1000;
|
||||
requests = (Select-Regex $abOutput "Complete requests:[ ]+([0-9]+)") -as [int];
|
||||
requests_failed = (Select-Regex $abOutput "Failed requests:[ ]+([0-9]+)") -as [int];
|
||||
requests_per_second = (Select-Regex $abOutput "Requests per second:[ ]+([0-9]+(?:\.[0-9]+)?) \[#\/sec\] \(mean\)") -as [double];
|
||||
request_time_ms = (Select-Regex $abOutput "Time per request:[ ]+([0-9]+(?:\.[0-9]+)?) \[ms\] \(mean\)") -as [double];
|
||||
}
|
||||
|
||||
# Stop the containers (will be removed thanks to --rm on start)
|
||||
& docker stop $clientContainer $serverContainer
|
||||
}
|
||||
}
|
||||
|
||||
# Export the results
|
||||
ConvertTo-Json -Compress $results | Out-File $outputFile
|
||||
|
||||
# Clean up
|
||||
& docker network rm $network
|
|
@ -0,0 +1,17 @@
|
|||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
|
||||
|
||||
ARG app
|
||||
|
||||
COPY ./config/peachpie /peachpie
|
||||
|
||||
COPY ./apps/$app /app
|
||||
WORKDIR /app
|
||||
RUN ["/app/install.sh", "/peachpie/Website"]
|
||||
|
||||
WORKDIR /peachpie
|
||||
RUN echo "{ \"msbuild-sdks\": { \"Peachpie.NET.Sdk\": \"0.9.981\" } }" > global.json
|
||||
RUN dotnet restore
|
||||
RUN dotnet build -c Release
|
||||
|
||||
WORKDIR /peachpie/Server
|
||||
ENTRYPOINT ["dotnet", "run", "--no-build", "-c", "Release"]
|
|
@ -0,0 +1,7 @@
|
|||
FROM php:7.4.6-apache
|
||||
|
||||
ARG app
|
||||
|
||||
COPY ./apps/$app /app
|
||||
WORKDIR /app
|
||||
RUN ["/app/install.sh", "/var/www/html"]
|
Загрузка…
Ссылка в новой задаче