Skip to content

Commit 283098b

Browse files
authored
Add gRPC benchmark client (#891)
1 parent 9b759a5 commit 283098b

File tree

23 files changed

+1156
-38
lines changed

23 files changed

+1156
-38
lines changed

Grpc.DotNet.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTestsGrpcWebWebsite"
118118
EndProject
119119
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTestsGrpcWebClient", "testassets\InteropTestsGrpcWebClient\InteropTestsGrpcWebClient.csproj", "{10DD7EEB-7B3A-4BF2-9562-78831FB06001}"
120120
EndProject
121+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcClient", "perf\benchmarkapps\GrpcClient\GrpcClient.csproj", "{D241B525-3B50-42EA-9E43-052745549BA6}"
122+
EndProject
121123
Global
122124
GlobalSection(SolutionConfigurationPlatforms) = preSolution
123125
Debug|Any CPU = Debug|Any CPU
@@ -236,6 +238,10 @@ Global
236238
{10DD7EEB-7B3A-4BF2-9562-78831FB06001}.Debug|Any CPU.Build.0 = Debug|Any CPU
237239
{10DD7EEB-7B3A-4BF2-9562-78831FB06001}.Release|Any CPU.ActiveCfg = Release|Any CPU
238240
{10DD7EEB-7B3A-4BF2-9562-78831FB06001}.Release|Any CPU.Build.0 = Release|Any CPU
241+
{D241B525-3B50-42EA-9E43-052745549BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
242+
{D241B525-3B50-42EA-9E43-052745549BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
243+
{D241B525-3B50-42EA-9E43-052745549BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
244+
{D241B525-3B50-42EA-9E43-052745549BA6}.Release|Any CPU.Build.0 = Release|Any CPU
239245
EndGlobalSection
240246
GlobalSection(SolutionProperties) = preSolution
241247
HideSolutionNode = FALSE
@@ -278,6 +284,7 @@ Global
278284
{39A9F2B5-2541-423E-83C9-46C7BFF53F41} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
279285
{AE2CF906-6C98-40F5-8EE5-3DBAC572F114} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
280286
{10DD7EEB-7B3A-4BF2-9562-78831FB06001} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
287+
{D241B525-3B50-42EA-9E43-052745549BA6} = {1B8B6117-CE39-4580-BAFA-D8026102767A}
281288
EndGlobalSection
282289
GlobalSection(ExtensibilityGlobals) = postSolution
283290
SolutionGuid = {CD5C2B19-49B4-480A-990C-36D98A719B07}

perf/benchmarkapps/GrpcAspNetCoreServer/Program.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static IHostBuilder CreateHostBuilder(string[] args)
4141
Console.WriteLine();
4242
Console.WriteLine("ASP.NET Core gRPC Benchmarks");
4343
Console.WriteLine("----------------------------");
44-
44+
Console.WriteLine($"Args: {string.Join(' ', args)}");
4545
Console.WriteLine($"Current directory: {Directory.GetCurrentDirectory()}");
4646
Console.WriteLine($"WebHostBuilder loading from: {typeof(WebHostBuilder).GetTypeInfo().Assembly.Location}");
4747

@@ -68,8 +68,10 @@ public static IHostBuilder CreateHostBuilder(string[] args)
6868
options.ListenAnyIP(endPoint.Port, listenOptions =>
6969
{
7070
var protocol = config["protocol"] ?? "";
71+
bool.TryParse(config["enableCertAuth"], out var enableCertAuth);
7172

72-
Console.WriteLine($"Protocol: {protocol}");
73+
Console.WriteLine($"Address: {endPoint.Address}:{endPoint.Port}, Protocol: {protocol}");
74+
Console.WriteLine($"Certificate authentication: {enableCertAuth}");
7375

7476
if (protocol.Equals("h2", StringComparison.OrdinalIgnoreCase))
7577
{
@@ -79,9 +81,11 @@ public static IHostBuilder CreateHostBuilder(string[] args)
7981
var certPath = Path.Combine(basePath!, "Certs/testCert.pfx");
8082
listenOptions.UseHttps(certPath, "testPassword", httpsOptions =>
8183
{
82-
#if CLIENT_CERTIFICATE_AUTHENTICATION
83-
httpsOptions.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.AllowCertificate;
84-
#endif
84+
if (enableCertAuth)
85+
{
86+
httpsOptions.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.AllowCertificate;
87+
httpsOptions.AllowAnyClientCertificate();
88+
}
8589
});
8690
}
8791
else if (protocol.Equals("h2c", StringComparison.OrdinalIgnoreCase))
@@ -103,7 +107,7 @@ public static IHostBuilder CreateHostBuilder(string[] args)
103107
{
104108
loggerFactory.ClearProviders();
105109

106-
if (Enum.TryParse<LogLevel>(config["LogLevel"], out var logLevel))
110+
if (Enum.TryParse<LogLevel>(config["LogLevel"], out var logLevel) && logLevel != LogLevel.None)
107111
{
108112
Console.WriteLine($"Console Logging enabled with level '{logLevel}'");
109113
loggerFactory.AddConsole(o => o.TimestampFormat = "ss.ffff ").SetMinimumLevel(logLevel);

perf/benchmarkapps/GrpcAspNetCoreServer/Startup.cs

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,28 @@
1818

1919
using System;
2020
using System.IO;
21+
using System.Security.Cryptography.X509Certificates;
2122
using System.Text;
2223
using Grpc.Testing;
24+
using Microsoft.AspNetCore.Authentication.Certificate;
2325
using Microsoft.AspNetCore.Builder;
2426
using Microsoft.AspNetCore.Http;
27+
using Microsoft.Extensions.Configuration;
2528
using Microsoft.Extensions.DependencyInjection;
2629
using Microsoft.Extensions.Hosting;
27-
using Microsoft.Extensions.Logging;
2830
using Newtonsoft.Json;
29-
#if CLIENT_CERTIFICATE_AUTHENTICATION
30-
using System.Security.Cryptography.X509Certificates;
31-
using Microsoft.AspNetCore.Authentication.Certificate;
32-
#endif
3331

3432
namespace GrpcAspNetCoreServer
3533
{
3634
public class Startup
3735
{
36+
private readonly IConfiguration _config;
37+
38+
public Startup(IConfiguration config)
39+
{
40+
_config = config;
41+
}
42+
3843
public void ConfigureServices(IServiceCollection services)
3944
{
4045
services.AddGrpc(o =>
@@ -45,19 +50,18 @@ public void ConfigureServices(IServiceCollection services)
4550
services.AddSingleton<BenchmarkServiceImpl>();
4651
services.AddControllers();
4752

48-
#if CLIENT_CERTIFICATE_AUTHENTICATION
49-
services.AddAuthorization();
50-
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
51-
.AddCertificate(options =>
52-
{
53-
// Not recommended in production environments. The example is using a self-signed test certificate.
54-
options.RevocationMode = X509RevocationMode.NoCheck;
55-
options.AllowedCertificateTypes = CertificateTypes.All;
56-
});
57-
#endif
58-
#if GRPC_WEB
59-
services.AddGrpcWeb(o => o.GrpcWebEnabled = true);
60-
#endif
53+
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
54+
if (enableCertAuth)
55+
{
56+
services.AddAuthorization();
57+
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
58+
.AddCertificate(options =>
59+
{
60+
// Not recommended in production environments. The example is using a self-signed test certificate.
61+
options.RevocationMode = X509RevocationMode.NoCheck;
62+
options.AllowedCertificateTypes = CertificateTypes.All;
63+
});
64+
}
6165
}
6266

6367
public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicationLifetime)
@@ -67,29 +71,34 @@ public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicat
6771

6872
app.UseRouting();
6973

70-
#if CLIENT_CERTIFICATE_AUTHENTICATION
71-
app.UseAuthentication();
72-
app.UseAuthorization();
73-
#endif
74+
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
75+
if (enableCertAuth)
76+
{
77+
app.UseAuthentication();
78+
app.UseAuthorization();
79+
}
7480

75-
#if GRPC_WEB
76-
app.UseGrpcWeb();
77-
#endif
81+
bool.TryParse(_config["enableGrpcWeb"], out var enableGrpcWeb);
82+
83+
if (enableGrpcWeb)
84+
{
85+
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
86+
}
7887

7988
app.UseMiddleware<ServiceProvidersMiddleware>();
8089

8190
app.UseEndpoints(endpoints =>
8291
{
83-
endpoints.MapGrpcService<BenchmarkServiceImpl>();
92+
ConfigureAuthorization(endpoints.MapGrpcService<BenchmarkServiceImpl>());
8493

85-
endpoints.MapControllers();
94+
ConfigureAuthorization(endpoints.MapControllers());
8695

87-
endpoints.MapGet("/", context =>
96+
ConfigureAuthorization(endpoints.MapGet("/", context =>
8897
{
8998
return context.Response.WriteAsync("Benchmark Server");
90-
});
99+
}));
91100

92-
endpoints.MapPost("/unary", async context =>
101+
ConfigureAuthorization(endpoints.MapPost("/unary", async context =>
93102
{
94103
MemoryStream ms = new MemoryStream();
95104
await context.Request.Body.CopyToAsync(ms);
@@ -108,8 +117,17 @@ public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicat
108117

109118
ms.Seek(0, SeekOrigin.Begin);
110119
await ms.CopyToAsync(context.Response.Body);
111-
});
120+
}));
112121
});
113122
}
123+
124+
private void ConfigureAuthorization(IEndpointConventionBuilder builder)
125+
{
126+
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
127+
if (enableCertAuth)
128+
{
129+
builder.RequireAuthorization();
130+
}
131+
}
114132
}
115133
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
jobs:
2+
grpcAspNetCoreServer:
3+
source:
4+
repository: https://github.com/JamesNK/grpc-dotnet
5+
branchOrCommit: jamesnk/benchmarch-grpcclient
6+
project: perf/benchmarkapps/GrpcAspNetCoreServer/GrpcAspNetCoreServer.csproj
7+
readyStateText: Application started
8+
waitForExit: false
9+
variables:
10+
protocol: h2c
11+
enableCertAuth: false
12+
logLevel: None
13+
arguments: "--LogLevel {{logLevel}} --enableCertAuth {{enableCertAuth}} --protocol {{protocol}}"
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"urls": "",
33
"server.urls": "",
4-
"protocol": "h2c" // This will be overriden when benchmarks are run
4+
"protocol": "h2c", // This will be overriden when benchmarks are run
5+
"certificateAuth": false
56
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#region Copyright notice and license
2+
3+
// Copyright 2019 The gRPC Authors
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
#endregion
18+
19+
using System.Diagnostics.Tracing;
20+
21+
namespace GrpcClient
22+
{
23+
internal sealed class BenchmarksEventSource : EventSource
24+
{
25+
public static readonly BenchmarksEventSource Log = new BenchmarksEventSource();
26+
27+
internal BenchmarksEventSource()
28+
: this("Benchmarks")
29+
{
30+
31+
}
32+
33+
// Used for testing
34+
internal BenchmarksEventSource(string eventSourceName)
35+
: base(eventSourceName)
36+
{
37+
}
38+
39+
[Event(1, Level = EventLevel.Informational)]
40+
public void Measure(string name, long value)
41+
{
42+
WriteEvent(1, name, value);
43+
}
44+
45+
public static void Measure(string name, double value)
46+
{
47+
Log.MeasureDouble(name, value);
48+
}
49+
50+
public static void Measure(string name, string value)
51+
{
52+
Log.MeasureString(name, value);
53+
}
54+
55+
[Event(2, Level = EventLevel.Informational)]
56+
public void MeasureDouble(string name, double value)
57+
{
58+
WriteEvent(2, name, value);
59+
}
60+
61+
[Event(3, Level = EventLevel.Informational)]
62+
public void MeasureString(string name, string value)
63+
{
64+
WriteEvent(3, name, value);
65+
}
66+
67+
[Event(5, Level = EventLevel.Informational)]
68+
public void Metadata(string name, string aggregate, string reduce, string shortDescription, string longDescription, string format)
69+
{
70+
WriteEvent(5, name, aggregate, reduce, shortDescription, longDescription, format);
71+
}
72+
}
73+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
These certs are generated via openssl according to https://stackoverflow.com/questions/37714558/how-to-enable-server-side-ssl-for-grpc. The server.crt and server.key were combined into server.pfx. The password is 1111. These certs are not secure, do not use in production.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
-----BEGIN CERTIFICATE-----
2+
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
32+
-----END CERTIFICATE-----
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
Proc-Type: 4,ENCRYPTED
3+
DEK-Info: DES-EDE3-CBC,09834CF7C507C60B
4+
5+
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
54+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)