自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

什么是流式輸出?

開(kāi)發(fā) 開(kāi)發(fā)工具
流式(Stream)亦稱(chēng)響應(yīng)式,是一種基于異步數(shù)據(jù)流研發(fā)框架,是一種概念和編程模型,并非一種技術(shù)架構(gòu),目前在各技術(shù)棧都有響應(yīng)式的技術(shù)框架,前端的React.js、RxJs,服務(wù)端以RxJava、Reactor,Android端的RXJava。由此而來(lái)的即是響應(yīng)式編程。

 [[375247]]

一 名詞理解

1 流式

流式(Stream)亦稱(chēng)響應(yīng)式,是一種基于異步數(shù)據(jù)流研發(fā)框架,是一種概念和編程模型,并非一種技術(shù)架構(gòu),目前在各技術(shù)棧都有響應(yīng)式的技術(shù)框架,前端的React.js、RxJs,服務(wù)端以RxJava、Reactor,Android端的RXJava。由此而來(lái)的即是響應(yīng)式編程。

2 反應(yīng)式/響應(yīng)式編程

反應(yīng)式編程/響應(yīng)式編程(Reactive Programming)是一種基于事件模型編程范式,眾所周知異步編程模式中通常有兩種獲得上一個(gè)任務(wù)執(zhí)行結(jié)果的方式,一個(gè)就是主動(dòng)輪訓(xùn),我們把它稱(chēng)為Proactive方式。另一個(gè)就是被動(dòng)接收反饋,我們稱(chēng)為Reactive。簡(jiǎn)單來(lái)說(shuō),在Reactive方式中,上一個(gè)任務(wù)的結(jié)果的反饋就是一個(gè)事件,這個(gè)事件的到來(lái)將會(huì)觸發(fā)下一個(gè)任務(wù)的執(zhí)行。

這也就是Reactive的內(nèi)涵。我們把處理和發(fā)出事件的主體稱(chēng)為Reactor,它可以接收事件并處理,也可以在處理完事件后,發(fā)出下一個(gè)事件給其他Reactor。

下面是一個(gè)Reactive模型的示意圖:

 

當(dāng)然一種新的編碼模式,它的RunTime會(huì)減少上下文切流從而提升性能,減少內(nèi)存消耗,與之相反帶來(lái)的是代碼的可維護(hù)性降低。衡量?jī)?yōu)劣需要根據(jù)場(chǎng)景帶來(lái)的收益來(lái)衡量。

3 流式輸出

流式輸出就比較神奇,源自于團(tuán)隊(duì)內(nèi)部在一次性能大賽結(jié)束后的總結(jié)中產(chǎn)生,是基于流式的理論基礎(chǔ)在頁(yè)面渲染以及渲染的HTML在網(wǎng)絡(luò)傳輸中的具體應(yīng)用而誕生,也有人也簡(jiǎn)單的稱(chēng)之為流式渲染。即:將頁(yè)面拆分成獨(dú)立的幾部分模塊,每個(gè)模塊有單獨(dú)的數(shù)據(jù)源和單獨(dú)的頁(yè)面模板,在server端流式的操作每個(gè)模塊進(jìn)行業(yè)務(wù)邏輯處理和頁(yè)面模板的渲染,然后流式的將渲染出來(lái)的HTML輸出到網(wǎng)絡(luò)中,接著分塊的HTML數(shù)據(jù)在網(wǎng)絡(luò)中傳輸,接著流式的分塊的HTML在瀏覽器逐個(gè)渲染展示。具體流程如下:

 

針對(duì)HTML可以如上所述進(jìn)行流式輸出,衍生出針對(duì)json數(shù)據(jù)的流式輸出,其實(shí)也是如出一轍,無(wú)非少了一層渲染的邏輯,數(shù)據(jù)流式輸出流程跟上圖類(lèi)似,不再贅述。這里可以把客戶(hù)端的請(qǐng)求當(dāng)做響應(yīng)式的一個(gè)事件,所以總結(jié)就是客戶(hù)端主動(dòng)發(fā)出請(qǐng)求,服務(wù)端流式返回?cái)?shù)據(jù),即流式輸出。

4 端到端響應(yīng)式

基于流式輸出,我們?cè)偕钊胍稽c(diǎn),可以發(fā)現(xiàn)其實(shí)不只是用戶(hù)端和web server之間的數(shù)據(jù)可以在網(wǎng)絡(luò)上進(jìn)行流式輸出,微服務(wù)的各個(gè)server之間的數(shù)據(jù)其實(shí)也可以在網(wǎng)絡(luò)上進(jìn)行流式輸出,如下圖所示:

 

數(shù)據(jù)可以在網(wǎng)絡(luò)之間的流式傳輸,再進(jìn)一步來(lái)看,數(shù)據(jù)在整條請(qǐng)求響應(yīng)鏈路上的流式傳輸會(huì)是什么樣子,見(jiàn)下圖所示:

 

綜上所述我們定義:端到端響應(yīng)式=流式輸出+響應(yīng)式編程。

二 流式輸出理論基礎(chǔ)

是什么基礎(chǔ)技術(shù)理論,支撐我們能夠像上述流程那樣對(duì)數(shù)據(jù)進(jìn)行流式輸出和接收,下面有幾個(gè)核心的技術(shù)點(diǎn):

1 HTTP分塊傳輸協(xié)議

分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協(xié)議(HTTP)中的一種數(shù)據(jù)傳輸機(jī)制,允許HTTP由網(wǎng)頁(yè)服務(wù)器發(fā)送給客戶(hù)端應(yīng)用( 通常是網(wǎng)頁(yè)瀏覽器)的數(shù)據(jù)可以分成多個(gè)部分。分塊傳輸編碼只在HTTP協(xié)議1.1版本(HTTP/1.1)中提供。

如果需要使用分塊傳輸編碼的響應(yīng)格式,我們需要在HTTP響應(yīng)中設(shè)置響應(yīng)頭Transfer-Encoding: chunked。它的具體傳輸格式是這樣的(注意HTTP響應(yīng)中換行符是\r\n):

  1. HTTP/1.1 200 OK\r\n 
  2. \r\n 
  3. Transfer-Encoding: chunked\r\n 
  4. ...\r\n 
  5. \r\n 
  6. <chunked 1 length>\r\n 
  7. <chunked 1 content>\r\n 
  8. <chunked 2 length>\r\n 
  9. <chunked 2 content>\r\n 
  10. ...\r\n 
  11. 0\r\n 
  12. \r\n 
  13. \r\n 

具體流程見(jiàn)流式輸出名詞理解部分,分塊傳輸編碼例子:

  1. func handleChunkedHttpResp(conn net.Conn) { 
  2.     buffer := make([]byte, 1024) 
  3.     n, err := conn.Read(buffer) 
  4.     if err != nil { 
  5.         log.Fatalln(err) 
  6.     } 
  7.     fmt.Println(n, string(buffer)) 
  8.  
  9.     conn.Write([]byte("HTTP/1.1 200 OK\r\n")) 
  10.     conn.Write([]byte("Transfer-Encoding: chunked\r\n")) 
  11.     conn.Write([]byte("\r\n")) 
  12.  
  13.     conn.Write([]byte("6\r\n")) 
  14.     conn.Write([]byte("hello,\r\n")) 
  15.  
  16.     conn.Write([]byte("8\r\n")) 
  17.     conn.Write([]byte("chunked!\r\n")) 
  18.  
  19.     conn.Write([]byte("0\r\n")) 
  20.     conn.Write([]byte("\r\n")) 

這里需要注意的是HTTP分塊傳輸對(duì)同步HTML輸出比較適合(對(duì)于瀏覽器來(lái)講),因?yàn)樵诤芏鄔eb頁(yè)面涉及SEO,SEO的TDK元素必須同步輸出,所以這種方式比較適合,針對(duì)于JSON數(shù)據(jù)的流式輸出通過(guò)SSE來(lái)實(shí)現(xiàn),具體如下。

2 HTTP SSE協(xié)議

sse(Server Send Events)是HTTP的標(biāo)準(zhǔn)協(xié)議,是服務(wù)端向客戶(hù)端發(fā)送事件流式的方式。在客戶(hù)端中為一些事件類(lèi)型綁定監(jiān)聽(tīng)函數(shù),從而做業(yè)務(wù)邏輯處理。這里要注意的是SEE是單向的,只能服務(wù)器向客戶(hù)端發(fā)送事件流,具體流程如下:

 

SSE協(xié)議中約束了下面幾個(gè)字段類(lèi)型

1)event

事件類(lèi)型。如果指定了該字段,則在客戶(hù)端接收到該條消息時(shí),會(huì)在當(dāng)前的EventSource對(duì)象上觸發(fā)一個(gè)事件,事件類(lèi)型就是該字段的字段值,你可以使用addEventListener()方法在當(dāng)前EventSource對(duì)象上監(jiān)聽(tīng)任意類(lèi)型的命名事件,如果該條消息沒(méi)有event字段,則會(huì)觸發(fā)onmessage屬性上的事件處理函數(shù)。

2)data

消息的數(shù)據(jù)字段。如果該條消息包含多個(gè)data字段,則客戶(hù)端會(huì)用換行符把它們連接成一個(gè)字符串來(lái)作為字段值。

3)id

事件ID,會(huì)成為當(dāng)前EventSource對(duì)象的內(nèi)部屬性"最后一個(gè)事件ID"的屬性值。

4)retry

一個(gè)整數(shù)值,指定了重新連接的時(shí)間(單位為毫秒),如果該字段值不是整數(shù),則會(huì)被忽略。

客戶(hù)端代碼示例

  1. // 客戶(hù)端初始化事件源 
  2. const evtSource = new EventSource("//api.example.com/ssedemo.php", { withCredentials: true } ); 
  3.  
  4. // 對(duì) message 事件添加一個(gè)處理函數(shù)開(kāi)始監(jiān)聽(tīng)從服務(wù)器發(fā)出的消息 
  5. evtSource.onmessage = function(event) { 
  6.   const newElement = document.createElement("li"); 
  7.   const eventList = document.getElementById("list"); 
  8.  
  9.   newElement.innerHTML = "message: " + event.data; 
  10.   eventList.appendChild(newElement); 

服務(wù)器代碼示例

  1. date_default_timezone_set("America/New_York"); 
  2. header("Cache-Control: no-cache"); 
  3. header("Content-Type: text/event-stream"); 
  4. $counter = rand(1, 10); 
  5. while (true) { 
  6.   // Every second, send a "ping" event. 
  7.   echo "event: ping\n"
  8.   $curDate = date(DATE_ISO8601); 
  9.   echo 'data: {"time": "' . $curDate . '"}'
  10.   echo "\n\n"
  11.   // Send a simple message at random intervals. 
  12.   $counter--; 
  13.   if (!$counter) { 
  14.     echo 'data: This is a message at time ' . $curDate . "\n\n"
  15.     $counter = rand(1, 10); 
  16.   } 
  17.   ob_end_flush(); 
  18.   flush(); 
  19.   sleep(1); 

效果示例

  1. event: userconnect 
  2. data: {"username""bobby""time""02:33:48"
  3. event: usermessage 
  4. data: {"username""bobby""time""02:34:11""text""Hi everyone."
  5. event: userdisconnect 
  6. data: {"username""bobby""time""02:34:23"
  7. event: usermessage 
  8. data: {"username""sean""time""02:34:36""text""Bye, bobby."

這里需要注意下,在未通過(guò)http2使用SSE時(shí),SSE會(huì)收到最大連接數(shù)限制,此時(shí)默認(rèn)的最大連接數(shù)只有6,即同一時(shí)間只能建立6個(gè)SSE連接,不過(guò)這里的限制是對(duì)同域名的,跨域的域名可以再建立6個(gè)SSE連接。通過(guò)HTTP2使用SSE時(shí)默認(rèn)的最大連接數(shù)是100。

目前SSE已集成到spring5,Springboot2的webflux其實(shí)就是通過(guò)SSE的方式進(jìn)行數(shù)據(jù)的流式輸出。

3 WebSocket

Websocket就比較老生常談了,這里主要介紹下它與SSE的區(qū)別:

  • Websocket是區(qū)別于HTTP的另外一種協(xié)議,是全雙工通信,協(xié)議相對(duì)來(lái)說(shuō)比較中,對(duì)代碼侵入度比較高。
  • SSE是標(biāo)準(zhǔn)的HTTP協(xié)議,是半雙工通信,支持?jǐn)嗑€(xiàn)重連和自定義事件和數(shù)據(jù)類(lèi)型,相對(duì)輕便靈活。

4 RSocket

在微服務(wù)架構(gòu)中,不同服務(wù)之間通過(guò)應(yīng)用協(xié)議進(jìn)行數(shù)據(jù)傳輸。典型的傳輸方式包括基于 HTTP 協(xié)議的 REST 或 SOAP API 和基于 TCP 字節(jié)流的 RPC 等。但是對(duì)于HTTP只支持請(qǐng)求響應(yīng)模式,如果客戶(hù)端需要獲取最新的推送消息,就必須使用輪詢(xún),這無(wú)疑造成了大量的資源浪費(fèi)。再者如果某個(gè)請(qǐng)求的響應(yīng)時(shí)間過(guò)長(zhǎng),會(huì)阻塞之后的其他請(qǐng)求的處理;雖然服務(wù)器發(fā)送事件(Server-Sent Events,SSE)可以用來(lái)推送消息,不過(guò) SSE 是一個(gè)簡(jiǎn)單的文本協(xié)議,僅提供有限的功能;而WebSocket 可以進(jìn)行雙向數(shù)據(jù)傳輸,不過(guò)它沒(méi)有提供應(yīng)用層協(xié)議支持,Rsocket很好的解決了已有協(xié)議面臨的各種問(wèn)題。

 

Rsocket是一個(gè)面向反應(yīng)式應(yīng)用程序的新型應(yīng)用網(wǎng)絡(luò)協(xié)議,它工作在網(wǎng)絡(luò)七層模型中 5/6 層的協(xié)議,是 TCP/IP 之上的應(yīng)用層協(xié)議,RSocket 可以使用不同的底層傳輸層,包括 TCP、WebSocket 和 Aeron。TCP 適用于分布式系統(tǒng)的各個(gè)組件之間交互,WebSocket 適用于瀏覽器和服務(wù)器之間的交互,Aeron 是基于 UDP 協(xié)議的傳輸方式,這就保證了 RSocket 可以適應(yīng)于不同的場(chǎng)景,見(jiàn)上圖。然后RSocket 使用二進(jìn)制格式,保證了傳輸?shù)母咝?,?jié)省帶寬。而且,通過(guò)基于反應(yīng)式流控保證了消息傳輸中的雙方不會(huì)因?yàn)檎?qǐng)求的壓力過(guò)大而崩潰。更多詳細(xì)資料請(qǐng)移步RSocket[1]。雷卷也開(kāi)源了alibaba-rsocket-broker[2],感興趣可以去深入了解請(qǐng)教。

Rsocket提供了四種不同的交互模式滿(mǎn)足所有場(chǎng)景:

 

RSocket 提供了不同語(yǔ)言的實(shí)現(xiàn),包括Java、Kotlin、JavaScript、Go、.NET和C++ 等,如下為僅供學(xué)習(xí)了解的簡(jiǎn)單Java實(shí)現(xiàn):

  1. import io.rsocket.AbstractRSocket; 
  2. import io.rsocket.Payload; 
  3. import io.rsocket.RSocket; 
  4. import io.rsocket.RSocketFactory; 
  5. import io.rsocket.transport.netty.client.TcpClientTransport; 
  6. import io.rsocket.transport.netty.server.TcpServerTransport; 
  7. import io.rsocket.util.DefaultPayload; 
  8. import reactor.core.publisher.Mono; 
  9.  
  10. public class RequestResponseExample { 
  11.  
  12.   public static void main(String[] args) { 
  13.     RSocketFactory.receive() 
  14.         .acceptor(((setup, sendingSocket) -> Mono.just( 
  15.             new AbstractRSocket() { 
  16.               @Override 
  17.               public Mono<Payload> requestResponse(Payload payload) { 
  18.                 return Mono.just(DefaultPayload.create("ECHO >> " + payload.getDataUtf8())); 
  19.               } 
  20.             } 
  21.         ))) 
  22.         .transport(TcpServerTransport.create("localhost", 7000)) //指定傳輸層實(shí)現(xiàn) 
  23.         .start() //啟動(dòng)服務(wù)器 
  24.         .subscribe(); 
  25.  
  26.     RSocket socket = RSocketFactory.connect() 
  27.         .transport(TcpClientTransport.create("localhost", 7000)) //指定傳輸層實(shí)現(xiàn) 
  28.         .start() //啟動(dòng)客戶(hù)端 
  29.         .block(); 
  30.  
  31.     socket.requestResponse(DefaultPayload.create("hello")) 
  32.         .map(Payload::getDataUtf8) 
  33.         .doOnNext(System.out::println) 
  34.         .block(); 
  35.  
  36.     socket.dispose(); 
  37.   } 

5 響應(yīng)式編程框架

如果要在全鏈路實(shí)現(xiàn)響應(yīng)式,那響應(yīng)式編程框架是支撐這個(gè)技術(shù)的核心技術(shù),這對(duì)于開(kāi)發(fā)者來(lái)說(shuō)是一種編程模式的變革,通過(guò)使用異步數(shù)據(jù)流進(jìn)行編程對(duì)于原流程化的編程模式來(lái)說(shuō)變化還很大。

簡(jiǎn)單示例如下:

  1. @Override 
  2. public Single<Integer> remaining() { 
  3.     return Flowable.fromIterable(LotteryEnum.EFFECTIVE_LOTTERY_TYPE_LIST) 
  4.         .flatMap(lotteryType -> tairMCReactive.get(generateLotteryKey(lotteryType))) 
  5.         .filter(Result::isSuccess) 
  6.         .filter(result -> !ResultCode.DATANOTEXSITS.equals(result.getRc())) 
  7.         .map(result -> (Integer) result.getValue().getValue()) 
  8.         .reduce((acc, lotteryRemaining) -> acc + lotteryRemaining) 
  9.         .toSingle(0); 

總的來(lái)說(shuō)通過(guò)HTTP分塊傳輸協(xié)議和HTTP SSE協(xié)議以及RSocket我們可以實(shí)現(xiàn)流式輸出,通過(guò)流式輸出和響應(yīng)式編程端到端的響應(yīng)式才得以實(shí)現(xiàn)。

三 流式輸出應(yīng)用場(chǎng)景

性能、體驗(yàn)和數(shù)據(jù)是我們?nèi)粘9ぷ髦凶サ淖罹o的三件事情。對(duì)于性能來(lái)說(shuō)也一直是我們追求極致和永無(wú)止境的核心點(diǎn),流式輸出也是在解決性能體驗(yàn)這個(gè)問(wèn)題而誕生,那是不是所有的場(chǎng)景都適合流式輸出呢?當(dāng)然不是,我們來(lái)康康哪些場(chǎng)景適合?

 

以上為Resource Timing API規(guī)范提供的請(qǐng)求生命周期包含的主要階段,通過(guò)上述來(lái)看下一下幾個(gè)場(chǎng)景對(duì)于請(qǐng)求生命周期的影響。

1 頁(yè)面流式輸出場(chǎng)景

對(duì)于動(dòng)態(tài)頁(yè)面來(lái)說(shuō)(相對(duì)于靜態(tài)頁(yè)面)主要由頁(yè)面樣式、頁(yè)面交互的JS以及頁(yè)面的動(dòng)態(tài)數(shù)據(jù)構(gòu)成,除了上述請(qǐng)求生命周期的各階段耗時(shí),還有頁(yè)面渲染耗時(shí)階段。瀏覽器拿到HTML會(huì)先進(jìn)行DOM樹(shù)構(gòu)建、預(yù)加載掃描器、CSSOM樹(shù)構(gòu)建,Javascript編譯執(zhí)行,在過(guò)程中CSS文件的加載和JS文件的加載阻塞頁(yè)面渲染過(guò)程。如果我們將頁(yè)面按照以下方式進(jìn)行拆分進(jìn)行流式輸出將會(huì)在性能上有很大的收益。

單接口動(dòng)態(tài)頁(yè)面

對(duì)于某些場(chǎng)景比如SEO,頁(yè)面需要同步渲染輸出,此時(shí)頁(yè)面通常是單接口動(dòng)態(tài)頁(yè)面,就可以將頁(yè)面拆分成body以上部分和body以下的部分,例如:

  1. <!-- 模塊1 --> 
  2. <html> 
  3.   <head> 
  4.   <meta  /> 
  5.     <link  />   
  6.   <style></style>   
  7.   <script src=""></script> 
  8.   </head> 
  9.   <body> 
  10.  
  11. <!-- 模塊2 --> 
  12.         <div>xxx</div> 
  13.         <div>yyy</div>   
  14.         <div>zzz</div>  
  15.     </body> 
  16. </html>   

 

當(dāng)模塊1到達(dá)頁(yè)面模塊2未到達(dá)時(shí),模塊1渲染后在等待模塊2到來(lái)的同時(shí)可以進(jìn)行CSS和JS的加載,在幾個(gè)方面進(jìn)行了性能提升:

  • 到達(dá)瀏覽器的首字節(jié)時(shí)間(TTFB)
  • 數(shù)據(jù)包到達(dá)瀏覽器下載HTML的時(shí)間
  • CSS和JS的加載及執(zhí)行時(shí)間
  • 拆成模塊之后網(wǎng)絡(luò)傳輸?shù)臅r(shí)間會(huì)有一定的降低

單接口多樓層頁(yè)面

  1. <!-- 模塊1 --> 
  2. <html> 
  3.   <head> 
  4.   <meta  /> 
  5.     <link  />   
  6.   <style></style>   
  7.   <script src=""></script> 
  8.   </head> 
  9.   <body> 
  10.  
  11. <!-- 模塊2 --> 
  12.         <div>xxx1</div> 
  13.         <div>yyy1</div>   
  14.         <div>zzz1</div>  
  15.      
  16. <!-- 模塊3 --> 
  17.         <div>xxx2</div> 
  18.         <div>yyy2</div>   
  19.         <div>zzz2</div> 
  20.      
  21. <!-- 模塊4 --> 
  22.         <div>xxx3</div> 
  23.         <div>yyy3</div>   
  24.         <div>zzz3</div> 
  25.     </body> 
  26. </html>   

 

很多場(chǎng)景是一個(gè)頁(yè)面展現(xiàn)多個(gè)樓層、譬如首頁(yè)的四大金剛以及各種導(dǎo)購(gòu)樓層,detail的信息樓層等等,甚至后面樓層依賴(lài)前面樓層的數(shù)據(jù),類(lèi)似這種情況可以將頁(yè)面樓層拆分成多個(gè)模塊進(jìn)行輸出,在上述幾個(gè)方面進(jìn)行了性能提升之外還有額外的性能提升:樓層之間數(shù)據(jù)相互依賴(lài)的數(shù)據(jù)處理時(shí)間。

多接口多樓層頁(yè)面

一般情況下大部分頁(yè)面都是由同步SSR渲染和異步CSR渲染進(jìn)行,這時(shí)會(huì)涉及到JS異步加載異步樓層,如果同步渲染部分按照單接口多樓層進(jìn)行拆分會(huì)在上述基礎(chǔ)上提前加載運(yùn)行異步樓層的渲染。

總的來(lái)說(shuō)基于HTTP分塊傳輸協(xié)議的流式輸出幾乎覆蓋所有頁(yè)面場(chǎng)景,供所有頁(yè)面提升性能體驗(yàn)。

2 數(shù)據(jù)流式輸出場(chǎng)景

單接口大數(shù)據(jù)

對(duì)于APP或者單頁(yè)面系統(tǒng)更多的是通過(guò)異步加載數(shù)據(jù)的方式進(jìn)行頁(yè)面渲染,單個(gè)接口會(huì)造成單個(gè)接口的RT時(shí)間較長(zhǎng),以及數(shù)據(jù)包體太大導(dǎo)致在網(wǎng)絡(luò)中拆包粘包的損耗較大。如果通過(guò)多個(gè)異步接口會(huì)因網(wǎng)絡(luò)帶寬受限而導(dǎo)致數(shù)據(jù)請(qǐng)求的延時(shí)較高以及網(wǎng)絡(luò)IO的帶來(lái)的CPU占有率較高,因此可以通過(guò)業(yè)務(wù)場(chǎng)景進(jìn)行分析將單接口拆分成多個(gè)相互獨(dú)立或者有一定耦合關(guān)系的業(yè)務(wù)模塊,將這些模塊的數(shù)據(jù)進(jìn)行流式輸出,以此帶來(lái)以下性能體驗(yàn)上的提升。

  • 到達(dá)瀏覽器的首字節(jié)時(shí)間(TTFB)
  • 數(shù)據(jù)包到達(dá)端側(cè)下載數(shù)據(jù)的時(shí)間
  • 數(shù)據(jù)在網(wǎng)絡(luò)傳輸?shù)臅r(shí)間

多相互依賴(lài)接口

但是在大部分場(chǎng)景中我們遇到的業(yè)務(wù)場(chǎng)景是相互耦合關(guān)聯(lián)的,比方說(shuō)榜單模塊數(shù)據(jù)依賴(lài)它上面的新品模塊的數(shù)據(jù)進(jìn)行業(yè)務(wù)邏輯處理,這種情況在服務(wù)器側(cè)處理完新品模塊數(shù)據(jù)后對(duì)數(shù)據(jù)進(jìn)行輸出,再接著處理榜單模塊數(shù)據(jù)進(jìn)行輸出,這里接節(jié)省了相互依賴(lài)等待的時(shí)間。

當(dāng)然日常的業(yè)務(wù)場(chǎng)景會(huì)相對(duì)復(fù)雜的多,但是通過(guò)流式輸出都會(huì)頁(yè)面性能和體驗(yàn)會(huì)有很大的提升和助力。

四 小結(jié)

  • 流式輸出的前世為流式渲染,今生為端到端的響應(yīng)式,這些雖然帶來(lái)了性能體驗(yàn)上的提升,但對(duì)研發(fā)模式變革的接受程度和運(yùn)維成本的增加需要加以權(quán)衡。
  • 簡(jiǎn)單介紹了幾種流式輸出的技術(shù)方案,適合不同的業(yè)務(wù)場(chǎng)景。
  • 提出了流式輸出適合的幾種場(chǎng)景,以及對(duì)頁(yè)面和數(shù)據(jù)進(jìn)行拆分的方法。

相關(guān)鏈接

[1]https://rsocket.io/

[2]https://github.com/alibaba/alibaba-rsocket-broker

 

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2022-02-16 22:37:00

流式SQLSQL數(shù)據(jù)庫(kù)

2024-02-04 16:22:13

Python流式輸出開(kāi)發(fā)

2018-11-05 15:15:38

大數(shù)據(jù)流式數(shù)據(jù)互聯(lián)網(wǎng)

2025-04-24 00:00:00

Spring AI流式輸出AI 模型

2023-07-19 08:00:00

Raft分布式系統(tǒng)

2017-08-15 15:33:41

動(dòng)力配電箱配電柜

2024-04-01 00:05:00

ChatGPTSSE

2022-01-16 08:02:01

pycharm日志記錄器

2021-03-20 22:46:22

IaaSSaaSPaaS

2025-02-12 09:04:20

2023-09-01 13:49:00

內(nèi)存進(jìn)程線(xiàn)程

2020-07-14 14:59:00

控制反轉(zhuǎn)依賴(lài)注入容器

2025-02-13 08:06:40

DeepSeekSpringAI前端

2017-12-19 21:29:58

物聯(lián)網(wǎng)區(qū)塊鏈大數(shù)據(jù)

2011-10-19 17:40:23

流式計(jì)算

2020-11-20 10:51:03

云計(jì)算

2010-08-26 09:27:53

DHCP服務(wù)器

2018-01-30 11:17:56

集群分布式SOA?

2011-08-16 18:39:05

Ubuntu

2016-05-09 10:31:29

DockerLinux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)