[Mastering Spring 5.0] 11.1 Reactive Programming
리μ‘ν°λΈ μμ€ν
μλ‘μ΄ λλ°μ΄μ€ (λͺ¨λ°μΌ, νλΈλ¦Ώ λ±) real-time data μ λν μμ μ¦κ°
- λλμ νλ‘μΈμ€ μ²λ¦¬ λ‘λ λ°μ
- λ°μ΄ν° λ³Όλ₯¨μ΄ κΈ°νκΈμμ μΌλ‘ μ¦κ°
- μΈνλΌ μ μ§ λ³΄μ λΉμ© μ¦κ°
Reactive μμ€ν νΉμ§
Reactive manifesto : https://www.reactivemanifesto.org/ko
Reative Manifesto λ λ€μ λ€ κ°μ§ ν΅μ¬ μμΉμ λ°λΌ Reactive System
μ νΉμ±μ κ°λ΅μ μΌλ‘ μ€λͺ
νκ³ μλ€.
λ°μμ± (Responsive)
: λͺ¨λ μλ΅μ μ μμ λΉ λ₯΄κ³ μΌκ΄λ λμμ μ 곡νλ©° μ λ’°ν μ μμΌλ©° μΌκ΄λ μλΉμ€ νμ§μ μ 곡νλ€.ν볡λ ₯ (Resilient)
: κ°κ°μ ꡬμ±μμ λ€μ΄ λΆλ¦¬λμ΄ μκΈ° λλ¬Έμ ꡬμ±μμ μ€ νλμ λ¬Έμ κ° λ°μνλλΌλ μ 체 μμ€ν μ΄ λ€μ΄λλ κ²μ λ°©μ§νκ³ λ³΅κ΅¬ ν μ μλλ‘ λ³΄μ₯νλ€. λν μ₯μ μ λ°μμ΄ μμΈμ μΈ νμμ΄ μλ μ μμ μΈ κΈ°λ₯μ μΌλΆλ‘ μ²λ¦¬νλ€.μ μ°μ± (Elastic)
: μμ²μ μ²λ¦¬νκΈ° μν΄ ν λΉλ 리μμ€λ₯Ό λ리거λ μ€μμΌλ‘μ¨ μμ² λ‘λμ λ³νμ λμν μ μλ€. ( auto scale )λ©μμ§ κΈ°λ°(Message-driven)
: μμ€ν μ ꡬμ±μμλ€μ΄ λ©μΈμ§(λλ μ΄λ²€νΈ) λ₯Ό ν΅ν΄ μ΄λ£¨μ΄μ§λ€. μ¬κΈ°μμ ꡬμ±μμλ€μ μ»΄ν¬λνΈ, μλΉμ€, κ°μ²΄, API 무μμ΄λΌλ λ μ μμΌλ©° κ³Όκ±°μ²λΌ λ©μλ νΈμΆμ΄λ RPC κ°μ λΈλ‘νΉ λ°©μμΌλ‘ μμ¬μν΅ νμ§ μκ³ , 보λ΄κ³ μλ(fire-and-forget) λ°©μμΌλ‘ λ©μμ§λ₯Ό μ£Όκ³ λ°μΌλ©° μν΅νλ€.
Reactive Keyworld
- A reactive stream should be
non-blocking
- It should be
a stream of data
- It should work
asynchronously
- And it should be able to handle
back pressure
.
Non-Bloking
Bloking
λΈλ‘νΉμ μμ²μ΄ λ°μνκ³ μμ μ μ§ννλ λμ νλ‘κ·Έλ¨μ μ§νμ λ©μΆκ³ (block) μλ£λ λκΉμ§ λͺ¨λ μΌμ μ€λ¨ν μνλ‘ λκΈ°ν΄μΌ νλ κ²μ λΈλ‘νΉ λ°©μμ΄λΌκ³ νλ€.
Blocking Java Socket ν΅μ μμ
ν΄λΌμ΄μΈνΈκ° μ μν λ κΉμ§ accept()
λ©μλλ νμ λΈλ‘νΉ λλ€.
|
|
- λν ν΄λΌμ΄μΈνΈκ° λ³΄λΈ μ€νΈλ¦Όμ΄
μλ£
λλμ λ ₯ λ λ¬Έμ
( Ctrl + C μ λ ₯ μ) λ₯Ό λ³΄λΌ λ κΉμ§ λ°μνλ€. - ν΄λΌμ΄μΈνΈκ° λ§μ μλ‘ μ€λ λ μκ° μ¦κ°νκ³ μλ²μ μ¬κ°ν μ±λ₯μ ν λ°μ -> λμμΌλ‘
μ€λ λ ν
μ μ¬μ©
Non-Blocking
μ΄λ€ μ€λ λμμ μ€λ₯κ° λ°μνκ±°λ λ©μΆμμ λ λ€λ₯Έ μ°λ λμκ² μν₯μ λΌμΉμ§ μλλ‘ νλ λ°©λ²μ΄λ€. μμ²ν μμ (μ€λ λ) μ΄ μ§ν λλ λμ μ¦μ λ€μ μμ μ μ²λ¦¬ν¨μΌλ‘μ¨ μμ€ν μμμ λ ν¨μ¨μ μΌλ‘ νμμ΄ κ°λ₯νλ€. κ·Έλ¬λ μμ²ν μμ μ΄ν νμ μμ μ μ΄μ΄μ μ§νν μ μλλ‘ λ³λμ μ½μ(Polling, Callback Function λ±) μ΄ νμνλ€.
|
|
accept()
λ©μλκ° λΈλ‘νΉ λμ§ μκ³ λ°λ‘ 리ν΄λκΈ° λλ¬Έμ, ν΄λΌμ΄μΈνΈκ° μ°κ²° μμ²μ 보λ΄κΈ° μ κΉμ§ while λΈλ‘ μ½λκ° μ΄μ μμ΄ λ°λ³΅λμ΄ CPUκ° κ³Όλνκ² μλΉλλ λ¬Έμ μ μ΄ λ°μνλ€. κ·Έλμ λλΈλ‘νΉμ μ΄λ²€νΈ 리μ€λ μν μ νλ μ
λ ν°(Selector)
λ₯Ό μ¬μ©νλ€. μ΄ Selector λ₯Ό λλΈλ‘νΉ μ±λμ λ±λ‘ν΄ λμΌλ©΄ ν΄λΌμ΄μΈνΈμ μ°κ²° μμ²μ΄ λ€μ΄μ€κ±°λ λ°μ΄ν°κ° λμ°©ν κ²½μ° μ±λμ Selector μ ν΅λ³΄νλ€. Selectorλ ν΅λ³΄ν μ±λλ€μ μ νν΄ μμ
μ€λ λκ° accept() λλ read() λ©μλλ₯Ό μ€ννλ€.
|
|
Backpressure
λΉλκΈ°μ λ°μ΄ν° μ€νΈλ¦Ό μ²λ¦¬μ λν μ΄μ
- λ무 ν° λ°μ΄ν° μ€νΈλ¦Ό ->
busy waiting
- λ무 λΉ λ₯Έ λ°μ΄ν° μ€νΈλ¦Ό μ μ‘ μλ ->
out of memory exception
Backpressure λ μμ μ μΌλ‘ μ²λ¦¬νκΈ°μ λ무 ν° λ°μ΄ν° νΉμ λ°μ΄ν°λ₯Ό μ λ’° μκ² μ²λ¦¬ ν μ μλ μλλ‘ κ΅¬λ μμκ² μ 곡νλ λ°©λ²μ΄λ€. Reactive λ°μ΄ν° μ€νΈλ¦Όμ Push μ Pull μ κ΄λ¦¬νλ Buffer λ₯Ό μ¬μ©νμ¬ κ΅¬λ μλ νΉμ μμ λ°μ΄ν°λ₯Ό μμ²νκ³ μμ€λ ꡬμ±λ λ°μ΄ν°λ₯Ό ν΄λΉ λ°μ΄ν°λ‘ μ λμ μΌλ‘ Push μ Pull μ νλ λ°©μμ΄λ€.
μΆμ² λ° μ°Έκ³ μ¬μ΄νΈ
- https://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/
- http://palpit.tistory.com/645
- https://tech.peoplefund.co.kr/2017/08/02/non-blocking-asynchronous-concurrency.html
- https://medium.com/coderscorner/tale-of-client-server-and-socket-a6ef54a74763
- http://www.zdnet.co.kr/view/?no=20161010104628
- https://www.slideshare.net/dnnddane/why-reactivereactive-programming-spring-5
- https://www.youtube.com/watch?v=UIrwrW5A2co
- ReactiveX History : https://ahea.wordpress.com/2017/02/03/reactive-history/
- https://www.slideshare.net/ktoso/reactive-stream-processing-with-akka-streams
- https://www.e4developer.com/2018/04/28/springs-webflux-reactor-parallelism-and-backpressure/