-
Notifications
You must be signed in to change notification settings - Fork 87
KeyRingProvider initialization causes thread pool starvation when server starts under load #233
Comments
Is your redis instance restarting at all? |
no it hasn't restarted at all |
after digging more on dump file
and
|
what should i do ? can i go for unc? should i change appname for migrating to unc? what other options do i have? |
So it looks like the redis connection is failing somehow. Is there anything in the redis logs to indicate failed connections at that time? |
redis log level is set to notice and i couldn't find any evidence of failed connection. |
FYI the key ring is a singleton, so this is expected behavior. Only one thread should load the key ring, and all other threads wait. The second stack you posted is the thread attempting to create the key ring, and it appears to be hung on communication with Redis. The Redis layer is actually pretty light (see RedisXmlRepository). To help isolate the issue, can you make sure the following code executes successfully? var database = RedisConnectionManager.SafeCoonect.CreateDatabase();
var keys = new List<XElement>();
RedisKey key = "xxxzzzz";
foreach (var value in database.ListRange(key))
{
keys.Add(XElement.Parse(value));
} |
@natemcmaster @blowdart
code execution time :
and it ran successfully. i don't know maybe load balancing and high traffic causes this problem. |
We also had this issue, in Azure App Services. It is writing to the shared filesystem. We also tried the Blob storage provider without any luck. We were running out of threads while the lock happened inside of GetCurrentKeyRingCore when apps randomly restarted under heavy load. n2y.Web.Websites.Login_7180_CrashHangAnalysis.mht.zip The only workaround we could find is to encrypt something during the Config method of the startup:
|
This looks like thread pool starvation.
The initialization in @michaelpaulus's workaround is simple and effective. It moves To triage team: possible solutions:
|
@natemcmaster just wanted to add my opinion as a consumer, it would be great if this was automatic, not opt-in since you have to realize this would be an issue in the first place to know to opt-in. It only happens when initializing during heavy load and is very hard to detect until production. We did many load tests on our site before hitting production, it was even working really well for a full day under production until one of the instances restarted for some reason during heavy load, then it was all over. A single instance was throwing 500 errors. This also happened with the default provider that writes the keys to the file system (FYI, not just Blob and Redis). Thanks! |
@michaelpaulus |
@michaelpaulus |
@1amirjalai you don't need to do anything more than you are probably already doing to register the IDataProtectionProvider at startup, services.AddDataProtection(). The unprotectedPayload is not needed for anything, what the code is doing is just encrypting / decrypting a string on startup so that as @natemcmaster described, it forces the loading of the keys before any load hits the server. This prevents the many 500 errors that you and I were seeing. |
👏 |
Thanks guys for getting this fixed. |
thank you it was frustrating 👍 |
Frustrating! One day before production I am getting This worked before, but apperantly something has changed. |
@vankampenp just add the code added by @michaelpaulus and don't change your cookie name or antiforgery token name ( i still can't figure out why changing name causes trouble ) but mine was solved after getting back to defaults
|
Thanks, I had tried adding this workaround, but that does not help. |
Just to add, this error occurs on my local development IIS server, hosting a few internal web sites and a staging environment. Not near a heavy load. It is also occurs (since it started) a 100%. The only way that I could avoid it is reboot the server and then access the web site. After redeployment of the solution, it came back. |
For reference, when deploying my application in to production, I ran in to a problem with the AntiforgeryToken.
It maybe a workaround, but it is a terrible one at that. |
@vankampenp which method did you add the work around to? I have not tried it with the files system store for data protection, did you try blob or redis instead to see if it was an issue with PersistKeysToFileSystem and the work around? |
To Configure. It wanted to write in an area that the IIS user did not have access to on the provider. |
Just wanted to mention that we experienced a similar issue when our azure service plan was scaling up due to heavy load. The newly added instance was failing and looking at the memory dump I found hundreds of threads waiting for GetCurrentKeyRingCore. I'm going to try the workarround, but it would be nice to have a solution out of the box as most users will probably only discover this when already in production. EDIT: To add, instead of using the Configure-method in startup, we ended up registering an IStartupFilter in the MVC container which encrypts a string. This could be a good way to implement this in the DataProtection Library itself as it does not require any additional method calls by the user. |
@aKzenT are you using ASP.NET Core 2.0.0? We made a small change in 2.0.0 that should resovle this issue. |
I'm still using 1.1, but it's good to know that it has been adressed. I assume you are talking about this commit fe83e69 ? |
@aKzenT yup. We haven't yet backported that change to 1.x patches. |
my application give me frequent
asp.net core 1.1.2 behind load balancer iis arr3
i made a dump file and inspected it using windbg i encountered the following lines. it's like all thread are waiting for keymanagement
could you please take a look at it my app crashes frequently and its a high traffic website
any help would be appreciated
@blowdart @natemcmaster @shanselman
it may be related to #228
the way i initialized redis at startup is :
and
safeconnect
isThe text was updated successfully, but these errors were encountered: