现在到处都在说高并发,没有应对过相关的情况都不好意思说自己是web工程师。这里整理一下自己关于这个问题的一些了解。
##问题成因
- 某些站点用户规模原本就大
- 页面元素增多,交互越发复杂
- 长连接要等到超时才会释放资源
- 浏览器的连接数增多
###应对思路 最有钱的解决思路就是……加机器。高性能的服务器,高性能的数据库,使用SSD。不过这样成本也上去了,还是要拿捏一个平衡点。
####前端 #####减少请求 将静态内容放入缓存,尽量使用本地资源,本地没有的尽量访问CDN。与此相关的是HTTP协议中的expire或max-age,以及HTML5中的Local Storage。
#####减轻请求 通过HTTP的Last-Modified或Etag,让服务器在内容没有发生变化时仅仅返回304(Not Modified)就可以了。
#####合并请求 合并图片;合并Ajax请求。
#####页面静态化 尽量采用静态页面,避免大量的数据库访问请求,有些网站有大量内容且更新频繁,于是也出现了CMS这种东西。
#####分离图片服务器 设立独立的图片服务器。图片服务器可以有不同于应用服务器的配置优化,比如Apache在配置ContentType时可以少支持,尽可能少地LoadModule。
####后端 #####业务逻辑 比如游戏与电商中常有的秒杀活动,会有很多用户刷票,可以在程序入口处,一个账号只允许一个请求,其它过滤掉。通过Redis这种内存缓存服务,写入一个标志位,成功的才可以继续。
如果有多个僵尸账号一起刷,可以检测IP请求的频率,过高弹一个验证码或者直接封掉。
设置账号门槛,比如限制账号等级,设定检查僵尸账号的逻辑等。
使用乐观锁保证数据的安全。如Redis中的watch。
#####Apache preforkMPM,通过fork预先产生一批子进程,然后等待服务。不适合高并发场合。
workerMPM,预先fork几个子进程,每个子进程创建一些线程(其中包括一个监听线程)。
eventMPM,引入Epoll的worker。
#####Nginx
#####PHP
#####MySQL ######读写分离 拆业务;拆库;一主(双主)多从。
######参数调优
#####Memcached 基于libevent。
#####Redis 单线程模式,逻辑处理线程即主线程。
hash + bucket结构。