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來創(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ù)注冊中心
Eureka:
Eureka客戶端會(huì)向Eureka注冊中心注冊為服務(wù),并通過心跳來更新它的服務(wù)租約得问。同時(shí)也可以從服務(wù)端查詢當(dāng)前注冊的服務(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)再次同步回來漓骚。
Zookeeper:
Zookeeper是大數(shù)據(jù)Hadoop中的一個(gè)分布式調(diào)度組件宣蔚,強(qiáng)調(diào)數(shù)據(jù)一致性和擴(kuò)展性,可用于服務(wù)的注冊和發(fā)現(xiàn)认境。
Consul:
Consul是一個(gè)高可用的分布式服務(wù)注冊中心胚委,由HashiCorp公司推出,Golang實(shí)現(xiàn)的開源共享的服務(wù)工具叉信。Consul在分布式服務(wù)注冊與發(fā)現(xiàn)方面有自己的特色亩冬,解決方案更加“一站式”,不再需要依賴其他工具硼身。
1硅急、通過HTTP接口和DNS協(xié)議調(diào)用API存儲鍵值對,使服務(wù)注冊和服務(wù)發(fā)現(xiàn)更容易佳遂;
2营袜、支持健康檢查,可以快速的告警在集群中的操作
3丑罪、支持key/value存儲動(dòng)態(tài)配置
4荚板、支持任意數(shù)量的區(qū)域
ETCD:
ETCD是一個(gè)高可用的分布式鍵值數(shù)據(jù)庫凤壁,可用于共享配置、服務(wù)的注冊和發(fā)現(xiàn)跪另。ETCD采用Raft一致性算法拧抖,基于Go語言實(shí)現(xiàn)。ETCD作為后起之秀免绿,又非常大的優(yōu)勢唧席。
1、基于HTTP+JSON的API嘲驾,使用簡單淌哟;
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ù)管理平臺。
2.客服端負(fù)載均衡
Ribbon客戶端:ribbon 是一個(gè)客戶端負(fù)載均衡器缴啡,可以簡單的理解成類似于 nginx的負(fù)載均衡模塊的功能壁晒。
Feign客戶端:是一個(gè)聲明式的Web Service客戶端
負(fù)載均衡算法:
1:簡單輪詢負(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),從流量控制业栅、熔斷降級秒咐、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度保護(hù)服務(wù)的穩(wěn)定性。
Nacos:一個(gè)更易于構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)碘裕、配置管理和服務(wù)管理平臺携取。
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)品姆坚,提供秒級澳泵、精準(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ù)類型的長度
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很相似,也是映射形式的存儲:
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è)置了過期時(shí)間的鍵空間中饿序,移除最近最少使用的 key勉失;
volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中原探,隨機(jī)移除某個(gè) key乱凿;
volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中咽弦,有更早過期時(shí)間的 key 優(yōu)先移除徒蟆;
5.Mysql
1.為什么用自增列作為主鍵
1、如果我們定義了主鍵(PRIMARY KEY)型型,那么InnoDB會(huì)選擇主鍵作為聚集索引段审。
如果沒有顯式定義主鍵,則InnoDB會(huì)選擇第一個(gè)不包含有NULL值的唯一索引作為主鍵索引闹蒜。
如果也沒有這樣的唯一索引寺枉,則InnoDB會(huì)選擇內(nèi)置6字節(jié)長的ROWID作為隱含的聚集索引(ROWID隨著行記錄的寫入而主鍵遞增,這個(gè)ROWID不像ORACLE的ROWID那樣可引用绷落,是隱含的)姥闪。
2、數(shù)據(jù)記錄本身被存于主索引(一顆B+Tree)的葉子節(jié)點(diǎn)上砌烁,這就要求同一個(gè)葉子節(jié)點(diǎn)內(nèi)(大小為一個(gè)內(nèi)存頁或磁盤頁)的各條數(shù)據(jù)記錄按主鍵順序存放
因此每當(dāng)有一條新的記錄插入時(shí)甘畅,MySQL會(huì)根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點(diǎn)和位置,如果頁面達(dá)到裝載因子(InnoDB默認(rèn)為15/16)往弓,則開辟一個(gè)新的頁(節(jié)點(diǎn))
3疏唾、如果表使用自增主鍵,那么每次插入新的記錄函似,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置槐脏,當(dāng)一頁寫滿,就會(huì)自動(dòng)開辟一個(gè)新的頁
4撇寞、如果使用非自增主鍵(如果身份證號或?qū)W號等)顿天,由于每次插入主鍵的值近似于隨機(jī)堂氯,因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁得中間某個(gè)位置
此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù),甚至目標(biāo)頁面可能已經(jīng)被回寫到磁盤上而從緩存中清掉牌废,此時(shí)又要從磁盤上讀回來咽白,這增加了很多開銷
同時(shí)頻繁的移動(dòng)、分頁操作造成了大量的碎片鸟缕,得到了不夠緊湊的索引結(jié)構(gòu)晶框,后續(xù)不得不通過OPTIMIZE TABLE來重建表并優(yōu)化填充頁面。
2.為什么使用數(shù)據(jù)索引能提高效率
數(shù)據(jù)索引的存儲是有序的
在有序的情況下懂从,通過索引查詢一個(gè)數(shù)據(jù)是無需遍歷索引記錄的
極端情況下授段,數(shù)據(jù)索引的查詢效率為二分法查詢效率,趨近于 log2(N)
3.Mysql鎖
mysql悲觀鎖:在整個(gè)數(shù)據(jù)處理過程中番甩,將數(shù)據(jù)處于鎖定狀態(tài)侵贵。悲觀鎖的實(shí)現(xiàn),依靠數(shù)據(jù)庫提供的鎖機(jī)制缘薛,每次會(huì)申請鎖并加鎖和解鎖操作for update?的悲觀鎖語法鎖住記錄
mysql樂觀鎖:樂觀鎖認(rèn)為一般情況下數(shù)據(jù)不會(huì)造成沖突窍育,所以在數(shù)據(jù)進(jìn)行提交更新時(shí)才會(huì)對數(shù)據(jù)的沖突與否進(jìn)行檢測。如果沒有沖突那就OK宴胧;如果出現(xiàn)沖突了漱抓,則返回錯(cuò)誤信息并讓用戶決定如何去做。
總結(jié)&對比
? ??????????????????????????????????????????悲觀鎖? ? ? ? ? ? ? ?? ??????????????????????????????????????????樂觀鎖
概念? ? ????? 查詢時(shí)直接鎖住記錄使得其它事務(wù)不能查詢更不能更新????????????? 提交更新時(shí)檢查版本或者時(shí)間戳是否符合
語法 ????????select ... for update? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 使用 version 或者 timestamp 進(jìn)行比較
實(shí)現(xiàn)者 ????數(shù)據(jù)庫本身 ????????????????????????????????????????????????????????????????????????????????????開發(fā)者
適用場景 ????并發(fā)量大 ????????????????????????????????????????????????????????????????????????????????????并發(fā)量小
類比Java ????Synchronized關(guān)鍵字? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CAS 算法
悲觀鎖
優(yōu)點(diǎn):寫多讀少的并發(fā)環(huán)境中使用
缺點(diǎn):加鎖會(huì)增加系統(tǒng)開銷牺汤,雖然能保證數(shù)據(jù)的安全辽旋,但數(shù)據(jù)處理吞吐量低,不適合在讀書寫少的場合下使用
樂觀鎖
優(yōu)點(diǎn):在讀多寫少的并發(fā)場景下檐迟,可以避免數(shù)據(jù)庫加鎖的開銷
缺點(diǎn):在寫多讀少的并發(fā)場景下补胚,即在寫操作競爭激烈的情況下,會(huì)導(dǎo)致CAS多次重試追迟,沖突頻率過高溶其,導(dǎo)致開銷比悲觀鎖更高
4.Mysql 如何設(shè)置隔離級別,以及事物隔離有幾種級別敦间。
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用于接受客戶端請求并想客戶端返回結(jié)果带猴,在選主過程中參與投票
Observer可以接受客戶端連接,將寫請求轉(zhuǎn)發(fā)給leader拴清,但observer不參加投票過程会通,只同步leader的狀態(tài)娄周,observer的目的是為了擴(kuò)展系統(tǒng)涕侈,提高讀取速度
客戶端(client),請求發(fā)起方
5.消息中間件
RabbitMQ
(1)生產(chǎn)者丟數(shù)據(jù)
從生產(chǎn)者弄丟數(shù)據(jù)這個(gè)角度來看裳涛,RabbitMQ提供transaction和confirm模式來確保生產(chǎn)者不丟消息掷酗。
transaction機(jī)制就是說调违,發(fā)送消息前窟哺,開啟事物(channel.txSelect())泻轰,然后發(fā)送消息且轨,如果發(fā)送過程中出現(xiàn)什么異常旋奢,事物就會(huì)回滾(channel.txRollback()),如果發(fā)送成功則提交事物(channel.txCommit())至朗。
(2)消息隊(duì)列丟數(shù)據(jù)
處理消息隊(duì)列丟數(shù)據(jù)的情況,一般是開啟持久化磁盤的配置矗钟。這個(gè)持久化配置可以和confirm機(jī)制配合使用嫌变,你可以在消息持久化磁盤后,再給生產(chǎn)者發(fā)送一個(gè)Ack信號东涡。這樣倘待,如果消息持久化磁盤之前,rabbitMQ陣亡了凸舵,那么生產(chǎn)者收不到Ack信號贞间,生產(chǎn)者會(huì)自動(dòng)重發(fā)雹仿。
如何保證消息的順序性整以?
針對這個(gè)問題,通過某種算法邑商,將需要保持先后順序的消息放到同一個(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)斥滤,通過引入?yún)f(xié)調(diào)者(Coordinator)來協(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ā)來的通知后,才進(jìn)行提交或者回滾直焙。
2. 存在的問題
2.1 同步阻塞?所有事務(wù)參與者在等待其它參與者響應(yīng)的時(shí)候都處于同步阻塞狀態(tài)奔誓,無法進(jìn)行其它操作。
2.2 單點(diǎn)問題?協(xié)調(diào)者在 2PC 中起到非常大的作用曲初,發(fā)生故障將會(huì)造成很大影響杯聚。特別是在階段二發(fā)生故障抒痒,所有參與者會(huì)一直等待狀態(tài),無法完成其它操作傀广。
2.3 數(shù)據(jù)不一致?在階段二彩届,如果協(xié)調(diào)者只發(fā)送了部分 Commit 消息樟蠕,此時(shí)網(wǎng)絡(luò)發(fā)生異常,那么只有部分參與者接收到 Commit 消息吓懈,也就是說只有部分參與者提交了事務(wù)靡狞,使得系統(tǒng)數(shù)據(jù)不一致。
2.4 太過保守?任意一個(gè)節(jié)點(diǎn)失敗就會(huì)導(dǎo)致整個(gè)事務(wù)失敗甘穿,沒有完善的容錯(cuò)機(jī)制。
二庆揪、補(bǔ)償事務(wù)(TCC)
TCC 其實(shí)就是采用的補(bǔ)償機(jī)制妨托,其核心思想是:針對每個(gè)操作,都要注冊一個(gè)與其對應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作内颗。它分為三個(gè)階段:
Try 階段主要是對業(yè)務(wù)系統(tǒng)做檢測及資源預(yù)留
Confirm 階段主要是對業(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é)起來急侥。
在 Confirm 階段侮邀,執(zhí)行遠(yuǎn)程調(diào)用的轉(zhuǎn)賬的操作绊茧,轉(zhuǎn)賬成功進(jìn)行解凍。
如果第2步執(zhí)行成功鹏秋,那么轉(zhuǎn)賬成功亡笑,如果第二步執(zhí)行失敗,則調(diào)用遠(yuǎn)程凍結(jié)接口對應(yīng)的解凍方法 (Cancel)百拓。
優(yōu)點(diǎn):?跟2PC比起來晰甚,實(shí)現(xiàn)以及流程相對簡單了一些厕九,但數(shù)據(jù)的一致性比2PC也要差一些
缺點(diǎn):?缺點(diǎn)還是比較明顯的,在2,3步中都有可能失敗腺阳。TCC屬于應(yīng)用層的一種補(bǔ)償方式穿香,所以需要程序員在實(shí)現(xiàn)的時(shí)候多寫很多補(bǔ)償?shù)拇a绎速,在一些場景中纹冤,一些業(yè)務(wù)流程可能用TCC不太好定義及處理。
三雁歌、MQ 事務(wù)消息
6.Netty
并發(fā)高知残,傳輸快,封裝好
Netty是一款基于NIO(Nonblocking I/O乏盐,非阻塞IO)開發(fā)的網(wǎng)絡(luò)通信框架,對比于BIO(Blocking I/O神凑,阻塞IO)何吝,他的并發(fā)性能得到了很大提高
Netty的傳輸快其實(shí)也是依賴了NIO的一個(gè)特性——零拷貝爱榕。我們知道,Java的內(nèi)存有堆內(nèi)存型宝、棧內(nèi)存和字符串常量池等等絮爷,其中堆內(nèi)存是占用內(nèi)存空間最大的一塊,也是Java對象存放的地方岖寞,一般我們的數(shù)據(jù)如果需要從IO讀取到堆內(nèi)存柜蜈,中間需要經(jīng)過Socket緩沖區(qū)淑履,也就是說一個(gè)數(shù)據(jù)會(huì)被拷貝兩次才能到達(dá)他的的終點(diǎn),如果數(shù)據(jù)量大狸吞,就會(huì)造成不必要的資源浪費(fèi)指煎。
Netty針對這種情況,使用了NIO中的另一大特性——零拷貝威始,當(dāng)他需要接收數(shù)據(jù)的時(shí)候像街,他會(huì)在堆內(nèi)存之外開辟一塊內(nèi)存,數(shù)據(jù)就直接從IO讀到了那塊內(nèi)存中去葫掉,在netty里面通過ByteBuf可以直接對這些數(shù)據(jù)進(jìn)行直接操作俭厚,從而加快了傳輸速度。
netty如何解決粘包和半包
消息定長叼丑,每發(fā)送一次消息扛门,在接收消息的同時(shí)截取固定長度的字節(jié)论寨。
以某種分隔符進(jìn)行分割。
把消息封裝成消息頭和消息體绰垂。
7.TCP/IP
1.DNS域名解析火焰;
2.建立TCP連接;
3.發(fā)送HTTP請求昌简;
4.服務(wù)器處理請求纯赎;
5.返回響應(yīng)結(jié)果;
6.關(guān)閉TCP連接餐蔬;
7.瀏覽器解析HTML佑附;
8.瀏覽器布局渲染仗考;
1秃嗜、 TCP面向連接 (如打電話要先撥號建立連接); UDP是無連接 的顿膨,即發(fā)送數(shù)據(jù)之前不需要建立連接
2恋沃、TCP提供可靠的服務(wù)必指。也就是說,通過TCP連接傳送的數(shù)據(jù)梅割,無差錯(cuò)葛家,不丟失癞谒,不重復(fù),且按序到達(dá);UDP盡最大努力交付双仍,即不保證可靠交付
Tcp通過校驗(yàn)和迅栅,重傳控制读存,序號標(biāo)識,滑動(dòng)窗口敬察、確認(rèn)應(yīng)答實(shí)現(xiàn)可靠傳輸尔当。如丟包時(shí)的重發(fā)控制椭迎,還可以對次序亂掉的分包進(jìn)行順序控制。
3缴阎、UDP具有較好的實(shí)時(shí)性简软,工作效率比TCP高,適用于對高速傳輸和實(shí)時(shí)性有較高的通信或廣播通信建炫。
4.每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對一肛跌,一對多,多對一和多對多的交互通信
5妒挎、TCP對系統(tǒng)資源要求較多西饵,UDP對系統(tǒng)資源要求較少眷柔。
校驗(yàn)和
序列號
確認(rèn)應(yīng)答
超時(shí)重傳
連接管理
流量控制
擁塞控制
TCP協(xié)議的三次握手連接和四次揮手?jǐn)嚅_
三次握手的目的是建立可靠的通信信道,說到通訊镶苞,簡單來說就是數(shù)據(jù)的發(fā)送與接收鞠评,而三次握手最主要的目的就是雙方確認(rèn)自己與對方的發(fā)送與接收機(jī)能正常剃幌。
第一次握手:Client什么都不能確認(rèn);Server確認(rèn)了對方發(fā)送正常
第二次握手:Client確認(rèn)了:自己發(fā)送牍白、接收正常茂腥,對方發(fā)送切省、接收正常;Server確認(rèn)了:自己接收正常仑性,對方發(fā)送正常
第三次握手:Client確認(rèn)了:自己發(fā)送诊杆、接收正常何陆,對方發(fā)送贷盲、接收正常;Server確認(rèn)了:自己發(fā)送铝穷、接收正常佳魔,對方發(fā)送接收正常
所以三次握手就能確認(rèn)雙發(fā)收發(fā)功能都正常,缺一不可宁脊。
1.第一次揮手:Client發(fā)送一個(gè)FIN榆苞,用來關(guān)閉Client到Server的數(shù)據(jù)傳送霞捡,Client進(jìn)入FIN_WAIT_1狀態(tài)碧信。
2.第二次揮手:Server收到FIN后,發(fā)送一個(gè)ACK給Client慨畸,確認(rèn)序號為收到序號+1(與SYN相同衣式,一個(gè)FIN占用一個(gè)序號)碴卧,Server進(jìn)入CLOSE_WAIT狀態(tài)。
3.第三次揮手:Server發(fā)送一個(gè)FIN婶博,用來關(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)序號為收到序號+1, Server進(jìn)入CLOSED狀態(tài)倒慧,完成四次揮手讥邻。