[纸上谈兵]Web服务器机制

目录

通信协议

Http协议

HTTPS协议

套接字协议

服务器模型


本文从通信协议、套接字通信(Socket)、Web服务模型三个方面了解Web服务器机制
web服务器就是指类tomcat服务器

通信协议

Http协议


http是请求/响应模型, 一个浏览器的http请求/响应的流程大概可以用以下4步表示
1、客户端浏览器先与服务端通过三次握手建立连接
2、连接建立后,客户端浏览器组装请求报文,发送一个请求到服务器
3、服务端接收到请求后,进行处理,将响应结果发送给客户端浏览器
4、客户端浏览器接受响应报文,通过浏览器内核进行解板=析展示。

http常见请求方法为 get、post、put、delete,分别对应Restful中的查、改、增、出。
http协议大家都比较熟悉,不过多介绍。请求报文和响应报文大家可自行在网上查到。


HTTPS协议


HTTPS本质上也是http协议,只是在http增加上了一个SSL或TLS协议。
http是直接进入TPC传输层,https是先进入SSL/TLS层再进入TCP传输层。
http和HTTPS都是应用协议,一般http默认端口为80,https默认端口为443。 参考下图

TLS/SSL主要职责如下
1、提供验证服务,验证本次会话客户端和服务端的身份的合法性
2、提供加密服务,保证通信过程中的消息不会被破译
3、提供防篡改服务,利用hash算法对消息进行签名,能过验签保证通信内容不被篡改


加解密算法与Hash算法
1、对称加密:密钥只有一个,加密、解密都用这个密钥
2、非对称加密:密钥成功出现,分为公钥和私钥。加密、解密使用不同的密钥,公钥加密需要私钥解密,私钥加密需要公钥觖密。
3、Hash算法, 不可解密的算法,常用于验证数据的完整性。

HTTPS的工作原理与流程
HTTPS是基于TCP/IP协议通信的,属于可靠传输,所以它必须要先进行三次握手,完成连接的建立。接着是SSL的握手协议,此协议让客户端和服务器之间完成相互之羊的身份验证及密钥协商。顺便说一句,TLS我个人理解是一系统密码工具的框架,提供加解密相关的信息,与SSL需要区分。

SSL握手协议流程
1、客户端浏览器向服务器发送SSL/TLS协议的版本号、加密算法的种类、产生的隋机数,以及其他需要的各种信息
2、服务端从客户端浏览器支持的加密算法中选择一组加密算法与Hash算法,并且把自己的证书(包含网站地址、加密公钥、证书颁发机构等)也发送给客户端
3、客户端浏览器获取服务器证书后验证其合法性,验证颁发机构是否合法,验证主导书中的网址是否正在访问的地址一致、通过验证的客户端浏览器会显示一个小锁头,否则,提示证书不受信
4、客户端浏览器生成一串随机数并用服务器传来的公钥加密,再使用约定好的Hash算法计算握手消息,发送到服务端。
5、服务器接到握手消息后用自己的私钥解密,并用散列算法验证,这样双方都有了此次通信的密钥。
6、服务器再使用密钥加密一段握手消息,返回给客户端浏览器
7、客户端浏览器用密钥解密,并用hash算法验证,确定算法与密钥
注意:
1、https在ssl握手协议完成后,确定了密钥和hash算法,所以后面在进行真正的内容请求与响应时,其实使用是对称加密即确定的密钥和hash算法。
2、ssl握手协议中使用了非对称加密是对后续使用的密钥和hash算进行加解密。这段话如果看不懂可以跳过,只要明白上面流程即可。


套接字协议

套接字是应用屋与TCP/IP协议族通信的中间抽象层,它是一组接口。应用层通过调用这些接口发送和接收数据。一般这种抽象层由操作系统提供或由JVM自己实现。

套接字抽象层位于传输层和应用层之间。类似于设计模式中的门面模式,TCP/IP协议族业务逻辑的细节隐藏在套接字接口下面,用户只要简单调用接口即可实现数据的通信操作。

套接字通信方式有以下几种:单播通信、组播通信、广播通信
单播通信:一对一模式,单个网络节点与单个网络节点之间的通信。网络节点可以直接理解为计算机。


组播通信:一对多的传播模式,需要路由及网络的支持能进行组播。简单的说就是一个网络节点,将消息发送到路由器上,与路由器在同一组内的成员才能接收组播的消息(组内不代表与路由建立连接就是一个组)。组播通信把通信压力转嫁到了路由器上。

特点:
1、节省网络资源
2、有针对性的向组内成员传播

广播通信:一对多的传播方式,与组播不同点在于,广播通信会向路由器连接的所有主机都发送消息不管主机想不想要,虽然浪费了网络资源,但它可以不用维护路由器与主机之间的成员关系。


服务器模型


这里说的服务器模型主要是指服务端对I/O的处理模型,分为阻塞I/O和非阻塞I/O两大类型。 按线程的角度可以分为单线程和多线程,单线程情况下由一条线程负责所客户端连接的I/O操作,多线程则是由若干组程共同处理所有客户端连接的I/O操作。

阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态。读数据时,服务端读取客户端数据时要等待客户端发送数据并且把客户端发送的数据由服务端操作系统内核复制到用户进程中,这时才解除阻塞状态。服务端写数据回给客户端时要等待服务端的用户进程将数据写入内核并发送到客户端后才能进入阻塞状态。

由于阻塞IO相对来讲比较简单,后面我们重点说一下非阻塞I/O模式。
在了解非阻塞IO前,我们需要先学习一下非阻塞情况下套接字事件的检测机制。一般会如下三种检测方式
1、应用层遍历套接字的事件检测
当多个客户端向服务器请求时,服务器端会保存到一个套接字连接列表中,应用层对套接字连接列表轮询尝试读取或写入。对于读取操作,如果成功读取到若干数据,则对读取的数据进行处理;如果读取失败,则下一个循环再继续尝试。对于写入操作,先尝试将数据写入指定的某个套接字中,写入失败则下一个循环再继续尝试。

2、内核遍历套接字的事件检测
也可以认为是一种事件驱动的非阻塞方式。之前我不太理解这个事件是怎么产生的,现在来看,这个事件的意思是指内核发出的事件,应用层接受事件进行处理。那么内核如何知道事件呢,其中一个种方式就是内核自己遍历套接字进行事件检测。
这种方式将套接字遍历工作交给了操作系统内核,把对套接字遍历的结果组成一系列的事件列表并返回应用层处理。对于应用层,它们需要处理的对象就是这些事件,这就是其中一种事件驱动的非阻塞方式。

服务器端有多个客户端连接,内核遍历所有套接字并生成对应的可读事列表readList和可写列表writeList。readList和writeList是全量列表,只是通过标识说明是否可读可写。应用层向内核请求读写事件列表,然后遍历读写事件列表进行相应的读写操作。

内核遍历套接字将遍历工作移到了内核中,提搞了检测效率。然后它需要将所有连接的可读事件列表和可写事件列表传到应层,假如套接字连接数量变大,列表从内核复制到应用层也是不小的开销。另外,当活跃连接较少时,内核与应用层之间存在很多无效的数据副本,因为它将活跃和不跃的连接状态都复制到应用层中。

3、内核基于回调的事件检测

无论应用层还是内核遍历套接字都是一种效率比较低的方式。有一种机制可以优化遍历的方式,即回调函数。内核中的套接字都对应一个回调函数,当客户端往套接字发送数据时,内核从网卡接收数据后会调用回计函数,在回调函数中维护事件列表,应用层获取此事件列表即可得到所有感兴趣的事件。

内核基于回调的事件检测有两种:
第一种:使用readList和writeList来实现。readList和writeList两个列表的长度与套接数量一样。当客户端发送数据过来时,内核从网卡复制数据成功后,调用回调函数将readList中相应连接的事件标识置为可读。应用层发送请求读、写事件列表,内核返回了包含事件标识的readList和writeList事件列表,进而分表遍历读写事件列表进行相应的操作。这样避免遍历套接字操作,但仍然有大量无用的数据从内核复制到应用层中,于是有了第二种事件检测方式。

第二种:event事件列表。event事件列表中包括了可读套接字event和可写套接字event。
应用层告诉内核每个套接字感兴趣的事件(我理解后面回调只会和感兴趣事件相关)。当客户端发送数据过来时,对应会有一个回调函数,内核从网卡复制数据成功后即调回调函数将套接字1作为可读事件event1加入到事件列表中。同样的内核发现网卡可写时就将套接字2作为可写事件event2加添加到事件列表中。最后,应用层向内核请求读、写事件列表,内核将event事件列表返回应用层,应用层通过遍历得知相应的操作进行处理。

这两种方式由操作系统内核维护客户端的所有连接并通过回调函数不断更新事件列表,而应用层线程只要遍历这些事件列表即可知道可读取或可写入的连接。

单线程非阻塞I/O
我个人理解是应用层有一个线程来进行循环遍历从内核获取的事件列表进行相应的处理。

多线程非阻塞I/O
最简单的方式是应用层将连接进行分组,每个线程处理一组。

最经典的多线程非阻塞I/O模式是Reactor模式。
先看单线程Reactor,Reactor将服务端的整理处理过程分成若干个事件。例如分为接收事件,读事件,写事件,执行事件等。Reactor通过事件检测是机制将这些事件分发给不同的处理器(process)去处理。

多线程Reactor有两种方式:一种在耗时的process处理器中引入多线程,如使用线程池。另一种直接使用多个Reactor实例,每个Reactor实例对应一个线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Java的网上商城的详细设计应该包含以下内容: 1. 系统架构设计:包括系统的整体架构、技术选型和系统分层等。 2. 数据库设计:包括数据库的表结构设计、数据字典、ER图等。 3. 模块设计:根据系统的功能划分出各个模块,并对每个模块进行详细设计,包括输入输出、数据处理和界面设计等。 4. 类设计:将每个模块抽象为类,并确定类之间的关系和方法的实现。 5. 接口设计:根据模块之间的交互关系,设计各个模块之间的接口和协议。 6. 安全设计:根据系统的安全需求,设计安全策略和措施,包括用户身份认证、访问控制、数据加密等。 7. 性能设计:根据系统的性能需求,设计性能策略和措施,包括系统缓存、负载均衡、数据库优化等。 8. 系统部署设计:根据系统的架构和技术选型,设计系统的部署方案,包括服务器的选择、软件的安装和配置等。 在详细设计的过程中,需要注意以下几点: 1. 设计文档要清晰、详细、准确,方便开发和维护。 2. 设计过程中要考虑系统的可扩展性和可维护性,避免过度复杂和耦合度过高。 3. 设计要遵循相关的设计原则和规范,例如SOLID原则、GRASP原则、设计模式等。 4. 设计要与实现相结合,避免“纸上谈兵”,确保设计的可行性和有效性。 希望这些内容能够帮助您进行基于Java的网上商城详细设计。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值