美文网首页
深入理解Java Web技术笔记

深入理解Java Web技术笔记

作者: 科学Jia | 来源:发表于2017-09-17 21:36 被阅读66次

这里只会记录我有印象的要点,不会对要点进行分析,因为具体分析,可以参考<深入分析Java Web技术(修订版)>这本书。然后,我觉得我应该买一个ipad pro做笔记 ( ^皿^)っHiahiahia…

1、Http Head, Cache-Control字段用于指定所有缓存机制在整个请求/响应链中必须服从的指令,Cache-Control的优先级别最高,如果它和其他字段(例如,expires)同时出现,它的设置会覆盖掉其他设置。

2、CDN网,中文名叫内容分布网,它在internet的基础之上架设的,以缓存网络中的静态数据为主,包含CSS、JS、图片、静态页面等,用户通过这个CDN网络可以就近取到所需要的内容。从CDN网络上取下静态数据,可以加速数据内容的加载速度,淘宝90%以上的数据都是来自CDN网络

3、负载均衡,一般有三种方式,链路负载均衡(DNS地址解析完成),集群负载均衡(也就是常见的LVS四层负载均衡 + HTTP的7层负载均衡系统),操作系统负载均衡(通过操作系统的级别来实现排队)。

4、磁盘I/O和网络I/O,是我们系统经常关注的重点,磁盘存储或者网络传输一定是以字节方式。inputstream和outputstream是操作字节的I/O,reader/writer是操作字符的I/O, *(其实这段我还是有点难以理解,但是想想文件存储在磁盘里,并且以字节方式存储,而inputstream和outputstream都是处理文件的流,那么就认为它是操作字节的I/O, 而reader和writer是提供直接操作字符的IO方式,因为我们的程序里都是直接操作字符形式的数据,如果没有操作字符的I/O,那么每次程序操作,还需要从字节转成字符,增加了编码转化的过程)

5、InputStreamReader:完成了字节到字符的转化功能,OutPutStreamWriter: 完成了从字符转成字节的功能。

6、NIO,主要三部分组成,Buffer、Channel、Selector, Buffer是用来接收和发送数据的缓存区(可以理解成从高速数据处理到低速数据处理的缓冲),channel注册到selector上,selector是个选择器,类似多路开关功能,它会监听各个channel的情况,并把用户感兴趣的事件作为监听条件,selector调用selector()方法进行监听。以前的BIO模式,一个socket的消息处理需要一个线程管理,效率很低,NIO里一个线程加Selector选择器就可以处理多个socket的信息。所以,在应用中,我们会在server上启动两个线程,一个是专门负责监听客户端的请求,采用阻塞模式;另外一个线程专职处理数据(Buffer)的读写,采用非阻塞IO,这样就达到简单2个线程,可以处理多路socket数据问题。Jetty和Tomcat(最近的版本,好像是7.5以上的?)都采用的NIO。(Tomcat实际是提供BIO和NIO两种模式)

7、NIO的Buffer另外提供了一种直接操作操作系统缓冲区数据的方法DirectByteBuffer,通过Native代码操作非JVM堆的内存空间提高了性能,适合数据量大,I/O多,生命周期较长业务场景。

8、关于压测系统,我们需要关注的指标, 磁盘和网络IO,例如4个CPU的情况下,理想磁盘的IO wait参数不应该超过25%。

9、TCP网络参数调优:如果观察到有大量tcp time-wait,那么这个时候压测系统是压不上去的,需要手动设置tcp_fin_timeout为更小值,这样可以快速释放tcp的请求,需要注意的是,以上设置都是临时的,系统重启后设置失效。这里需要注意的是,tcp的通信双方,谁主动释放tcp连接,谁就会产生time-wait,所以为了避免tcp time-wait,一般都不会主动请求断开。

10、网络IO优化原则:1. 减少网络交互的次数,比如你需要查询10条数据,你可以查10次,也可以一次查10条数据;2、减少网络上传输数据的大小,尽量避免读取整个通信数据来取得所需要的信息。

11、根据应用场景,设计合适的交互方式,1、同步和异步: 任务之间有依赖,比如A必须需要B完成,才算整个任务完成,而异步模式,模块相互之间是独立的,是不可靠的任务序列。或者说,同步是希望你回复response越快越好,而异步并不期待你的response。2、阻塞和非阻塞:通过CPU是否需要等待当前线程完成任务来区分,如果是采用非阻塞,会增加CPU上下线程的切换开支。总之,同步/异步、阻塞/非阻塞这4种模式存在都是为了具体场景提高I/O读写。

12、Javac的任务是将代码翻译成JVM能识别的语言,JVM最后翻译成机器语言。

13、类加载器ClassLoader负责将类加载到JVM中,加载方式有2种,一是隐式加载,JVM自动加载类到JVM内存中,第二自己代码显示调用,自己实现ClassLoader的目的: 1、可以加载自定义路径下的class文件;2、加载自定义格式的Class;3、实现类的热部署。为了分别完成上面3个任务,我们需要自己实现findClass()方法(ClassLoader抽象类),因为,findClass是用来定义类加载规则的方法,它是通过获取加载类的字节码,并通过defineClass()方法将字节码转成Class对象。并且,需要注意的是,在加载类之前,我们需要通过findLoadedClass()方法来判断当前JVM是否已经加载了此Class, 判断条件是:1、类的名字是否一致? 2、加载整个类的ClassLoader是否为同一个?如果已经加载了,那么就不能再次加载。如下代码:

Paste_Image.png

14、ClassLoader在JVM里面是有等级加载制度,服务"java.ext.dirs”目录下的类加载器是:ExtClassLoader,服务“java.class.path”目录下的类加载器是:AppClassLoader,它的父类是ExtClassLoader。我们如果要实现自己的类加载器,不管你是直接实现抽象类ClassLoader, 还是继承URLClassLoader这个类(也是实现了抽象类ClassLoader),或者其他子类,它的父加载器都是AppClassLoader。

Paste_Image.png

15、关于java应不应该动态加载类的讨论:java的痛楚之一是,修改了某一个类,不得不重启JVM,如果动态加载,就可以避免这个重启的过程,结论是如果知道JVM的工作机制,应该放弃这个念头。因为一旦类对象被创建出来以后,就会被其他引用或者把持,如果对象只是被单纯的替换掉,其引用关系是不可以被JVM一起修改替换的,一个简单的解决方法是,不保持该类的状态,用完就释放该对象,那么是可以做到动态替换。但明显,作者不主张大家这样做。

16、ClassLoader对象和其他对象一样,如果没有被其他对象引用也会被JVM回收,但注意的是,被ClassLoader加载类的字节码会保存在JVM的PermGen区(JDK8(含)以后,PermGen区被更名为元空间),这个区只有执行Full GC时候才会被回收,如果存在大量动态加载的类,而Full GC不频繁,那么可能会导致内存溢出。

  1. 计算机的地址空间(例如4G大小)程序并不能完全使用,因为地址空间分了用户空间和内核空间。

  2. JVM启动时候,堆大小一次向操作系统申请完成, -Xms(初始大小) 和-Xmx(堆最大值)。

  3. JDK8以前, 存在永久代区域,永久代区域跟堆是放在一起的,存放类、类的方法和数据、类加载器本身,以及常量池。

  4. 在JDK8以后,永久代被更名为元空间,并移植到了一个与堆不相连的本地内存区域,元空间的最大可分配空间就是系统可用内存空间,因此我们不会遇到16点说的永久代存在内存溢出的错误,但是不代表自定义的类加载器泄露问题就解决了,因为可能一旦发生泄露会继续占用本地内存的大小,造成本地内存不够用。

  5. 堆:存放对象,堆中的对象是共享的,不一定随着方法执行结束而消失;栈:执行程序,保存参数、局部变量、中间计算等,存取速度比堆快。

  6. 基于分代的垃圾收集算法:Old区满了以后,会触发Full GC(造成程序停顿)。

  7. Sun对堆中的不同代的大小划分也给了建议: Young区为整个堆大小的1/3,Survivor区(from/to)为Eden区的1/8。因为YoungGen= Eden + 2*Survivor. 所以Survivor区占Young区的1/10 GC的过程.png

24.Spring是面向Bean编程,把对象之间的依赖关系转而用配置文件来管理(IOC依赖注入)。Spring核心: Core(道具)、Context(舞台)和 Bean(演员)。Context发现并维护Bean之间的关系,Core是发现和维护之间关系所需要的一系列工具。

  1. Session、Cookie:
    Cookie由服务器生成,发送给浏览器,并保存在客户端本地。Cookie的限制:1). 不安全,容易被截获;2). 单个cookie数据不超过4k,浏览器最多保留一个站点的cookie大约为20个。
    Session, 用户信息保留在服务器,session比cookie更安全。Session的限制:1). 访问增多,占用服务器资源;2). 一旦负载均衡后,如果没有session缓存服务器,下一个请求达到不同的server,会导致Session丢失。
    总结:
    在大型互联网中,单独使用cookie和session都不可行。
    Session用来存放敏感信息。
    Cookie用来存放其他信息,cookie是可以压缩的。
    在大型互联网中,一个订阅服务器可以统一配置这个应用哪些可以写session,哪些可以写cookie项,比如Zookeeper集群管理服务器,可以统一管理所有服务器的配置文件。

  2. Tomcat容器
    核心组件: Connector和Container. Container可以选择多个connector,以便对外提供服务。Container容器设计是典型的责任链的设计模式。

  3. Netty和Jetty(我知道这里应该写Tomcat和Jetty比较符合逻辑,但是。。。我第一次真的傻傻分不清)
    Jetty is a lightweight servlet container, easy to embed within a java application, there is an easy to use jetty client also.
    Netty is an asynchronous event-driven network application framework. You can write your own servlet container or http client app with help of the Netty framework for example.

    这下就分的清楚了o( ̄︶ ̄)o

相关文章

网友评论

      本文标题:深入理解Java Web技术笔记

      本文链接:https://www.haomeiwen.com/subject/vtymsxtx.html