如何进行网站优化构建高性能网站

说到网站优化其实是一个很大的概念,网站优化的手段太多,一个小小代码合并也算是网站的优化,下面我从网站前端到后端逐步说下各个部分优化方法。
浏览器访问的优化
1、减少HTTP请求
HTTP协议是工作在应用层的无状态协议,意味着每次HTTP请求都要建立通信链路,进行数据传输,而在服务器端每个HTTP请求都要启动独立的线程去处理。这些通信和服务的开销都很昂贵,减少HTTP请求数目可以有效提高访问性能。
我们可以通过合并JS、CSS、图片的方式来减少HTTP请求数目。如果多张图片合成一张,每张图片都有不同的超链接,可以通过CSS偏移响应鼠标点击操作,构造不同URL。
2、使用浏览器缓存
通过设置HTTP头中的Cache-Control和Expires的属性,可以设定浏览器缓存,但是需要注意一个问题,当我们更新大量的静态资源时,例如我们更新10个文件不宜把10个文件一次全部更新,而是一个一个的更新,以免用户浏览器大量缓存失效,集中更新缓存,造成服务器负载骤增、网络阻塞等。
3、启用压缩
通过文件压缩可以减少数据通信数量,文本的压缩率可以达到80%以上,因此HTML、JS、CSS启用GZip压缩可达到较好的效果。但是压缩会对服务器和浏览器产生压力,在通信良好,而服务器资源不足的情况下需要权衡一下
4、CSS放在页面最上面,JavaScript放在页面的最下面
浏览器会下载完所有的CSS之后才会对页面进行渲染。JavaScript则相反,浏览器在加载JavaScript之后立即执行,有可能阻塞整个页面,造成页面显示缓慢。但是如果页面解析时就需要JavaScript,放到就最后就不合适了,我们因地制宜,进行合理的安排
5、减少cookie的传输
cookie包含在每一次的请求和响应中,太大的cookie会严重影响数据传输,应尽量cookie的传输。另外,对于某些静态资源的访问,发送cookie没有意义,可以考虑静态资源使用独立的域名访问,避免请求静态资源时发送cookie,减少cookie的传输次数。
CDN加速
CDN(Content Distribute Network,内容分发网络)的本质仍然是一个缓存,并且将数据缓存在离用户最近的地方,加快用户的访问,减少数据中心的负载压力。
反向代理
传统代理服务器位于用户浏览器一侧,代理浏览器将HTTP请求发送到互联网,而反向代理服务器位于机房一侧,代理网站Web服务器接收HTTP请求。
这里写图片描述
反向代理服务器和传统代理服务器一样,也具有保护网络安全的作用,来自互联网的请求必须经过代理服务器,相当于在Web服务器和网络之间添加了一个屏障。
除了安全功能,反向代理服务也能缓存静态资源,加速了用户的访问速度
应用服务器的性能优化
优化手段:缓存、集群、异步
1、分布式缓存
当我们的网站访问速度遇到瓶颈时我们首先想到的就是使用缓存,缓存存在于我们网站的每一个角落,页面缓存,静态资源缓存,数据缓存,文件缓存等等
那么缓存为什么这么快,从缓存获取数据的算法复杂度肯定很低,我们知道Map的get方法时间复杂度是o(1),无论Map多么庞大我获取数据时总是那么快。缓存的本质和Map类型是一个内存Hash表,数据缓存以一对key、value的形式存储在Hash表中。hash表数据读写的时间复杂度为o(1)。
计算KV对中的key的HashCode对应的Hash表索引,可快速的访问Hash表中的数据。Java的hashCode方法包含在Object中,返回值int,然后通过HashCode计算Hash表的索引下标,最简单的是余数法,使用Hash表数组长度对HashCode取余,余数即为Hash表的索引下标。
这里写图片描述
缓存中一般存放哪些读写比很高,并且变化很少的数据。网站的数据通常遵循二八定律,80%的访问定位在20%的数据上,将这20%的数据缓存起来可以很高的改善系统性能,提高读取速度降低存储压力。
下面我们说一下缓存使用中应该注意的问题
频繁修改的数据不宜缓存
非热点数据不宜缓存
一段时间的数据不一致,例如当我们修改商品属性,缓存在有效期内用户读取的一直是老数据,这个需要我们在自己的业务场景中合理掌控。
缓存的高可用,当某台缓存服务器失效,应该访问另一个备机的数据,而不应该使用户大量请求访问数据库,从而短时间给数据库造成巨大压力甚至出现宕机。
缓存预热
缓存中的存放的是热点数据,热点数据是通过缓存的LRU(最近最久未用算法)对不断访问的数据 筛选出来的。新启动的缓存中如果没有数据在重建缓存数据的过程中系统的性能和数据库负载都不太好,那么最好在缓存系统启动时就把热点数据加载好
说到缓存简单介绍下Memcached
memcached的简单通信协议,远程通信设计要考虑两个方面因素,一是通信协议,即使选择TCP协议还是UDP协议抑或是HTTP协议;一是通信序列化协议,数据传输的两端必须使用彼此可识别的数据序列化方式才使得通信完成,例如:XML、JSON等文本序列化协议,或者谷歌的Protobuffer等二进制序列化协议。Memcached使用TCP协议(也支持UDP)协议,其序列化协议规则是一套基于文本的自定义协议。例如读取一个数据命令get(key)。
memcached的高性能网络通信,基于Libevent,一个基于事件触发的网络通信程序库。
memcached的高效内存管理,内存管理中最让人头疼的问题就是内存碎片管理。在JVM垃圾回收中也存在这个问题,为了解决这个问题JVM采取了压缩、复制等算法。而Memcached采用的固定空间分配。
memcached将内存空间分为一组slab(片),每个slab里有包含一组chunk(块),同一个Slab中的chunk大小是固定的,拥有相同大小chunk的slab被组织在一起,叫做slab_class,存储数据时根据数据Size的大小,寻找一个大于Size的最小chunk将数据写入。这种内存管理方式避免了内存碎片管理的问题,内存的分配和释放都是以chunk为单位的。和其他缓存一样,memcached采用LRU算法释放数据空间,释放的chunk被标记未使用,等待下一个合适的数据写入。
当然这种方式也会带来内存浪费的问题,数据只能存入一个比他大的chunk中,剩余的空间就浪费了,如果启动参数配置不合理发现没存多少数据内存已经耗尽了。
至于Memcached的集群数据分配(一致性哈希算法)后续再详细介绍。
2、异步操作
使用消息队列异步化能够大大提高网站性能和吞吐量
特别是在高并发的时候,用户大量的请求数据如果直接入库会给数据库造成极大的压力,如果此时使用异步用户请求之后提示用户处理中,然后再消费消息队列中的数据入库
3、使用集群
在网站高并发的场景下,使用负载均衡技术为一个应用构建一个由多台服务器组成的集群,并将请求分发到多台服务器上处理。避免单一服务器因负载过高而反应缓慢,给用户带来极差的体验,互联网拼的就是速度。
4、代码优化
4.1多线程编程
将对象设计为无状态对象(对象无成员变量,例如Servlet),似乎有违面向对象设计理念
使用局部对象
并发访问时使用锁
4.2资源复用
系统运行时尽量减少那些开销很大的系统资源的创建和销毁,比如数据库连接、网络通信连接、线程、复杂对象等。资源复用一般有两种方式:单例( singleton)和对象池(Object pool)。
4.3数据结构
Hash表的读写依赖于HashCode,HashCode越随机读写性能越高
4.4垃圾回收
垃圾回收可能会对系统的性能造成巨大的影响。理解垃圾回收机制有助于程序优化和参数调优以及编写内存安全的代码。
以JVM为例其内存可划分为堆(heap)和堆栈(stack)。堆栈用于存储上下文信息,如方法参数,局部变量等。堆则存储对象的内存空间,对象的创建释放垃圾回收都在这里进行。大部分的对象的生命周期都是短暂的,这部分对象产生的垃圾应该被更快的收集,以释放内存,这就是JVM分代垃圾回收。
在JVM分代垃圾回收机制中,将应用程序可用的堆空间分为年轻代(Young Generation)和老年代(Old Generation),又将年轻代分为Eden区、from区和To区,新建的对象都是在Eden区中被创建,当Eden空间已满,就触发一次GC,将还被使用的对象复制到From区,这样整个Eden区继续创建对象,当Eden区再次被用满,再触发一次Young GC,将Eden区和From区复制到To区,下一次Young GC将Eden和To区复制到From区。经过多次Young GC之后某些对象会在From和To区之间多次复制,如果超过某个阀值对象还未被释放,则将该对象复制到old generation。如果old generation也用完,那么就触发Full GC,Full GC对系统性能影响较大,尽量避免。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值