This commit is contained in:
xiaolipro 2024-10-06 11:09:15 +08:00
parent 276263f85b
commit 775256c128
8 changed files with 68 additions and 27 deletions

View File

@ -4,11 +4,11 @@
"commandName": "Project", "commandName": "Project",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SJZY.Expand.ABP.Core;SkyAPM.Agent.AspNetCore", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SJZY.Expand.ABP.Core",
"SKYWALKING__SERVICENAME": "Track" "SKYWALKING__SERVICENAME": "Track"
}, },
"dotnetRunMessages": true, "dotnetRunMessages": true,
"applicationUrl": "http://*:5054" "applicationUrl": "http://*:5056"
} }
}, },
"$schema": "https://json.schemastore.org/launchsettings.json" "$schema": "https://json.schemastore.org/launchsettings.json"

View File

@ -20,7 +20,7 @@
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="8.2.0"/> <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="8.2.0"/>
<PackageReference Include="DotNetCore.CAP.MySql" Version="8.2.0"/> <PackageReference Include="DotNetCore.CAP.MySql" Version="8.2.0"/>
<PackageReference Include="DotNetCore.CAP.InMemoryStorage" Version="8.2.0"/> <PackageReference Include="DotNetCore.CAP.InMemoryStorage" Version="8.2.0"/>
<PackageReference Include="SJZY.OTel" Version="1.0.0"/> <PackageReference Include="SJZY.OTel" Version="1.0.8"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Authorization;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
namespace SJZY.Track.Application.Services.DebugApis;
[AllowAnonymous]
[ApiExplorerSettings(GroupName = "调试专用")]
public class NormalService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
public NormalService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task<string> Hello(string name)
{
var order = await _orderRepository.GetFirstAsync(x => true);
if (order == null)
{
throw new BusinessException(message: "订单不存在");
}
return $"hello {name}";
}
}

View File

@ -3,6 +3,7 @@ using FreeRedis;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core;
using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.Forewarning; using SJZY.Track.Application.Contract.Dtos.Forewarning;
using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Application.Options; using SJZY.Track.Application.Options;
@ -90,14 +91,18 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
} }
var redisKey = GetForewarningNotifySetKeyRedisKey(dto.SubSystemId); var redisKey = GetForewarningNotifySetKeyRedisKey(dto.SubSystemId);
long addCounter, delCounter = 0; long addCounter = 0, delCounter = 0;
// 左区间加入预警队列,【只有第一次发生的才会被加入】 // 左区间加入预警队列,【只有第一次发生的才会被加入】
addCounter = await RedisHelper.Client.ZAddNxAsync(redisKey, adds.Select(x => var left = adds.Select(x =>
{ {
var entry = new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter); var entry = new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter);
return new ZMember(entry.ToString(), x.ts); return new ZMember(entry.ToString(), x.ts);
}).ToArray()); }).ToArray();
if (!left.IsNullOrEmpty())
{
addCounter = await RedisHelper.Client.ZAddNxAsync(redisKey, left);
}
// 右区间移出预警队列,【只要发生了就移除】 // 右区间移出预警队列,【只要发生了就移除】
var right = dels.Select(x => new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter)).ToList(); var right = dels.Select(x => new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter)).ToList();
@ -106,7 +111,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
delCounter = await RedisHelper.Client.ZRemAsync(redisKey, right.Select(x => x.ToString()).ToArray()); delCounter = await RedisHelper.Client.ZRemAsync(redisKey, right.Select(x => x.ToString()).ToArray());
} }
LogHelper.Info($"本次共计产生{addCounter}条预警,移除{delCounter}条预警,触发缘由是{dto}"); LogHelper.Info($"{nameof(ForewarningNotifyService)} 本次共计产生{addCounter}条预警,移除{delCounter}条预警,触发缘由是{dto}");
await _warningRecordEsRepository.BulkUpdateAsync(dels); // 标记处理完成 await _warningRecordEsRepository.BulkUpdateAsync(dels); // 标记处理完成
} }
@ -119,7 +124,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
if (set.IsNullOrEmpty()) if (set.IsNullOrEmpty())
{ {
LogHelper.Info("没有运输时效需要预警"); LogHelper.Info($"{nameof(ForewarningNotifyService)} 子系统:{subSystemId} 没有运输时效需要预警");
return 0; return 0;
} }
@ -174,7 +179,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
return warningRecords; return warningRecords;
} }
private Task SendCoreAsync(int subSystemId, List<WarningNotifyCacheEntry> entries, private async Task SendCoreAsync(int subSystemId, List<WarningNotifyCacheEntry> entries,
List<GetWarningNotifiesVo> notifyRules) List<GetWarningNotifiesVo> notifyRules)
{ {
var userRules = new Dictionary<int, List<GetWarningNotifiesVo>>(); var userRules = new Dictionary<int, List<GetWarningNotifiesVo>>();
@ -192,14 +197,16 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
} }
// 以人的维度发送通知,异步 // 以人的维度发送通知,异步
var tasks = new List<Task>();
foreach (var userRule in userRules) foreach (var userRule in userRules)
{ {
_ = DoNotifyAsync(subSystemId, userRule.Key, userRule.Value, entries, tasks.Add(DoNotifyAsync(subSystemId, userRule.Key, userRule.Value, entries, NotifyMode.SiteInternal));
NotifyMode.SiteInternal); tasks.Add(DoNotifyAsync(subSystemId, userRule.Key, userRule.Value, entries, NotifyMode.FeiShu));
_ = DoNotifyAsync(subSystemId, userRule.Key, userRule.Value, entries, NotifyMode.FeiShu);
} }
return Task.CompletedTask; // 等待所有任务完成
await Task.WhenAll(tasks);
} }
private string GetForewarningNotifySetKeyRedisKey(int subSystemId) => private string GetForewarningNotifySetKeyRedisKey(int subSystemId) =>
@ -266,7 +273,9 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
if (res.Code != GlobalConst.SuccessCode) if (res.Code != GlobalConst.SuccessCode)
{ {
LogHelper.Error($"发送{mode.ToString()}通知失败,用户:{userId},内容:{msgContent}"); // todo:失败是否上报重试?
LogHelper.Error(
$"{nameof(ForewarningNotifyService)} 发送{mode.ToString()}通知失败,用户:{userId},内容:\n{msgContent}\n失败报文:{res.ToJson()}");
} }
} }

View File

@ -67,6 +67,7 @@ public class ForewarningService : ApplicationService
/// </summary> /// </summary>
/// <param name="warningId"></param> /// <param name="warningId"></param>
/// <param name="statusQuery"></param> /// <param name="statusQuery"></param>
/// <param name="kpiAreaRepository"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("EditWarning")] [HttpGet("EditWarning")]
public async Task<EditWarningOutput> EditWarning(int warningId, public async Task<EditWarningOutput> EditWarning(int warningId,

View File

@ -14,6 +14,15 @@ namespace SJZY.Track.Application.Services.TimerTaskss;
[ApiExplorerSettings(GroupName = "定时任务")] [ApiExplorerSettings(GroupName = "定时任务")]
public class TrackWarningTask : ApplicationService public class TrackWarningTask : ApplicationService
{ {
private readonly IOptionsSnapshot<Track2InterfaceRelayOptions> _options;
private readonly IOrderRepository _orderRepository;
public TrackWarningTask(IOrderRepository orderRepository, IOptionsSnapshot<Track2InterfaceRelayOptions> options)
{
_orderRepository = orderRepository;
_options = options;
}
/// <summary> /// <summary>
/// 轨迹运输时效预警通知 /// 轨迹运输时效预警通知
/// </summary> /// </summary>
@ -22,29 +31,23 @@ public class TrackWarningTask : ApplicationService
[HttpPost("/TimerTask/SendWarning")] [HttpPost("/TimerTask/SendWarning")]
public async Task<bool> SendWarningForTaskAsync() public async Task<bool> SendWarningForTaskAsync()
{ {
using var serviceScope = LazyServiceProvider.CreateScope(); var configs = _options.Value;
var configs = serviceScope.ServiceProvider.GetRequiredService<IOptionsSnapshot<Track2InterfaceRelayOptions>>()
.Value;
if (configs == null || configs.Keys.Count == 0) if (configs == null || configs.Keys.Count == 0)
{ {
throw new BusinessException("未配置子系统"); throw new BusinessException("未配置子系统");
} }
var orderRepository = serviceScope.ServiceProvider.GetRequiredService<IOrderRepository>(); var subSystemIds = await _orderRepository.GetSubSystemListByCodesAsync(configs.Keys.ToList());
var subSystemIds = await orderRepository.GetSubSystemListByCodesAsync(configs.Keys.ToList());
foreach (var item in subSystemIds) foreach (var item in subSystemIds)
{ {
var ttl = configs[item.code].WarningNotifyInterval * 60; var ttl = configs[item.code].WarningNotifyInterval * 60;
await TrackWarningBySubSystemAsync(serviceScope, item.id, ttl); await TrackWarningBySubSystemAsync(item.id, ttl);
} }
await Task.Delay(1000); // life-time possible dispose
return true; return true;
} }
private async Task TrackWarningBySubSystemAsync(IServiceScope serviceScope, int subSystemId, int ttl) private async Task TrackWarningBySubSystemAsync(int subSystemId, int ttl)
{ {
// 如果已经发送过通知,不再发送 // 如果已经发送过通知,不再发送
var redisKey = $"{GlobalConst.ForewarningNotifyCheckKey}:{subSystemId}"; var redisKey = $"{GlobalConst.ForewarningNotifyCheckKey}:{subSystemId}";
@ -60,6 +63,8 @@ public class TrackWarningTask : ApplicationService
{ {
try try
{ {
using var serviceScope = LazyServiceProvider.CreateScope();
var forewarningNotifyService = var forewarningNotifyService =
serviceScope.ServiceProvider.GetRequiredService<IForewarningNotifyService>(); serviceScope.ServiceProvider.GetRequiredService<IForewarningNotifyService>();
var cnt = await forewarningNotifyService.SendNotificationAsync(subSystemId); var cnt = await forewarningNotifyService.SendNotificationAsync(subSystemId);

View File

@ -2,6 +2,5 @@ global using SJZY.Expand.ABP.Core;
global using SJZY.Expand.ABP.Core.Common.Dto; global using SJZY.Expand.ABP.Core.Common.Dto;
global using SJZY.Expand.ABP.Core.SqlSugar; global using SJZY.Expand.ABP.Core.SqlSugar;
global using SJZY.Expand.ABP.Core.SqlSugar.Entitys; global using SJZY.Expand.ABP.Core.SqlSugar.Entitys;
global using SJZY.Expand.ABP.Core.SqlSugar.Tools;
global using SqlSugar; global using SqlSugar;
global using Volo.Abp.DependencyInjection; global using Volo.Abp.DependencyInjection;

View File

@ -8,7 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="SJZY.LoggerCenter.HttpApi" Version="7.0.5" /> <PackageReference Include="SJZY.LoggerCenter.HttpApi" Version="7.0.5" />
<PackageReference Include="SJZY.OTel.Extension" Version="1.0.4"/> <PackageReference Include="SJZY.OTel.Extension" Version="1.0.6"/>
<PackageReference Include="Volo.Abp.Autofac" Version="7.0.2" /> <PackageReference Include="Volo.Abp.Autofac" Version="7.0.2" />
<PackageReference Include="SJZY.UserCenter.HttpApi" Version="3.0.9-alpha9"/> <PackageReference Include="SJZY.UserCenter.HttpApi" Version="3.0.9-alpha9"/>
</ItemGroup> </ItemGroup>