这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」。
最近以PostgreSQL为存储介质,实现了分布式缓存的一个组件开发,在经过开发环境的测试后,顺利推送到产品组的手里,经过开发环境的验证后,终于发布到测试环境了,但问题来了,产品组反应频繁出现访问异常,返回的信息大致是:Exception while reading from stream ... (0x80004005)
- 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
- 📢本文作者:由webmote 原创,首发于 【CSDN】
- 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪
1. 缘起分布式缓存
大家经常用的无非是Redis,Memcache,很少使用数据库做缓存吧?当然有些特殊场景,数据库也未必不能承担分布式缓存的功能,微软还实现了SQL Server的分布式缓存组件呢?不是吗?
因此不要纠结为什么了!先收藏吧,长文不易,先收藏,后阅读!
再次Review我的代码,基本的Get/Set操作均是使用Dapper.net进行sql操作,一条或者2条语句就实现了基本功能,使用using包括链接,也不存在链接的资源泄露,按理说,不应该出现异常。
异常日志如下:
最关键的语句无非是 Exception while reading from stream了。
2. 超时设置
在看到这个异常时,我的脑子基本一片空白,这个处女秀的组件就这么脆弱吗?看起来很有可能是连接断开了,那是不是需要增加超时设定呢?
由于开发环境无法复现问题,因此只能有劳产品组增加超时设定了。增加超时比较容易了,我们参考文档,即可找到: Npgsql .net 版本的PostgreSQL数据库连接字符串及参数
Timeout :单位秒,链接的建立链接的超时时间,默认15s
Command Timeout: 单位秒,链接的命令执行超时时间,默认:30s
当然,我也不能闲着,赶快搜索下相关问题的解决办法。
主要查阅StackOverflow和github上的issue。 主要建议如下:
conn = new NpgsqlConnection("Server=myserver;
User Id=postgres;
Password=somepw;
Database=somedb;
Pooling=false;
Timeout=300;
CommandTimeout=300");
以及
KeepAlive = 300
经过尝试后,均返回说无效,此时进入了漫长的技术攻关期。
3.编写多线程测试用例
复现问题,才能排查之,因此花费了几个小时,编写了多线程的测试用例,在开发环境反复测试,一切都是OK的,说明程序的问题应该不大,难道有死锁的现象?
经过监控,并未发现数据库死锁。
连接上测试环境的数据库,经过长时间运行,几乎没有出现过错误。偶尔一次也未能分析出什么,可以说出现的频率极其低,但产品组出现的机率极高。
这时候不得不怀疑是环境的问题了!
4.环境分析
开发环境比较简单,postgreSQL就部署到本机,因此也没有问题出现,说明该环境没有问题,也不能触发问题。
测试环境采用的是Kubernetes + pod模式,postgresql部署在pod中,访问数据库奇怪的采用了外部dns转发到pod的形式。
那这里面就会有很多网络环节,网关帮忙分析认为是dns解析延迟导致,因此它配置了k8s的内部域名,经过产品组的测试,感觉问题得到了修复。
5. 小结
👓都看到这了,还在乎点个赞吗?
👓都点赞了,还在乎一个收藏吗?
👓都收藏了,还在乎一个评论吗?