添加健康检查
This commit is contained in:
parent
ed750f66b6
commit
7dd26dc89b
@ -24,7 +24,6 @@ namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_protocolInfoRepository = serviceProvider.GetRequiredService<IRepository<ProtocolInfo, Guid>>();
|
_protocolInfoRepository = serviceProvider.GetRequiredService<IRepository<ProtocolInfo, Guid>>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
namespace JiShe.CollectBus.Host
|
namespace JiShe.CollectBus.Host
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CollectBusHostConst
|
||||||
|
/// </summary>
|
||||||
public static class CollectBusHostConst
|
public static class CollectBusHostConst
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -23,9 +26,15 @@
|
|||||||
public const string HangfireDashboardEndPoint = "/hangfire";
|
public const string HangfireDashboardEndPoint = "/hangfire";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CAP 端点
|
/// 健康检查 端点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CapDashboardEndPoint = "/cap";
|
public const string HealthEndPoint = "/health";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 健康检查 端点
|
||||||
|
/// </summary>
|
||||||
|
public const string HealthDashboardEndPoint = "/health-ui";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.Redis.StackExchange;
|
using Hangfire.Redis.StackExchange;
|
||||||
using JiShe.CollectBus.Host.Hangfire;
|
using JiShe.CollectBus.Host.Hangfire;
|
||||||
|
using JiShe.CollectBus.Host.HealthChecks;
|
||||||
using JiShe.CollectBus.Host.Swaggers;
|
using JiShe.CollectBus.Host.Swaggers;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
@ -16,6 +17,9 @@ using Volo.Abp.Modularity;
|
|||||||
using TouchSocket.Core;
|
using TouchSocket.Core;
|
||||||
using TouchSocket.Sockets;
|
using TouchSocket.Sockets;
|
||||||
using JiShe.CollectBus.Plugins;
|
using JiShe.CollectBus.Plugins;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
using JiShe.CollectBus.Cassandra;
|
||||||
|
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Host
|
namespace JiShe.CollectBus.Host
|
||||||
@ -206,7 +210,6 @@ namespace JiShe.CollectBus.Host
|
|||||||
private void ConfigureCustom(ServiceConfigurationContext context, IConfiguration configuration)
|
private void ConfigureCustom(ServiceConfigurationContext context, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
context.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
context.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
context.Services.AddHealthChecks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -241,5 +244,37 @@ namespace JiShe.CollectBus.Host
|
|||||||
.SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter());
|
.SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 健康检查
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="configuration"></param>
|
||||||
|
private void ConfigureHealthChecks(ServiceConfigurationContext context, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
if (!configuration.GetValue<bool>("HealthChecks:IsEnable")) return;
|
||||||
|
var cassandraConfig = new CassandraConfig();
|
||||||
|
configuration.GetSection("Cassandra").Bind(cassandraConfig);
|
||||||
|
context.Services.AddHealthChecks()
|
||||||
|
.AddMongoDb(configuration.GetConnectionString("Default"), "MongoDB", HealthStatus.Unhealthy)
|
||||||
|
.AddRedis(configuration.GetValue<string>("Redis:Configuration") ?? string.Empty, "Redis",
|
||||||
|
HealthStatus.Unhealthy)
|
||||||
|
.AddKafka(new Confluent.Kafka.ProducerConfig
|
||||||
|
{
|
||||||
|
BootstrapServers = configuration.GetConnectionString("Kafka")
|
||||||
|
}, "Kafka", failureStatus: HealthStatus.Unhealthy)
|
||||||
|
|
||||||
|
.AddCheck<CassandraHealthCheck>("Cassandra")
|
||||||
|
.AddCheck<IoTdbHealthCheck>("IoTDB");
|
||||||
|
|
||||||
|
context.Services
|
||||||
|
.AddHealthChecksUI(options =>
|
||||||
|
{
|
||||||
|
options.AddHealthCheckEndpoint("JiSheCollectBus", "/health"); // 映射本地端点
|
||||||
|
})
|
||||||
|
.AddInMemoryStorage();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
|
using HealthChecks.UI.Client;
|
||||||
using JiShe.CollectBus.Host.Extensions;
|
using JiShe.CollectBus.Host.Extensions;
|
||||||
using JiShe.CollectBus.Host.HealthChecks;
|
using JiShe.CollectBus.Host.HealthChecks;
|
||||||
using JiShe.CollectBus.Host.Swaggers;
|
using JiShe.CollectBus.Host.Swaggers;
|
||||||
@ -45,9 +46,9 @@ namespace JiShe.CollectBus.Host
|
|||||||
ConfigureNetwork(context, configuration);
|
ConfigureNetwork(context, configuration);
|
||||||
ConfigureJwtAuthentication(context, configuration);
|
ConfigureJwtAuthentication(context, configuration);
|
||||||
ConfigureHangfire(context);
|
ConfigureHangfire(context);
|
||||||
//ConfigureKafkaTopic(context, configuration);
|
|
||||||
ConfigureAuditLog(context);
|
ConfigureAuditLog(context);
|
||||||
ConfigureCustom(context, configuration);
|
ConfigureCustom(context, configuration);
|
||||||
|
ConfigureHealthChecks(context, configuration);
|
||||||
Configure<AbpClockOptions>(options => { options.Kind = DateTimeKind.Local; });
|
Configure<AbpClockOptions>(options => { options.Kind = DateTimeKind.Local; });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,11 +90,16 @@ namespace JiShe.CollectBus.Host
|
|||||||
});
|
});
|
||||||
app.UseConfiguredEndpoints(endpoints =>
|
app.UseConfiguredEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
|
if (!configuration.GetValue<bool>("HealthChecks:IsEnable")) return;
|
||||||
endpoints.MapHealthChecks("/health", new HealthCheckOptions
|
endpoints.MapHealthChecks("/health", new HealthCheckOptions
|
||||||
{
|
{
|
||||||
Predicate = _ => true,
|
Predicate = _ => true,
|
||||||
ResponseWriter = HealthCheckResponse.Writer
|
ResponseWriter = HealthCheckResponse.Writer
|
||||||
});
|
});
|
||||||
|
endpoints.MapHealthChecksUI(options =>
|
||||||
|
{
|
||||||
|
options.UIPath = "/health-ui";
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
using Cassandra;
|
||||||
|
using JiShe.CollectBus.Cassandra;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
|
||||||
|
namespace JiShe.CollectBus.Host.HealthChecks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CassandraHealthCheck
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck" />
|
||||||
|
public class CassandraHealthCheck : IHealthCheck
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CassandraHealthCheck"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configuration">The configuration.</param>
|
||||||
|
public CassandraHealthCheck(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the health check, returning the status of the component being checked.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">A context object associated with the current execution.</param>
|
||||||
|
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> that can be used to cancel the health check.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="T:System.Threading.Tasks.Task`1" /> that completes when the health check has finished, yielding the status of the component being checked.
|
||||||
|
/// </returns>
|
||||||
|
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var cassandraConfig = new CassandraConfig();
|
||||||
|
_configuration.GetSection("Cassandra").Bind(cassandraConfig);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var clusterBuilder = Cluster.Builder();
|
||||||
|
foreach (var node in cassandraConfig.Nodes)
|
||||||
|
{
|
||||||
|
clusterBuilder.AddContactPoint(node.Host)
|
||||||
|
.WithPort(node.Port);
|
||||||
|
}
|
||||||
|
clusterBuilder.WithCredentials(cassandraConfig.Username, cassandraConfig.Password);
|
||||||
|
var cluster = clusterBuilder.Build();
|
||||||
|
using var session = await cluster.ConnectAsync();
|
||||||
|
var result = await Task.FromResult(session.Execute("SELECT release_version FROM system.local"));
|
||||||
|
var version = result.First().GetValue<string>("release_version");
|
||||||
|
return HealthCheckResult.Healthy($"Cassandra is healthy. Version: {version}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HealthCheckResult(context.Registration.FailureStatus, $"Cassandra is unhealthy: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
web/JiShe.CollectBus.Host/HealthChecks/IoTDBHealthCheck.cs
Normal file
51
web/JiShe.CollectBus.Host/HealthChecks/IoTDBHealthCheck.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System.Net.Sockets;
|
||||||
|
using JiShe.CollectBus.Cassandra;
|
||||||
|
using JiShe.CollectBus.IoTDB.Interface;
|
||||||
|
using JiShe.CollectBus.IoTDB.Options;
|
||||||
|
using JiShe.CollectBus.IoTDB.Provider;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
|
||||||
|
namespace JiShe.CollectBus.Host.HealthChecks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IoTDBHealthCheck
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck" />
|
||||||
|
public class IoTdbHealthCheck : IHealthCheck
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="IoTdbHealthCheck"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configuration">The configuration.</param>
|
||||||
|
public IoTdbHealthCheck(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the health check, returning the status of the component being checked.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">A context object associated with the current execution.</param>
|
||||||
|
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> that can be used to cancel the health check.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="T:System.Threading.Tasks.Task`1" /> that completes when the health check has finished, yielding the status of the component being checked.
|
||||||
|
/// </returns>
|
||||||
|
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ioTDbOptions = new IoTDbOptions();
|
||||||
|
_configuration.GetSection("IoTDBOptions").Bind(ioTDbOptions);
|
||||||
|
var pool = new SessionPoolAdapter(ioTDbOptions);
|
||||||
|
await pool.OpenAsync();
|
||||||
|
return HealthCheckResult.Healthy($"IoTDB is healthy.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HealthCheckResult(context.Registration.FailureStatus, $"IoTDB不健康: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,9 +20,14 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.Kafka" Version="9.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="8.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="9.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="9.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="9.0.0" />
|
||||||
|
|
||||||
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.9.4" />
|
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.9.4" />
|
||||||
<PackageReference Include="MassTransit" Version="8.4.0" />
|
|
||||||
<PackageReference Include="MassTransit.Kafka" Version="8.4.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" />
|
||||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||||
|
|||||||
@ -11,59 +11,59 @@
|
|||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet"/>
|
<link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
<title>后端服务</title>
|
<title>后端服务</title>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="container projects">
|
|
||||||
<div class="projects-header page-header">
|
|
||||||
<h2>后端服务列表</h2>
|
|
||||||
@* <p>这些项目或者是对Bootstrap进行了有益的补充,或者是基于Bootstrap开发的</p> *@
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
|
||||||
<div class="thumbnail" style="height: 180px">
|
|
||||||
<a href="@CollectBusHostConst.SwaggerUiEndPoint" target="_blank">
|
|
||||||
<img class="lazy" src="/images/swagger.png" width="300" height="150"/>
|
|
||||||
</a>
|
|
||||||
<div class="caption">
|
|
||||||
<h3>
|
|
||||||
<a href="@CollectBusHostConst.SwaggerUiEndPoint" target="_blank">SwaggerUI</a>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
<body>
|
||||||
<div class="thumbnail" style="height: 180px">
|
<div class="container projects">
|
||||||
<a href="@CollectBusHostConst.HangfireDashboardEndPoint" target="_blank">
|
<div class="projects-header page-header">
|
||||||
<img class="lazy" src="/images/hangfire.png" width="300" height="150"/>
|
<h2>后端服务列表</h2>
|
||||||
</a>
|
@* <p>这些项目或者是对Bootstrap进行了有益的补充,或者是基于Bootstrap开发的</p> *@
|
||||||
<div class="caption">
|
</div>
|
||||||
<h3>
|
<div class="row">
|
||||||
<a href="@CollectBusHostConst.HangfireDashboardEndPoint" target="_blank">Hangfire面板</a>
|
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||||
</h3>
|
<div class="thumbnail" style="height: 180px">
|
||||||
|
<a href="@CollectBusHostConst.SwaggerUiEndPoint" target="_blank">
|
||||||
|
<img class="lazy" src="/images/swagger.png" width="300" height="150" />
|
||||||
|
</a>
|
||||||
|
<div class="caption">
|
||||||
|
<h3>
|
||||||
|
<a href="@CollectBusHostConst.SwaggerUiEndPoint" target="_blank">SwaggerUI</a>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||||
<div class="thumbnail" style="height: 180px">
|
<div class="thumbnail" style="height: 180px">
|
||||||
<a href="@CollectBusHostConst.CapDashboardEndPoint" target="_blank">
|
<a href="@CollectBusHostConst.HangfireDashboardEndPoint" target="_blank">
|
||||||
<img class="lazy" src="/images/cap.png" width="300" height="150"/>
|
<img class="lazy" src="/images/hangfire.png" width="300" height="150" />
|
||||||
</a>
|
</a>
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<h3>
|
<h3>
|
||||||
<a href="@CollectBusHostConst.CapDashboardEndPoint" target="_blank">CAP</a>
|
<a href="@CollectBusHostConst.HangfireDashboardEndPoint" target="_blank">Hangfire面板</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||||
@* <div class="col-sm-6 col-md-4 col-lg-3">
|
<div class="thumbnail" style="height: 180px">
|
||||||
|
<a href="@CollectBusHostConst.HealthDashboardEndPoint" target="_blank">
|
||||||
|
<img class="lazy" src="/images/hangfire.png" width="300" height="150" />
|
||||||
|
</a>
|
||||||
|
<div class="caption">
|
||||||
|
<h3>
|
||||||
|
<a href="@CollectBusHostConst.HealthEndPoint" target="_blank">健康检查API</a> |
|
||||||
|
<a href="@CollectBusHostConst.HealthDashboardEndPoint" target="_blank">UI</a>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* <div class="col-sm-6 col-md-4 col-lg-3">
|
||||||
<div class="thumbnail" style="height: 180px">
|
<div class="thumbnail" style="height: 180px">
|
||||||
<a href="@CollectBusHostConst.MoreEndPoint" target="_blank">
|
<a href="@CollectBusHostConst.MoreEndPoint" target="_blank">
|
||||||
<img class="lazy" src="/images/more.png" width="300" height="150"/>
|
<img class="lazy" src="/images/more.png" width="300" height="150"/>
|
||||||
@ -75,99 +75,113 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> *@
|
</div> *@
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<style>
|
<style>
|
||||||
*:before,
|
*:before,
|
||||||
*:after {
|
*:after {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.container {
|
|
||||||
width: 1170px;
|
|
||||||
padding-right: 15px;
|
|
||||||
padding-left: 15px;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
.projects-header {
|
|
||||||
width: 60%;
|
|
||||||
text-align: center;
|
|
||||||
font-weight: 200;
|
|
||||||
display: block;
|
|
||||||
margin: 60px auto 40px !important;
|
|
||||||
}
|
|
||||||
.page-header {
|
|
||||||
padding-bottom: 9px;
|
|
||||||
margin: 40px auto;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.projects-header h2 {
|
|
||||||
font-size: 42px;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: inherit;
|
|
||||||
/* text-align: center; */
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 0 0 10px;
|
|
||||||
}
|
|
||||||
.row {
|
|
||||||
margin-right: -15px;
|
|
||||||
margin-left: -15px;
|
|
||||||
}
|
|
||||||
.col-lg-3 {
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
.projects .thumbnail {
|
|
||||||
display: block;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.thumbnail {
|
|
||||||
display: block;
|
|
||||||
padding: 4px;
|
|
||||||
line-height: 1.42857143;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
.transition(border 0.2s ease-in-out);
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #337ab7;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
.projects .thumbnail img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
.thumbnail a > img,
|
|
||||||
.thumbnail > img {
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
/* .projects .thumbnail .caption {
|
|
||||||
overflow-y: hidden;
|
|
||||||
color: #555;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.caption {
|
.container {
|
||||||
padding: 9px;
|
width: 1170px;
|
||||||
overflow-y: hidden;
|
padding-right: 15px;
|
||||||
color: #555;
|
padding-left: 15px;
|
||||||
}
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.projects-header {
|
||||||
|
width: 60%;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 200;
|
||||||
|
display: block;
|
||||||
|
margin: 60px auto 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
padding-bottom: 9px;
|
||||||
|
margin: 40px auto;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.projects-header h2 {
|
||||||
|
font-size: 42px;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.1;
|
||||||
|
color: inherit;
|
||||||
|
/* text-align: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-right: -15px;
|
||||||
|
margin-left: -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-lg-3 {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.projects .thumbnail {
|
||||||
|
display: block;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
display: block;
|
||||||
|
padding: 4px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
.transition(border 0.2s ease-in-out);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #337ab7;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.projects .thumbnail img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail a > img,
|
||||||
|
.thumbnail > img {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
/* .projects .thumbnail .caption {
|
||||||
|
overflow-y: hidden;
|
||||||
|
color: #555;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
padding: 9px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -4,6 +4,7 @@ namespace JiShe.CollectBus.Host.Pages
|
|||||||
{
|
{
|
||||||
public class Monitor : PageModel
|
public class Monitor : PageModel
|
||||||
{
|
{
|
||||||
|
|
||||||
public void OnGet()
|
public void OnGet()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
using JiShe.CollectBus.Host;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Volo.Abp.Modularity.PlugIns;
|
using Volo.Abp.Modularity.PlugIns;
|
||||||
|
|
||||||
|
namespace JiShe.CollectBus.Host;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Program
|
||||||
|
/// </summary>
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Main
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -19,47 +23,13 @@ public class Program
|
|||||||
loggerConfiguration.ReadFrom.Configuration(context.Configuration);
|
loggerConfiguration.ReadFrom.Configuration(context.Configuration);
|
||||||
})
|
})
|
||||||
.UseAutofac();
|
.UseAutofac();
|
||||||
|
var configuration = builder.Configuration;
|
||||||
await builder.AddApplicationAsync<CollectBusHostModule>(options =>
|
await builder.AddApplicationAsync<CollectBusHostModule>(options =>
|
||||||
{
|
{
|
||||||
// 加载插件,固定模式,可热插拔
|
options.PlugInSources.AddFolder((configuration["PlugInFolder"].IsNullOrWhiteSpace()? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"): configuration["PlugInFolder"]) ?? string.Empty);
|
||||||
options.PlugInSources.AddFolder(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"));
|
|
||||||
});
|
});
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
await app.InitializeApplicationAsync();
|
await app.InitializeApplicationAsync();
|
||||||
await app.RunAsync();
|
await app.RunAsync();
|
||||||
|
|
||||||
|
|
||||||
//await CreateHostBuilder(args).Build().RunAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
||||||
Host.CreateDefaultBuilder(args)
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseSerilog((context, loggerConfiguration) =>
|
|
||||||
{
|
|
||||||
loggerConfiguration.ReadFrom.Configuration(context.Configuration);
|
|
||||||
})
|
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
|
||||||
{
|
|
||||||
webBuilder.UseStartup<Startup>();
|
|
||||||
})
|
|
||||||
.UseAutofac();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static IHostBuilder CreateConsoleHostBuilder(string[] args) =>
|
|
||||||
Host.CreateDefaultBuilder(args)
|
|
||||||
.ConfigureServices((hostContext, services) => { ConfigureServices(services, hostContext); })
|
|
||||||
.UseAutofac()
|
|
||||||
.UseSerilog((context, loggerConfiguration) =>
|
|
||||||
{
|
|
||||||
loggerConfiguration.ReadFrom.Configuration(context.Configuration);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
private static async Task ConfigureServices(IServiceCollection services, HostBuilderContext hostContext)
|
|
||||||
{
|
|
||||||
await services.AddApplicationAsync<CollectBusHostModule>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,53 +0,0 @@
|
|||||||
using TouchSocket.Core;
|
|
||||||
using Volo.Abp.Modularity.PlugIns;
|
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Host
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Startup
|
|
||||||
/// </summary>
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Startup"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration">The configuration.</param>
|
|
||||||
public Startup(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configures the services.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">The services.</param>
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddApplication<CollectBusHostModule>(options =>
|
|
||||||
{
|
|
||||||
// 加载插件,固定模式,可热插拔
|
|
||||||
options.PlugInSources.AddFolder(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configures the specified application.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="app">The application.</param>
|
|
||||||
/// <param name="lifetime">The lifetime.</param>
|
|
||||||
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime)
|
|
||||||
{
|
|
||||||
|
|
||||||
app.Use(async (context, next) =>
|
|
||||||
{
|
|
||||||
// 在请求处理之前调用 InitializeApplicationAsync
|
|
||||||
await app.InitializeApplicationAsync();
|
|
||||||
|
|
||||||
// 继续请求管道中的下一个中间件
|
|
||||||
await next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -51,16 +51,11 @@
|
|||||||
"Issuer": "JiShe.CollectBus",
|
"Issuer": "JiShe.CollectBus",
|
||||||
"ExpirationTime": 2
|
"ExpirationTime": 2
|
||||||
},
|
},
|
||||||
"HealthCheck": {
|
"HealthChecks": {
|
||||||
"IsEnable": true,
|
"IsEnable": true,
|
||||||
"MySql": {
|
"HealthCheckDatabaseName": "HealthChecks",
|
||||||
"IsEnable": true
|
"EvaluationTimeInSeconds": 10,
|
||||||
},
|
"MinimumSecondsBetweenFailureNotifications": 60
|
||||||
"Pings": {
|
|
||||||
"IsEnable": true,
|
|
||||||
"Host": "https://www.baidu.com/",
|
|
||||||
"TimeOut": 5000
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"SwaggerConfig": [
|
"SwaggerConfig": [
|
||||||
{
|
{
|
||||||
@ -84,7 +79,7 @@
|
|||||||
"SaslPassword": "lixiao1980",
|
"SaslPassword": "lixiao1980",
|
||||||
"KafkaReplicationFactor": 3,
|
"KafkaReplicationFactor": 3,
|
||||||
"NumPartitions": 30,
|
"NumPartitions": 30,
|
||||||
"ServerTagName": "JiSheCollectBus99",
|
"ServerTagName": "JiSheCollectBus30",
|
||||||
"FirstCollectionTime": "2025-04-22 16:07:00"
|
"FirstCollectionTime": "2025-04-22 16:07:00"
|
||||||
},
|
},
|
||||||
"IoTDBOptions": {
|
"IoTDBOptions": {
|
||||||
@ -95,7 +90,7 @@
|
|||||||
"DataBaseName": "energy",
|
"DataBaseName": "energy",
|
||||||
"OpenDebugMode": false,
|
"OpenDebugMode": false,
|
||||||
"UseTableSessionPoolByDefault": false
|
"UseTableSessionPoolByDefault": false
|
||||||
},
|
},
|
||||||
"Cassandra": {
|
"Cassandra": {
|
||||||
"ReplicationStrategy": {
|
"ReplicationStrategy": {
|
||||||
"Class": "NetworkTopologyStrategy", //策略为NetworkTopologyStrategy时才会有多个数据中心,SimpleStrategy用在只有一个数据中心的情况下
|
"Class": "NetworkTopologyStrategy", //策略为NetworkTopologyStrategy时才会有多个数据中心,SimpleStrategy用在只有一个数据中心的情况下
|
||||||
@ -144,5 +139,6 @@
|
|||||||
"SerialConsistencyLevel": "Serial",
|
"SerialConsistencyLevel": "Serial",
|
||||||
"DefaultIdempotence": true
|
"DefaultIdempotence": true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"PlugInFolder": ""
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user