在浏览器输入域名之后,浏览器会先从缓存中寻找域名对应的IP地址。如果没有找到,会在操作系统缓存中寻找是否有对应的IP地址。如果在/etc/hosts文件中设置了IP地址,则会优先使用这个IP。我们在测试时可以将域名指向一台测试服务器。
如果这两个过程无法解析,操作系统会将域名发送给本地区的域名服务器。如果还是没有命中缓存,那么将会请求Root Server的服务器。
可以通过nslookup命令来查询域名的解析结果。
网关(Gateway)就是一个网络连接到另一个网络的“关口”。也就是网络关卡。
要实现两个网络之间的通信,必须通过网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。
网关实质上是一个网络通向其他网络的IP地址,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。
一台主机可以有多个网关。默认网关的意思是一台主机如果找不到可用的网关,就把数据包发给默认指定的网关,由这个网关来处理数据包
当用户访问某个静态文件,首先向local DNS服务器发起请求,最后这个域名会被指向公司内部的DNS负载均衡服务器,最后返回给离用户最近的CDN节点。
负载均衡(Load Balance)是对工作任务进行平衡、分摊到多个操作单元上执行,如图片服务器、应用服务器等。它可以提高服务器响应速度及利用效率。
负载均衡包括链路负载均衡、集群负载均衡和操作系统负载均衡。链路负载均衡就是前面提到的通过DNS解析成不同的IP,然后用户根据不同的IP访问不同的服务器。
为了满足来自客户端的请求,服务器通常需要与其他下游服务建立其他连接,以获取服务器没有的其他信息。在这种情况下,服务器会代表客户端尝试访问下游服务的信息。
IO是机器间获取和交换信息的渠道,Java的I/O操作都在包java.io下,这些类可以分为4组:
前两组是传输数据的格式,后两组是传输数据的方式
无论是磁盘还是网络传输,最小单位都是字节,所以IO操作的都是字节,而不是字符。那为什么还要提供字符的接口呢,因为在程序中操作的数据都是字符形式的,从字符到字节需要经过编码转换。
读取和写入文件I/O操作都要调用操作系统提供的接口,应用程序要访问物理设备只能通过系统调用的方式。读和写分别要调用read和write的接口。
Java序列化就是将一个对象转化成一串二进制表示的字节数组,通过保存或转移这些数据来达到持久化的目的。需要持久化,对象必须继承自java.io.Serializable接口。在纯Java环境中,对象的序列化和反序列可以很好工作,但是用其他语言还原Java的序列化结果就比较困难了,所以推荐使用JSON或者XML这种通用的数据结构。
在序列化的时候,先利用反射找到对象类的所有get方法,接下来去get,然后小写化,作为json的每个key值,而get方法的返回值作为value。接下来再反射field,添加到json中。
将一份数据从一个地方传到另一个地方所需要的时间我们称为响应时间。影响整个响应时间的因素有很多:
socket这个概念没有对应的实体,它描述计算机通信间的一种抽象功能。在TCP协议三次握手成功之后,Socket实例对象将被创建完成。
适配器模式的有这个几个类
为什么要编码:
涉及编码的地方一般都在从字符到字节的转换上或者从字节到字符的转换上,需要这种转换的场景主要是I/O,这个I/O包括磁盘I/O和网络I/O。
Read类是Java中的I/O中读字符的父类,而inputStream类则是读字节的父类。InputStreamReader类就是关联字节到字符的桥梁。
用户从浏览器发起一个HTTP请求,需要编码的是URL、cookie和header中的参数。
用户提交一个URL,这个URL中可能存在中文,因此需要编码。何谓percent encode呢?意指百分号编码,借助%来进行有效编码,percent编码是在对非法字符采用某种编码(约定为UTF8)转成字节流后,逐字节加上%构成percent编码。
Java编译器的作用就是将符合Java语言规范的源代码转化成符合Java虚拟机规范的Java字节码。
首先要读取java源代码,一个字节一个字节读进来,找出关键词,如if、else、for等。识别关键词的过程就是词法分析,好比一个句子区分出主谓宾。
接着对这些关键词进行语法分析,看是否正确符合java语言规范,好比一个句子是否符合语法。语法分析的结果是形成一个符合Java语言规范的语法树。
接下来是语义分析,比如把foreach转化成for循环等,形成注解过后的抽象语法树。
最后根据这棵树形成字节码。
##分布式session
需要一个服务订阅服务器,在应用启动时可以从订阅服务器获取该应用需要的可写session项和可写cookie项。统一订阅服务器推送配置可以有效集中管理资源,避免重复配置cookie。如果应用需要新增cookie,可以通过一个统一的后台来申请,申请通过服务器才将这个配置项添加到订阅服务器。
由于应用是一个集群,不可能将所有创建的session实例都保存在每台应用服务器的内存中。因为如果每台服务器有几十万的用户,那么服务器的内存肯定不够用。即使够用,这些session也无法到这个应用的所有服务器。所以要共享这些session必须把它们存储在一个分布式缓存中,可以随时写入和读取。
servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法 init()和destroy(),还有一个处理请求的service(),也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要回答这三个问题:
那请求怎么来到servlet呢?答案是servlet容器,比如我们最常用的tomcat,需要把servlet部署到一个容器中。servlet的作用是为java提供一个统一的web应用的规范,比如tomcat和jetty的代码就不一样,但作为程序员只需要了解servlet就能从request对象中取值,不必在意服务器底层的实现。
tomcat是servlet容器的一种,能够运行基于servlet的应用程序并响应相应的http请求。Connector组件是tomcat核心组件之一,它的主要任务是负责接收浏览器发过来的TCP请求,创建一个Request和Response对象分别用于和请求端交换数据,然后将Request和Response对象传递给servlet Container容器处理。
servlet调用Request对象的有关方法,获取Http请求信息,servlet调用Response对象的有关方法,生成响应数据。
jsp作为view层,servlet作为controller层实例化JavaBean,JavaBean作为model层,通过JavaBean的处理进行数据库读写,JavaBean是以get和set读写属性为规范的类。
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。
使用spring框架之后,service层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了spring框架去实现。
spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,部分模块的功能如下:
Bean包装的是Object,而Object必然有数据,如何给这些数据提供生存环境就是Context需要解决的问题。所以Context是Bean关系的集合,这个关系集合又叫Ioc容器。Core是一系列发现、建立和维护每个Bean之间关系所需要的工具,把Core叫做Util更好理解。
Bean的定义完整描述了在配置文件中定义的
节点中所有的信息,Bean的解析非常复杂,功能被分得很细,因为这里需要被扩展的地方很多。
Context实际就是给spring提供一个运行时环境。