相信做为一个web开发者,大家都有遇到过网站访问瓶颈的情况,那么如何通过一些技术手段来解决这个网站访问的性能问题呢?
首先,需要明确的一点是引发网站性能瓶颈的因素有哪些?
一、服务器
服务器方面又可以细分为硬件和系统架构的原因,比如当一个日常在2000 DAU的电商网站突然因为做促销活动网站的pv暴增的时候,肯定就要考虑扩容了,另一方面系统架构的原因,主要体现在我们选择的服务器端框架有时候决定了网站的瓶颈,Apache和Ngix支持的并发数量就不一样,另一方面,我们可以通过负载均衡的方式来降低服务器的压力,来加快服务器的访问速度。
一般负载均衡的几种方式:
负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载
均衡策略,还有2种常用的第三方策略。
1.RU(轮询的方式)这是Nginx默认的
#每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
upstream test {
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
Remark:
这里我配置了2台服务器,实际上也可能只有一台,只是端口不一样而已,如果服务器处于不能访问(服务器挂了),就不会跳转到这台服务器,所以也避免了一台服务器挂了影响使用的情况,由于Nginx默认是RR策略,所以我们不需要其他更多的设置
2.ip-hash
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
3.权重的方式
#指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
upstream test {
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
备注:上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一
台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4.fair
#按后端服务器的响应时间来分配请求,响应时间短的优先分配
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
复制代码
5.url-hash
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
另一方面,在服务器的代码设计上,我们可以把一些页面静态化设置,这样可以适当减少对数据库的访问压力
二、数据库
在用户与服务器的交互过程中,很大一部分时间是耗费在数据库的CURD操作上,所以对于数据库的优化可以很大成都上来优化页面的访问体验。那么如何优化服务器的访问速度呢?
I)数据库表的设计:
1.数据表在设计的时候,在需要经常查询的字段上添加索引
2.主键使用自增还是UUID?
主键肯定还是使用自增,innodb的主键是聚族索引,如果主键是自增的,那么每次插入的新数据都会顺序添加到当前索引节点的后续位置,当一页写满时,就会自动开启第二页,如果不是自增键,那么就可能在中间插入,就会引发页的分裂,产生很多碎片,总之用自增的主键性能更好。
UUID产生的索引文件更大,当数据量超过一百万行时,主键查询性能和索引文件大小都比UUID要更有效率和更小。
3.枚举的字段最好不要使用enum类型
原因如下:
a).ENUM类型,order by操作效率低,需要额外的操作
b). 如果枚举是数值,有陷阱
例如:表结构如下create table test(sex enum('0','1'))此时执行插入语句insert into test values(1) 查询的结果为0
只有这样插入insert into test values('1')此时结果才是1
c).字段为什么要定义为not null
1)索引性能更好
2)使用not null会出现一些不可预料的结果
II).数据库的设计
常用的方式有主从数据库的设计以及读写分离,对于一些访问量大的网站或应用,我们还需要做主从数据库的设计,和数据库的读写分离。
III)数据库的选择
数据库通常分为SQL和NoSQL类型,具体他们的区别建议看这篇文章:Sql or NoSql,看这一篇就够了 ,关于选择SQL还是NoSQL,一般的建议是,如果公司的业务并发量不大的情况下,可以选择Mysql此类的Sql数据库,Mysql的服务稳定,数据一致性更好一些,但是如果公司的业务并发量比较大,那么非常建议使用NoSQL类型的数据库,常见的代表类型是MongoDB和Redis,Redis以其高性能,高并发,吞吐量大在电商、游戏等行业内应用普遍。加之Redis是在内存中处理一些操作的,在使用RDB或者AOF来持久化到硬盘的方式,决定了Redis是天生的性能强者。 关于Redis 的运用我会再另外写一篇的文章来介绍。
the end>>>>>>>>>>>>>>>>>>
关于页面的优化的一些浅显的认识,后面在实战过程中有好的经验,我会继续更新到这里,大家有好的经验也欢迎写到留言区里面。