B/S架构两方面好处:客户端使用统一的浏览器Browser;服务端基于统一的HTTP协议。
HTTP协议采用无状态的短连接的通信方式,通常情况下一次请求就完成了一次数据交互,通常也对应一个业务逻辑,然后这次通信连接就断开了。
如何发起一个请求
当一个用户在浏览器里输入www.pingan.com这个URL时:
1.请求DNS把这个域名解析成对应的IP地址。
2.根据IP地址在互联网上找到对应的服务器,向这个服务器发起一个get请求。
3.由这个服务器决定返回默认的数据资源给访问的用户。
在服务器端实际上还有很复杂的业务逻辑:
服务器可能有很多台,到底指定哪台服务器来处理请求,需要一个负载均衡设备来平均分配所有用户的请求。
请求的数据是存储在分布式缓存中还是一个静态文件中,或是在数据库里。
当数据返回浏览器时,浏览器解析数据发现还有一些静态资源(如CSS、js或者图片)时又会发起另外的HTTP请求,而这些请求很可能会在CDN上,那么CDN服务器上又会处理这个用户的请求。
不管网络架构如何变化,始终有一些固定不变的原则:
互联网上所有资源都要用一个URL来表示。
必须基于HTTP协议与服务端交互。
数据展示必须在浏览器中进行。
如何发起一个HTTP请求和如何建立一个Socket连接区别不大,只不过outputStream.write写的二进制字节数据格式要符合HTTP协议。
浏览器在建立Socket连接之前,必须根据地址栏里输入的URL的域名DNS解析出IP地址,再根据这个IP地址和默认80端口与远程服务器建立socket连接,然后浏览器根据这个URL组装成一个get类型的HTTP请求头,通过outputStream.write发送到目标服务器,服务器等待inputStream.read返回数据,最后断开这个连接。
不同浏览器在如何使用这个已经建立好的连接,以及根据什么规则来管理连接,有各种不同的实现方法。
一句话:发起一个HTTP请求的过程就是建立一个socket通信的过程。
HTTP协议解析
要理解HTTP协议,最重要的就是要熟悉HTTP协议中的HTTP Header, HTTP Header控制着互联网上成千上万的用户的数据的传输。
最关键的是,它控制着用户浏览器的渲染行为和服务器的执行逻辑。
常见的HTTP请求头:
Accept-Charset: 用于指定客户端接受的字符集
Accept-Encoding 指定可接受的内容编码,如Accept-Encoding:gzip.defate
Accept-Language 指定一种自然语言,如Accept-Language;zh-cn
Host 用于指定被请求资源的Internet主机和端口号,如Host:www.pingan.com
User-Agent 客户端将它的操作系统、浏览器和其他属性告诉服务器
Connection 当前连接是否保持,如Connection:Keep-Alive
常见的HTTP响应头:
Server 使用的服务器名称,如Server.Apache/1.3.6(UNIX)
Content-Type 用来指明发送给接收者的实体正文的媒体类型,如Content-Type:text/html;charset=GBK
Content-Encoding 与请求报头Accept-Encoding对应,告诉浏览器服务端采用的是什么压缩编码
Content-Language 描述了资源所用的自然语言,与Accept-Language对应
Content-Length 指明实体正文的长度,用以字节方式存储的十进制数字来表示
Keep-Alive 保持连接的时间,如Keep-Alive:timeout
常见的HTTP状态码
200 客户端请求成功
302 临时跳转,跳转的地址通过Location指定
400 客户端请求有语法错误,不能被服务器识别
403 服务器收到请求,但是拒绝提供服务
404 请求的资源不在
500 服务器发生不可预期的错误
浏览器缓存机制
在我们浏览一个页面时发现有异常的情况下,通常考虑是不是浏览器做了缓存,一般的做法是按Ctrl+F5重新请求一次,重新请求的页面肯定是最新的页面。
原因: 在浏览器端,如果是按Ctrl+F5组合键刷新页面,浏览器会直接向目标URL发送请求,而不是使用浏览器缓存的数据。
其次,即使请求发送到服务端,也有可能访问到的是缓存的数据,比如,在我们的应用服务器的前端部署一个缓存服务器,如Varnish代理,那么Varnish也可能直接使用缓存数据。
所以为了保证用户能够看到最新的数据,必须通过HTTP协议来控制。
当我们在使用CTRL + F5组合键刷新一个页面时,在HTTP的请求头中会增加一些请求头,告诉服务器我们要获取最新的数据而不是缓存。Cache-Control,Pragma,Expires,Last-Modified,Etag
DNS域名解析
当用户在浏览器中输入域名并按下回车键后:
1.浏览器会检查缓存中有没有这个域名对应的解析过的IP地址,如果缓存中有,这个解析过程就将结束。浏览器缓存是受这个域名的失效时间和缓存的空间大小控制的。
2.如果用户的浏览器缓存中没有,浏览器会查找操作系统缓存中的是否有这个域名对应的DNS解析结果。
操作系统会有一个域名解析的过程,在WINDOWS中可以通过C:\Windows\System32\drivers\etc\hosts文件来设置。可以将任何域名解析到任何可以访问的IP地址。如果在这个文件中指定了一个域名对应的IP地址,那么浏览器会首先使用这个IP地址。在Linux中这个配置文件是/etc/hosts,修改这个文件可以达到同样的目的。
3.在我们的网络配置中都会有“DNS服务器地址”,这个地址就用于解决前面所说的如果两个过程无法解析时要怎么办,操作系统会把这个域名发送给这里设置的LDNS,也就是本地区的域名服务器。这个DNS通常都提供给你本地互联网接入的一个DNS解析服务。这个专门的域名解析服务器性能都会很好,它们一般都会缓存域名解析结果,当然缓存时间是受域名的失效时间控制的,一般缓存空间不是影响域名失效的主要因素。大约80%的域名解析都到这里就已经完成了,所以LDNS主要承担了域名的解析工作。
4.如果LDNS仍然没有命中,就直接到Root Server域名服务器请求解析
5.根域名服务器返回给本地域名服务器一个所查询的域的主域名服务器(gTLD Server)地址。gTLD是国际顶级域名服务器,如.com,.cn、.org等。全球只有13台左右。
6.本地域名服务器(Local DNS Server)再向上一步返回的gTLD服务器发送请求。
7.接受请求的gTLD服务器查找并返回此域名对应的Name Server域名服务器的地址,这个Name Server通常就是你注册的域名服务器,例如你在某个域名服务提供商申请的域名,那么这个域名解析任务就由这个域名提供商的服务器来完成
8.Name Server域名服务器会查询存储的域名和IP的映射关系表,正常情况下都根据域名得到目标IP记录,连同一个TTL值返回给DNS Server域名服务器。
9.返回该域名对应的IP和TTL值,Local DNS Server会缓存这个域名和IP的对应关系,缓存的时间由TTL值控制。
10.把解析的结果返回给用户,用户根据TTL值缓存在本地系统缓存中,域名解析过程结束。
在实际的DNS解析过程中,可能还不止这10个步骤,如Name Server也可能有多级,或者有一个GTM来负载均衡控制,这都有可能会影响域名解析的过程。
DNS域名解析后会缓存解析结果,其中主要在两个地方缓存结果,一个是Local DNS Server,另外一个是用户的本地机器。这两个缓存都是TTL值和本机缓存大小控制的,但是最大缓存时间是TTL值,基本上Local DNS Server 的缓存时间就是TTL控制的,很难人工介入,但是我们的本机缓存可以通过如下方式清除:
Windows在命令行模式下执行ipconfig/flushdns命令来刷新缓存
linux下可以通过/etc/init.d/nscd restart来清除缓存。
重启依然是解决很多问题的第一选择。
在Java应用中JVM也会缓存DNS的解析结果,这个缓存是在InetAddress类中完成的,有两种缓存策略:一种是正确解析结果缓存,另一种是失败的解析结果缓存。这两个缓存时间由两个配置项控制,配置项是在%JAVA_HOME%\lib\security\java.security文件中配置的。两个配置项分别是networkaddress.cache.ttl和networkaddress.cache.negative.ttl,他们的默认值分别是-1(永不失效)和10(缓存10秒)。修改这两个值的几种方式:直接修改java.security文件中的默认值、在java的启动参数中增加-Dsun.NET.inetaddr.ttl=xxx来修改默认值、通过InetAddress类动态修改。
如果我们需要用InetAddress类解析域名时,一定要是单例模式,不然会有严重的性能问题,如果每次都创建InetAddress实例,每次都要进行一次完整的域名解析,非常耗时。
几种域名解析方式:
域名解析记录主要分为:
A记录,A代表的是Address,用来指定域名对应的IP地址,如将item.pingan.com指定到115.238.23.241,将switch.pingan.com指定到121.14.24.241。A记录可以将多个域名解析到一个IP地址,但是不能将一个域名解析到多个IP地址。
MX记录,表示的是Mail Exchange,就是可以将某个域名下的邮件服务器指向自己的Mail Server,如pingan.com域名的A记录IP地址是115.238.25.245,如果MX记录设置为115.238.25.246所在的服务器,而正常通过Web请求的话仍然解析到A记录的IP地址。
CNAME记录,全称是Canonical Name(别名解析)。所谓的别名解析就是可以为一个域名设置一个或者多个别名。如将pingan.com解析到sunk.net,,将srcfan.com也解析到到sunk.Net。其中sunk.net分别是pingan.com和srcfan.com的别名。
NS记录,为某个域名指定DNS解析服务器,也就是这个域名有指定 的IP地址去解析。
TXT记录,为某个主机名或域名设置说明。
CDN工作机制
CDN即内容分布网络(Content Delivery Network),它是构筑在现有Internet上的一种先进的流量分配网络。其目的是通过现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。有别于镜像,它比镜像更智能,可以这样做一个比喻:CDN=镜像(Mirror) + 缓存(cache) + 整体负载均衡(GSLB),因而,CDN可以明显提高Internet中信息流动的效率。
目前CDN都以缓存网站中的静态数据为主,如CSS、JS、图片和静态网页等数据。用户在从主站服务器请求到动态内容后再从CDN上下载这些静态数据,从而加速网页数据内容的下载速度,如淘宝有90%以上的数据都是由CDN来提供的。
通常来说CDN要达到以下几个目标:
可扩展(Scalability)。性能可扩展性:应对新增的大量数据、用户和事务的扩展能力;成本可扩展性:用低廉的运营成本提供动态的服务能力和高质量的内容分发。
安全性(Security)。强调提供物理设备、网络、软件、数据和服务过程的安全性,(趋势)减少因为DDoS攻击或者其他恶意行为造成商业网站的业务终端。
可靠性、响应性和执行(Reliability、Responsiveness和Performance)。服务可用性,能够处理可能的故障和用户体验的下降,通过负载均衡及时提供网络的容错机制。
CDN架构
一个用户访问某个静态文件(如CSS),这个静态文件的域名假如是cdn.pingan.com,那么首先要向Local DNS服务器发起请求,一般经过迭代解析后回到这个域名的注册服务器去解析,一般每个公司都会有一个DNS解析服务器。这时这个DNS解析服务器通常会把它重新CNAME解析到另外一个域名,而这个域名最终会被指向CDN全局中的DNS负载均衡服务器,再由这个GTM来最终分配是哪个地方的访问用户,返回给离这个访问用户最近的CDN节点。
拿到DNS解析结果,用户就直接去这个CDN节点访问这个静态文件了,如果这个节点中请求的文件不存在,就会再回到源站去获取这个文件,然后再返回给用户。
负载均衡(Load Balance)
负载均衡就是对工作任务进行平衡、分摊到多个操作单元上执行,如图片服务器、应用服务器等,共同完成工作任务。它可以提高服务器响应速度及利用效率,避免软件
或者硬件模块出现单点失效,解决网络拥塞问题,实现地理位置无关性,为用户提供较一致的访问质量。
三种负载均衡架构:
链路负载均衡
链路负载均衡也就是前面提到的通过DNS解析成不同的IP,然后用户根据这个IP来访问不同的目标服务器
负载均衡是由DNS的解析来完成的,用户最终访问哪个Web Server是由DNS Server来控制的,在这里就是由Global DNS Server来动态解析域名服务。这种DNS解析的优点是用户会直接访问目标服务器,而不需要经过其他的代理服务器,通常访问速度会更快。但是也有缺点,由于DNS在用户本地和Local DNS Server都有缓存,一旦某台Web Server挂掉,那么很难及时更新用户的域名解析结构。如果用户的域名没有及时更新,那么用户将无法访问这个域名,带来的后果非常严重。
集群负载均衡
硬件负载均衡:
硬件负载均衡的关键就是这是价格非常昂贵的设备,如F5,通常为了安全需要一主一备。它的优点很显然就是性能非常好,缺点就是非常贵,一般公司用不起的,还有就是当访问量陡然增大超出服务极限时,不能进行动态扩容。
软件负载均衡:
软件负载均衡是使用最普遍的一种负载方式,它的特点是使用成本非常低,直接使用廉价的PC就可以搭建。缺点是一般一次访问请求要经过多次代理服务器,会增加网络延时。
操作系统负载均衡
就是利用操作系统级别的软中断或者硬件中断来达到负载均衡,如可以设置多队列网卡等来实现