深入分析JavaWeb技术内幕笔记(知识补充)

一、深入Web请求过程

  • Web2.0

Web2.0,指的是一个利用Web的平台,由用户主导而生成的内容互联网产品模式。Web2.0的应用可以让人了解到目前万维网正在进行的一种改变——从一系列网站到一个成熟的为最终用户提供网络应用的服务平台

这种概念的支持者期望Web2.0服务将在很多用途上最终取代桌面计算机应用。Web2.0并不是一个技术标准,不过它包含了技术架构及应用软件。它的特点是鼓励作为信息最终利用者通过分享,使得可供分享的资源变得更丰盛;相反的,过去的各种网上分享方式则显得支离破碎。

主要特点


用户参与网站内容制造

web2.0更加注重交互性

符合web标准的网站设计

web2.0网站与web1.0没有绝对的界限

web2.0的核心不是技术而在于指导思想

web2.0是互联网的一次理念和思想体系的升级换代,由原来的自上而下的由少数资源控制者集中控制主导的互联网体系,转变为自下而上的由广大用户集体智慧和力量主导的互联网体系

web2.0体现交互,可读可写,体现出的方面是各种微博、相册,用户参与性更强

相关技术

对于Web2.0概念的说明,通常采用典型Web2.0网站案例介绍,加上对部分Web2.0相关技术的解释,这些Web2.0技术主要包括:博客(BLOG)、RSS、百科全书(Wiki)、网摘 、社会网络(SNS)、P2P、即时信息(IM)等。


开发平台

Spacebuilder、UCenterHome、phpwind、Elgg、OpenPNE、FocusSNS等等

现有产品




  • CDN(内容分发网络)

全称是Content Delivery Network,即内容分发网络

基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决Internet网络拥挤的状况,提高用户访问网站的响应速度

CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

内容分发网络(CDN)是一个经策略性部署的整体系统,包括分布式存储负载均衡、网络请求的重定向和内容管理4个要件,而内容管理和全局的网络流量管理(Traffic Management)是CDN的核心所在

关键技术


内容存储技术

CDN需要考虑两个方面的内容存储问题,一个是内容源的集中存储,另一个是内容在Cache节点中的分布式存储。由于内容的规模比较大,内容的吞吐量较大,因此,通常采用海量存储架构。目前常用的存储技术主要有直连附加存储(DAS)、网络附加存储(NAS)和存储区域网(SAN)

媒体内容分发技术

内容分发技术通过网络的构建减小IP骨干网络的传输压力,将连接到IP网络上的内容迅速分发到用户终端

CDN主要由初始服务器、分布在边缘的缓存服务器重定向DNS服务器内容交换服务器组成。

初始服务器负责生成服务器信息内容;

缓存服务器负责存储初始服务器的部分或全部信息内容;

重定向DNS服务器向用户提供最近的服务器IP地址,减轻骨干网的压力;

内容交换服务器完成各缓存服务器之间的负载均衡功能;内容管理服务器负责整个网络各缓存服务器中存储的内容的管理,为各缓存服务器制定相应的缓存策略,以提高缓存服务器的服务质量。

负载均衡技术

负载均衡是整个CDN的核心,负载均衡的准确性和效率直接决定了整个CDN的效率和性能。

负载均衡技术将网络的流量尽可能均匀地分配到几个能完成相同任务的服务器或网络节点上进行处理,避免部分网络节点过载而另一部分节点空闲的不利状况,既可以提高网络流量,又可以提高网络的整体性能

  • 查看HTTP信息
要看一个HTTP请求的请求头和响应头等信息,很多浏览器都支持F12来查看
搜狗浏览器如下所示

火狐浏览器如下所示

二、深入分析Java I/O的工作机制

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

  • 为什么需要第三次握手?

还要再发送一次确认是为了,防止已失效的连接请求报文段突然又传到了B,因而产生错误。

已失效的报文段:正常情况下:A发出连接请求,但因为丢失了,故而不能收到B的确认。于是A重新发出请求,然后收到确认,建立连接,数据传输完毕后,释放连接,A发了2个,一个丢掉,一个到达,没有“已失效的报文段”

但是,某种情况下,A的第一个在某个节点滞留了,延误到达,本来这是一个早已失效的报文段,但是在A发送第二个,并且得到B的回应,建立了连接以后,这个报文段竟然到达了,于是B就认为,A又发送了一个新的请求,于是发送确认报文段,同意建立连接,假若没有三次的握手,那么这个连接就建立起来了(有一个请求和一个回应),此时,A收到B的确认,但A知道自己并没有发送建立连接的请求,因为不会理睬B的这个确认,于是呢,A也不会发送任何数据,而B呢却以为新的连接建立了起来,一直等待A发送数据给自己,此时B的资源就被白白浪费了。但是采用三次握手的话,A就不发送确认,那么B由于收不到确认,也就知道并没有要求建立连接。

简而言之:第三次握手,主机A发送一次确认是为了防止:如果客户端迟迟没有收到服务器返回的确认报文,这时他会放弃连接,重新启动一条连接请求;但问题是:服务器不知客户端没收到,所以他会收到两个连接请求,白白浪费了一条连接开销。

  • 为什么TCP释放连接需要四次?

TCP建立连接要进行三次握手,而断开连接要进行四次。这是由于TCP的半关闭造成的。因为TCP连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时每个方向上都要单独进行关闭。这个单方向的关闭就叫半关闭。当一方完成它的数据发送任务,就发送一个FIN来向另一方通告将要终止这个方向的连接。

  • 注意:

1)发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据,比如:如主机A收到主机B的FIN断开TCP连接请求,只是表示主机B已经发送完数据,主机A收到FIN后作出应答,并终止这个方向的数据传输,此时处于半关闭状态。但是主机A仍然可以发送数据的,只有当主机A发送完数据并发送FIN给主机B时,主机B才停止这个方向的数据传输,并关闭TCP连接。

2)在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关闭,你可以写代码试试。
参考地址:

http://blog.youkuaiyun.com/guyuealian/article/details/52535294

http://blog.youkuaiyun.com/superficial_/article/details/74910352

http://blog.youkuaiyun.com/sinat_36118270/article/details/73610518?locationNum=5&fps=1

http://blog.youkuaiyun.com/Payshent/article/details/73773789?locationNum=8&fps=1

八、JVM内存管理

Java程序实际上是把内存控制的权力交给了Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那排查错误将会成为一项异常艰难的工作。而且了解了Java的内存管理,有助于优化JVM,从而使得自己的应用获得最佳的性能体验。所以还等什么,赶紧跟着我来一起学习这方面的知识吧~

Java内存管理分为两个方面:内存分配和垃圾回收,下面我们一一的来看一下。

Jvm定义了5个区域用于存储运行时的数据,如下:

  • 程序计数器(PC、Program Counter Register)

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看做当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来取下一条需要执行的字节码指令,分支、跳转、循环、异常处理、线程恢复等基础功能都需要这个计数器来完成。

当线程正在执行的是一个Java方法,这个计数器记录的是在正在执行的虚拟机字节码指令的地址;当执行的是Native方法,这个计数器值为空。

注:每条线程都会有一个独立的程序计数器,唯一不会出现OOM的。

  • Java栈/虚拟机栈(VM Stack)

Java栈就是Java中的方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧,这个栈帧用于存储局部变量表、操作数栈、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用、方法返回地址等信息,每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表,顾名思义,想必不用解释大家应该明白它的作用了吧。就是用来存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参)。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。局部变量表的大小在编译器就可以确定其大小了,因此在程序执行期间局部变量表的大小是不会改变的。

操作数栈,想必学过数据结构中的栈的朋友想必对表达式求值问题不会陌生,栈最典型的一个应用就是用来对表达式求值。想想一个线程执行方法的过程中,实际上就是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。

指向运行时常量池的引用,因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。

方法返回地址,当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

异常可能性:对于栈有两种异常情况,如果线程请求的栈深度大于栈所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态拓展,在拓展的时无法申请到足够的内存,将会抛出OutOfMemoryError异常

  • 本地方法栈(Native Method Stack)

本地方法栈与Java栈所发挥的作用是非常相似的,它们之间的区别不过是Java栈执行Java方法,本地方法栈执行的是本地方法。有的虚拟机直接把本地方法栈和虚拟机栈合二为一。

异常可能性:和Java栈一样,可能抛出StackOverflowError和OutOfMemeryError异常

  • Java堆(Heap)

对于大多数应用来说,Java堆是Java虚拟机所管理的内存中最大的一块,在虚拟机启动时创建。此内存区域的目的就是存放对象实例以及数组(当然,数组引用是存放在Java栈中的),几乎所有的对象实例都在这里分配内存,当然我们后面说到的垃圾回收器的内容的时候,其实Java堆就是垃圾回收器管理的主要区域。

从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(TLAB)。Java堆可以处于物理上不连续的内存空间,只要逻辑上连续的即可。在实现上,既可以实现固定大小的,也可以是扩展的。

异常可能性:如果堆中没有内存完成实例分配,并且堆也无法再拓展时,将会抛出OutOfMemeryError异常

  • 方法区(Method Area)

方法区它用于存储已被虚拟机加载的类信息(包括类的名称、方法信息、字段信息)、常量、静态变量、以及编译器编译后的代码等数据。

1)运行时常量池

运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载器进入方法区后的运行时异常常量池存放。它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法(将字符串的值放到常量池)。

相对而言,垃圾收集行为在这个区域比较少出现,但并非数据进了方法区就永久的存在了,这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。 

异常可能性:当方法区无法满足内存分配需求时,将抛出OutOfMemeryError异常

直接内存

直接内存不是虚拟机运行时数据区的一部分,在NIO类中引入一种基于通道与缓冲区的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,或直接使用Unsafe.allocateMemory,但不推荐这种方式。

直接内存的分配不会受到Java堆大小的限制,但是会受到本机内存大小的限制,所有也可能会抛OutOfMemoryError异常。

说明:

线程私有:程序计数器,Java栈,本地方法栈

线程共享:Java堆,方法区

  • Java中的引用类型有4种,由强到弱依次如下

1) 强引用(StrongReference)是使用最普遍的引用,类似:“Object obj = new Object()” 。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

2) 软引用(Soft Reference)是用来描述一些有用但并不是必需的对象,如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

3) 弱引用(WeakReference)也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

4) 虚引用(PhantomReference)也称为幽灵引用或者幻影引用,它是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。


参考地址:

http://blog.youkuaiyun.com/wdong_love_cl/article/details/51597854?locationNum=1&fps=1

http://blog.youkuaiyun.com/u013142781/article/details/50830754?locationNum=2&fps=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值