在我们将站点从 ASP.NET + Windows 迁移至 ASP.NET Core + Linux 的过程中,目前遇到的最大障碍就是 —— 没有可用的支持 .NET Core 的 memcached 客户端。
我们一直用的是 EnyimMemcached ,在没有其它选择的情况下,我们自己尝试着将 EnyimMemcached 迁移至 .NET Core。。。基于 .NET Core 修改好了代码,在开发环境下测试通过,在 Linux 服务器上自己访问很正常(没有并发访问量),但是只要接入一定的访问量就会发生死锁(deadlock),浏览器请求卡死。
这个问题困扰了我们很长时间,昨天才定位到是发生在将 memcached 服务器名称解析为 IP 地址的时候。
var addresses = System.Net.Dns.GetHostAddressesAsync(host).Result;
这是我们在将 EnyimMemcached 迁移至 .NET Core 时修改过的代码,之前调用的是同步方法:
var addresses = System.Net.Dns.GetHostEntry(host);
由于在 .NET Core Framework 的 System.Net.Dns 中没有同步方法,只有异步方法,所以我们只能这样调用异步方法。
看到上面的代码,你也许会诧异:怎么用 .Result ,为什么不用 await ?不死锁才怪呢。。。
你的诧异非常正确。我们也深知 .Result 的危害,在平时的代码中坚决不用。但当时在修改 EnyimMemcached 的代码时,由于这个方法是在 MemcachedClient 的构造函数中调用的,没法改为 await 调用,被迫用了 .Result ,然后又把这个地方的修改给忘了。。。昨天才刚刚发现,立马意识到罪魁祸首非常有可能就是这里的 .Result ,于是以此为突破口,想尽一切办法实现在同步方法中调用异步办法,并且在博问中寻求支援 —— 在同步方法中调用异步方法时如何避免死锁问题 。
结果,用尽一切能想到与能找到的同步方法调用异步方法的方法,都没能解决死锁问题。如果实在找不到解决方法,我们准备采用最后一招也是最丑陋的一招 —— 不用 Dns.GetHostAddressesAsync() ,用 ProcessStartInfo 调用命令行命令解析 IP ,比如在 Linux 上用 getent hosts 主机名 。
在准备放弃之前,今天又想了想还有哪些可能带来线索的地方漏掉了呢?突然想到有个重要地方竟然忘了,还没看 Dns.GetHostAddressesAsync() 的源代码实现。虽然不报太大希望,不就是个异步方法吗,但还是要看一下。
于是从 github 上签出 corefx 的源代码,打开 Dns.GetHostAddressesAsync() 源代码一看,感觉有点怪怪的,怎么用了 Task.Factory.FromAsync() ?
public static Task<IPAddress[]> GetHostAddressesAsync(string hostNameOrAddress) { NameResolutionPal.EnsureSocketsAreInitialized(); return Task<IPAddress[]>.Factory.FromAsync( (arg, requestCallback, stateObject) => BeginGetHostAddresses(arg, requestCallback, stateObject), asyncResult => EndGetHostAddresses(asyncResult), hostNameOrAddress, null); }
开始没反应过来,只是把这段代码贴到博问的补充问题中,在贴完后突然反应过来了,咦,怎么没有 async 关键字?方法名最后是 Async,我们一直以为是 async 方法,而且丝毫没有怀疑过。。。
没有 async ,只是返回参数是 Task 类型,那在同步方法中调用完全没问题,只要在访问 .Result 之前调用一下 .Wait() 方法就行了,于是改为下面的代码:
Task<IPAddress[]> task = System.Net.Dns.GetHostAddressesAsync(host); task.Wait(); var addresses = task.Result;
死锁问题立马解决!
方法名以 Async 结尾,却不是 async 方法,当时的感想就是 —— 你的眼睛背叛你的心。如果不是我自己的误解(只要以 Async 结尾,就应该是 async 方法),那就是一种流氓行为,就如 HttpClient 的流氓 —— 实现了 IDispose 接口,却没真正 Dispose 。
不管怎么样,这个影响我们迁移至 .NET Core 的最大障碍终于消除了,值得庆祝!
支持 .NET Core 的 EnyimMemcached 的代码还需要一些修改与完善,等修改好了,我们会把源代码与 NuGet 包都发布出来。
通过此文希望能帮助到你解决这种问题,谢谢大家对本站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 国风大师纯音系列《古筝仙子 常静演奏 十指弹一》1CD[FLAC][919MB]
- DasKapital-OneMustHaveChaosInsidetoGiveBirthtoaDancingStar(2024)[24-44.1]WAV
- 王菲.1999-《只爱陌生人》日本东芝版[低速原抓WAV+CUE]
- 张小英1987-金奖金曲第一集[新加坡版][WAV+CUE]
- 鹿晗.2015-重启【海蝶】【FLAC分轨】
- 张芸京.2012-小女孩【金牌大风】【WAV+CUE】
- 余天.2002-雄狮魅力金曲2CD(南方金点系列)【南方】【WAV+CUE】
- 银霞.1982-《结·SAYYESMYBOY》台湾复刻版[WAV+CUE]
- 梁汉文1993-火热动感[引进版][WAV+CUE]
- 梁汉文2008-EDMONDHITS48[香港]3CD[WAV+CUE]
- 国风大师纯音系列《童丽-[渭城曲]》1CD[WAV分轨][593.5MB]
- 国风大师纯音系列《许菱子《烧筝2》古筝曲集》1CD[WAV分轨][1.3GB]
- 王子异《1996 Part.2》[320K/MP3][18.29MB]
- 群星.1994-宝丽金最倾情3CD【宝丽金】【WAV+CUE】
- 乐俊亨.2024-同泪【CharioticMusic】【FLAC分轨】