读 【深入分析 java web 技术内幕 ---许令波著】有感

C/S 互联网采用的长连接,B/S 采用无状态的短连接,一次请求就完成了一次数据交互,通常对应一个业务逻辑,然后这次通信链接就断开了,这是为了能够同时服务更多的用户。

互联网上的所有资源都要用一个URL来表示。URL就是统一资源定位符,如果你要发布一个服务或者一个资源到互联网上,让别人能够访问到,那么首先要确保这个URL是独一无二的。
必须基于HTTP与服务器端交互。
数据展示必须在浏览器上进行。

发起一个HTTP请求的过程实质就是建立一个socket通信的过程。

HTTP状态码:

200客户端请求成功
302 临时跳转,跳转的地址通过Location指定
400客户端请求语法错误,不能被服务器端识别
403 服务器端收到请求,但是拒绝提供服务
404  请求的资源找不到
500 服务器发生不可预期的错误
CTRL+F5:CTRL+F5刷新页面时,在HTTP的请求头中会增加一个请求头,它会告诉服务端我要获取最新的数据而不是缓存。
Cache-Control:no-cache. 它和其他请求字段(Expires)同时出现时,会覆盖别的字段。
Expires:Sat,25 Feb 2012 12:22:17 GMT,后面跟着一个日期和时间,超过这个时间值后,缓存的内容将失效,也就是浏览器在发出请求前检查这个页面的这个字段,看页面是否过期,过期了就重新向服务器发起请求。
使用dos命令查看解析结果:nslookup
如果需要用InetAddress 类解析域名,必须是单例模式,不然会有严重的性能问题。
HTTP header控制着互联网的用户的数据传输,浏览器的渲染行为和服务器的执行逻辑。
CDN都以缓存网站中的静态数据为主:css js 图片 和静态页面等数据。
用户在主站服务器请求到动态内容后,再从CDN上下载这些静态数据,从而加速网页数据内容的下载速度。

CDN要达到以下目标:

1.可扩展:1.性能可扩展性:应对新增的大量数据,用户和事务的扩展能力;
2.成本可扩展性:用低廉的运营成本提供动态的服务能力和高质量的内容分发。
2.安全性:强调提供物理设备,网络,软件,数据和服务过程的安全性,减少因为DDos攻击或者其他恶意行为造成商业网站的业务中断。
3.可靠性,响应和执行服务可用性指能够处理可能的故障和用户体验下降的问题,通过负载均衡及时提供网络的容错机制。
负载均衡结构:链路负载均衡,集群负载均衡,操作系统负载均衡。
链路负载均衡:通过DNS解析成不同的IP,然后用户根据这个IP来访问不同的目标服务器。负载均衡是由DNS的解析来完成的,用户最终房屋内哪个web server是由DBS server来控制的。优点是用户会直接访问目标服务器,不需要经过其他代理服务器,通常访问速度会更快。缺点:由于DNS在用户本地和LOCAL DNS SERVER都有缓存,一旦某台web server 挂掉,就很难及时更新用户的域名解析结构。如果用户的域名没有及时更新,那么用户将无法访问这个域名。

集群负载均衡分为硬件负载均衡和软件负载均衡:

软负载均衡软件负载均衡是使用最普遍的一种负载均衡方式,特点是使用成本非常低,直接使用廉价的PC就可以搭建。缺点是一般一次访问请求要经过多次代理服务器,会增加网络延迟。
硬件负载均衡硬件负载均衡的关键就是机器贵,通常为了安全需要一主一从,性能非常好,就是贵,当访问量突然增大超出服务极限时,不能进行动态扩容。
CDN :技术原理就是在CDN的DNS解析中通过动态的链路探测来寻找回源最好的一条路径,然后通过DNS的调度将所有请求调度到选定的这条路径上的回源,从而加速用户访问的效率。

java io 分为四组:

1.基于字节操作的I/O 接口:inputStream /outputStream 
2.基于字符操作的I/O 接口:writer /reader 传输的数据格式  
3.基于磁盘操作的I/O 接口:File
4.基于网络操作的I/O 接口:Socket    传输的数据方式
总结:不管是磁盘还是网络传输,最小的存储单元都是字节。
标准访问文件的方式:就是当应用程序调用Read()接口时,操作系统检查在内核的高速缓存中有没有需要的数据,如果已经有缓存了,那么就直接从缓存中返回,如果没有,则从磁盘中读取,然后缓存在操作系统的缓存中。

写入的方式是,用户的应用程序调用write()接口将数据从用户地址空间复制到内核地址空间的缓存中。

直接的访问I/O的方式:应用程序直接访问磁盘数据,而不经过操作系统内核数据缓冲区,这样做的目的就是减少一次从内核缓冲区到用户程序缓冲的数据复制。[负面影响:如果访问的数据不在应用程序缓存中,那么每次数据都会直接从磁盘进行加载,这种加载会非常慢]通常直接I/O和异步I/O 结合使用,会得到比较好的性能。
异步访问文件的方式:异步访问文件的方式就是当访问数据的线程发出请求之后,线程会接着去处理其他的事情,而不是阻塞等待。但请求的数据返回后继续处理下面的操作。这种访问文件的方式可以明显的提高应用程序的效率,但是不会改变访问文件的效率。
NIO:FileChanel.transferTo,FileChannel.transferFrom   FileChannel.map

FileChannel.transferXXX与传统的访问文件方式相比可以减少数据从内核到用户空间的复制,数据直接在内核空间中移动,在Linux中使用sendfile 系统调用。

现在为了提升磁盘I/O的性能,通常采用一种叫做RAID的技术,就是将不同的磁盘组合起来已提高I/O性能。

通常提升磁盘I/O性能的方法有:

1.增加缓存,减少磁盘访问次数。
2.优化磁盘的管理系统,设计最优的磁盘方式策略,以及磁盘的寻址策略,这是在底层操作系统层面考虑的。
3.设计合理的磁盘存储数据块,以及访问这些数据块的策略,这是在应用层面考虑的。[设计索引,通过寻址索引来加快和减少磁盘的访问量,还可以采用异步和非阻塞的方式加快磁盘的访问速度]
4.应用合理的RAID策略提升磁盘I/O

网络I/O优化:

1.减少网络交互的次数
2.减少网络传输数据量的大小
3.尽量减少编码

编码格式:在计算机中存储信息的最小单元是1个字节,8个bit ,所以能表示的字符范围是0-255个。人们要表示的符号太多,无法用1个字节表示。

ASCII码:共128个,用1个字节的低7位表示,0-31是控制字符如换行,回车,删除等,32-126是打印字符,可以通过键盘输入并且能够显示出来。
ISO-88859-1码:在ASCII码上发展起来,共256个字符,但仍然时候单字节编码。
 
GB2312码:双字节编码,范围是:A1-F7,其中A1-A9是符号区,共682个字符,B0-F7是汉字区,包含6763个汉字。
GBK码:范围:7140-菲菲,总共有23940个码位,能表示21003个汉字,与GB2312兼容。
GB18030:是我国强制标准,可能是单字节,双字节,或四字节编码,与GB2312兼容
 
UTF-16:超语,unicode,采用两个字节表示unicode的转化,采用定长的表示方法。[16个bit],这也是java以utf-16作为内存的字符存储格式的一个很重要的原因。
UTF-8:因为utf-16统一采用两个字节表示一个字符,虽然非常简单,方便,但很大一部分字符用一个字节表示就可以了,所以浪费了存储空间,增大了网络传输的流量。UTF-8采用了一种变长。
编码格式比较:GB2312与GBK比较,GBK范围更大,它能处理所有的汉字字符,所以取GBK.
utf-16 和utf-8都是处理unicode编码,相对来说,utf-16的编码效率较高,从字符到字节的相互转换更简单,进行字符串操作也更好。它适合在本地和内存之间使用,可以进行字符和字节间的快速切换。但是不适合在网络间传输,因为网络传输容易损坏字节流,一旦字节流损坏将很难恢复,所以UTF-8更适合网络传输。utf-8 对ASCII字符采用单字节存储。


Reader类是在java的i/o中 读字符的父类,而inputstream 类是读字节的父类,inputstreamreader 类就是关联字节到字符的桥梁,它负责在I/O 过程中处理读取字节到字符的转换,委托streamdecoder解码。

enodeURIComponent() =>encodeURI().对编码进行处理。
String value = String(request.getParameter(name).getBytes("utf-8"),"GBK");

页面编码,controller,js 编码 

序列化java 序列化就是将一个对象转变成一串二进制表示的字节数组,通过保存或转移这些字节数据来达到持久化的目的,需要持久化,对象必须继承java.io.Serializable接口。反之,就是将这个字节数再重新造成对象。
获取classpath路径:String aa = this.getClass().getClassLoader().getResource("").toString();
内核空间和用户空间:(如果是一台登陆服务器,那么要分配更多的内核空间,因为每一个登陆用户操作系统都会初始化一个用户进程,这个进程大部分都在内核空间里运行)
java堆

java堆是用来存储java对象的内存区域,堆的大小在JVM启动时就一次向操作系统申请完成,通过-Xmx 和 Xms 两个选项来控制大小,Xmx表示堆的最大大小,Xms表示初始大小。一旦分配完成,堆的大小就将固定,不能在内存不够时再向操作系统重新申请,同时当内存空闲时也不能够多余的空间交还给操作系统。

在java堆中内存空间的管理由JVM来控制,对象创建有java应用程序控制,但是对象所占用的空间释放由管理堆内存的垃圾收集器来完成。

JVMJVM运行实际程序的实体是线程,当然线程需要内存空间来存储一些必要的数据。每个线程创建时JVM都会为它创建一个堆栈,堆栈的大小根据不同的JVM实现而不同,通常在256KB-756KB之间。
JNIJNI技术使得本机代码可以调用java方法,也就是通常所说的native memory。实际上java 运行时本身也依赖于JNI代码来实现类库功能,如文件操作,网络I/O操作或者其他系统调用。
PC寄存器:PC寄存器严格说是一个数据结构,它用于保存当前正常执行的程序的内存地址。
java 栈:总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。
cookie作用:当一个用户通过http访问一个服务器时,这个服务器会将一些key/value键值对返回给客户端服务器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据又被完整的带回给服务器。


cookie 是http 头中的一个字段,虽然http本身对这个字段并没有多少限制,但是cookie最终还是存储在浏览器里,所以不同的浏览器对cookie的存储都有一些限制(大小,数量)。【50个,不超过4KB】
session作用 :同一个客户端每次和服务器交互时,不需要每次都回传所有的cookie值,而是只要回传一个id,这个ID是客户端第一次访问服务器生成的,而且每个客户端是i为移动,这样每个客户端就有了一个唯一的ID,客户端只要回传这个ID就可以了。
cookie缺点:使用cookie来传递信息时,随着cookie个数的增加和访问量的增加,它占用的网络带宽也很大。
session缺点:大访问量时希望用session,但是session的致命弱点是不容易在多台服务器之间共享,这也限制了session的使用。
cookie 安全问题:

cookie 和session都可以跟踪客户端的访问记录,但是他们的工作方式不同,cookie通过把所有要保存的数据通过http的头部从客户端传递给服务端,又从服务端回传给客户端,所有的数据都存储在客户端的浏览器中,所以这些cookie数据可以被访问到,且可以修改,所以不安全。

cookie限制:cookie在http头部,所以通常的gzip和deflate针对http body 的压缩不能压缩cookie,如果cookie的量非常大,则可以考虑将cookie也做压缩,压缩的方式是将cookie的多个k对看成普通文本,做文本压缩。根据cookie规范,在cookie中不能包含控制字符,仅能包含ASCII 码为34-126的可见字符。所以要将压缩后的结果再进行转码,可以进行Base32 或Base64编码
分布式session 框架可以解决的问题:session配置的统一管理
cookie使用的监控和统一规范管理
session存储的多元化
session配置的动态修改
session加密key的定期修改
充分的容灾机制,保持框架的使用稳定性
session各种存储的监控和报警支持
session框架的可扩展性,兼容更多的session机制如wapsession
总结:session与cookie 的作用都是为了保持访问用户与后端服务器的交互状态。它们的有点和使用场景又是矛盾的。


设计软件的基本出发点:

OCP:开闭原则:对扩展开发,对修改关闭。
LSP:里氏代换原则:凡是基类能使用的地方,子类也一定能使用。
DIP:依赖倒转原则:要依赖与抽象,不要依赖于具体。
ISP:接口尽量单一:只代表一个角色。
CARP:合成/聚合复用:尽量使用合成/聚合复用,尽量不要使用继承。
LOD:迪米特原则:一个对象应当对其他对象的细节有尽可能少的了解。

ibatis 是一种典型的交互式框架,事先准备好交互的必要条件,然后构建一个交互的环境。sqlMapSession可以共享使用,也可以自己创建。如果是自己创建的,在结束时必须调用关闭接口进行关闭。

ibatis做的两件事:

1.根据JDBC规范建立与数据库的连接
2.通过反射打通Java对象与数据库参数交互之间相互转化的关系。

模板引擎:jsp ,velocity,freemark 都是用java语言设计的。

模板引擎:velocity渲染模板时是先把模板解析成一棵语法树,然后去遍历这棵树,分别渲染每个节点,知道了它的工作原理,我们就可以根据它的工作机制来优化渲染的速度。

1.减少树的总节点数量
2.减少渲染耗时的节点数量

velocity与 jsp 的区别:

1.执行方式不一样:

1.jsp是编译执行的,而velocity 是解释执行的。

2.如果jsp文件被修改 ,那么对应的java类也会被重新编译,而velocity却不需要,只是会重新生成一棵语法树。

2.执行效率不同:从理论上说:编译执行效率明显浩宇解释执行。
3.需要的环境支持不一样:jsp的执行必须要有servlet的运行环境,需要servletContext,httpServletRequest,httpservletResponse类。而渲染velocity完全不需要其他环境类的支持。
总结:jsp 文件实际上执行的是jsp 对应的java类,简单的说就是将jsp 的HTML转换成out.write输出。


优化以提高模板的渲染速度:

1.去掉页面输出中多余的非中文空格
2.压缩Tab 和换行
3.提取相同的数据,比如css 和js 的通用方法
4.异步渲染。在用户需要的时候采取服务器去请求,能够减少很多不必要的数据传输。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值