1.StringBoot
啟動(dòng)流程:
1.創(chuàng)建一個(gè)StopWatch并執(zhí)行start方法,這個(gè)類主要記錄任務(wù)的執(zhí)行時(shí)間
2.配置Headless屬性,Headless模式是在缺少顯示屏、鍵盤或者鼠標(biāo)時(shí)候的系統(tǒng)配置
3.在文件META-INF\spring.factories中獲取SpringApplicationRunListener接口的實(shí)現(xiàn)類EventPublishingRunListener,主要發(fā)布SpringApplicationEvent
4.把輸入?yún)?shù)轉(zhuǎn)成DefaultApplicationArguments類
5.創(chuàng)建Environment并設(shè)置比如環(huán)境信息,系統(tǒng)熟悉,輸入?yún)?shù)和profile信息
6.打印Banner信息
7.創(chuàng)建Application的上下文,根據(jù)WebApplicationTyp來(lái)創(chuàng)建Context類,如果非web項(xiàng)目則創(chuàng)建AnnotationConfigApplicationContext,在構(gòu)造方法中初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
8.在文件META-INF\spring.factories中獲取SpringBootExceptionReporter接口的實(shí)現(xiàn)類FailureAnalyzers
9.準(zhǔn)備application的上下文
10.初始化ApplicationContextInitializer
11.執(zhí)行Initializer的contextPrepared方法,發(fā)布ApplicationContextInitializedEvent事件
12.如果延遲加載,在上下文添加處理器LazyInitializationBeanFactoryPostProcessor
13.執(zhí)行加載方法,BeanDefinitionLoader.load方法,主要初始化了AnnotatedGenericBeanDefinition
14.執(zhí)行Initializer的contextLoaded方法,發(fā)布ApplicationContextInitializedEvent事件
15.刷新上下文(后文會(huì)單獨(dú)分析refresh方法),在這里真正加載bean到容器中。如果是web容器,會(huì)在onRefresh方法中創(chuàng)建一個(gè)Server并啟動(dòng)。
Spring Boot 的核心注解是哪個(gè)?它主要由哪幾個(gè)注解組成的?
啟動(dòng)類上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要組合包含了以下 3 個(gè)注解:
@SpringBootConfiguration:組合了 @Configuration 注解,實(shí)現(xiàn)配置文件的功能。
@EnableAutoConfiguration:打開自動(dòng)配置的功能,也可以關(guān)閉某個(gè)自動(dòng)配置的選項(xiàng),如關(guān)閉數(shù)據(jù)源自動(dòng)配置功能:@SpringBootApplication(exclude{DataSourceAutoConfiguration.class})
@ComponentScan:Spring組件掃描。
2.SpringCloud
springcloud五大組件:
1、服務(wù)發(fā)現(xiàn)Netflix Eureka;
2、客服端負(fù)載均衡Netflix Ribbon;
3、斷路器Netflix Hystrix;
4、服務(wù)網(wǎng)關(guān)Netflix Zuul;
5、分布式配置。
1.服務(wù)注冊(cè)中心

Eureka:
Eureka客戶端會(huì)向Eureka注冊(cè)中心注冊(cè)為服務(wù),并通過(guò)心跳來(lái)更新它的服務(wù)租約。同時(shí)也可以從服務(wù)端查詢當(dāng)前注冊(cè)的服務(wù)信息并把他們緩存到本地并周期性的刷新服務(wù)狀態(tài)。若服務(wù)集群出現(xiàn)分區(qū)故障時(shí),Eureka會(huì)轉(zhuǎn)入自動(dòng)保護(hù)模式,允許分區(qū)故障的節(jié)點(diǎn)繼續(xù)提供服務(wù);若分區(qū)故障恢復(fù),集群中其他分區(qū)會(huì)把他們的狀態(tài)再次同步回來(lái)。
Zookeeper:
Zookeeper是大數(shù)據(jù)Hadoop中的一個(gè)分布式調(diào)度組件,強(qiáng)調(diào)數(shù)據(jù)一致性和擴(kuò)展性,可用于服務(wù)的注冊(cè)和發(fā)現(xiàn)。
Consul:
Consul是一個(gè)高可用的分布式服務(wù)注冊(cè)中心,由HashiCorp公司推出,Golang實(shí)現(xiàn)的開源共享的服務(wù)工具。Consul在分布式服務(wù)注冊(cè)與發(fā)現(xiàn)方面有自己的特色,解決方案更加“一站式”,不再需要依賴其他工具。
1、通過(guò)HTTP接口和DNS協(xié)議調(diào)用API存儲(chǔ)鍵值對(duì),使服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)更容易;
2、支持健康檢查,可以快速的告警在集群中的操作
3、支持key/value存儲(chǔ)動(dòng)態(tài)配置
4、支持任意數(shù)量的區(qū)域
ETCD:
ETCD是一個(gè)高可用的分布式鍵值數(shù)據(jù)庫(kù),可用于共享配置、服務(wù)的注冊(cè)和發(fā)現(xiàn)。ETCD采用Raft一致性算法,基于Go語(yǔ)言實(shí)現(xiàn)。ETCD作為后起之秀,又非常大的優(yōu)勢(shì)。
1、基于HTTP+JSON的API,使用簡(jiǎn)單;
2、可選SSL客戶認(rèn)證機(jī)制,更安全;
3、單個(gè)實(shí)例支持每秒千次寫操作,快速。
4、采用Raft一致性算法保證分布式。
Nacos:
一個(gè)更易于構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺(tái)。
2.客服端負(fù)載均衡
Ribbon客戶端:ribbon 是一個(gè)客戶端負(fù)載均衡器,可以簡(jiǎn)單的理解成類似于 nginx的負(fù)載均衡模塊的功能。
Feign客戶端:是一個(gè)聲明式的Web Service客戶端
負(fù)載均衡算法:
1:簡(jiǎn)單輪詢負(fù)載均衡(RoundRobin)
2:隨機(jī)負(fù)載均衡 (Random)
3:加權(quán)響應(yīng)時(shí)間負(fù)載均衡 (WeightedResponseTime)
4:區(qū)域感知輪詢負(fù)載均衡(ZoneAvoidanceRule)
3.Spring Cloud Alibaba
Sentinel:把流量作為切入點(diǎn),從流量控制、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度保護(hù)服務(wù)的穩(wěn)定性。
Nacos:一個(gè)更易于構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺(tái)。
RocketMQ:一款開源的分布式消息系統(tǒng),基于高可用分布式集群技術(shù),提供低延時(shí)的、高可靠的消息發(fā)布與訂閱服務(wù)。
Dubbo:Apache Dubbo? 是一款高性能 Java RPC 框架。
Seata:阿里巴巴開源產(chǎn)品,一個(gè)易于使用的高性能微服務(wù)分布式事務(wù)解決方案。
Alibaba Cloud SchedulerX: 阿里中間件團(tuán)隊(duì)開發(fā)的一款分布式任務(wù)調(diào)度產(chǎn)品,提供秒級(jí)、精準(zhǔn)、高可靠、高可用的定時(shí)(基于 Cron 表達(dá)式)任務(wù)調(diào)度服務(wù)。
4.Redis
1.redis的5種數(shù)據(jù)類型:
string 字符串(可以為整形、浮點(diǎn)型和字符串,統(tǒng)稱為元素)
list 列表(實(shí)現(xiàn)隊(duì)列,元素不唯一,先入先出原則)
set 集合(各不相同的元素)
hash hash散列值(hash的key必須是唯一的)
sort set 有序集合
2.string類型的常用命令:
自加:incr
自減:decr
加: incrby
減: decrby
3.list類型支持的常用命令:
lpush:從左邊推入
lpop:從右邊彈出
rpush:從右變推入
rpop:從右邊彈出
llen:查看某個(gè)list數(shù)據(jù)類型的長(zhǎng)度
4.set類型支持的常用命令:
sadd:添加數(shù)據(jù)
scard:查看set數(shù)據(jù)中存在的元素個(gè)數(shù)
sismember:判斷set數(shù)據(jù)中是否存在某個(gè)元素
srem:刪除某個(gè)set數(shù)據(jù)中的元素
5.hash數(shù)據(jù)類型支持的常用命令:
hset:添加hash數(shù)據(jù)
hget:獲取hash數(shù)據(jù)
hmget:獲取多個(gè)hash數(shù)據(jù)
6.sort set和hash很相似,也是映射形式的存儲(chǔ):
zadd:添加
zcard:查詢
zrange:數(shù)據(jù)排序
內(nèi)存淘汰機(jī)制
noeviction: 當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò);
allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中移除最近最少使用的 key;
allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中隨機(jī)移除某個(gè) key;
volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,移除最近最少使用的 key;
volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,隨機(jī)移除某個(gè) key;
volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,有更早過(guò)期時(shí)間的 key 優(yōu)先移除;
5.Mysql
1.為什么用自增列作為主鍵
1、如果我們定義了主鍵(PRIMARY KEY),那么InnoDB會(huì)選擇主鍵作為聚集索引。
如果沒有顯式定義主鍵,則InnoDB會(huì)選擇第一個(gè)不包含有NULL值的唯一索引作為主鍵索引。
如果也沒有這樣的唯一索引,則InnoDB會(huì)選擇內(nèi)置6字節(jié)長(zhǎng)的ROWID作為隱含的聚集索引(ROWID隨著行記錄的寫入而主鍵遞增,這個(gè)ROWID不像ORACLE的ROWID那樣可引用,是隱含的)。
2、數(shù)據(jù)記錄本身被存于主索引(一顆B+Tree)的葉子節(jié)點(diǎn)上,這就要求同一個(gè)葉子節(jié)點(diǎn)內(nèi)(大小為一個(gè)內(nèi)存頁(yè)或磁盤頁(yè))的各條數(shù)據(jù)記錄按主鍵順序存放
因此每當(dāng)有一條新的記錄插入時(shí),MySQL會(huì)根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點(diǎn)和位置,如果頁(yè)面達(dá)到裝載因子(InnoDB默認(rèn)為15/16),則開辟一個(gè)新的頁(yè)(節(jié)點(diǎn))
3、如果表使用自增主鍵,那么每次插入新的記錄,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置,當(dāng)一頁(yè)寫滿,就會(huì)自動(dòng)開辟一個(gè)新的頁(yè)
4、如果使用非自增主鍵(如果身份證號(hào)或?qū)W號(hào)等),由于每次插入主鍵的值近似于隨機(jī),因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁(yè)得中間某個(gè)位置
此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù),甚至目標(biāo)頁(yè)面可能已經(jīng)被回寫到磁盤上而從緩存中清掉,此時(shí)又要從磁盤上讀回來(lái),這增加了很多開銷
同時(shí)頻繁的移動(dòng)、分頁(yè)操作造成了大量的碎片,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過(guò)OPTIMIZE TABLE來(lái)重建表并優(yōu)化填充頁(yè)面。
2.為什么使用數(shù)據(jù)索引能提高效率
數(shù)據(jù)索引的存儲(chǔ)是有序的
在有序的情況下,通過(guò)索引查詢一個(gè)數(shù)據(jù)是無(wú)需遍歷索引記錄的
極端情況下,數(shù)據(jù)索引的查詢效率為二分法查詢效率,趨近于 log2(N)
3.Mysql鎖

mysql悲觀鎖:在整個(gè)數(shù)據(jù)處理過(guò)程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制,每次會(huì)申請(qǐng)鎖并加鎖和解鎖操作for update?的悲觀鎖語(yǔ)法鎖住記錄
mysql樂觀鎖:樂觀鎖認(rèn)為一般情況下數(shù)據(jù)不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新時(shí)才會(huì)對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè)。如果沒有沖突那就OK;如果出現(xiàn)沖突了,則返回錯(cuò)誤信息并讓用戶決定如何去做。
總結(jié)&對(duì)比
? ??????????????????????????????????????????悲觀鎖? ? ? ? ? ? ? ?? ??????????????????????????????????????????樂觀鎖
概念? ? ????? 查詢時(shí)直接鎖住記錄使得其它事務(wù)不能查詢更不能更新????????????? 提交更新時(shí)檢查版本或者時(shí)間戳是否符合
語(yǔ)法 ????????select ... for update? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 使用 version 或者 timestamp 進(jìn)行比較
實(shí)現(xiàn)者 ????數(shù)據(jù)庫(kù)本身 ????????????????????????????????????????????????????????????????????????????????????開發(fā)者
適用場(chǎng)景 ????并發(fā)量大 ????????????????????????????????????????????????????????????????????????????????????并發(fā)量小
類比Java ????Synchronized關(guān)鍵字? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CAS 算法
悲觀鎖
優(yōu)點(diǎn):寫多讀少的并發(fā)環(huán)境中使用
缺點(diǎn):加鎖會(huì)增加系統(tǒng)開銷,雖然能保證數(shù)據(jù)的安全,但數(shù)據(jù)處理吞吐量低,不適合在讀書寫少的場(chǎng)合下使用
樂觀鎖
優(yōu)點(diǎn):在讀多寫少的并發(fā)場(chǎng)景下,可以避免數(shù)據(jù)庫(kù)加鎖的開銷
缺點(diǎn):在寫多讀少的并發(fā)場(chǎng)景下,即在寫操作競(jìng)爭(zhēng)激烈的情況下,會(huì)導(dǎo)致CAS多次重試,沖突頻率過(guò)高,導(dǎo)致開銷比悲觀鎖更高
4.Mysql 如何設(shè)置隔離級(jí)別,以及事物隔離有幾種級(jí)別。
1)read uncommitted : 讀取尚未提交的數(shù)據(jù) :就是臟讀
2)read committed:讀取已經(jīng)提交的數(shù)據(jù) :可以解決臟讀
3)repeatable read:重讀讀取:可以解決臟讀 和 不可重復(fù)讀 ---mysql默認(rèn)的
4)serializable:串行化:可以解決 臟讀 不可重復(fù)讀 和 虛讀---相當(dāng)于鎖表
4.Zookeeper
Zookeeper的角色:
領(lǐng)導(dǎo)者(leader),負(fù)責(zé)進(jìn)行投票的發(fā)起和決議,更新系統(tǒng)狀態(tài)
學(xué)習(xí)者(learner),包括跟隨者(follower)和觀察者(observer),follower用于接受客戶端請(qǐng)求并想客戶端返回結(jié)果,在選主過(guò)程中參與投票
Observer可以接受客戶端連接,將寫請(qǐng)求轉(zhuǎn)發(fā)給leader,但observer不參加投票過(guò)程,只同步leader的狀態(tài),observer的目的是為了擴(kuò)展系統(tǒng),提高讀取速度
客戶端(client),請(qǐng)求發(fā)起方
5.消息中間件

RabbitMQ
(1)生產(chǎn)者丟數(shù)據(jù)
從生產(chǎn)者弄丟數(shù)據(jù)這個(gè)角度來(lái)看,RabbitMQ提供transaction和confirm模式來(lái)確保生產(chǎn)者不丟消息。
transaction機(jī)制就是說(shuō),發(fā)送消息前,開啟事物(channel.txSelect()),然后發(fā)送消息,如果發(fā)送過(guò)程中出現(xiàn)什么異常,事物就會(huì)回滾(channel.txRollback()),如果發(fā)送成功則提交事物(channel.txCommit())。
(2)消息隊(duì)列丟數(shù)據(jù)
處理消息隊(duì)列丟數(shù)據(jù)的情況,一般是開啟持久化磁盤的配置。這個(gè)持久化配置可以和confirm機(jī)制配合使用,你可以在消息持久化磁盤后,再給生產(chǎn)者發(fā)送一個(gè)Ack信號(hào)。這樣,如果消息持久化磁盤之前,rabbitMQ陣亡了,那么生產(chǎn)者收不到Ack信號(hào),生產(chǎn)者會(huì)自動(dòng)重發(fā)。
如何保證消息的順序性?
針對(duì)這個(gè)問題,通過(guò)某種算法,將需要保持先后順序的消息放到同一個(gè)消息隊(duì)列中(kafka中就是partition,rabbitMq中就是queue)。然后只用一個(gè)消費(fèi)者去消費(fèi)該隊(duì)列。
我的觀點(diǎn)是保證入隊(duì)有序就行,出隊(duì)以后的順序交給消費(fèi)者自己去保證,沒有固定套路。
5.分布式事務(wù)
一、兩階段提交(2PC)
兩階段提交(Two-phase Commit,2PC),通過(guò)引入?yún)f(xié)調(diào)者(Coordinator)來(lái)協(xié)調(diào)參與者的行為,并最終決定這些參與者是否要真正執(zhí)行事務(wù)。
1.1 準(zhǔn)備階段
協(xié)調(diào)者詢問參與者事務(wù)是否執(zhí)行成功,參與者發(fā)回事務(wù)執(zhí)行結(jié)果。
1.2 提交階段
如果事務(wù)在每個(gè)參與者上都執(zhí)行成功,事務(wù)協(xié)調(diào)者發(fā)送通知讓參與者提交事務(wù);否則,協(xié)調(diào)者發(fā)送通知讓參與者回滾事務(wù)。
需要注意的是,在準(zhǔn)備階段,參與者執(zhí)行了事務(wù),但是還未提交。只有在提交階段接收到協(xié)調(diào)者發(fā)來(lái)的通知后,才進(jìn)行提交或者回滾。
2. 存在的問題
2.1 同步阻塞?所有事務(wù)參與者在等待其它參與者響應(yīng)的時(shí)候都處于同步阻塞狀態(tài),無(wú)法進(jìn)行其它操作。
2.2 單點(diǎn)問題?協(xié)調(diào)者在 2PC 中起到非常大的作用,發(fā)生故障將會(huì)造成很大影響。特別是在階段二發(fā)生故障,所有參與者會(huì)一直等待狀態(tài),無(wú)法完成其它操作。
2.3 數(shù)據(jù)不一致?在階段二,如果協(xié)調(diào)者只發(fā)送了部分 Commit 消息,此時(shí)網(wǎng)絡(luò)發(fā)生異常,那么只有部分參與者接收到 Commit 消息,也就是說(shuō)只有部分參與者提交了事務(wù),使得系統(tǒng)數(shù)據(jù)不一致。
2.4 太過(guò)保守?任意一個(gè)節(jié)點(diǎn)失敗就會(huì)導(dǎo)致整個(gè)事務(wù)失敗,沒有完善的容錯(cuò)機(jī)制。
二、補(bǔ)償事務(wù)(TCC)
TCC 其實(shí)就是采用的補(bǔ)償機(jī)制,其核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作。它分為三個(gè)階段:
Try 階段主要是對(duì)業(yè)務(wù)系統(tǒng)做檢測(cè)及資源預(yù)留
Confirm 階段主要是對(duì)業(yè)務(wù)系統(tǒng)做確認(rèn)提交,Try階段執(zhí)行成功并開始執(zhí)行 Confirm階段時(shí),默認(rèn) Confirm階段是不會(huì)出錯(cuò)的。即:只要Try成功,Confirm一定成功。
Cancel 階段主要是在業(yè)務(wù)執(zhí)行錯(cuò)誤,需要回滾的狀態(tài)下執(zhí)行的業(yè)務(wù)取消,預(yù)留資源釋放。
舉個(gè)例子,假入 Bob 要向 Smith 轉(zhuǎn)賬,思路大概是: 我們有一個(gè)本地方法,里面依次調(diào)用
首先在 Try 階段,要先調(diào)用遠(yuǎn)程接口把 Smith 和 Bob 的錢給凍結(jié)起來(lái)。
在 Confirm 階段,執(zhí)行遠(yuǎn)程調(diào)用的轉(zhuǎn)賬的操作,轉(zhuǎn)賬成功進(jìn)行解凍。
如果第2步執(zhí)行成功,那么轉(zhuǎn)賬成功,如果第二步執(zhí)行失敗,則調(diào)用遠(yuǎn)程凍結(jié)接口對(duì)應(yīng)的解凍方法 (Cancel)。
優(yōu)點(diǎn):?跟2PC比起來(lái),實(shí)現(xiàn)以及流程相對(duì)簡(jiǎn)單了一些,但數(shù)據(jù)的一致性比2PC也要差一些
缺點(diǎn):?缺點(diǎn)還是比較明顯的,在2,3步中都有可能失敗。TCC屬于應(yīng)用層的一種補(bǔ)償方式,所以需要程序員在實(shí)現(xiàn)的時(shí)候多寫很多補(bǔ)償?shù)拇a,在一些場(chǎng)景中,一些業(yè)務(wù)流程可能用TCC不太好定義及處理。
三、MQ 事務(wù)消息
6.Netty
并發(fā)高,傳輸快,封裝好
Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)開發(fā)的網(wǎng)絡(luò)通信框架,對(duì)比于BIO(Blocking I/O,阻塞IO),他的并發(fā)性能得到了很大提高
Netty的傳輸快其實(shí)也是依賴了NIO的一個(gè)特性——零拷貝。我們知道,Java的內(nèi)存有堆內(nèi)存、棧內(nèi)存和字符串常量池等等,其中堆內(nèi)存是占用內(nèi)存空間最大的一塊,也是Java對(duì)象存放的地方,一般我們的數(shù)據(jù)如果需要從IO讀取到堆內(nèi)存,中間需要經(jīng)過(guò)Socket緩沖區(qū),也就是說(shuō)一個(gè)數(shù)據(jù)會(huì)被拷貝兩次才能到達(dá)他的的終點(diǎn),如果數(shù)據(jù)量大,就會(huì)造成不必要的資源浪費(fèi)。
Netty針對(duì)這種情況,使用了NIO中的另一大特性——零拷貝,當(dāng)他需要接收數(shù)據(jù)的時(shí)候,他會(huì)在堆內(nèi)存之外開辟一塊內(nèi)存,數(shù)據(jù)就直接從IO讀到了那塊內(nèi)存中去,在netty里面通過(guò)ByteBuf可以直接對(duì)這些數(shù)據(jù)進(jìn)行直接操作,從而加快了傳輸速度。
netty如何解決粘包和半包
消息定長(zhǎng),每發(fā)送一次消息,在接收消息的同時(shí)截取固定長(zhǎng)度的字節(jié)。
以某種分隔符進(jìn)行分割。
把消息封裝成消息頭和消息體。
7.TCP/IP
1.DNS域名解析;
2.建立TCP連接;
3.發(fā)送HTTP請(qǐng)求;
4.服務(wù)器處理請(qǐng)求;
5.返回響應(yīng)結(jié)果;
6.關(guān)閉TCP連接;
7.瀏覽器解析HTML;
8.瀏覽器布局渲染;
1、 TCP面向連接 (如打電話要先撥號(hào)建立連接); UDP是無(wú)連接 的,即發(fā)送數(shù)據(jù)之前不需要建立連接
2、TCP提供可靠的服務(wù)。也就是說(shuō),通過(guò)TCP連接傳送的數(shù)據(jù),無(wú)差錯(cuò),不丟失,不重復(fù),且按序到達(dá);UDP盡最大努力交付,即不保證可靠交付
Tcp通過(guò)校驗(yàn)和,重傳控制,序號(hào)標(biāo)識(shí),滑動(dòng)窗口、確認(rèn)應(yīng)答實(shí)現(xiàn)可靠傳輸。如丟包時(shí)的重發(fā)控制,還可以對(duì)次序亂掉的分包進(jìn)行順序控制。
3、UDP具有較好的實(shí)時(shí)性,工作效率比TCP高,適用于對(duì)高速傳輸和實(shí)時(shí)性有較高的通信或廣播通信。
4.每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對(duì)一,一對(duì)多,多對(duì)一和多對(duì)多的交互通信
5、TCP對(duì)系統(tǒng)資源要求較多,UDP對(duì)系統(tǒng)資源要求較少。
校驗(yàn)和
序列號(hào)
確認(rèn)應(yīng)答
超時(shí)重傳
連接管理
流量控制
擁塞控制
TCP協(xié)議的三次握手連接和四次揮手?jǐn)嚅_
三次握手的目的是建立可靠的通信信道,說(shuō)到通訊,簡(jiǎn)單來(lái)說(shuō)就是數(shù)據(jù)的發(fā)送與接收,而三次握手最主要的目的就是雙方確認(rèn)自己與對(duì)方的發(fā)送與接收機(jī)能正常。
第一次握手:Client什么都不能確認(rèn);Server確認(rèn)了對(duì)方發(fā)送正常
第二次握手:Client確認(rèn)了:自己發(fā)送、接收正常,對(duì)方發(fā)送、接收正常;Server確認(rèn)了:自己接收正常,對(duì)方發(fā)送正常
第三次握手:Client確認(rèn)了:自己發(fā)送、接收正常,對(duì)方發(fā)送、接收正常;Server確認(rèn)了:自己發(fā)送、接收正常,對(duì)方發(fā)送接收正常
所以三次握手就能確認(rèn)雙發(fā)收發(fā)功能都正常,缺一不可。
1.第一次揮手:Client發(fā)送一個(gè)FIN,用來(lái)關(guān)閉Client到Server的數(shù)據(jù)傳送,Client進(jìn)入FIN_WAIT_1狀態(tài)。
2.第二次揮手:Server收到FIN后,發(fā)送一個(gè)ACK給Client,確認(rèn)序號(hào)為收到序號(hào)+1(與SYN相同,一個(gè)FIN占用一個(gè)序號(hào)),Server進(jìn)入CLOSE_WAIT狀態(tài)。
3.第三次揮手:Server發(fā)送一個(gè)FIN,用來(lái)關(guān)閉Server到Client的數(shù)據(jù)傳送,Server進(jìn)入LAST_ACK狀態(tài)。
4.第四次揮手:Client收到FIN后,Client進(jìn)入TIME_WAIT狀態(tài),接著發(fā)送一個(gè)ACK給Server,確認(rèn)序號(hào)為收到序號(hào)+1, Server進(jìn)入CLOSED狀態(tài),完成四次揮手。