记一次高并发情况,服务器和代码修改过程记录。

            2016年12月,苹果新通知必须HTTPS。 原本我们的项目运行在windows server 2008R2(内存32G cpu 16 带宽 10M)下面,是没有任何问题的,已经正常运行半年有余了。我们服务器有2个项目 暂时叫做项目A  B。升级HTTPS  2个项目都需要 IIS7.5 是无法做到的 ,必须支持SNI 才可以。然后着手升级阿里云服务器,升级到最新版本windows server 2012R2 IIS8.5,所有配置保持不变,硬盘有SSD 换成了高效云。然后问题开始出现了。

            平常运行是没有问题的,我们每个周三都有一个秒杀活动。每个周三下午2点30分钟准时 400或者200个物品一元抢购,然后周三开始瘫痪了。 这个问题是有历史渊源的。刚入到这个公司接受项目 这个项目 是Nhibernate+webform+webservice 做的,是一个比较老的项目,中间还穿插了几个维护人自己的技术。网站没什么流量 也就运行着,然后公司开始上线秒杀活动,根本无法运行,日志测试下 发现Nhibernate 根本数据处理太慢 ,高并发 下 CPU直接爆了,这个CPU 都爆了 肯定代码问题了。然后着手换订单流程 和主页面的代码,换框架是来不及了 然后 就用ado.net 重写了,顺便加入了缓存机制。

          说下这里的缓存机制吧,但是想的是reids 来做的,也比较潮流 口碑比较好。但是当时项目着急上线 来不及给你实验了 就用了 最简单的硬盘txt 来缓存,我们网站的在线人数 是足够的。

         问题解决,秒杀活动也就正常了。很轻松 换下数据获取方式 加上缓存。

         服务器升级后问题又来了,老毛病又犯了。但是这次不一样 CPU 内存 带宽 一切正常,但是网站卡死,但是同服务器的网站B 正常运行。然后自己想想 应该不是代码的问题,毕竟成功运行了这么久了,服务器应该也没有问题 网站B 都可以正常运行,应该是程序池的原因。 开始排查服务器 研究IIS8.5,把IIS8.5的发布视频都给看了,然后在事件查看器→windows 日志→应用程序 里面 查看到错误一句英文:The state server has closed an expired TCP/IP connection. The IP address of the client is 127.0.0.1. The expired Read operation began at 01/04/2017 16:36:57。网上查下状态服务连接关闭了,转到服务看了下 asp.net state service 正常运行啊。思前顾后 也就秒杀这个时间段出现了这一个错误,然后把 状态服务 直接存到了 数据库,具体方法可以百度。以为问题解决了 真是so young 啊,没有压力测试下 就上线了,第二周又挂了 这次没有报那句英文错误了,但是还是卡死。头大了,临近年关你给我整这出,还要不要让我过年了啊。这次直接开始压力测试,但是网上的压力测试大多数都是压整个服务器起的 和我们出现的情况不太相同啊,中间找了很多的资料,看的感觉最像的就是博客园的黑色30秒事件 具体可以看连接http://www.cnblogs.com/cmt/p/3682642.html,博客园写了好几篇文章 大家可以看看,说的非常细致。也根据他们提供的解决方案 

<processModel enable="true" requestQueueLimit="5000" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" minIoThreads="50"/>

对machine.config(位于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config)经行了修改。 然后进行压力测试(我们用的压力测试工具是WebPerformanceTest)发现某些页面 某些接口 是没有问题,有些接口有些页面 进行压力测试项目就开始卡了(我们 压力测试 进行是 本机 和一台测试服务器同时进行 并发用户数 每台是1000,一台进行10分钟压力测试
另一台是10000个请求),然后查看 性能测试页面 发现requestd current 爆了,requestd queued 没有了,在没有进行machine.cofig修改时候 requsted queued 会很大 但是不至于爆了。说明这个设置有效果,但是还是卡 还是没有根本的解决问题啊。后来把state service 又还原到以前的内存读取。

         再次分析阿里云,发现在压力测试的时候 阿里云的IO 网络 带宽会到峰值 也就达到了顶值,会不会是因为 缓存写在硬盘导致的高效云太差劲 没有SSD好。开始倔起来了啊,直接打电话找阿里云 问问题 人家小姑娘那里懂这些问题啊, 提交工单。。。。尼玛 提交工单,问题描述下提交过去。阿里云那边的答复是:二者相同,在XXX功能上面 高效云比SSD的好,顺便帮我们查看了说 带宽不够。 这个怎么可能啊 10M 带宽 这才多少人啊。 (后来我们通过IIS 日志分析请求 用的是秋式网站日志分析器 当天的请求 才 60W个,秒杀活动 当时的请求也就 2.30 到3.00的请求 才 25W 多点),靠阿里云是不行了,自己动脑丰衣足食。影响带宽,影响IO 会有那些了。图片下载,硬盘写缓存。 一个一个来 我们对图片的读取经行了一次压力测试 发现没有问题啊。这个可以排除了,剩下就是 缓存写入硬盘了。

       换缓存的读写方式,弃掉硬盘读取 缓存redis,具体怎么读写 就是网上最简单的,我们也就是对几个频繁页面进行缓存,没什么技术可言。压力测试 还是挂,但是 又换了展现方式了,我缓存是 接口读写的json ,压力测试PC 网站。我没有把所有的都缓存。诶 继续想。 

          又把问题转移到代码上面 在次进行日志测试,发现某些压力测试卡的接口 和页面 居然的底层数据库还有些 Nhibernate 获取数据,Nhibernate +sql 的获取方式,真是高估了Nhbienate了,继续换成 ADO.NET。 然后在网上又找到了一篇文章关于设置IIS 支持高并发的文章,我写在上一篇的文章中,具体可以自己查阅。然后压力测试 OK了。每个接口都压了下 发现都可以了。 具体解决方案 我也不太清楚了 毕竟改了太多设置,代码也换了不少东西。下面我会总结 我修改 的地方。前面大多数都是自己的抱怨,可以直接转移到 终极解决方案。

      中途一个小插曲,没想到 这么点用户的项目 都给我整上 伪分布式。我将 IOS pc  android 进行了分开部署,这样 就算卡了 也就卡了单方面 ,其他端还是可以参与活动,这个当作备胎方案实施吧。不怕一万就怕万一啊,领导再次说抢不了  今年就别想提加工资了。 这个也是大项目的一个 基本部署, 接口 登录 支付 PC端 静态文件 数据库 分开部署。

      终极解决方案:1.修改machine.config

                         2.根据我上一篇随笔 修改了IIS 配置 和电脑TCP/TP的连接数

                         3.硬盘缓存换成redis缓存

                         4.将项目中残余的Nbibienate+sql 全部换成 ado.net

                         5. IOS PC  Android分开部署

      具体哪一步解决了我的问题 我也不太清楚, 

                            

posted @ 2017-02-21 12:00  KainJC  阅读(1180)  评论(0编辑  收藏  举报