一、网站架构及其演变过程
1.软件的三大类型
软件分为三个类型:单机软件、BS结构的软件(浏览器-服务端)、CS结构的软件(客户端-服务端)。
2.BS的基础结构
BS的网络传输的分解方式有两种:一种是标准的OSI参考模型,另一种是TCP/IP模型。它们的分层和对应的关系如下图所示。
OSI主要用于教学,TCP/IP主要有四层:
网络接入层:将需要连接的节点接入网络中,从而为数据传输提供条件
网际互联层:找到要传输数据的目标节点
传输层:实际传输数据
应用层:应用接收到的数据
由于网络应用传输非常广泛,所以需要大家都遵守规矩,不过网络传输中的这些规矩并不是强制性了,所以不叫制度也不叫标准,而是叫协议。TCP/IP参考模型也可以看成一种协议。BS结构中TCP/IP模型中的网络接入层没有相应的协议,网际互联层是IP协议,传输层是TCP协议,应用层是HTTP协议。
另外在BS结构中还用到了DNS协议,而且在HTTP上层还有相关的规范,如Java Web开发中使用的是Servlet标准。
3.海量数据的解决方案
(1)缓存和页面静态化
(2)数据库优化
(3)分离活跃数据
(4)批量读取和延迟修改
(5)读写分离
(6)分布式数据库
(7)NoSQL和Hadoop
4.高并发的解决方案
(1)应用和静态资源分离
(2)页面缓存
(3)集群与分布式
(4)反向代理
(5)CDN
二、常见的协议和标准
1.DNS协议
DNS协议的作用是将域名解析为IP。
2.TCP/IP协议与Socket
TCP/IP协议通常放在一起说,不过它们是两个不同的协议,起的作用也不一样。IP协议是用来查找地址的,对应着网际互联层,TCP协议是用来规范传输协议的,对应着传输层。IP只负责找地址,TCP负责具体的传输工作。
TCP在传输之前会进行三次沟通,一般称为“三次握手”,传完数据断开的时候要进行四次沟通,称为“四次挥手”。TCP中有两个序号和三个标志位。
seq:sequence number的缩写,表示所传数据的序号。TCP传输时,每一个字节都有一个序号,发送数据时会将数据的第一个序号发送给对方,接收方会按序号检查是否接收完整了,如果没接收完整就需要重新传送,这样就可以保证数据的完整性。
ack:acknoledgement number的缩写,表示确认号。接收端用它来给发送端反馈已经成功接收到数据信息,它的值为希望接收的下一个数据包起始序号,也就是ack值所代表的序号前面数据已经成功接收到了。
ACK:确认位,只有ACK=1的时候ack才起作用。正常通信时ACK为1,第一次发起请求时因为没有需要确认接收的数据,所以ACK为0。
SYN:同步位,用于在建立连接时同步序号。刚开始建立连接时并没有历史接收的数据,所以ack也就没办法设置,这时按照正常的机制就无法运行了,SYN的作用就是来解决这个问题的,当接收端接收到SYN=1的报文时就会直接将ack设置为接收到的seq+1的值,注意这里的值并不是校验后设置的,而是根据SYN直接设置的,这样正常的机制就可以运行了,所以SYN叫同步位。需要注意的是,SYN会在前两次握手时都为1,这时因为通信的双方的ack都需要设置一个初始值。
FIN:终止位,用来在数据传输完毕后释放连接。
整个传输过程如下图所示。
用于传输层的协议除了TCP还有UDP,它们的区别主要是TCP是有连接的,UDP是没有连接的。这样TCP协议传输的数据更可靠,UDP传输的速度更快。TCP就像是打电话,UDP就像是对讲机。
HTTP协议的底层传输默认使用的是可靠的TCP协议,不过它对互联网的高速发展带来了很大的制约,Google制定了一套基于UDP的QUIC协议,这种协议基于TCP和UDP之间,不过现在还没有广泛使用。
TCP/IP协议只是一套规则,并不能具体工作,就像是程序中的接口一样,而Socket是TCP/IP协议的一个具体的实现。
3.HTTP协议
HTTP协议是应用层的协议,在TCP/IP协议接收到数据之后需要通过HTTP协议来解析才可以使用。就像过去的发电报一样,电报机就相当于Socket,负责选好发送的目标并将内容发过去,但是直接发过去的数据并不能直接使用,还需要解码,电报中的编码和解码就相当于网络传输中的HTTP协议。
4.Servlet与Java Web开发
Servlet是J2EE标准的一部分,是Java Web开发的标准。
通过前面的TCP/IP协议、HTTP协议已经可以得到数据了,Servlet的作用是对接收到的数据进行处理并生成要返回给客户端的结果。
Servlet制定了Java 中处理Web请求的标准,不过标准不能自己干活,要想使用Servlet需要有相应的Servlet容器才行,Tomcat就是一个Servlet容器。
5.Java中Socket的用法
Socket是TCP/IP的一个具体的实现,而Socket又分为普通Socket和NioSocket两种。
6.详解Servlet
Servlet是Server+Applet的缩写,表示一个服务器应用。Servlet其实就是一套规范,我们按照这套规范写的代码就可以直接在Java的服务器上面运行了。Servlet3.1中的Servlet结构如下图所示。
(1)Servlet接口
既然Servlet是一套规范,那么最重要的就是接口了。
Servlet3.1中Servlet的接口定义如下:
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
init方法在容器启动时被容器调用(当load-on-startup设置为负数或者不设置时会在Servlet第一次用到时才被调用),只会调用一次;getServletConfig方法用于获取ServleConfig;
Service方法用于具体处理一个请求;getServletInfo方法可以获取一些Servlet相关的信息,如作者、版权等,这个方法需要自己实现,默认返回空字符串;destroy主要用于在Servlet销毁(一般指关闭服务器)时释放一些资源,也只会调用一次。
(2)GenericServlet
GenericServlet是Servlet的默认实现,主要做了三件事:1.实现了ServletConfig接口,我们可以直接调用ServletConfig里面的方法;2.提供了无参的init方法;3.提供了log方法。
GenericServlet实现了ServletConfig接口,我们在需要调用ServletConfig中方法的时候可以直接调用,而不再需要先获取ServletConfig。
GenericServlet实现了Servlet的init(ServletConfig config)方法,在里面将config设置给了内部变量config,然后调用了无参的init()方法,这个方法是个模板方法,在子类中可以通过覆盖它来完成自己的初始化工作。
(3)HttpServlet
HttpServlet是用Http协议实现的Servlet的基类,写Servlet时直接继承它就可以了,不需要再从头实现Servlet接口,我们要分析的SpringMVC中的DispatcherServlet就是继承的HttpServlet。既然HttpServlet是跟协议相关的,当然关心的是如何处理请求,所以HttpServlet主要重写了service方法。在service方法中首先将ServletRequest和ServletResponse转换为了HttpServletRequest和HttpServletResponse,然后根据Http请求的类型不同将请求路由到了不同的处理方法。