如何解决Azure 函数在“压力测试”中抛出 SimpleInjector.ActivationException
我们在基于消费计划的功能应用中有几个功能。当我使用 JMeter(同时 200 个线程)对这些函数进行压力测试时,这些函数在大约 50% 的时间内抛出 SimpleInjector.ActivationException。并非所有请求都失败。
我不明白为什么这仅适用于部分请求。
调用栈:
2021-07-06T08:43:41.159 [错误] Er is een 问题 opgetreden
SimpleInjector.ActivationException:GetLocalKeyDataByDateQueryHandler 类型的构造函数包含名称为“queryValidator”且类型为 IValidator 的参数,但 IValidator 未注册。要解析 IValidator,它必须在 SimpleInjector.Container.ThrowParameterTypeMustBeRegistered(InjectionTargetInfo target)at SimpleInjector.Advanced.DefaultDependencyInjectionBehavior.GetInstanceProducer(InjectionConsumerInfo dependency,Boolean throwOnFailure)at SimpleInjector.ContainerOptions.GetInjectInstanceProducerat SimpleInjector.Registration.BuildConstructorParameters(ConstructorInfo constructor)at SimpleInjector.Registration.BuildNewExpression()at SimpleInjector.Registration.BuildTransientExpression()at SimpleInjector.Registration.BuildTransientDelegate()at SimpleInjector.Lifestyles.ScopedRegistration.BuildExpression()at SimpleInjector.BuildTransientInternal() )at SimpleInjector.Internals.LazyEx`1.InitializeAndReturn()at SimpleInjector.InstanceProducer.BuildInstanceCreator()at SimpleInjector.InstanceProducer.BuildAndReplaceInstanceCreatorAndCreateFirstInstance()at SimpleInjector.InstanceProducer。 GetInstance()at SimpleInjector.Container.GetInstanceTServiceat async ProRail.PUIC2.Web.Functions.GetPuicDataByChangeDate.Run(GetPuicDataByDate inputParams,ILogger logger,ExecutionContext context) at D:\a\1\s\Src\Web\ProRail.PUIC2.Web .Functions\Functions\GetPuicDataByChangeDate.cs:35
功能:
public class GetPuicDataByLocalKey
{
[FunctionName("GetPuicDataByLocalKey")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous,"post",Route = null)]
Models.GetPuicDataByLocalKey queryInput,ExecutionContext context)
{
var container = DependencyInjection.GetContainerInstance(context);
await using (AsyncScopedLifestyle.BeginScope(container))
{
var loggingUtils = container.GetInstance<ILoggingUtils>();
try
{
logger.LogTrace(loggingUtils.MethodBegin);
container.GetInstance<Configuration.ILoggerFactory>().SetLogger(logger);
var queryHandler = container.GetInstance<IQueryHandler<GetPuicDataQuery,IEnumerable<PuicData>>>();
var results = await queryHandler.Handle(new GetPuicDataQuery
{
Source = queryInput.source,DateValid = queryInput.DateValid,Localkeyvalues = queryInput.Localkeyvalues.Select(lkv => new Core.Entities.Data.keyvalue
{
Key = lkv.Key,Value = lkv.Value
})
});
if (results == null)
{
return new JsonResult(Enumerable.Empty<Models.PuicData>());
}
// Get local keys grouped by Puic
var puicDataList = results.GroupBy(l => l.Puic).Select(g => PuicDataConverter.Convert(g));
return new JsonResult(puicDataList);
}
catch (PuicException e)
{
logger.LogError(e,"Data is waarschijnlijk niet goed");
return new BadRequestErrorMessageResult(e.Message);
}
catch (Exception e)
{
logger.LogError(e,"Er is een probleem opgetreden");
return new InternalServerErrorResult();
}
finally
{
logger.LogTrace(loggingUtils.MethodEnd);
}
}
}
}
容器配置
public static class DependencyInjection
{
private static Container containerInstance = null;
public static Container GetContainerInstance(ExecutionContext context)
{
if (containerInstance == null)
{
containerInstance = new Container();
containerInstance.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
InitializeConfiguration(containerInstance,context);
RegisterSimpleTypes(containerInstance);
RegisterQueryHandlers(containerInstance);
RegisterCommandHandlers(containerInstance);
RegisterValidators(containerInstance);
RegisterDatabaseTypes(containerInstance);
}
return containerInstance;
}
[...]
private static void RegisterQueryHandlers(Container container)
{
var businessLogicAssembly = typeof(GetUsersQuery).Assembly;
container.Register(typeof(IQueryHandler<,>),businessLogicAssembly,Lifestyle.Scoped);
}
[...]
}
解决方法
您的代码似乎存在多线程问题; @client.command()
@commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True)
async def ban(ctx,member: discord.Member=None,*,reason=None):
if not member:
await ctx.send("**Please specify a `user`.**")
return
if reason==None:
return await ctx.send("**Please include a** **`valid reason`.**")
if member == ctx.message.author:
return await ctx.send("**You cannot ban** **`yourself`**.")
await member.ban(reason=None)
await ctx.channel.send(f"****Banned**** **`{member}`** **for the following reason :** **`{reason}` **")
await member.send(f"you have been banned from: {ctx.guild.name}")
@ban.error
async def banerror(ctx,error):
error = getattr(error,"original",error)
if isinstance(error,discord.Forbidden):
return await ctx.send("**I don't have the permsission `ban members`.**")
@ban.error
async def ban_error(ctx,error):
if isinstance(error,commands.MissingPermissions):
embed=discord.Embed(color=0xff8800)
embed.add_field(name="Access denied",value="You do not have permission to ban members :no_entry:",inline=True)
await ctx.send(embed=embed)
方法。
DependencyInjection.GetContainerInstance
可能会在并行调用时创建许多 GetContainerInstance
实例,最终 Container
实例的配置将不确定。
要解决此问题,您必须同步容器的创建。有很多方法可以做到这一点,但例如,您可以试试这个:
Container
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。