- 通讯协议在分布式架构中的核心应用
- 深入料及TCP/IP和UDP/IP通信协议
- TCP流量整形
- 基于Java自身技术实现系统通讯
- 多任务处理及优化
- 了解什么是NIO
- 组播协议 Multicast
从集中式的架构到分布式架构粗粒度的架构模型图
相当于是在整个架构层面上去做一个分层,分层以后会存在按照某一个领域去切分的服务层,存在web层,然后,
如果我们以前是在一个独立的服务模型里边,不需要涉及到远程通信,唯一的远程通讯就是客户端和远程端的通讯,现在变成一个分布式架构,那么就意味着:服务层之间彼此会通讯,这样一个通讯的话,就会涉及到一个通讯协议,比如我们现在Web层调用Dubbo层是通过Dubbo协议去调用的,然后Dubbo调用基础服务,是通过socked的TCP通讯去完成一些服务间的对接。
这是通讯在整个分布式架构中的用途。
如果说没有一个远程通信的话,就意味着我们的分布式架构就没有存在的意义和价值。
所以说:
在整个架构的里边的一个通信会涉及到协议涉及到序列化,涉及到网络通信协议底层的TCP协议和UDP协议,
任务目标
怎么完成一个远程通信???
如果没有远程通信,就没有所谓的分布式系统,我们发送一个消息,会被某一个接收端去接收,那这个消息的形式有很多种。
传输的数据类型
1. 字节流
2. 字节数组
3. java对象
协议类型
外部的系统收到这样一个请求以后需要做一个相应的处理,那这种基于消息方式的通信,在我们的网络层里边,一般来说就涵盖两种,
TCP/IP协议
UDP/IP协议
网络领域的知识
协议:
TCP/UDP/multicast
IO
远程通信一定涉及IO的形式(BIO、NIO、AIO)
Socket
套接字
NIO
(Netty/Mina)
序列化和反序列化
在网络通信中需要传输一个对象的话,就涉及到序列化和反序列化了。
一个Http请求在整个网络中的请求过程
基于OSI的七层网络模型
( 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层)
TCP/IP的四层概念模型
网络为什么要分层,以及在通信时,我们的数据是怎么去传输的。
首先是我们打开一个浏览器,浏览一个网站,这时候相当于应用程序和客户端会产生一个交互。交互(TCP的三次握手协议),握手协议是建立一个连接,那在整个通信过程中,数据是怎么一个传输。
先增加一个TCP头,表示一个协议头,
第二个增加IP头,因为IP地址是网卡在网络中的一个通讯地址,相当于要给门牌号,有时候会提示IP地址冲突,因为IP地址是不能冲突的,相当于小区内部的门牌号,是我们网卡的唯一的通讯地址,相当于我们的门牌号,
增加MAC头,MAC头是我们的网卡地址,标识的是这个数据包要发送到的网卡地址,增加的IP头是目标的IP头,它本身自带当前的源IP头,
到了物理层,转换成一个Byte流进行一个传输,通过网络通讯进行一个传输,
比作寄包裹的话:
选择快递公司,
地方,省市
姓名,门牌号
Ip定位到地方,mac头定位到它是发给你的,
IP协议,提供了一组数据报文服务,每组服务都是由网络统一处理分发的
Ip头有两个东西,一个目的IP地址,一个源IP地址。
接收方的接受步骤
当我们的目标主机收到这样一个目标以后,收到网络上的一个数据帧以后,他就会开始从协议层有底向上升,先到网卡,有两种形式,一种是所有数据包都接收,一种是,先判断这个MAC头是不是我的,如果不是我的就不会进来,所以拿到这个数据以后,到数据链路层去摘取这个MAC头,去判断当前的一个网卡地址,和发送的MAC是不是匹配,
网络层,会摘取IP头,如果不是自己的就会做一个转发,最后到了传输层。协议层会携带端口号,通过端口号,定位到具体的进程内,把这个数据包送到我们对应的接收端。
MAC头是唯一的,理论上是可以通过MAC头去发送消息,MAC就像身份证一样,他是一个唯一的,但是我要去定位,是用IP去定位到我要发送到那个服务器,是个分层结构!
网络是一个分层,它会有四层。
IP协议
TCP/UDP协议都是基于IP网络协议之上的,IP协议会提供一组数据报文服务,每组报文会由网络去统一处理和分发的。
每组报文都必须包含目的地址的地址段,IP层地址段
IP协议,不可靠,经力而为的协议,报文丢失,无序,或者说重复发送的情况。
TCP可靠协议
UDP不可靠协议
TCP头里边有目标端口号
协议
协议是两种网络通讯中达成的一个约定。
协议目的:
就是规范好通讯之间的约定。
http:超文本传输协议。
拿到服务器上不同格式的数据
返回给浏览器,去做一个解析。(html/json/xml/jpg/png)
基于约定,拿到我想要拿到的东西,就是协议。
实现一个对我们产生作用的网络,必须解决一些问题,为了让这些问题便于管理和模块化。
基于模块化的东西,设计了两种协议
TCP协议
能够检测和恢复IP层提供的主机和主机的通讯中可能发生的报文丢失,重复和错误的情况。解决了数据丢失、重复发送的问题,提供了可以信赖的字节流通道。
UDP
不可信的协议,不会对协议进行改造修复,提供了一个扩展于IP之上的尽力而为的数据报文服务。能够提供应用之间的工作,而不是主机之间的工作。不会解决数据丢失和重复,和顺序混乱的问题。
用户输入域名,解析出ip,http请求报文
深入分析 TCP/IP
1) DNS解析
2) 网关进行数据传输
3) 路由协议
4) 握手协议
DNS解析
DNS解析得到IP地址,由网关进行数据传输,由路由协议传输到目的端。
(就像打电话,喂,你好,你好,我是。。。, 我是。。。 就是我们的握手协议)
握手协议放置了数据包的丢失。
TCP通过三次握手建立一个可靠的通道。
三次握手
相当于客户端和服务端进行通信时有三个数据包。
三个状态:SYN-SEND >> SYN-RCVD >> ESTAB-LISHED
SYN攻击
在短时间内客户端伪造大量不存在的ip地址,发送给服务端
服务端发送给客户端之后,客户端的确认包一直不发给service,这时候存在大量的连接是空闲的,会消耗我们的资源,导致我们很多正常的请求没有办法进去,因为队列满了。
TCP协议断开:
四次挥手协议:
FIN_WAIT_1 CLOSE_WAIT FIN_WAIT2 LAST_WAIT TIME_WAIT.
客户端请求关闭发送给服务端,服务端发送ACK告诉客户端,我收到你的请求了,然后服务端全部请求处理完毕以后发送FIN到客户端,客户端收到FIN报文以后就代表我可以关闭这个连接了,服务端没有收到ACK,就可以重新传输,客户端在两个生命周期以内没有收到回复,服务端就已经关闭了,客户端也可以关闭了。
为什么三次四次:
接收端接收到报文以后可以直接告诉发送端,我收到你的消息了,
关闭的时候,服务器知道告诉发送端,你发送的请求我收到了,我要等到连接处理完,才处理完。
TCP协议,全双工协议。
发送时间在两个报文的生命周期内,
协议是建立连接,建立连接之后通讯,针对会话发送数据包,发送数据包,基于这个协议去传输。如果接收方不及时接收的情况,发送方应该是可以调控的,
如果接收方不及时处理的时候,发送方是可以控制的。
TCP流量控制
滑动窗口,是一种流量控制技术,
为什么用滑动窗口
保证数据不会丢失
网络拥塞的情况下会存在数据阻塞
所以在这样的情况下,引入了滑动窗口,去对我们的流量去做一个整形
动态地址:
缓冲区是有大小的,控制流量,
缓冲区的大小就是窗口大小,发送消息,收到ack以后就可以发送下一个窗口
可以设置缓冲区的大小。
根据接收端的缓冲区可以动态调整窗口大小,
发送窗口,允许发送的数据帧的数据量的大小,
接收窗口,
没有收到消息,会重新发,
使用TCP协议进行通讯
协议层之上就是应用,协议这块会很复杂
在现在的变成语言中,提供很完整的机制,屏蔽复杂过程,便于开发应用程序
TCP、UDP都是基于socket概念上为某一个应用场景上扩展出来的协议。
什么是Socket
socket可以认为是一个抽象层,应用程序通过它来发送和接收消息。
这个时候通过应用程序打开文件句柄,读取数据磁盘,或者把数据写入到磁盘上。
使用socket可以把我们的应用程序添加到网络上,而且能跟和它处于一个网络的应用去通信,这就是socket。
不同的类型的socket和底层的协议是有关系的。
Stream socket(TCP) 字节流
datagram socket (UDP) 数据报文
Socket 套接字。
基于socket 选择协议(TCP [1-65535端口] UDP),然后带上IP(基于IP协议)
Netty是一个基于NIO的框架
TCP协议是一个全双工的协议
BIO:
BIO 客户端一个客户端请求,一个线程
BIO 阻塞
缓冲区被占用
TCP协议是一个基于缓冲区,内核里边都会有个发送缓冲区,接收缓冲区,TCP的全双工模式是以TCP的滑动窗口,和依赖于这两个独立的缓冲区的填充状态,去处理的, 接收缓冲区把数据缓存到内核里边,如果说应用程序,没有调用read方法去读取的话,就会存在我们的接收缓冲区里边,这个缓冲区都不会被清理掉。
我们接收端receive去调用read去读取数据,实际上就是把内核读取到的数据复制到我们应用程序的buffer里边,再做一个处理。
进程里边调用socket去发送数据
在IO的层存在一个IO的调度线程,不断扫描socket缓冲区,
发现写某个写入缓冲区为空,扫描到了就可以产生一个socket可写事件,我们的程序就可以对数据进行socket写入。如果一次写入没有写完,等下次写入再去写
(Epoll Selector机制)
当接收端发现socket接收缓冲区有数据时,会产生socket可读事件,即使缓冲区满了,我也可以去接受其他请求。
有一个事件通知,可以读取这个数据
NIO:
发现你不可写,会有一个事件通知,我这个事件告诉你什么时候可以写了,然后我就可以去调用,去做一个处理消息的过程。
就是要给Epoll 和Selector模型的概念。
New IO或者no black IO;
NIO 非阻塞通信 (Non-blocking I/O,在Java领域,也称为New I/O)
通过一个事件机制,实现解耦
多路复用基于的是NIO机制。
客户端 都注册一个channel
客户端 都注册一个channel
NIO以多路复用为基础,服务端有一个多路复用器,轮询每一个channel,选择一个具备已经能够运行任务的能力的channel,如果某个注册上来的channel上的TCP产生以一个可写事件的话,那么就能够被轮询出来,去做一个执行,如果满足状态,执行相应的机制,然后不断的轮询。
产生socket可写事件
组播协议
单播协议
TCP UDP 都是基于点对点的通讯, 可以称为单播协议。
广播
网络中的所有的主机都可以收到一份数据副本
多播
消息只发送给一个多播地址,网络会把数据发送给那些想要监听的主机
只有订阅了这个感兴趣的主机才能收到
广播:
子网主机发送消息,子网内的主机都能收到信息
NIO是基于IO的更好性能的技能
Java本身提供了NIO技术,netty基于NIO做了一个封装,提供了一个更优化的功能而已。