๐ŸŒฑ ๋ฐฑ์—”๋“œ : Backend

[Spring WebFlux] 0. ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์†Œ๊ฐœ

๊ฐœ๋ฐœ์ž HOON 2023. 1. 1. 18:59

 

 

๐Ÿค” 1. ๋ฆฌ์•กํ„ฐ(Reactor)๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

 

 

๊ฐ„๋‹จ ์šฉ์–ด ์ •๋ฆฌ

- Reactive Stream : JVM ์œ„์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ‘œ์ค€ํ™”์‹œํ‚จ ๊ฒƒ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค์˜ ํ˜•ํƒœ๋กœ ์ŠคํŽ™์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

- Reactor3 : Reactive Stream ์ŠคํŽ™์„ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. JVM ์œ„์—์„œ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„์„ ์ ์šฉ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. 

- TCK(Reactive Streams Technology Compatibility Kit) : Reactive Streams ๊ตฌํ˜„์ž๊ฐ€ ์‚ฌ์–‘์— ์ •์˜๋œ ๊ทœ์น™์— ๋Œ€ํ•ด ๊ตฌํ˜„์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ์ง€์นจ์œผ๋กœ, TestNG๋ผ๋Š” Java์˜ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„ ์›Œํฌ๋กœ ๊ฐœ๋ฐœ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ์ŠคํŠธ๋ฆผ์˜ ์ŠคํŽ™์€ JVM ์œ„์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฐ์—…์—์„œ ์ฃผ๋„์ ์œผ๋กœ ๊ฐœ๋ฐœ๋˜์–ด ํ‘œ์ค€ํ™” ๋œ ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 

 

4๊ฐ€์ง€์˜ ๋งค์šฐ ๋‹จ์ˆœํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•œ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ์ด ๋˜์–ด์žˆ์œผ๋ฉฐ, ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•จ๊ณผ ๋™์‹œ์— TCK(Reactive Streams Technology Compatibility Kit) ๊ทœ์น™์„ ํ†ต๊ณผํ•ด์•ผ Reactor Streams๋ฅผ ๊ตฌ์ถ•ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์šฐ๋ฆฌ๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ ‡๊ฒŒ Reactive Stream ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ชจ๋‘ ๊ตฌํ˜„ํ•˜๊ณ , TCK๋ฅผ ํ†ต๊ณผํ•œ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ตฌํ˜„์ฒด์˜ ์ข…๋ฅ˜ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ Reactor3์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์•กํ„ฐ๋“ค์€ Reactor3, RxJava2, Akka Streams ๋“ฑ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„์ฒด๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Reacitve Streams๋Š” ๋ฆฌ์•กํ„ฐ ๊ฐ„์˜ ์ƒํ˜ธ ์šด์šฉ(ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•˜๋„๋ก)์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋™์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

Reactive Streams๋Š” ์—ฌ์ „ํžˆ ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” Low-Level์˜ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ตฌํ˜„์ฒด์ธ Reactor3๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Reactor3๋Š” Reactive Streams Publisher ์œ„์— ๋นŒ๋“œํ•จ์œผ๋กœ์จ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์˜ํ–ฅ๋ ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋„๋ก High Level API๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๐Ÿค” 2. ๊ทธ๋Ÿผ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ญ”๊ฐ€์š”? / ์™œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Reactive Programming)์€ ๋น„๋™๊ธฐ์ ์ธ ํ”„๋กœ์„ธ์‹ฑ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋˜์—ˆ๊ณ , ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์œ ์‚ฌํ•œ "์„ ์–ธ์  ์ฝ”๋“œ"๋ฅผ ์‚ฌ์šฉํ•œ ์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„์ž…๋‹ˆ๋‹ค. 

 

๋ฐฑ๊ธฐ์„ ๋‹˜๋„ ์ด "์„ ์–ธ์  ์ฝ”๋“œ"์˜ ์˜๋ฏธ์— ๋Œ€ํ•ด ๊ต‰์žฅํžˆ ์˜์•„ํ•ด ํ•˜์…”์„œ ๋‹ค์–‘ํ•œ ๊ธ€์„ ์„œ์น˜ํ•ด๋ณด์…จ์ง€๋งŒ, ๋ช…ํ™•ํ•œ ๋‹ต์€ ์–ป์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ,

 

๊ธฐ์กด์˜ ๋ช…๋ นํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ : 
์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‹ฌ์„ฑํ•ด ๋‚˜์•„๊ฐ€๋Š” ๊ณผ์ •์—๋งŒ ๊ด€์‹ฌ์„ ๋‘๋Š” ๋ฐฉ์‹์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ. URL์—์„œ ๊ณต๋ฐฑ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•˜์ดํ”ˆ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ณผ์ •์„ ๊ทธ๋Œ€๋กœ ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ์‹.

var string = 'THis is the midday show with Cheryl Waters';    
var urlFriendly = "";    

for(var i=0; i<string.length; i++){    
    if(string[i] === " "){    
        urlFriendly += "-";    
    }else{    
        urlFriendly += string[i];    
    }    
}    
    
console.log(urlFriendly);โ€‹


์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„, ์„ ์–ธ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ : 

const string = 'This is the midday show with Cheryl Waters';    
const urlFriendly = string.replace(/ /g, '-');    

console.log(urlFriendly);


์„ ์–ธ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ๊ตฌ์ฒด์ ์ธ ์ ˆ์ฐจ ๋Œ€์‹ ์— replace๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ถ”์ƒ์ ์ธ ๊ฐœ๋…์„ ํ‘œํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์„ ์–ธ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ฝ”๋“œ ๊ตฌ๋ฌธ์—์„œ๋Š” ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ธฐ์ˆ ํ•˜๊ณ , ์‹ค์ œ๋กœ ๊ทธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ถ”์ƒํ™”๋กœ ์•„๋žซ๋‹จ์— ๊ฐ์ถ”์–ด์ง‘๋‹ˆ๋‹ค.

[๋งํฌ : https://velog.io/@hyun_sang/%EB%AA%85%EB%A0%B9%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EA%B3%BC-%EC%84%A0%EC%96%B8%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EB%B9%84%EA%B5%90 ]

 

์ด๋Ÿฌํ•œ ๊ธ€์„ ์ฐพ์•„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜๋œ ๊ทœ์น™ ๊ฐ™์€๊ฒŒ ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์™€๋‹ฟ์ง€ ์•Š๊ณ  ์ถ”์ƒ์ ์ด๋‹ค๋ผ๊ณ  ๋А๋‚„ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์ œ๊ฐ€ ์ดํ•ดํ•œ ๋ฐ”๋กœ๋Š”, ๊ฐ๊ฐ์˜ ์ž‘์€ ํ•จ์ˆ˜์— ๊ทธ ํ•จ์ˆ˜๊ฐ€ ํ•˜๋Š” ์ผ์„ ์ž˜ ์„ค๋ช…ํ•˜๋Š” ์ด๋ฆ„์„ ๋ถ™์—ฌ ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ , ์ถ”๋ก ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœํ•˜๋ฉฐ, ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ๊ฐ์ถ”์–ด ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ดํ•ดํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋ชจ๋ธ์œผ๋กœ, ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋˜๋ฉด ์†Œ๋น„์ž์—๊ฒŒ pushํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ด๋กœ์จ ์šฐ๋ฆฌ๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ด๋ฒคํŠธ์˜ ์‹œํ€€์Šค๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ž์›์„ ๋”์šฑ ๋” ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๋” ๋งŽ์€ ์‚ฌ์šฉ์ž๋“ค์„ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. 

๋˜ํ•œ Runnable, Thread์™€ ๊ฐ™์€ Low-Level์˜ ์ง์ ‘์ ์ธ ๊ธฐ์ˆ  ์‚ฌ์šฉ์œผ๋กœ ์ธํ•ด ์ŠคํŠธ๋ ˆ์Šค๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ ๋„ ๋ณ‘ํ–‰ / ๋ณ‘๋ ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ฒƒ์ด ํฐ ๋ฉ”๋ฆฌํŠธ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ํ‚ค์›Œ๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ "๋น„๋™๊ธฐ(Asynchronous)"์™€ "๋…ผ๋ธ”๋กœํ‚น(Non-Blocking)"์ด์ฃ .

์ฆ‰, ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ Callback ๊ธฐ๋ฐ˜ API ํ˜น์€ Future ํ‚ค์›Œ๋“œ๋ฅผ ๋Œ€์ฒดํ•˜์—ฌ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ๋Œ€์•ˆ์ด ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ๋ฐฉ์‹์˜ ์ฝ”๋“œ๋ฅผ ์ข€ ๋” readableํ•˜๊ณ  maintainableํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ค€๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

๐Ÿ’ก 3. ์—ฌ๊ธฐ๊นŒ์ง€ ์ค‘๊ฐ„ ์ •๋ฆฌ!

 

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ๋น„๋™๊ธฐ์ ์ธ ํ”„๋กœ์„ธ์‹ฑ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ / ๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์„ ํ†ตํ•ด ์ž์›์˜ ํšจ์œจ์  ์‚ฌ์šฉ๊ณผ ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž ์ˆ˜์šฉ์„ ๊ฐ€๋Šฅ์ผ€ ํ•ฉ๋‹ˆ๋‹ค.

Reactors Streams : ์ด๋Ÿฌํ•œ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ฐ€๋Šฅ์ผ€ ํ•˜๋„๋ก ๋งŒ๋“  ํ‘œ์ค€ํ™”๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ธํ…ŒํŽ˜์ด์Šค์˜ ํ˜•ํƒœ๋กœ ์ŠคํŽ™์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Reactors3 : Reactors Streams ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด, TCK๋ฅผ ํ†ต๊ณผํ•œ ๊ตฌํ˜„์ฒด์— ํ•ด๋‹นํ•˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ์‰ฝ๊ฒŒ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. 

 

 

 

๐Ÿค” 4.  Reactive Streams Interface ๋ช…์„ธ

๊ฐ„๋‹จ ์š”์•ฝ!
์•„๋ž˜ 4๊ฐœ์˜ API Components๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

1. Publisher
2. Subscriber
3. Subscription
4. Processor

 

์ž์„ธํ•œ ๋ช…์„ธ๋Š” ์•„๋ž˜์˜ ๊นƒํ—ˆ๋ธŒ Readme์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

GitHub - reactive-streams/reactive-streams-jvm: Reactive Streams Specification for the JVM

Reactive Streams Specification for the JVM. Contribute to reactive-streams/reactive-streams-jvm development by creating an account on GitHub.

github.com

 

์ถ”๊ฐ€์ ์ธ ๊ณต๋ถ€๋ฅผ ํ†ตํ•ด ๋‚˜์ค‘์— ์ž์„ธํžˆ ๊ณต๋ถ€ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค :)

 

 

 

๐Ÿค” 5.  Reactive Stream Sequence์˜ ์ƒํ˜ธ์ž‘์šฉ

https://tech.io/playgrounds/929/reactive-programming-with-reactor-3/Intro

 

Reactive Stream์˜ ์‹œํ€€์Šค๋Š” Publisher๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์‚ฐํ•ด๋ƒ…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ Subscriber๊ฐ€ ๋“ฑ๋ก๋˜๊ธฐ(๊ตฌ๋…ํ•˜๊ธฐ)์ „๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ์ผ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฆ‰, Publisher๋Š” Subscriber๊ฐ€ ๋“ฑ๋ก๋˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ push ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆผ์„ ์ž์„ธํžˆ ๋ณด์‹œ๋ฉด, Subscriber๋Š” Publisher์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ์ค๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด, ์ด ํ”ผ๋“œ๋ฐฑ์€ ํ˜ผ์žก์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋กœ "๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ๋‹ค pushํ•˜์ง€ ๋ง๊ณ , N๊ฐœ๋งŒ ๋ณด๋‚ด์ค˜"์™€ ๊ฐ™์€ ์š”๊ตฌ์— ํ•ด๋‹นํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ์จ Subscriber์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ง€๋‚˜์น˜๊ฒŒ ์Œ“์—ฌ์„œ ๊ฐ๋‹นํ•  ์ˆ˜ ์—†๋Š” ํ˜„์ƒ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ด ํ”ผ๋“œ๋ฐฑ์€ ๊ต‰์žฅํžˆ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ํ”ผ๋“œ๋ฐฑ์„ ๊ด€์žฅํ•˜๋Š” ์š”์†Œ๊ฐ€ ๋ฐ”๋กœ Back-Pressure ์ž…๋‹ˆ๋‹ค. ํ•œ๊ตญ์–ด๋กœ๋Š” '๋ฐฐ์••'์ด๋ผ๊ณ  ํ•œ๋‹ต๋‹ˆ๋‹ค.

๋ฐฑ๊ธฐ์„ ๋‹˜์˜ ์œ ํŠœ๋ธŒ์—์„œ ์ด Back-Pressure๋Š” ๊ต‰์žฅํžˆ ์ค‘์š”ํ•œ ํ‚ค์›Œ๋“œ๋ผ๊ณ  ํ–ˆ์ง€๋งŒ, ์ž๋ฃŒ์—์„œ Back-Pressure์„ ์„ค๋ช…ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ๊ต‰์žฅํžˆ ๋ถ€์‹คํ•˜๋‹ค๊ณ  ๋ง์”€์„ ํ•˜์…จ๋„ค์š”. ๊ทธ๋ž˜์„œ ์ถ”๊ฐ€์ ์ธ ์ž๋ฃŒ๋ฅผ ์ฐพ์•„ ์ •๋ฆฌ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐฐ์••์€ ์‚ฌ์ „์  ์˜๋ฏธ๋กœ ํŒŒ์ดํ”„๋ฅผ ํ†ตํ•œ ์œ ์ฒด ํ๋ฆ„์— ๋ฐ˜ํ•˜๋Š” ์ €ํ•ญ, ํž˜์„ ์˜๋ฏธํ•˜๋ฉฐ ์œ ์ฒด๊ฐ€ ํ๋ฅด๋Š” ๋ฐฉํ–ฅ๊ณผ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ์ž‘์šฉํ•˜๋Š” ์ €ํ•ญ ์••๋ ฅ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

๋„๋Œ€์ฒด ์ด๊ฒŒ ์†Œํ”„ํŠธ์›จ์–ด ์–˜๊ธฐ๋ฅผ ํ•˜๋‹ค๊ฐ€ ์™œ ๋‚˜์˜ค๋А๋ƒ? ๋ผ๋Š” ์˜๋ฌธ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, Reactive Streams๋Š” ์‹ค์ œ ์„ธ์ƒ์— ์žˆ๋Š” ํŒŒ์ดํ”„์™€ ๊ทธ ํ๋ฆ„์„ ๋น—๋Œ€์–ด ์„ค๊ณ„๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹จ์ง€ ๊ทธ ๋‚ด์šฉ๋ฌผ์ด ์•ก์ฒด์™€ ๊ธฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ๋กœ ๋ฐ”๋€ ๊ฒƒ ๋ฟ์ด์ฃ . ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ด Reactive Streams์—์„œ๋„ ๋ฐฐ์••์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐฐ์••์˜ ํ•„์š”์„ฑ์€ ์•„๋ž˜ ๊ทธ๋ฆผ์œผ๋กœ ์‰ฝ๊ฒŒ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐฐ์••์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค๋ฉด, ๋ชจ๋‘๊ฐ€ ์ผ์ •ํ•œ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Fast Producer๊ฐ€ Slow Consumer์—๊ฒŒ ์ ์ ˆํ•œ ์†๋„๋กœ ๋ฒฝ๋Œ์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์ด ์ž˜ ์ง„ํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ๋ฐฐ์••์ด ์—†๋‹ค๋ฉด, Fast Producer๋Š” Slow Consumer๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๋ฌด์ง€์„ฑ ๋ฒฝ๋Œ ์ „์†กํ•˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Slow Consumer๋Š” ๊ฐ๋‹นํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋„๋ง์ณ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. 

 

 

์†Œํ”„ํŠธ์›จ์–ด ํ™˜๊ฒฝ์—์„œ๋Š” CPU์™€ ๋ฉ”๋ชจ๋ฆฌ, Data Drop ํ˜„์ƒ์„ ๊ฒช์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Network I/O, Disk I/O, Out of Memory ๋“ฑ์˜ ํ˜„์ƒ์„ ๊ฒช์„ ์ˆ˜๋„ ์žˆ๊ณ ์š”.

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ ๋ง‰๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

Reactor๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋Œ€ํ•ด์„œ ๊ฐ๊ฐ์˜ ๋‹จ๊ณ„๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๊ธฐ์ˆ ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋กœ ๋ฌถ์—ฌ์žˆ๋Š”, ์˜คํผ๋ ˆ์ดํ„ฐ๋ผ๋Š” ๊ฐœ๋…์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜คํผ๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•˜๋ฉด, ์ค‘๊ฐ„ ํผ๋ธ”๋ฆฌ์…”(upstream์— ๋Œ€ํ•œ subscriber, downstream์— ๋Œ€ํ•œ publisher)๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

Flux<String> flux = Flux.just("A");
flux.map(s -> "foo" + s); // ์ƒˆ๋กœ์šด Publisher ์ƒ์„ฑ, ๊ฑ”๋ฅผ ๊ตฌ๋…ํ•ด์•ผ fooA๊ฐ€ ์ฐํž˜.
flux.subscribe(System.out::println); // ์–˜๋Š” 1๋ฒˆ ๋ผ์ธ์˜ flux๋ฅผ ๊ตฌ๋…, ๋”ฐ๋ผ์„œ "A"๊ฐ€ ๋‚˜์˜จ๋‹ค.

Flux<String> flux = Flux.just("A");
Flux<String> flux2 = flux.map(s -> "foo" + s);
flux2.subscribe(System.out::println); // fooA

๋‘ ๋ฒˆ์งธ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, flux.map()์„ ํ†ตํ•ด์„œ ์ƒˆ๋กœ์šด ์ค‘๊ฐ„ publisher๊ฐ€ ์ƒ์„ฑ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์…‹์งธ ์ค„์—์„œ ์ฒซ์งธ ์ค„์˜ flux๋ฅผ subscribe ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— "fooA"๊ฐ€ ์•„๋‹Œ "A"๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋˜์ฃ .

 

๊ทธ ์•„๋ž˜์˜ ์ฝ”๋“œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด, ๊ธฐ์กด์˜ ์˜๋„๋Œ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  flux2๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ด์–ด์„œ ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๐Ÿ ์ถœ์ฒ˜

[๋งํฌ] https://www.youtube.com/watch?v=VeSHa_Xsd2U&list=LL&index=2 (๋ฐฑ๊ธฐ์„ ๋‹˜ ์œ ํŠœ๋ธŒ)
[๋งํฌ] https://tech.io/playgrounds/929/reactive-programming-with-reactor-3/Intro (Introduction to Reactive Programming)
[๋งํฌ] https://doublem.org/stream-backpressure-basic/ (back-pressure์— ๋Œ€ํ•œ ์ดํ•ด)
[๋งํฌ] https://www.oreilly.com/library/view/spring-50-projects/9781788390415/fd86b987-d9dd-465e-837f-ab4534e9d337.xhtml (TCK)