fix: align backend APIs and upload flow
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json;
|
||||
using IM.InitCommon.Management;
|
||||
using MySqlConnector;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace IM.Admin.Services;
|
||||
public sealed class HealthSampler(IConfiguration config, IServiceScopeFactory scopes)
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, DateTime> successes = new();
|
||||
public async Task<ServiceHealth[]> Read(CancellationToken ct)
|
||||
{
|
||||
using var scope = scopes.CreateScope(); var client = scope.ServiceProvider.GetRequiredService<InternalClient>();
|
||||
var tasks = new[] { "admin", "user", "contact", "group", "message", "file", "connector" }.Select(name => Check(name, async token => {
|
||||
var response = await client.Send<JsonElement>(name, "/internal/management/health", ct: token);
|
||||
if (response.GetProperty("status").GetString() != "healthy") throw new InvalidOperationException();
|
||||
return response.TryGetProperty("configVersion", out var version) ? version.GetInt64() : (long?)null;
|
||||
}, ct)).ToList();
|
||||
tasks.Add(Check("MySQL", async token => { await using var db = new MySqlConnection(config.GetConnectionString("Admin")); await db.OpenAsync(token); return null; }, ct));
|
||||
tasks.Add(Check("Redis", async token => { var options = ConfigurationOptions.Parse(config.GetConnectionString("Redis") ?? throw new InvalidOperationException()); options.ConnectTimeout = 2000; options.AbortOnConnectFail = true; using var redis = await ConnectionMultiplexer.ConnectAsync(options).WaitAsync(token); await redis.GetDatabase().PingAsync().WaitAsync(token); return null; }, ct));
|
||||
tasks.Add(Check("RabbitMQ(TCP)", async token => { using var tcp = new TcpClient(); await tcp.ConnectAsync(config["Management:RabbitHost"] ?? "rabbitmq", config.GetValue("Management:RabbitPort", 5672), token); return null; }, ct));
|
||||
tasks.Add(Check("Consul", async token => { using var http = new HttpClient(); using var response = await http.GetAsync((config["Management:ConsulUrl"] ?? throw new InvalidOperationException()).TrimEnd('/') + "/v1/status/leader", token); response.EnsureSuccessStatusCode(); return null; }, ct));
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
async Task<ServiceHealth> Check(string name, Func<CancellationToken, Task<long?>> check, CancellationToken ct)
|
||||
{
|
||||
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct); timeout.CancelAfter(TimeSpan.FromSeconds(3)); var sw = Stopwatch.StartNew();
|
||||
try { var version = await check(timeout.Token); var now = DateTime.UtcNow; successes[name] = now; return new(name, "healthy", Math.Round(sw.Elapsed.TotalMilliseconds), now, now, null, version); }
|
||||
catch { return new(name, "unavailable", null, DateTime.UtcNow, successes.TryGetValue(name, out var time) ? time : null, "连接或就绪检查失败,请检查服务日志"); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user