网站高并发解决方案-理论知识

网站高并发解决方案-理论知识1

本文章转自:http://www.php20.cn/article/sw/%E9%AB%98%E5%B9%B6%E5%8F%91/138

当面试官问:“网站高并发怎么做?”时,该怎么回?
在高并发下,我们(初级程序员)能做什么?

接下来我将从数据库、服务器硬盘、服务器带宽、使用什么服务器、PHP代码逻辑的一些优化等这5个方面简单说说我的看法。

一、MySQL方面

MySQL方面,我们主要要从以下几点去考虑:

1、索引

MySQL其实没有想象中的那么差,相反,MySQL表数据,只要查到了索引,都不会慢,(1.5亿数据表查索引0.0几秒),所以MySQL索引是个好东西,用好之后,查询效率自然很快。所以,数据表设计,一定要考虑全面,给查询频繁使用的字段增加索引,或者使用组合索引。

数据库索引学习传送门:https://www.cnblogs.com/zhaobingqing/p/7071331.html

2、查询数据缓存

常用的一些配置数据,或者某些变更不频繁查询频繁的数据可以通过Redis,Memcache,File(不推荐)等方式增加缓存来处理,避免数据库频繁查询造成额外的数据库性能消耗。

场景一:进网站的轮播图,由于变更不频繁,可以设置缓存1天,当轮播图修改更新时,更新缓存

场景二:10万个会员的聊天室,进来需要查询聊天记录,由于聊天记录变更频繁并且查询频繁,可设置缓存1-3秒,缓存失效才去取一次数据库,将大部分查询都进入缓存中查询,大大降低了数据库压力。

3、查询逻辑优化

场景一:当你想在一个数据量为1000万的访问表,统计会员A的访问记录时,你会发现,就算给会员id增加了索引,也会很慢,因为这个涉及到了数据命中条数

MySQL命中条数越多,则查询越慢。

优化方案:由于是访问表,不算是重要数据,可增加一个统计表,统计每天的访问数量,当你要查会员A的访问总数,则可以直接去查sum统计表中的数据,大大提高了性能。

场景二:某个抽奖程序,A奖品限制每天只能出1万个,判断当天是否超出限制时,一般情况是count(1) 查出奖记录表,这样做是不正确的,正确做法:

1、增加个库存字段,每天自动更新为10000,每次抽中减一,判断是否出完只需要查看库存字段

2、增加个计数表,按每天为单位,每次抽中则字段num+1,判断是否超出限制,只需要查出当天记录的num字段比对就行

场景三:高并发下,会员抢10万个红包怎么做?

每天新增1万条奖品记录,并生成缓存队列(Redis),每次抢完则从队列中取数据,抢完批量更新回数据库。

场景四:当有一个表,字段数有50,而你取数据只需要10个字段时,尽量把select * 写成 select 字段名,字段名,可以让mysql节省没必要的返回数据,从而影响效率。

二、服务器硬盘方面

大多数人,可能不知道有iops(硬盘每秒输入输出量)这个东西存在,所以在硬盘方面的优化直接被忽略了。

下图是阿里云的各硬盘比对

1

通俗来讲,就是硬盘的每秒读取文件的数量有限,举个例子,你的程序从启动到输出include了100个文件,高效云盘的iops是3000,代表着你的程序,每秒最多只可以访问3000/100=30的并发数(只是理论数据,当在大并发下,操作系统会适当的优化)

这就是laravel框架慢的原因,加载的文件太多了。

优化方案?优化方案,在前几个月,我的圈子有讨论过,具体方案有以下几种:

1、将PHP框架,编译成一个PHP文件,这样一次请求下来,只有一个文件的输出,大大的降低了硬盘的压力,其实,tp3.2就已经有了这个功能,只是大家没注意而已。http://document.thinkphp.cn/manual_3_2.html#app_compile

2、在swoole文档中,韩大有说https://wiki.swoole.com/wiki/page/836.html

2

在linux中,/dev/shm是映射的内存路径,当框架启动时,将框架代码复制到该文件夹下面去运行(注意,内存,关机数据就会没有,只能保存固定的业务代码,不能保存业务数据)。windows也有内存盘,也可以实现该操作。内存读取速度非常快,所以并不用担心磁盘I/O问题。

三、服务器带宽方面

服务器的带宽是非常贵的,而网站的访问都离不开带宽,下图是我的博客一次请求下来的网页大小。

3

假设一次请求就需要600kb,这相当于什么呢?当我服务器带宽只有1M(出口带宽128kb/s)时,某次访问进来,最少需要600/128约等于5秒的时间。相当于我服务器的秒并发量只有1/6。

何况这只是个博客,商城呢?假设商城的请求大小有1M,服务器带宽有100M(12.8M/s)的话,秒并发量最多只有12.8。这就是带宽方面的限制了。

当然,浏览器在一次请求之后,会智能的缓存页面(js,css,图片等静态文件),这样大大的节省了服务器带宽,但是新进来的用户,或者有用户禁止了缓存页面,就得请求这么多数据了。

至于优化方案,我的方案是上cdn(内容分发网络)。它的大致原理是:将域名转到他们的dns服务器,由他们进行管理域名的请求ip。

例如:我的[blog.huanghui.xyz](blog.huanghui.xyz),将dns转移到百度云cdn,那么所有访问blog.huanghui.xyz的请求都会被百度云cdn接管。

在某个地区(百度云cdn有多个地区的服务器,保证网站资源第一时间响应给用户)第一次请求时,由于百度云还没有缓存,将会请求正确的服务器地址(百度云cdn后台域名解析),把数据返回给用户端并缓存到百度云cdn。

当有缓存之后,百度云将不再请求服务器的资源,将百度云缓存的静态数据,直接返回给用户端,这就是cdn的作用了。

四、使用Nginx服务器

可能大家都知道,高并发下,都得使用Nginx服务器,这是为什么呢?

咳咳,可以看以下文章https://www.cnblogs.com/yum777/p/6244935.html

五、PHP代码逻辑

再好的架构,也会死在垃圾代码上面,上面的一系列优化好了,那就是PHP方面了,主要注意以下几点:

1、多使用PHP内置函数(内置函数写在了PHP C底层,无需编译,速度快)

2、判断逻辑,(当有个奖品需要判断是每周2万个,每天最多5000个时,先判断是否超过了每周限制,当真的超出了每周限制时,将节省每天判断的时间)

3、避免循环运行SQL语句(需要插入/更新多条数据时,请在循环外批量插入/更新)

http://www.php20.cn/article/sw/%E6%95%B0%E6%8D%AE/105 tp5内部好像已经实现了批量更新功能。

4、尽量减少查询数据库的次数

能用一条语句查出的,尽量不要多条。例如,有个订单表,有2种付款方式(payment_type=1,payment_type=2),对应1个付款金额的字段(total_money),当你需要统计2种付款方式总计金额时,大多数人会根据payment_type=1,payment_type=2进行查询2次数据,该怎么优化呢?

可以使用MySQL的判断查询:http://www.php20.cn/article/sw/%E5%88%A4%E6%96%AD/95

5、过滤掉恶意请求

通过验证码、手机短信等方法,将机器人排除在外,为了避免恶意请求,可限制每秒请求次数不得超过10(普通人哪能点击这么快),当超过时,则系统底层拒绝响应,等到下一秒才可以继续请求。

六、其他

本文一切都是理论知识,算是实践过,但是并发量不大,所以大神们勿喷,互相学习,如果有错误或者有其他优化方案,希望大神们批评指正。

文章目录
  1. 1. 网站高并发解决方案-理论知识1
    1. 1.1. 一、MySQL方面
      1. 1.1.1. 1、索引
      2. 1.1.2. 2、查询数据缓存
      3. 1.1.3. 3、查询逻辑优化
    2. 1.2. 二、服务器硬盘方面
    3. 1.3. 三、服务器带宽方面
    4. 1.4. 四、使用Nginx服务器
    5. 1.5. 五、PHP代码逻辑
    6. 1.6. 六、其他
本站总访问量 | 本页面被访问 | 您是第位小伙伴

© 炫彩信息科技有限公司 版权所有 备案号 : 赣ICP备19008485号