目录

动静分离

所谓的动静分离,就是将 Web 应用程序中静态和动态的内容分别放在不同的 Web 服务器上,有针对性的处理动态和静态内容,从而达到性能的提升。我们知道如果一个 HTML 有多个域名请求数据文件会提高
Tomcat 服务器在处理静态和并发问题上比较弱,所以事先动静分离的方式一般会用 Apache+Tomcat、Nginx+Tomcat 等。

以 Apache+Tomcat 为例,其运行机理是:页面请求首先给 Apache,然后 Apache 分析请求信息是静态还是动态,静态则本机处理,动态则交给 Tomcat 做处理这其实是负载均衡的雏形,这样的实现不用让开发人员做任何特殊开发,一个<img src="demo.jpg">交给服务器即可,至于这个文件是从 Apache 还是从 Tomcat 取得,开发人员完全无需关注。

HTTP 持久连接

持久连接(Keep-Alive)也叫做长连接,它是一种 TCP 的连接方式,连接会被浏览器和服务器所缓存,在下次连接同一服务器时,缓存的连接被重新使用。HTTP 无状态性表示了它不属于长连接,但 HTTP/1.1 提供了对长连接的支持(不过这必须依赖浏览器和服务器双方均支持长连接功能才行),最常见的 HTTP 长连接例子是“断点下载”。
浏览器在请求的头部添加 Connection:Keep-Alive,以此告诉服务器“我支持长连接,你支持的话就和我建立长连接吧”,而倘若服务器的确支持长连接,那么就在响应头部添加“Connection:Keep-Alive”,从而告诉浏览器“我的确也支持,那我们建立长连接吧”。服务器还可以通过 Keep-Alive:timeout=..., max=...的头部告诉浏览器长连接失效时间。
配置长连接通常是要服务器支持设置,有测试数据显示,使用长连接和不使用长连接的性能对比,对于 Tomcat 配置的 maxKeepAliveRequests 为 50 来说,效率竟然提升了将近 5 倍。

GZIP 压缩技术

HTTP协议支持GZIP的压缩格式,当服务器返回的HTML信息报头中包含Content-Encoding:gzip,它就告诉浏览器,这个响应的返回数据已经压缩成GZIP格式,浏览器获得数据后要进行解压缩操作,一定程度上减轻了服务器传输数据的压力。
很多服务器已经支持通过配置来自动将HTML信息压缩成GZIP,比如tomcat、又比如很火的Nginx。如果无法配置服务器级别的GZIP压缩机制,可以改为程序压缩。

HTTP 协议的合理使用

浏览器缓存带来的性能提升已经众人皆知了,而很多人却并不知道浏览器的缓存过期时间、缓存删除、什么页面可以缓存等,都可以由我们程序员来控制,只要您熟悉 HTTP 协议,就可以轻松的控制浏览器。

扩展阅读:深入理解 HTTP 协议

CDN 机制

    所谓的CDN,就是一种内容分发网络,它采用智能路由和流量管理技术,及时发现能够给访问者提供最快响应的加速节点,并将访问者的请求导向到该加速节点,由该加速节点提供内容服务。
    通俗点说,你在成都(浏览器)购买了北京卖家(服务器)的产品,北京卖家通过快递(CDN服务)寄送包裹,从北京到成都可以走路、坐汽车、火车或飞机,而采用CND的快递会选择飞机直达,因为这种寄送方式最快。

当然使用 CDN 有两个注意事项:
1、CDN 加速服务很贵,如果你觉得你的网站值得加速,可以选择购买;
2、CDN 不适合局域性网站,比如你的网站只有某一个片区访问或者局域网访问,因为区域性网络本来就很近,无需 CDN 加速。

懒加载与预加载

    预加载和懒加载,是一种改善用户体验的策略,它实际上并不能提高程序性能,但是却可以明显改善用户体验或减轻服务器压力。
    预加载表示当前用户在请求到需要的数据之后,页面自动预加载下一次用户可能要看的数据,这样用户下一次操作的时候就立刻呈现,依次类推。
    懒加载表示用户请求什么再显示什么,如果一个请求要响应的时间非常长,就不推荐懒加载。

渐进式增强设计

    渐进式增强设计的通俗解释就是:首先写一段满足所有浏览器的基本样式,再在后面针对不同高级浏览器编写更漂亮的样式
    如下代码,所有浏览器都支持background-color: #2067f5;满足了浏览器基本现实需求,而后面的background-image: -webkit-gradient等则为不同高级浏览器使用,只要浏览器识别就能执行这段代码(不识别,CSS也不会报错只会直接忽略)。

避免空链接属性

    如`<img src=""><a href="">`这样的设置方式是非常不可取的,即使链接为空,在旧的浏览器也会以固定步骤发送请求信息。
    另外`<a href="#"></a>`也不可取,最好的方式是在链接中加一个空的js代码`<a href="javascript:void();"></a>`

    # web访问流程

    用户输入网站域名

    通过DNS解析,找到目标服务器IP

    向ip地址发起请求,数据经互联网达到目标服务器

    目标服务器收到请求数据,进行处理(执行程序、访问数据库、文件服务器等)

    处理完成,将响应数据又经互联网返回给用户浏览器

    浏览器得到结果进行计算渲染显示给用户

    # DNS 解析优化

    从这个过程我们可以看到,优化的地方主要是减少DNS解析次数,而如果用户浏览器设置了缓存,则再第二次访问相同域名的时候就不会去请求DNS服务器,直接用缓存中的IP地址发出请求。

    因此这个过程主要取决于浏览器的设置。现在主流的浏览器默认设置了DNS的预取功能(DNS Prefetch),当然你也可以主动告知浏览器我的网站需要做DNS预取:

    `<meta http-equiv="x-dns-prefetch-control" content="on" />`

    # 数据传输的优化

    CDN 部署

    增加网站服务器上传宽带

    # 处理上的优化

    ##缓存

    根据需要使用本地缓存或分布式缓存

    ##使用异步操作

    这种方式不仅可以提高性能,也提高了系统的扩展性

    使用同步请求的方式,在高并发的情况下,会对数据库造成很大的压力,也会让用户感觉响应时间过长。

    异步请求方式,则可以快速的对用户做出响应,而具体的数据库操作请求,则通过消息队列服务器发送给数据库服务器,做具体的插入操作。插入操作的结果则已其他方式通知客户端。

    例如一般在订票系统当中,出票行为就是异步完成,最终的出票结果会以邮件或其他方式告知用户

    ##代码优化

    这里就不在详细描述,另一篇随笔《怎样编写高质量的java代码》对代码质量和风格做过大致的介绍,有兴趣可以看一下。

    ##存储优化

    大型网站中海量的数据读写对磁盘造成很大压力,系统最大的瓶颈还是在磁盘的读写。可以考虑使用磁盘阵列、分布式储存来改善存储的性能。

    性能的指标和测试