本文主要是介绍电商系统系统笔记之freemark和velocity,CDN,长连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. Velocity和freemark是什么,为什么
我们都知道,缓存可以提高查询性能,但是当用户访问量很大时,单纯依靠缓存已经不行了,为什么这么说呢?这是因为我们在访问商品详情的时候由于每款商品都不一样,因此每款商品的详情页都是动态生成的,每查看一次,页面就要重新渲染一次,渲染的过程是消耗时间的,当用户访问量很大时,这便在一定程度上降低了系统性能。那么怎么解决这个问题呢?这便引出了我们今天要学习的内容--"网页静态化",所谓网页静态化,是指我们根据一定的模板,事先把要展示的页面生成静态页面,存放到服务器,当用户访问某商品详情页时便可以直接从服务器获取相应的静态页,不用重新渲染,这就在很大程度上提升了系统性能。
那么用什么技术来实现静态化呢?目前常用的两种技术是velocity和freemarker,我们学习其中最流行的freemarker。那么什么是freemarker?
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。需要准备数据在真实编程语言中来显示,比如数据库查询和业务运算,之后模板显示已经准备好的数据。在模板中,主要用于如何展现数据,而在模板之外注意于要展示什么数据
2. 网页静态化
网站静态化的关键点是动静分离,解决这个关键点的本质就是为了降低网速对网站加载效率的影响
静态网站非常简单,它就是通过一个url访问web服务器上的一个网页,web服务器接收到请求后在网络上使用http协议将网页返回给浏览器,浏览器通过解析http协议最终将页面展示在浏览器里,有时这个网页会比较复杂点,里面包含了一些额外的资源例如:图片、外部的css文件、外部的js文件以及一些flash之类的多媒体资源,这些资源会单独使用http协议把信息返回给浏览器,浏览器从页面里的src,href、Object这样的标签将这些资源和页面组合在一起,最终在浏览器里展示页面。但是不管什么类型的资源,这些资源如果我们不是手动的改变它们,那么我们每次请求获得结果都是一样的。这就说明静态网页的一个特点:静态网页的资源基本是不会发生变化的。因此我们第一次访问一个静态网页和我们以后访问这个静态网页都是一个重复的请求,这种网站加载的速度基本都是由网络传输的速度,以及每个资源请求的大小所决定,既然访问的资源基本不会发生变化,那么我们重复请求这些资源,自己在那里空等不是很浪费时间吗?如是乎,浏览器出现了缓存技术,我们开发时候可以对那些不变的资源在http协议上编写相应指令,这些指令会让浏览器第一次访问到静态资源后缓存起这些静态资源,用户第二次访问这个网页时候就不再需要重复请求了,因为请求资源本地缓存,那么获取它的效率就变得异常高效
看看我们管理后台的登录页面,不请求服务端数据,也不会发生数据变化,所以不用每次请求,可以cache
PS:页面指令
网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。其作用根据不同的重新浏览方式分为以下几种情况:
(1) 打开新窗口
值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。
而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:
Cache-control: max-age=5(表示当访问此网页后的5秒内再次访问不会去服务器)
(2) 在地址栏回车
值为private或must-revalidate则只有第一次访问时会访问服务器,以后就不再访问。
值为no-cache,那么每次都会访问。
值为max-age,则在过期之前不会重复访问。
(3) 按后退按扭
值为private、must-revalidate、max-age,则不会重访问,
值为no-cache,则每次都重复访问
(4) 按刷新按扭
无论为何值,都会重复访问
Cache-control值为“no-cache”时,访问此页面不会在Internet临时文章夹留下页面备份。
3. 静态资源加速利器-CDN
静态资源一般不会变化,所以很容易迁移。我们可以利用CDN服务,把静态资源部署到专业提供商的CDN服务节点上去,从而实现资源的加速下载。CDN节点也具有缓存功能。CDN节点具有两个主要特性:
1 就近访问,负载均衡
2 CDN节点缓存静态资源
看一个阿里云的网站加速实战场景:
4. 减少请求-长连接
每次连接都会经历以下阶段:
创建socket-打开socket-socket连接-传输数据-关闭socket
如果在高并发,小数据量的情况下,频繁建立关闭连接相当耗费资源,所以此场景下适合用长连接(究竟是同步还是异步??每个请求之间)。答案是同步的,非pipeline模式下,一个请求处理完再处理下一个请求
在http1.1,keep-alive 默认是开启的,但是1.0是关闭的
长连接优点:
1. 减少cpu,内存消耗,因为连接数减少
2.长连接分为两个版本:pipeline和非pipeline,pipeline只是应用于幂等请求get和head,post和put不应该使用,新建连接也不适用,因为不知道server是否支持,所以pipeline长连接适用于重启一个存在等keepalive连接.但是现在很多浏览器默认关闭pipeline功能,因为产生很多bug,chrome暂时不支持开启,firefox可以手动开启,比如图片混乱,性能问题
Only idempotent requests can be pipelined, such as GET and HEAD requests. POST and PUT requests should not be pipelined. We also should not pipeline requests on a new connection, since it has not yet been determined if the origin server (or proxy) supports HTTP/1.1. Hence, pipelining can only be done when reusing an existing keep-alive connection.
如果不是pipeline,接受到响应后才会发送下一个请求,相比短连接减少了连接的建立关闭开销,也减少了1个RTT。
如果是pipeline,那么一次pipeline多个请求,不需要等待结果,处理更加高效.但是因为http是无状态,所以response返回的顺序必须与请求发送的顺序一致。这个很难做到。
For pipelining to work, responses must come back in the order they were requested. A naive server implementation might just send the response as soon as it has been calculated. If multiple requests are sent in parallel, and the first request one takes longer to process (e.g. processing a larger image), then the responses will be out of order.
This is a problem for the client since HTTP is a stateless protocol, the client has no way to match the requests with the responses. It is reliant on the order the responses came back in.
A server MUST send its responses to those requests in the same order that the requests were received.
- Safari apparently used HTTP pipelining for images at least. This results in an issue where images would be swapped around.
- AFNetworking used to use pipelining, but it was pulled after a reported issue.
- All major browsers (other than Opera) have HTTP pipelining is disabled or not implemented.
HTTP/1.1的默认模式使用带流水线的持久连接。这种情况下,HTTP客户每碰到一个引用就立即发出一个请求,因而HTTP客户可以一个接一个紧挨着发出各个引用对象的请求。服务器收到这些请求后,也可以一个接一个紧挨着发出各个对象。如果所有的请求和响应都是紧挨着发送的,那么所有引用到的对象一共只经历1个RTT的延迟(而不是像不带流水线的版本那样,每个引用到的对象都各有1个RTT的延迟)。另外,带流水线的持久连接中服务器空等请求的时间比较少。与非持久连接相比,持久连接(不论是否带流水线)除降低了1个RTT的响应延迟外,缓启动延迟也比较小。其原因在于既然各个对象使用同一个TCP连接,服务器发出第一个对象后就不必再以一开始的缓慢速率发送后续对象。相反,服务器可以按照第一个对象发送完毕时的速率开始发送下一个对象。
如何开启pipeline?如何知道请求处理完成?
如何知道http消息的长度:
Keep-Alive模式,客户端如何判断请求所得到的响应数据已经接收完成(或者说如何知道服务器已经发生完了数据)?
我们已经知道 了,Keep-Alive模式发送完数据HTTP服务器不会自动断开连接,所有不能再使用返回EOF(-1)来判断;
(当然你一定要这样使用也没有办法,可 以想象那效率是何等的低)!下面我介绍两种来判断方法。
3.1、使用消息首部字段Conent-Length
故名思意,Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。
但是如果消息中没有Conent-Length,那该如何来判断呢?又在什么情况下会没有Conent-Length呢?请继续往下看……
3.2、使用消息首部字段Transfer-Encoding
当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,
然后通过Content-length消息首部字段告诉客户端 需要接收多少数据。
但是如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encoding:chunk模式来传输 数据了。
即如果要一边产生数据,一边发给客户端,服务器就需要使用"Transfer-Encoding: chunked"这样的方式来代替Content-Length。
长连接缺点
正确设置超时,没有其他问题,现在http默认开启长连接
5. Tcp的keepalive和http的keep-alive
其中keep-alive相关的参数有三个:
tcp_keepalive_intvl (integer; default: 75; since Linux 2.4)The number of seconds between TCP keep-alive probes.tcp_keepalive_probes (integer; default: 9; since Linux 2.2)The maximum number of TCP keep-alive probes to send before giving up and killing the connection if noresponse is obtained from the other end.tcp_keepalive_time (integer; default: 7200; since Linux 2.2)The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep-alives are sent only when the SO_KEEPALIVE socket option is enabled. The default value is 7200 seconds (2hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes an intervalof 75 seconds apart) when keep-alive is enabled.
这些的默认配置值在/proc/sys/net/ipv4 目录下可以找到。
可以直接用cat来查看文件的内容,就可以知道配置的值了。
也可以通过sysctl命令来查看和修改:
# 查询
cat /proc/sys/net/ipv4/tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_time
#修改
sysctl net.ipv4.tcp_keepalive_time=3600
为什么应用层需要heart beat/心跳包?
默认的tcp keep-alive超时时间太长
默认是7200秒,也就是2个小时。
socks proxy会让tcp keep-alive失效
socks协议只管转发TCP层具体的数据包,而不会转发TCP协议内的实现细节的包(也做不到),参考socks_proxy。
所以,一个应用如果使用了socks代理,那么tcp keep-alive机制就失效了,所以应用要自己有心跳包。
socks proxy只是一个例子,真实的网络很复杂,可能会有各种原因让tcp keep-alive失效。
这篇关于电商系统系统笔记之freemark和velocity,CDN,长连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!