ABP 6.4 Angular .NET 5
Hi,
I'm using zero for a while now and the journey for getting a performant app is quite hard :) As the trafic grows, I had to switch SignalR from self hosted to dedicated service. I also had to configure app scaling according to trafic load. I'm running on Azure and my app is currently scaling out to 2 or 3 instances.
Multi-instances means also cache issues... then I switch MemoryCache to RedisCache. Every thing works as expected on production but the app is, at least, two times slower when it comes to get information from cache. GetAll method access as increased a lot...
I've followed all previous post about Redis performance and AbpPerRequestRedisCache.
Should I use AbpPerRequestRedisCache for the entire project ? What happens if a tenant setting is changed in one instance ? The other instances will not be aware of it and will use invalid data no ?
I've tried to test it by following the docs : https://aspnetboilerplate.com/Pages/Documents/PerRequestRedisCache I was able to download nuget package and add [DependsOn(typeof(AbpAspNetCorePerRequestRedisCacheModule))] but I don't found the way to activate option usePerRequestRedisCache to true
Configuration.Caching.UseRedis(usePerRequestRedisCache: true);
How can I activate it ?
Sorry for all that questions but app performance is really sensitive for all users
6 Answer(s)
-
0
Hi @ricavir
Yes, for performance purposes, we suggest using AbpPerRequestRedisCache. This class only caches the values during a request. So, if the value of a cache item is changed in another instance. It will be used for the next HTTP reqeust, so it will not be a problem.
UsePerRequestRedisCache is currently available in ABP 6.6 and 7.0-rc.1.
-
0
Hi @ismcagdas,
Tks for your quick answer. I will do it.
-
0
Hi @ismcagdas,
I've updated the project to Abp 6.6 to test redis usePerRequestRedisCache option. When I activate redis with this option, I'm getting an Internal Server Error :
ERROR 2021-11-30 18:23:14,135 [36 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'. System.InvalidCastException: Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'. at Abp.Runtime.Caching.TypedCacheWrapper`2.Get(TKey key, Func`2 factory) at Abp.Runtime.Caching.TypedCacheExtensions.Get[TKey,TValue](ITypedCache`2 cache, TKey key, Func`1 factory) at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionaryFromCache(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionary(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetLanguages(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetActiveLanguages(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageProvider.GetActiveLanguages() at Abp.Localization.LanguageManager.GetActiveLanguages() at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserLocalizationConfig() at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll() at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll() at lambda_method1396(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
I've followed abp documentation to activate this option : import NuGet package and add depends on. Then, I use it like that :
Configuration.Caching.UseRedis(options => { options.ConnectionString = _appConfiguration["Abp:RedisCache:ConnectionString"]; options.DatabaseId = _appConfiguration.GetValue<int>("Abp:RedisCache:DatabaseId"); }, usePerRequestRedisCache: true);
if I deactivate option usePerRequestRedisCache, the app works again.
Could you please check it ?
-
0
Hi,
Could you upgrade to 6.6.1 and use it as explained here https://aspnetboilerplate.com/Pages/Documents/PerRequestRedisCache ?
Thanks
-
0
Hi @ismcagdas,
I just tried with 6.6.1 and it is not working. If I deactivate usePerRequestRedisCache option like below, everything works again :
Configuration.Caching.UseRedis(options => { options.ConnectionString = _appConfiguration["Abp:RedisCache:ConnectionString"]; options.DatabaseId = _appConfiguration.GetValue<int>("Abp:RedisCache:DatabaseId"); }, usePerRequestRedisCache : false);
If I connect to host, I have following error :
ERROR 2021-12-02 16:18:33,653 [28 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.Authorization.Users.UserPermissionCacheItem' to type 'Abp.Authorization.Roles.RolePermissionCacheItem'. System.InvalidCastException: Unable to cast object of type 'Abp.Authorization.Users.UserPermissionCacheItem' to type 'Abp.Authorization.Roles.RolePermissionCacheItem'. at Abp.Runtime.Caching.TypedCacheWrapper`2.GetAsync(TKey key, Func`2 factory) at Abp.Authorization.Roles.AbpRoleManager`2.GetRolePermissionCacheItemAsync(Int32 roleId) at Abp.Authorization.Roles.AbpRoleManager`2.IsGrantedAsync(Int32 roleId, Permission permission) at Abp.Authorization.Users.AbpUserManager`2.IsGrantedAsync(Int64 userId, Permission permission) at Abp.Authorization.Users.AbpUserManager`2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Authorization.PermissionChecker`2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Authorization.PermissionChecker`2.IsGrantedAsync(String permissionName) at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserAuthConfig() at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll() at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll() at lambda_method1396(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
If I connect to a tenant, I have following error :
ERROR 2021-12-02 16:18:54,004 [33 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'. System.InvalidCastException: Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'. at Abp.Runtime.Caching.TypedCacheWrapper`2.Get(TKey key, Func`2 factory) at Abp.Runtime.Caching.TypedCacheExtensions.Get[TKey,TValue](ITypedCache`2 cache, TKey key, Func`1 factory) at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionaryFromCache(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionary(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetLanguages(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageManager.GetActiveLanguages(Nullable`1 tenantId) at Abp.Localization.ApplicationLanguageProvider.GetActiveLanguages() at Abp.Localization.LanguageManager.GetActiveLanguages() at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserLocalizationConfig() at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll() at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll() at lambda_method1396(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
-
0
Hi @ricavir
I will test this again and inform you.