fix(scadabridge): default MetricsPort to 8084 (avoid site RemotingPort collision) + validate port distinctness
This commit is contained in:
@@ -20,6 +20,11 @@ public class NodeOptions
|
||||
public int RemotingPort { get; set; } = 8081;
|
||||
/// <summary>Gets or sets the gRPC port for the site stream server.</summary>
|
||||
public int GrpcPort { get; set; } = 8083;
|
||||
/// <summary>HTTP/1.1 port serving the Prometheus /metrics scrape endpoint on site nodes.</summary>
|
||||
public int MetricsPort { get; set; } = 8082;
|
||||
/// <summary>
|
||||
/// HTTP/1.1 port serving the Prometheus /metrics scrape endpoint on site nodes.
|
||||
/// Defaults to 8084 — deliberately distinct from <see cref="RemotingPort"/> (8082)
|
||||
/// and <see cref="GrpcPort"/> (8083) so the Kestrel metrics listener never contends
|
||||
/// with the Akka remoting port a site node binds.
|
||||
/// </summary>
|
||||
public int MetricsPort { get; set; } = 8084;
|
||||
}
|
||||
|
||||
@@ -293,10 +293,12 @@ try
|
||||
// Read GrpcPort from config (NodeOptions already has default 8083)
|
||||
var grpcPort = configuration.GetValue<int>("ScadaBridge:Node:GrpcPort", 8083);
|
||||
|
||||
// Read MetricsPort from config (NodeOptions already has default 8082).
|
||||
// Read MetricsPort from config (NodeOptions already has default 8084).
|
||||
// Separate HTTP/1.1 listener so a standard HTTP/1.1 Prometheus scraper can
|
||||
// reach /metrics; the gRPC port stays HTTP/2-only below.
|
||||
var metricsPort = configuration.GetValue<int>("ScadaBridge:Node:MetricsPort", 8082);
|
||||
// reach /metrics; the gRPC port stays HTTP/2-only below. The default is
|
||||
// 8084 — distinct from RemotingPort (8082, Akka) and GrpcPort (8083) so the
|
||||
// metrics listener never collides with the Akka remoting port on site nodes.
|
||||
var metricsPort = configuration.GetValue<int>("ScadaBridge:Node:MetricsPort", 8084);
|
||||
|
||||
// Configure Kestrel for HTTP/2 only on the gRPC port
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
|
||||
@@ -58,6 +58,21 @@ public static class StartupValidator
|
||||
if (port == grpcPort)
|
||||
errors.Add("ScadaBridge:Node:GrpcPort must differ from RemotingPort");
|
||||
|
||||
var metricsPortStr = nodeSection["MetricsPort"];
|
||||
int metricsPort = 8084; // NodeOptions default when the key is absent
|
||||
if (metricsPortStr != null && (!int.TryParse(metricsPortStr, out metricsPort) || metricsPort < 1 || metricsPort > 65535))
|
||||
errors.Add("ScadaBridge:Node:MetricsPort must be 1-65535");
|
||||
|
||||
// Host-007 / REQ-HOST-4: the Kestrel metrics (HTTP/1.1) listener port
|
||||
// must differ from BOTH the Akka remoting port and the gRPC port.
|
||||
// A collision makes the metrics listener contend with Akka.Remote or
|
||||
// the gRPC listener for the same TCP port and fail opaquely at runtime.
|
||||
// Uses the resolved MetricsPort, including the 8084 default.
|
||||
if (metricsPort == port)
|
||||
errors.Add("ScadaBridge:Node:MetricsPort must differ from RemotingPort");
|
||||
if (metricsPort == grpcPort)
|
||||
errors.Add("ScadaBridge:Node:MetricsPort must differ from GrpcPort");
|
||||
|
||||
var dbSection = configuration.GetSection("ScadaBridge:Database");
|
||||
if (string.IsNullOrEmpty(dbSection["SiteDbPath"]))
|
||||
errors.Add("ScadaBridge:Database:SiteDbPath required for Site nodes");
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"SiteId": "site-a",
|
||||
"RemotingPort": 8082,
|
||||
"GrpcPort": 8083,
|
||||
"MetricsPort": 8084,
|
||||
"NodeName": "node-a"
|
||||
},
|
||||
"Cluster": {
|
||||
|
||||
Reference in New Issue
Block a user