高并发和大流量的解决方案

生成唯一ID-雪花算法:https://github.com/godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake)

一、高并发的问题,我们该关心什么

1、QPS :每秒钟请求或查询的数量(QPS 不等于并发连接数  并发连接数是系统同时处理请求的数量)
2、吞吐量:单位时间内处理的请求数量(通常由QPS和并发数决定)
3、响应时间
4、PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客24小时内访问的页面数量,
       同一个人浏览网站的同个页面多次刷新,只记做一个PV
5、UV:独立访客(Unique Visitor),即一定时间范围内相同的访客多次访问网站,只计算为1个UV
6、带宽:日网站带宽 = PV/统计时间(换算成秒)* 平均页面大小(单位KB)* 8
7、峰值的QPS := (总PV数 * 80%)/(6小时秒数 * 20%)
8、压力测试:ab、wrk、http_load、Apache JMeter

二、 不同QPS下的优化

1、QPS达到100,数据库缓存、数据库负载均衡
2、QPS达到800,如果网站带宽为100M,那么带宽就会吃完。CDN加速、负载均衡
3、QPS达到1000, 如果使用Memcache缓存,Memcache的悲观锁并发2W左右,那么内网的带宽可能以及吃完。静态HTML缓存
4、QPS达到2000,文件系统访问锁成为了灾难,做业务分离、分布式存储

三、优化方案

1、流量优化。防盗链
2、前端优化。减少http请求、添加异步请求、开启浏览器缓存和文件压缩、CND加速、建立独立图片服务器、
3、服务端优化。页面静态化、并发处理(队列、异步)
4、数据库优化。数据库缓存、分库分表分区、读写分离、负载均衡
5、web服务器优化。负载均衡、

四、具体的优化方案

1、防盗链:使用Referer请求地址判断或者签名
Referer nginx配置

location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
 valid_referers none blocked test.com *.test.com;
if($invalid_referer){
   #return 403;
   rewrite ^/ http://www.test.com/403.jpg;
   }

}

加密签名:使用第三方模块HttpAccessKeyModule实现Nginx防盗链

location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
    accesskey on; 
  accesskey_hashmethod md5; #加密算法,和php的加密算法保持一直
  accesskey_arg "sign"; #url请求签名的参数名
  accesskey_signatrue "mypass$remote_addr"; #加密规则  md5( 'mypass'+客服端的ip地址);
}

2、数据库优化

  • 数据库类型的正确选择
  • 数据表引擎的不同
InnoDB:默认事务型引擎,性能优秀。
        数据存储共享表空间(索引等),可通过配置分开
        主键查询性能高于其他类型的引擎
        通过一些机制和工具支持真正的热备份
        支持崩溃后 的安全恢复
        支持行级锁  
       支持外键
MyISAM
       支持全文索引
       不支持事务和行级锁,表锁
       不支持崩溃后 的安全恢复
       表存储在2个文件,MYD和MYI
       查询效果比较高
       统计效率比较高(count)
  • MySQL索引,主键、唯一索引、联合索引 的区别,以及对数据库性能的影响
 1、索引对性能的影响
        大大减少服务器需要扫描的数据量‘
        帮助服务器避免排序和临时表
        将随机I/O 变成顺序的I/O
        大大提高查询速度
     缺点:降低写的速度,占用磁盘

 2、索引的使用场景
        对于小的表,全表扫描效率更高 
        中大型的表,索引非常有效
        特大型的表,建立索引和使用索引代价也会提高,可使用分区技术解决

3、主键索引和唯一索引的区别
       一个表只能有一个主键,可以有多个唯一索引
      主键索引一定是唯一索引,唯一索引不是主键索引
      主键可以和外键构成参照完整性约束,防止数据不一致

4、索引的创建原则
       where中的列,或者连接子句中的列
       索引列基数越大,索引效果越好
       对字符串进行索引,应该制定一个前缀长度,可以节省大量空间
       根据情况创建复合索引,复合索引可以提高查询效率
       避免创建过多的索引,索引或占用磁盘空间,降低写的效率
       主键尽可能使用较短的类型,比比如整型

5、索引生效
    . 复合联合索引的原则(前缀原则 ) key(a,b,c)
    . 索引生效:where a=1 and b =2 and c=3
                        where a=1 and b=2   
                        where a=1 其他都不生效
    . ike 查询,%不能在前,可以使用全文索引
    . is not null 和 is null 不走索引
    . order by 加上索引
    . != 索引失效
    . 如果MySQL估计使用索引比全表扫描慢,会放弃使用索引
    . or 前面会使用索引,后面不会,可以使用UNION ALL来代替
        select * from temp where age=20 or age=30;不走索引,可以使用下面的代替
        select * from temp where age=20
         UNION ALL
        select * from temp where age=30
    . 列类型是字符串,查询时一定要给值加引号,否则索引失效
    .

6、SQL优化

 . 不要select * 

 . 谨慎使用模糊查询。只有 s% (%在后面)才走索引

 . 对order by 加索引

 . 少用IS NULL和IS NOT NULL 不走索引 可以使用>或者<代替

 . 少用!=运算符 可以使用>和< 代替

 . 少用OR; OR前面会使用索引,后面不会,可以使用UNION ALL来代替
        select * from temp where age=20 or age=30;不走索引,可以使用下面的代替
        select * from temp where age=20
         UNION ALL
        select * from temp where age=30

. 少用 IN 和NOT IN
    select * from user where age in(20,30); 可以使用下面的代替
    select * from user where age= 20
    UNION ALL
    select * from user where age=20

. 避免条件语句中的数据类型转换
  如果数据类型是整型,不要加引号

. 在表达式左侧使用运算符和函数会是索引失效

你可能感兴趣的:(高并发和大流量的解决方案)