DanZ's Blog

a normal developer daily blog

0%

传输层协议

既然了解了 IP协议 的内容,上一篇通篇没有说到数据的安全性,因为 IP协议 只负责将数据运输到对应的计算机而已,不会对数据做任何操作,也不会验证数据是否完整到达或者有没有被破坏,或者交给哪个程序进行处理。而这些操作,是由 传输层协议 来做保证的。

传输层目前我们最流行的协议应该是 TCPUDP 了吧。前者是有连接的情况下传输数据,而后者则不会考虑数据是否完整到达,但是效率会比 TCP 略胜一筹。当然两者都有合适的使用场景。TCP 很多时候会用于设备之间的连接和数据传递,比如仓库 PDA 的使用。而 UDP 则多用于通话、视频方面的应用,还有我们熟知的 微信QQ,也是使用 UDP 作为传输协议的,他利用了 UDP 的效率,然后在 应用层 适配了数据完整性的校验。所以很多时候我们会有这种场景,我这边发送的消息显示个红色的❌,但是其实对方已经接受到刚刚发送的消息了,但是我们以为没有接收到又重新发了一次。还有直播类型的 应用层协议 多用 UDP协议

那,既然 IP协议 已经将数据传送到当前服务器了,服务器就应该具有一定的程序进行处理,要不然服务器也会懵逼。这个过程就通过解开客户端发送的数据,里面包含了一个参数称为 端口号,服务器系统就会交给监听这个 端口 对应的应用程序进行处理。依然是拿快递行业做类比,我们知道我们的地址一般会写到家里或者附近的地方,IP协议 就是负责将这个件送给对应的这个区域而已,但是这个区域有那么多人,根本不知道要交给谁,所以这时候快递员就需要用电话联系快递单号上的收件人电话,然后将件交给收件人。那么这个 收件人电话 就相当于端口号了。

这些服务端处理的 程序,将会监听着服务器系统上的 空闲端口。当这些端口有数据进来的时候,自然他们就可以接收到数据进行处理。当然如果这个 端口 被占用的话,程序是会启动失败的。但是不同的协议是可以监听同一个端口的,比方说当前有个 Tomcat 程序监听着 8080,我们还可以用另外一个程序,以 UDP 的协议继续监听这个 端口

一般来说,0 ~ 1023 留给一些知名程序进行处理(比如 sshd HTTP),如果我们需要占用端口,一般从 1024 开始,最大的端口号是 65535。当然这些端口也可能被我们启动的某些比较有名的程序占用,比如 Redis 占用 6379Tomcat 占用 8080 等等。但是通常如果不需要这些程序的话,我们是可以使用这些端口的。

阅读全文 »

互联网层-IP协议簇

上一节聊完了数据链路层,我们知道,两台计算机如果需要进行通讯的话,就需要先知道彼此的 MAC地址,然后将数据封装成 以太网帧 进行传输。但是我们的野心并没有止于此,因为需要更多的计算机参与网络(这个数量是+∞),那总不能把所有计算机的 MAC地址 在每一台上面都存储一份吧,即使这样,物理介质的互通也不现实。所以还能怎么办,那就包多一层嘛。

所以,IP协议 这一层又应运而生。

那么我们可以重新看一下分层模型:

与七层模型的匹配(via《图解TCP/IP》)

他主要位于互联网层,那他在这一层主要解决的问题就是数据的走向问题,也仅仅是走向的问题,不会对数据进行纠错,也不会负责重发的动作(即使数据丢失的话)。而这些问题会在再上一层的 传输层 进行补充解决。

阅读全文 »

TCP/IP协议的诞生

说到 TCP/IP协议 我相信各位光头们并不陌生,那他怎么变得如此流行的,我想有个很重要的原因,刚好生在他应该诞生的时机。

期初,军用方面的应用,需要进行信息的交换,所以有一套这样的网络:

网络

这样就有一个问题,如果中心节点被敌人偷袭了,那么整套军用系统就全部瘫痪。那为了防止这种事情的发生,我们可以多加几个中心节点:

这样的话如果中心的节点被袭击了(变成红色表示故障),那么其他计算机还可以通过比较远的输送距离将数据传达到彼此。

阅读全文 »

生活中熟悉又陌生的网络

在我刚开始了解算计网络之前,我一直认为计算机网络应该指的是:一台电脑连着网线,他可以通过操作系统上的各个软件访问网络上的资源 才叫网络。但是其实不是,作为一个 94 年出生的臭男人,其实在小的时候就已经接触到了网络了。那就是电视。

以前我家里的电视大概是这种(图片来自百度):

以前这台电视可贵了,3000 多块,可以想象在 1994 年的时候,是什么样的概念。

阅读全文 »

SpringCloud开篇

那么最近是想要来阅读一下 SpringCloud 的文章的,于是乎逗了几个圈子,又是去 GitHub原生 Eureka 的源码,又是去 Springspring-cloud-netflix 的源码,最后也是基本锁定只要从 spring-cloud-netflix 进去了解 SpringCloud 组件即可,毕竟 原生Eureka 我没用过…

spring-cloud-context项目

那么为啥是从 SpringCloudContext 开始咧,是因为这样的,如果我们某个组织想要开发 SpringCloud 套件的话,就需要使用到 Spring 官方提供的 spring-cloud-commons 项目,这个项目是一个 套件工具包,提供的是官方已经写好的一些注解和工具包,比方说 @EnableDiscoveryClient @LoadBalanced 这些我们常用的 SpringCloud 注解,并且提供了一些少量的支持,其中最重要的莫过于 SpringCloud 的上下文。 那我们之前读过 Spring 的源码的时候了解到,无论是 context 还是 application,都是支持父级容器的,而从容器中取出 Bean实例 的时候,也是 双亲加载机制,如果父级容器有了,那么子级容器是不会重新去加载的,这样我们在设计我们的业务项目的时候,就可以把一些基础架构的 Bean实例 丢到父级容器,并且子级容器只需要加载业务相关的类就可以了,当需要对第三方服务(如:MySQL Redis 都可以称为第三方服务)进行访问的时候,让我们的子级业务容器去父级容器取出来进行使用。有什么好处呢,我感觉就是专业的容器,做专业事情,我们编码弄出那么多设计,不外乎就是为了让程序的 拓展性会更好,当我们的基础服务发生改变的时候,那就可以将父级容器换一个,而不需要去动我们的业务容器。 带着这个想法来了解一下 spring-cloud-context 项目,spring-cloud-context 项目提供了一个容器,名为 bootstrap,那使用过的 spring-cloud 组件搭建过项目的同学肯定想到了我们常见的 bootstrap.yml,没错,这个配置文件就是配置 bootstrap 容器的,当我们在我们的项目中加入类似于 eureka zuul 或者 eureka-client 的时候,我们的项目容器就发生了翻天覆地的变化。 SpringApplication 会先根据 SPI 协议加载 BootstrapApplicationListener 类,并且在初始化 ConfigurableApplicationContext 之前,先执行这个上面的 ApplicationListener 的回调方法,把 Bootstrap容器 给初始化出来,并且设置为当前容器的 parent (典型的 我把你当朋友你居然要做我爸爸)。而如果有 SpringCloud 架构经验的同学肯定也明白一个事情,为啥我们在整合 spring-cloud-config-client 的时候,spring-cloud 的配置内容需要写在 bootstrap.yml 中,当然是因为 bootstrap.yml 是第一个被加载的,然后他获取到了配置以后,再初始化我们自己的容器,这时候我们自己的容器如果需要一些 远程配置 的时候,就可以先从 爸爸 那里去命中了。

阅读全文 »

上一节我们来到了 getAdapter().service(request, response); 这里,接下来需要看一个 连接器 -- Coyote框架 Coyote 的中文意思是 山狗 ,北美的一种狼,我想用这个名字应该是指他非常的迅猛。 它实现了自己的 RequestResponse(不是 servlet 标准),主要用于将 byte数组 翻译成必要的 HTTP信息

阅读全文 »

一.处理流程

1.1 系统IO多路复用

OK,要知道 Tomcat 请求的流程,首先我们得先知道 I/O复用模型,同等级的模型还有 阻塞式I/O非阻塞式I/OI/O复用(select/poll/epoll)信号驱动式I/O异步I/O,目前的 Tomcat8.5 版本,使用的就是 I/O复用模型,也叫 多路复用 模型。 I/O复用模型

阅读全文 »

上一篇的时序图:

一. StandardRoot启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class StandardRoot extends LifecycleMBeanBase implements WebResourceRoot {

@Override
protected void startInternal() throws LifecycleException {
mainResources.clear();

// 根据类型,创建对应的资源包实例
main = createMainResourceSet();

mainResources.add(main);

// 一次启动此类指定的资源
for (List<WebResourceSet> list : allResources) {
// Skip class resources since they are started below
if (list != classResources) {
for (WebResourceSet webResourceSet : list) {
webResourceSet.start();
}
}
}

// 扫描lib下的所有jar包
processWebInfLib();
// Need to start the newly found resources
for (WebResourceSet classResource : classResources) {
classResource.start();
}

cache.enforceObjectMaxSizeLimit();

setState(LifecycleState.STARTING);
}

}
阅读全文 »

零.Bootstrap初始化

Bootstrap 可以看成是一个 TomcatServer 运行时需要的环境的准备,这里通过加载配置文件,设置全局数据以便让后面的 组件 初始化的时候可以使用到。

阅读全文 »