이 글은 ReactiveX - Intro를 번역한 글입니다.


Original Text

[1] ReactiveX - Intro



ReactiveX

ReactiveX는 observable sequences를 사용하여 비동기(asynchronous) 및 이벤트 기반 프로그램(event-based programs)을 작성하기 위한 라이브러리입니다.


옵져버 패턴(observer pattern)을 확장하여 데이터 및 / 또는 이벤트의 시퀀스를 지원하고 낮은 수준의 스레딩(low-level threading), 동기화(synchronization), 스레드 안전성(thread-safety), 동시 데이터 구조(concurrent data structures,) 및 논 블로킹 I/O(non blocking I/O)과 같은 문제를 추상화하는 동시에 선언적으로 시퀀스를 조합 할 수있는 연산자를 추가합니다.


Observables는 여러 항목의 비동기 시퀀스(asynchronous sequences)에 액세스하는 이상적인 방법이므로 간격을 메웁니다.


 

 single items

 multiple items

 synchronous

 T getData()

 Iterable<T> getData()

 asynchronous

 Future<T> getData()

 Observable<T> getData()


때로는 "functional reactive programming"이라고도하지만 이는 잘못된 이름입니다.
ReactiveX는 함수형(functional)일 수도 있고 리액티브(reactive)일 수도 있지만 "functional reactive programming"은 다른 동물입니다.


차이점 중 하나는

functional reactive programming은 시간이 지남에 따라 지속적으로 변하는 값에서 작동하는 반면

ReactiveX는 시간이 지남에 따라 방출되는 불연속 값에서 동작한다는 것입니다.

(functional reactive programming에 대한 자세한 정보는 Conal Elliott의 작업을 참조하십시오.)




Why Use Observables?

ReactiveX Observable 모델을 사용하면 배열과 같은 데이터 항목 컬렉션에 사용하는 것과 동일한 종류의 단순하고 구성 가능한 작업으로 비동기 이벤트 스트림을 처리 할 수 ​​있습니다. 그것은 콜백의 얽힌 웹에서 당신을 자유롭게하고, 따라서 코드를 더 읽기 쉽고 버그를 적게 만듭니다.


Observables Are Composable

 Java Futures와 같은 기술은 단일 레벨의 비동기 실행(single level of asynchronous execution)에 사용하기 쉽지만 중첩 될 때 적지 않은 복잡성을 추가하기 시작합니다.

Futures를 사용하여 조건부 비동기 실행 흐름을 최적으로 구성하는 것은 어렵습니다.

(또는 각 요청의 대기 시간이 런타임에 다양하기 때문에 불가능 함).
물론 이렇게 할 수는 있지만 복잡해지며 (따라서 오류가 발생하기 쉽다) 또는 Future.get ()을 조기에 차단하여 비동기 실행의 이점을 없애줍니다.

 ReactiveX Observables은 한편으로는 흐름(flows)과 비동기 데이터 시퀀스(sequences of asynchronous data)를 구성하기위한 것입니다.


Observables Are Flexible

 ReactiveX Observables는 단일 스칼라 값(single scalar values, Futures처럼)뿐만 아니라 값의 시퀀스(sequences of values) 또는 무한 스트림(infinite streams)의 배출도 지원합니다. Observable은 이 유스 케이스에 사용할 수있는 단일 추상화입니다. Observable은 미러 이미지 사촌 인 Iterable과 관련된 모든 유연성(flexibility)과 우아함(elegance)을 갖추고 있습니다.


Observable은 동기(synchronous) / pull Iterable에 대한 비동기(asynchronous) / 푸시(push)입니다.

event

 Iterable (pull)

 Observable (push)

 retrieve 

 T next()

 onNext(T)

 discover 

 throws Exception

 onError(Exception)

 complete

 !hasNext()

 onCompleted()




Observables Are Less Opinionated

Observables은 덜 독선적입니다.

ReactiveX는 동시성 또는 비 동시성의 특정 소스에 편향되지 않습니다. Observables는 스레드 풀, 이벤트 루프, 논 블로킹 I / O, 액터 (예 : Akka) 또는 요구 사항, 스타일 또는 전문 지식에 적합한 구현을 사용하여 구현할 수 있습니다. 클라이언트 코드는 Observables와의 모든 상호 작용을 기본 구현이 블로킹 또는 비 블로킹 여부에 관계없이 비동기로 처리하지만 이를 구현하도록 선택합니다.



이 Observable은 어떻게 구현됩니까?

 public Observable<data> getData();


 Observer의 관점에서 볼 때, 그것은 중요하지 않습니다!

 호출자와 동일한 스레드에서 동기적으로 작동합니까?

 그것은 별개의 스레드에서 비동기적으로 작동합니까?

 어떤 순서로든 호출자에게 데이터를 반환 할 수있는 여러 스레드를 통해 작업을 분할합니까?

 스레드 풀 대신 액터 (또는 여러 액터)를 사용합니까?

 비동기 네트워크 액세스를하기 위해 NIO를 이벤트 루프와 함께 사용합니까?

 그것은 콜백 스레드에서 작업 스레드를 분리하는 이벤트 루프를 사용합니까?


Observer의 관점에서 볼 때, 그것은 중요하지 않습니다!

그리고 중요한 것은 ReactiveX를 사용하여 나중에 당신의 마음을 바꿀 수 있고, Observable의 Consumer를 없애지 않으면서 Observable 구현의 근본적인 특성을 바꿀 수 있다는 것입니다.



Callbacks Have Their Own Problems

콜백에는 자신만의 문제가 있습니다.

콜백은 Future.get()의 빠른 블로킹 문제를 해결합니다. 응답 준비가 되면 실행되므로 자연스럽게 효율적입니다.

그러나 Futures와 마찬가지로 콜백은 단일 레벨의 비동기 실행으로 사용하기 쉽고 중첩된 컴포지션을 사용하면 다루기 힘들어집니다.



ReactiveX Is a Polyglot Implementation
ReactiveX는 현재 다양한 언어로 구현되어있어 해당 언어의 숙어를 존중하며 더 많은 언어가 빠른 클립에 추가되고 있습니다.


Reactive Programming

ReactiveX는 Observables를 필터링, 선택, 변환, 결합 및 작성할 수있는 연산자(operators)  모음을 제공합니다. 이를 통해 효율적인 실행 및 구성이 가능합니다.

Observable 클래스는 "pull"인 Iterable에 해당하는 "push"로 생각할 수 있습니다. Iterable을 사용하면 소비자는 값이 도달 할 때까지 제작자와 스레드 블록에서 값을 가져옵니다. 대조적으로 Observable을 사용하면 값을 사용할 수있을 때마다 생산자가 소비자에게 값을 푸시합니다. 값이 동기적 또는 비동기적으로 도착할 수 있기 때문에이 방법은 보다 융통성이 있습니다.


예제 코드) 유사한 고차 함수(high-order functions)가 Iterable과 Observable에 어떻게 적용될 수 있는지

 Iterable

 Observable

 

 getDataFromLocalMemory()

  .skip(10)

  .take(5)

  .map({ s -> return s + " transformed" })

  .forEach({ println "next => " + it })


 

 getDataFromNetwork()

  .skip(10)

  .take(5)

  .map({ s -> return s + " transformed" })

  .subscribe({ println "onNext => " + it })



Observable 유형은 Gang of Four의 Observer pattern에 두 개의 누락 된 의미를 추가합니다.

Iterable 유형에서 사용할 수 있는 것이 어울리는 : 


  1. 더 이상 사용할 수있는 데이터가 없다는 것을 소비자에게 알릴 수있는 능력
    (Iterable의 foreach 루프가 완료되고 그러한 경우에 정상적으로 복귀하며, Observable이 옵저버의 onCompleted 메소드를 호출)

  2. 생산자가 소비자에게 오류가 발생했다는 신호를 보내는 능력
    (반복 중에 오류가 발생하면 Iterable은 예외를 throw하고 Observable은 관찰자의 onError 메서드를 호출 함)

이러한 추가 기능을 통해 ReactiveX는 Iterable 및 Observable 유형을 조화시킵니다. 이들 간의 유일한 차이점은 데이터가 흐르는 방향입니다. 이것은 Iterable에서 수행 할 수있는 모든 연산이 가능하기 때문에 Observable에서도 수행 할 수 있기 때문에 매우 중요합니다.




Leave a Comment

이 글은 "What's in a Name : Reactive"를 번역하고 정리한 글입니다.


Original Text

[1] What's in a Name : Reactive




 용어, 뜻

상세 정보, 사용 예 

 반응형(Responsive)

 사용자 인터페이스의 일시적인 동작을 설명할 때

 UI가 사용자 입력에 신속하게 반응하거나 응답하는 경우
 예) 반응형 웹(Responsive web)

 리액션을 보여준다

 예) 스프레드 시트, Model-View-Controller 패턴

 Spreadsheet

 스프레드 시트에서 셀 "A42"의 값을 변경하면 수식에서 A42를 참조하는 다른 모든 셀이 즉시 업데이트되는 예

 즉각적인 의미이므로이 행동을 "리액티브"라고 생각할 수도 있음

 데이터 바인딩

 데이터 바인딩이 되어서 실시간으로 GUI 출력되는 것

 예) 비즈니스 대시 보드, 자동차 속도계

 Reactive manifesto

 Reactive Manifesto는 다음과 같은 반응 시스템의 특성을 나타냅니다.

  • Responsive (응답성)
  • Resilient (탄력성)
  • Elastic (유연성)
  • Message Driven (메시지 기반)

 이 선언문의 주된 아이디어는 비동기 메시징을 마이크로 수준으로 가져 오는 것
 Akka와 Vert.x를 기반으로하는 시스템에서는 이를 실제로 볼 수 있음
 리액티브 선언 이전에 비동기는 소프트웨어 아키텍처 내에서 거시적 또는 글로벌 수준으로 어느 정도 제한됨

 Reactive programming

 비동기 데이터 스트림을 사용한 프로그래밍

 Reactive Extensions (Rx)

 관찰 가능한 시퀀스를 사용하여 비동기 및 이벤트 기반 프로그램을 작성하기 위한 라이브러리


 옵져버 패턴을 확장하여 데이터 및 / 또는 이벤트의 시퀀스를 지원하고 낮은 수준의 스레딩, 동기화, 스레드 안전성, 동시 데이터 구조 및 비 실시간 스레딩과 같은 문제를 추상화하는 동시에 선언적으로 시퀀스를 조합 할 수있는 연산자를 추가함

 Functional
 Reactive Programming

 FRP는 20 년 전에 Conal Elliott에 의해 매우 정확하게 정의
 (http://conal.net/papers/push-pull-frp/)
 
 ELM은 Functional Reactive Programming을 위해 만들어진 언어
 시간이 지남에 따라 변하는 값인 신호를 중심으로 함
 예) 화면의 커서 위치, 브라우저 창의 크기 또는 장시간 실행되는 계산 상태 등

 Meteor

 대화 형 웹 응용 프로그램을 위한 JavaScript 기반 프레임 워크
 모든 변경 사항은 연결된 모든 브라우저에서 반응적으로 반영됨

 웹 소켓과 자체 데이터 직접 프로토콜을 통해 연관된 모든 클라이언트를 자동으로 업데이트함




요약

리액티브(Reactive)라는 용어를 사용하기 전에 두 번 또는 더 자주 생각하십시오. 좋아하는 웹 사이트가 제시하는 것만큼 명확하지 않습니다.
다양하고 유효한 해석이 존재합니다. 누군가가 데이터 바인딩, 관찰 가능, 응답 또는 이벤트 처리를 의미하든 모두는 어떤 방식으로든 어떤 방식으로든 반응할 수 있습니다.

이벤트가 함께 하길!



Leave a Comment

아래 글은 LightBend의 "Reactive Programming versus Reactive Systems"를 번역한 글입니다.




리액티브 프로그래밍 대 리액티브 시스템
Reactive Programming vs Reactive Systems


끊임없는 혼란과 과부하가 걸린 바다에서 단순한 반응 설계 원리 세트에 착수

Jonas Boner와 Viktor Klang, Lightbend Inc.


요약

2013년에 Reactive Manifesto를 공동 저작 한 이후, Reactive는 선택한 일부 기업 내에서 단지 프린지 프로젝트에서만 사용되는 애플리케이션 구축을위한 사실상 확인되지 않은 기술이 되었습니다. - 미들웨어 분야의 수많은 대기업에서 전반적인 플랫폼 전략의 일부가되었습니다.
 
이 글의 목표는 Reactive Programming 스타일에서 코드를 작성하는 것과 Reactive Systems의 디자인을 응집력있는 전체로서 디자인하는 것의 차이를 살펴봄으로써 "Reactive"의 다양한 측면을 정의하고 명확히하는 것입니다.


주요 골자 (TL; DR)

  • 2015년, 특히 ​​2016 년 이후로 상업용 미들웨어 공급 업체와 사용자 모두에서 Reactive에 대한 관심이 크게 증가했습니다.
  • 리액티브 프로그래밍은 구현 수준에서 리액티브 시스템의 뚜렷한 하위 집합입니다.
  • Reactive Programming은 내부 논리 및 데이터 흐름 관리를위한 구성 요소 수준에서 성능 및 자원 효율성을 통해 개발자에게 생산성을 제공합니다.
  • Reactive Systems는 "Cloud Native"1 또는 기타 대규모 분산 시스템 구축을 위해 시스템 수준에서 복원력과 탄력성을 통해 Architects 및 DevOps의 생산성을 제공합니다.
  • 리액티브 시스템 구성 요소 내에서 리액티브 프로그래밍을 사용하는 것이 매우 유용합니다.
  • 리액티브 프로그래밍을 사용하여 작성된 컴포넌트로 만들어진 리액티브 시스템을 사용하는 것이 매우 유용합니다.

리액티브(Reactive) - 일련의 설계 원칙

성공의 최근 지표 중 하나는 리액티브가 과부하 된 용어가 되어 현재 "스트리밍(streaming)", "경량의(lightweight)" 및 "실시간(real-time)"과 같은 단어를 사용하는 좋은 회사에서 여러 사람들과 여러 가지 다른 것들과 연관되어 있다는 것입니다.

이 글의 관점에서 보면 "리액티브(Reactive)"는 응집력있는 시스템을 만들기위한 일련의 설계 원칙입니다. 구현 테크닉, 툴링 및 디자인 패턴이 더 큰 전체 구성 요소인 분산 환경에서 시스템 아키텍처 및 디자인에 대해 생각하는 방법입니다.

다음과 같은 비유를 생각해보십시오 :
운동 팀 (예 : 축구, 농구 등)은 특별한 개인으로 구성되는 경우가 많습니다. 그럼에도 불구하고 "열등한" 팀에 패배하는 것은 팀이한데 모여 무언가를 클릭하지 않을 때 흔히 볼 수 있습니다. 이처럼 시너지 효과가 부족하여 효과적으로 팀을 운영 할 수 없습니다.

이 유추는 개개인이 생각 나지 않고 자갈로 엮은 일련의 개별 리액티브 서비스 (Reactive Service)의 차이점을 보여줍니다.

리액티브 시스템에서 모든 차이를 만드는 것은 개별 부품 간의 상호 작용입니다. 이는 개별적으로 작동하면서 동시에 의도한 결과를 얻기 위해 함께 행동하는 기능입니다.

리액티브 시스템은 이러한 여러 개별 서비스를 하나의 단위로 통합하고 서로를 인식하면서 주변 환경에 대응할 수있는 아키텍처 스타일을 기반으로합니다.이 방식은 서로 대칭적으로 확장 / 축소,로드 균형 조정, 이러한 단계 중 일부는 사전에 수행합니다.

따라서 리액티브 스타일 (즉 리액티브 프로그래밍 사용)에서 단일 애플리케이션을 작성할 수 있음을 알 수 있습니다. 그러나 그것은 퍼즐의 한 부분 일뿐입니다. 위의 각 측면은 "리액티브"으로 간주되는 것처럼 보일 수 있지만 시스템 자체를 리액티브적으로 만들지는 않습니다.

사람들이 소프트웨어 개발 및 디자인의 맥락에서 리액티브에 대해 이야기 할 때 일반적으로 다음 세 가지 중 하나를 의미합니다.

  • 리액티브 시스템 (아키텍처 및 디자인)
  • 리액티브 프로그래밍 (선언적 이벤트 기반)
  • Functional Reactive Programming (FRP)

처음 두 가지를 강조하면서 이러한 관행과 기법이 의미하는 바를 살펴 보겠습니다. 보다 구체적으로 말하자면, 멀티 코어, 클라우드 및 모바일 아키텍처를위한 시스템 구축의 맥락에서, 언제 사용하는지, 어떻게 서로 관련되는지, 그리고 각각의 이점을 기대할 수 있는지에 대해 논의 할 것입니다.

2013년 Akka 기반 시스템의 생성, 유지 및 운영에 대한 오랜 경험을 쌓은 후 동시성 및 배포 문제를 해결하는 전통적인 접근 방식에 비해 엄청난 이점을 보았던 경험과 교훈을 형식화하는 아이디어는 리액티브 선언서(Reactive manifesto)의 우산 아래에서 촉발되었습니다 

현대 시스템의 핵심은 응답성(Responsiveness)입니다. 클라이언트 / 고객이 적시에 가치를 얻지 못하면 다른 곳으로 갈 것이라는 점을 인정합니다. 근본적으로 가치를 얻지 못하고 가치가 없을 때 차이가 없다.

응답성(Responsiveness)을 높이기 위해서는 두 가지가 필요합니다. :

  • 탄력성 (Resilience) : 실패 상태에서 반응성
  • 유연성 (Elasticity) : 부하 상태에서 반응성

Reactive Manifesto는 이를 달성하기 위해 시스템이 Message-Driven이어야한다고 규정합니다.

Reactive Manifesto의 네 가지 교리.


2016년 JVM 분야의 주요 벤더 중 일부는 리액티브 프로그래밍 (Reactive Programming)을 수용하기위한 핵심 계획(initiative)을 발표했습니다. 이는 오늘날 기업이 직면 한 문제를 엄청나게 검증 한 것입니다.

전통적인 프로그래밍 기법에서 이러한 변화를 시도하는 것은 크고 도전적인 작업입니다. 기존 기술과의 호환성을 유지하고 사용자 기반을 다른 사고 방식으로 유도하는 동시에 내부 개발자 및 운영 경험을 구축해야합니다. 따라서 이들 회사의 투자는 결코 쉬운 일이 아니며 이것이 엔지니어링에 대한 큰 도전이라고 언급 할 필요가 없습니다.

리액티브 프로그래밍 공간에는 많은 활동이 있는 것처럼 보이지만 시스템 아키텍처 레벨에서는 아키텍처 및 운영 경험을 구축하는 데 시간이 걸릴 것입니다. 이는 다른 프로그래밍 패러다임을 채택하여 자동으로 해결되지는 않습니다. 리액티브 시스템을 구축 할 필요가있는 리액티브 선언(Reactive Manifesto)의 배경이되면서 앞으로 무엇이 부상 할 것인지를 보는 것이 흥미로울 것입니다.

함수형 리액티브 프로그래밍 (Functional Reactive Programming)에 대해 이야기하고, 왜 이 글에서 더 이상 논의하지 않기로 결정했는지 알아 보겠습니다.


Functional Reactive Programming (FRP)

Functional Reactive Programming (일반적으로 "FRP"라고 함)은 자주 오해됩니다. FRP는 20 년 전에 Conal Elliott에 의해 매우 정확하게 정의되었습니다. 이 용어는 가장 최근에 Elm, Bacon.js, Reactive Extensions (RxJava, Rx.NET, RxJS)와 같은 기술을 설명하기 위해 부정확하게 사용되었습니다.[2] FRP를 지원한다고 주장하는 대부분의 라이브러리는 거의 독점적으로 리액티브 프로그래밍에 대해 이야기하고 있으므로 더 이상 논의하지 않을 것입니다.


리액티브 프로그래밍

리액티브 프로그래밍은 함수형 리액티브 프로그래밍(Functional Reactive Programming)과 혼동하지 않고 비동기 프로그래밍의 하위 집합이며 새로운 정보의 가용성이 실행 흐름에 의해 제어 흐름을 제어하는 ​​대신 논리 전달을 주도하는 패러다임입니다.

문제를 여러 개별 단계로 분해하여 비동기 및 논블로킹(non-blocking) 방식으로 각각 실행하고 워크 플로우를 생성하도록 구성 할 수 있습니다. 입력 또는 출력에 제한이 없습니다. 비동기는 Oxford Dictionary에 의해 "존재하지 않거나 동시에 발생 함"으로 정의됩니다.이 문맥에서 메시지 또는 이벤트 처리는 임의의 시간에, 아마도 미래에 일어날 수 있음을 의미합니다.

이것은 논블로킹 실행 (non-blocking execution)을 허용하기 때문에 리액티브 프로그래밍 (Reactive Programming)에서 매우 중요한 기술입니다. 공유 리소스에 대해 경쟁하는 실행 스레드가 차단 (현재 작업이 완료 될 때까지 실행 스레드가 다른 작업을 수행하는 것을 방지 할 필요는 없습니다. ), 자원이 가득 차있는 동안 다른 유용한 작업을 수행 할 수 있습니다. 암달의 법칙(Amdahl 's Law[3])은 얘기합니다. 논쟁이 확장성의 가장 큰 적임을, 따라서 리액티브 프로그램은 거의 블로킹(blocking)하지 않아야 합니다.


동기식, 통신 차단 (왼쪽)은 자원이 비효율적이며 병목 현상이 발생하기 쉽습니다.
리액티브 접근법 (오른쪽)은 위험을 줄이고 귀중한 자원을 보존하며 하드웨어 / 인프라를 덜 필요로합니다.



리액티브 프로그래밍은 일반적으로 메시지 기반의 리액티브 시스템과는 달리 이벤트 주도형입니다. 이벤트 주도형과 메시지 구동 형의 차이점은 다음 섹션에서 명확히 설명됩니다.

리액티브 프로그래밍 라이브러리용 API (Application Program Interface)는 일반적으로 다음 중 하나입니다.

  • 콜백 기반 - 익명의 부작용 콜백이 이벤트 소스에 첨부되며 이벤트가 데이터 흐름 체인을 통과 할 때 호출됩니다.
  • 일반적으로 맵, 필터, 폴드 (fold) 등과 같이 잘 확립 된 연결자를 사용하는 선언적 스루 기능 구성

대부분의 라이브러리는이 두 스타일을 혼합하여 제공합니다. 종종 윈도우 잉, 카운트, 트리거 등과 같은 스트림 기반 연산자가 추가되었습니다.
리액티브 프로그래밍은 데이터 흐름 프로그래밍과 관련이 있다고 주장하는 것이 타당합니다. 컨트롤 흐름보다는 데이터 흐름에 중점을 둡니다.
이 프로그래밍 기법을 지원하는 프로그래밍 추상화의 예는 다음과 같습니다.

  • Futures / Promises- 값의 비동기 변환을 아직 사용할 수없는 경우에도 추가 할 수있는 단일 값, 많은 읽기 / 단일 쓰기 의미의 컨테이너.
  • 리액티브 스트림에서와 마찬가지로 스트림 - 무한대의 데이터 처리 흐름으로 다수의 출처와 목적지 간 비동기식 비 차단 백압 변환 파이프 라인을 가능하게합니다.
  • 데이터 흐름 변수 - 입력, 절차 및 기타 셀에 의존 할 수있는 단일 할당 변수 (메모리 셀). 따라서 변경 사항이 자동으로 업데이트됩니다. 실용적인 예는 스프레드 시트입니다. 셀에서 값의 변화가 모든 종속 함수를 통해 파급되어 새로운 값 "다운 스트림"을 생성합니다.

JVM에서 Reactive Programming 기술을 지원하는 인기있는 라이브러리로는 Akka Streams, Ratpack, Reactor, RxJava 및 Vert.x가 있습니다. 이러한 라이브러리는 JVM의 리 액티브 프로그래밍 라이브러리 간의 상호 운용성을 위한 표준인 리액티브 스트림 스펙(Reactive Streams specification, 논블로킹 백프레셔로 비동기 스트림 처리 표준을 제공하기위한 계획)을 구현합니다.


리액티브 프로그래밍의 이점 (그리고 한계)

리액티브 프로그래밍의 주요 이점은 다음과 같습니다. 멀티 코어 및 멀티 CPU 하드웨어에서 컴퓨팅 리소스 사용 증가. 암달의 법칙(Amdahl's law)과 확장성(extension), Günther의 USL(Universal Scalability Law)에 따라 직렬화 지점을 줄임으로써 성능을 향상 시켰습니다.

2차 이익은 전통적인 프로그래밍 패러다임이 모두 비동기 및 비 차단 컴퓨팅 및 IO를 처리하기 위해 직접적이고 유지 보수 가능한 접근법을 제공하기 위해 애쓰고 있기 때문에 개발자 생산성 중 하나입니다. 리 액티브 프로그래밍은 일반적으로 활성 구성 요소 간의 명시적 조정의 필요성을 제거하므로 대부분의 문제를 해결합니다.

Reactive Programming이 빛나는 곳은 구성 요소를 만들고 워크 플로를 구성하는 것입니다. 비동기 실행을 최대한 활용하려면 과도한 사용 또는 자원의 무한한 소비를 피하기 위해 백 프레셔(back-pressure)을 포함하는 것이 중요합니다.


데이터 흐름 측면에서 안정적인 상태를 유지하기 위해 끌어 오기 기반 백 프레셔(back-pressure)는 업스트림으로 이동하고 다운 스트림으로 메시지를 수신하므로 생산자가 소비자를 압도하지 않습니다. 이미지 Kevin Webber (@ kvnwbbr).


그러나 Reactive Programming은 최신 소프트웨어를 구축 할 때 매우 유용하지만, 시스템을 더 높은 수준으로 판단하기 위해서는 Reactive Systems를 설계하는 프로세스인 Reactive Architecture를 사용해야합니다. 또한, 많은 프로그래밍 패러다임과 Reactive Programming이 있다는 것을 기억하는 것이 중요합니다. 그 중 하나는 툴과 마찬가지로 모든 유스케이스를 위한 것이 아닙니다.


이벤트 중심 VS 메시지 기반

이전에 언급했듯이, 일시적인 데이터 흐름 체인을 통한 계산에 중점을 둔 리액티브 프로그래밍은 이벤트 주도형인 반면, 리액티브 시스템(분산 시스템의 통신 및 조정을 통한 탄력성과 유연성에 중점을 둠)은 메시지 기반입니다.

오랫동안 지속되는 주소 지정 가능 구성 요소가 있는 메시지 기반 시스템과 이벤트 중심 데이터 흐름 기반 모델의 주요 차이점은 메시지는 본질적으로 전달되고 이벤트는 그렇지 않다는 것입니다. 메시지에는 깨끗한 단일 대상이 있습니다. 이벤트는 다른 사람들이 관찰하는 사실입니다. 또한, 메시징은 송신자와 수신자가 각각 분리 된 송신 및 수신과 함께 비동기인 것이 바람직하다.


이벤트 중심의 커뮤니케이션은 "비누 상자"방식을 사용하지만 다른 사람들이 관찰하는 사실 (이벤트)을 듣는 경우 메시지 중심의 커뮤니케이션은 수신자와 단일 목적을 가지고 있습니다.


리액티브 선언(Reactive Manifesto)의 용어집은 개념상의 차이점을 다음과 같이 정의합니다.

메시지는 특정 대상으로 보내지는 데이터 항목입니다. 이벤트는 주어진 상태에 도달했을 때 구성 요소가 내 보낸 신호입니다. 메시지 기반 시스템에서 주소 지정 가능한 수신자는 메시지 도착을 기다리고 메시지에 응답합니다. 그렇지 않으면 휴면합니다. 이벤트 중심 시스템 알림에서 리스너는 이벤트 소스가 첨부되어 이벤트가 발생할 때 호출됩니다. 즉, 이벤트 중심 시스템은 주소 지정이 가능한 이벤트 소스에 초점을 맞추고 메시지 중심 시스템은 주소 지정이 가능한 수신자에 집중합니다.

메시지는 네트워크를 통해 통신하는 데 필요하며 분산 시스템에서 통신을위한 기반을 형성하는 반면, 이벤트는 로컬에서 생성됩니다. 일반적으로 메시지 내부에서 이벤트를 보내서 네트워크를 통해 이벤트 중심 시스템을 연결하기 위해 메시징을 사용합니다. 이를 통해 분산 환경에서 Event-driven 프로그래밍 모델의 상대적 단순성을 유지할 수 있으며, 전문화되고 잘 정의 된 유스 케이스 (예 : AWS Lambda, Spark Streaming, Flink, Kafka 및 Akka Streams와 같은 분산 스트림 처리 제품 Gearpump 및 Kafka 및 Kinesis와 같은 Distributed Publish Subscribe 제품)가 있습니다.

그러나, 프로그래밍 모델의 추상화와 단순화에서 무엇이 이득을 얻는 지, 통제면에서 손실되는 것이 트레이드 오프입니다.

메시징은 부분적 실패, 실패 감지, 삭제 / 중복 / 재정렬 된 메시지, 궁극적 인 일관성, 여러 동시 현실의 관리 등과 같은 분산 시스템의 현실과 제약을 포용하도록 강요합니다. 과거에 너무 많은 시간 (예 : EJB, RPC, CORBA 및 XA)이 수행 된 것처럼 네트워크가 존재하지 않는 것처럼 보이는 새는 추상화.

이러한 의미 및 적용 가능성의 차이는 복원성, 탄력성, 이동성, 위치 투명성 및 분산 시스템의 복잡성 관리와 같은 응용 프로그램 설계에 중대한 영향을 미칩니다. 자세한 내용은이 백서에서 설명합니다.

리액티브 시스템, 특히 리액티브 프로그래밍을 사용하는 리액티브 시스템에서 이벤트와 메시지는 모두 커뮤니케이션 (메시지)을 위한 훌륭한 도구이고 사실 (이벤트)을 표현하는 훌륭한 방법이기 때문에 존재합니다.


리액티브 시스템 및 아키텍처

리액티브 시스템(Reactive System)은 리액티브 선언(Reactive Manifesto)에서 정의한대로 현대적인 시스템을 구축하기위한 아키텍처 설계 원칙으로, 오늘날 애플리케이션이 직면하는 증가하는 요구 사항을 충족 할 수 있도록 잘 준비되어 있습니다.

리액티브 시스템의 원칙은 전혀 새로운 것이 아니며, 70년대와 80년대까지 거슬러 올라갈 수 있습니다. Jim Grey와 Pat Helland는 Tandem System, Joe Armstrong과 Robert Virding의 Erlang입니다. 그러나 이 사람들은 시간을 앞섰고 기술 산업계는 기업 시스템 개발을위한 현재 "모범 사례"를 다시 생각해야만했던 지난 5 ~ 10년 동안만 있었습니다. 이는 오늘날의 멀티 코어, 클라우드 컴퓨팅 및 사물의 세계에 대한 반응 원칙에 대한 지식을 적용하는 법을 배우는 것을 의미합니다.

리액티브(Reactive System)의 토대는 Message-Passing입니다. 구성 요소간에 시간적 경계가 생겨 구성 요소가 제 시간에 분리 될 수 있습니다. 이는 동시성(Concurrency) 및 공간(space)을 허용하여 배포(distribution) 및 이동성(mobility)을 허용합니다. 이 디커플링은 구성 요소 간의 완전한 격리에 대한 요구 사항이며 탄력성(Resilience)과 유연성(Elasticity)의 기초를 형성합니다.


프로그램에서 시스템으로

우리는 더 이상 시스템을 구축하는 것만 큼 단일 운영자를 위해 무언가를 계산하기위한 종단 간 논리 (end-to-end logic)를 구축하지 않습니다.

세계는 점점 더 상호 연결되어 가고 있습니다. 시스템은 정의에 의해 복잡합니다. 각 구성 요소는 여러 구성 요소로 구성되며 각 구성요소 자체가 시스템이 될 수 있습니다. 소프트웨어가 제대로 작동하려면 점점 다른 소프트웨어에 의존하게됩니다.

오늘날 우리가 만들어내는 시스템은 크고 작은 컴퓨터, 서로 가까이 있거나 거의 반으로 떨어진 컴퓨터에서 작동해야합니다. 동시에 일상 생활이 원활하게 기능할 수있는 시스템의 가용성에 점점 더 의존하고 있기 때문에 사용자의 기대는 점점 더 어려워지고 있습니다.

사용자 및 비즈니스가 의존 할 수있는 시스템을 제공하려면 응답이 필요할 때 사용할 수없는 경우 올바른 응답을 제공하는지 여부는 중요하지 않으므로 응답해야합니다. 이를 달성하기 위해 우리는 실패 (탄력성)와 동적으로 변화하는 부하 (유연성) 에서 반응성을 유지할 수 있어야합니다. 그렇게하기 위해 우리는 이러한 시스템을 메시지 기반(Message-Driven)으로 만들고 리액티브 시스템(Reactive Systems)라고 부릅니다.


리액티브 시스템의 탄력성(Resilience)

탄력성은 실패시의 대응성에 대한 것이며, 시스템의 고유 한 기능적 특성이며, 소급하여 추가 할 수있는 것이 아니라 설계해야 할 것입니다.

복원력은 내결함성을 뛰어 넘습니다.
이는 시스템의 매우 유용한 특성이지만 정상적인 성능 저하가 아니라 장애로부터 완전히 복구 할 수있는 것입니다 :자가 치유합니다.

이를 위해서는 인접한 구성 요소로 전파되는 오류를 피하기 위해 구성 요소 격리 및 오류 억제가 필요합니다. 결과적으로 대개의 경우 치명적인 계단식 오류 시나리오가 발생합니다.

복원력 있고자가 치유적인 시스템을 구축하는 열쇠는 포함되어 메시지로 구체화되고 다른 구성 요소 (감독자의 역할을 담당)로 전송되고 실패한 구성 요소 외부의 안전한 컨텍스트에서 관리되도록하는 것입니다. 여기에서 Message-Driving이 가능합니다 : 강하게 결합되고 부서지기 쉽고 깊게 중첩 된 동기식 호출 체인에서 벗어나 모두가 겪어 보거나 묵살하는 것을 배웠습니다. 이 아이디어는 호출 체인에서 실패 관리를 분리하여 클라이언트가 서버의 오류를 처리 할 책임을 없애는 것입니다.


리액티브 시스템의 유연성(Elasticity)

탄력성은 부하에서의 응답 성입니다. 즉, 시스템의 처리량이 자동으로 증가하거나 감소하여 (즉, 단일 시스템에서 코어 추가 또는 제거) 데이터 센터의 노드 / 머신 추가 또는 제거와 같이 자동으로 리소스가 비례 적으로 추가되거나 제거 될 때 다양한 요구를 충족시킵니다. 이는 클라우드 컴퓨팅의 약속을 활용하는 데 필요한 필수 요소입니다. 시스템을 자원 효율적, 비용 효율적, 환경 친화적 및 사용량 당 지불 할 수 있습니다.

시스템은 적응성이 있어야합니다. 시스템을 다시 작성하거나 심지어 재구성하지 않고도 자동 조정, 상태 및 동작 복제, 통신로드 밸런싱, 장애 조치 및 업그레이드 등의 개입이 가능합니다. 이에 대한 실현 요인은 위치 투명성입니다. CPU 코어에서 데이터 센터에 이르는 모든 규모의 규모에서 동일한 프로그래밍 추상화를 사용하여 같은 의미로 동일한 방식으로 시스템을 확장 할 수있는 기능입니다.

Reactive Manifesto는 다음과 같이 말합니다.

이 문제를 대단히 단순화하는 핵심 통찰력은 우리 모두가 분산 컴퓨팅을 수행하고 있다는 것을 깨닫는 것입니다. 이는 단일 노드 (QPI 링크를 통해 통신하는 여러 독립 CPU 포함) 또는 노드 클러스터 (네트워크를 통해 통신하는 독립 시스템)에서 시스템을 실행하든 상관 없습니다. 이 사실을 받아들이면 멀티 코어에서 수직으로 스케일링하거나 클러스터에서 수평으로 스케일링하는 것과 개념적으로 차이가 없다는 것을 의미합니다.

비동기 메시지 전달을 통해 활성화 된 공간에서의 이러한 분리 (decoupling) [...]와 런타임 인스턴스의 참조에서의 분리는 Location Transparency라고합니다.

수신자가 어디에 있든 상관없이 우리는 같은 방식으로 메시지를 교환합니다. 의미상 동등하게 수행 할 수있는 유일한 방법은 메시징을 사용하는 것입니다.


리액티브 시스템의 생산성(Productivity)

대부분의 시스템은 기본적으로 본질적으로 복잡하기 때문에 가장 중요한 측면 중 하나는 시스템 아키텍처가 구성 요소의 개발 및 유지 보수에서 최소한의 생산성 감소를 보장하면서 동시에 실수로 인한 복잡성을 줄이는 것입니다. 최저한의.

이는 시스템의 수명주기 동안 (제대로 설계되지 않은 경우) 유지 관리가 더 어려워지고 어려워지고 문제를 지역화하고 해결하기 위해 이해해야 할 시간과 노력이 계속 증가해야하기 때문에 중요합니다.

Reactive Systems는 우리가 알고있는 (멀티 코어, 클라우드 및 모바일 아키텍처의 맥락에서) 가장 생산적인 시스템 아키텍처를 나타냅니다.

  • 장애 격리는 구성 요소간에 격벽을 제공하여 계단식 연결 실패를 방지하고 장애 범위와 심각도를 제한합니다.
  • 감독자 계층 구조는 자체 복구 기능과 함께 여러 수준의 방어 체계를 제공하므로 조사 비용을 들이지 않고 일시적인 실패를 많이 제거합니다.
  • 메시지 전달 및 위치 투명성을 통해 최종 사용자 환경에 영향을주지 않고 구성 요소를 오프라인으로 전환하고 교체하거나 경로를 변경할 수 있습니다. 이를 통해 중단 비용, 상대적 긴급 성 및 진단 및 수정에 필요한 리소스를 줄일 수 있습니다.
  • 복제는 데이터 손실 위험을 줄이고 장애가 정보 검색 및 저장의 가용성에 미치는 영향을 줄입니다.
  • 탄력성은 사용량이 변동함에 따라 리소스를 절약 할 수 있으므로 부하가 적을 때 운영 비용을 최소화하고 부하가 증가 할 때 정전 또는 확장성에 대한 긴급한 투자의 위험을 최소화합니다.


타이타닉에서 제대로 수행되지는 않았지만 배수 시설 건설 업계에서는 다른 작업에 영향을주는 계단식 실패를 방지하기 위해 오랫동안 벌크 헤드가 사용되었습니다.

따라서 Reactive Systems는 시간이 지남에 따라 낮은 소유 비용을 제공하면서 장애 발생시에도 부하 및 변화의 변화에 효과적으로 대처할 수있는 생성 시스템을 지원합니다.


리액티브 프로그래밍은 리액티브 시스템과 어떤 관련이 있습니까?

리액티브 프로그래밍은 코드 명확성, 성능 및 리소스 효율성을 최적화하는 방법으로 구성 요소 내에서 로컬로 내부 논리 및 데이터 흐름 변환을 관리하는 훌륭한 기술입니다. Reactive Systems는 일련의 아키텍처 원칙으로 분산 통신에 중점을두고 분산 시스템의 탄력성과 탄력성을 해결할 수있는 도구를 제공합니다.

리액티브 프로그래밍을 활용할 때 가장 많이 발생하는 문제 중 하나는 이벤트 기반 콜백 기반 또는 선언적 프로그램에서 계산 단계 간의 긴밀한 연결로 인해 탄력성 체인이 종종 일시적이며 콜백 또는 결합자인 익명임을 나타내는 Resilience를 달성하기가 더 어려워집니다. 즉, 주소 지정이 불가능합니다.

즉, 대개 외부 세계에 알리지 않고 성공 또는 실패를 직접 처리합니다. 이러한 주소 지정 기능이 부족하면 예외를 전파해야하는 위치가 분명하지 않고 일반적으로 전파 될 수 없기 때문에 개별 단계의 복구가 어려워집니다. 결과적으로 오류는 구성 요소의 전반적인 상태가 아닌 일시적인 클라이언트 요청에 연결됩니다. 데이터 흐름 체인의 단계 중 하나에서 오류가 발생하면 전체 체인을 다시 시작해야하며 클라이언트에서이를 알립니다. 이는 클라이언트에 알리지 않고자가 치료할 수있는 메시지 기반 대응 시스템과는 대조적입니다.

리액티브 시스템 접근법과는 달리 순수 리 액티브 프로그래밍을 사용하면 시간에 따라 디커플링이 가능하지만 공간에서는 사용할 수 없습니다 (앞에서 설명한대로 Message-passing을 사용하여 데이터 흐름 그래프를 네트워크 전체에 배포하지 않는 한).

디커플링은 동시성을 가능하게하지만 공간에 디커플링을 적용하여 배포 및 이동성을 허용하므로 탄력성에 필수적인 정적 토폴로지뿐만 아니라 동적 토폴로지를 고려할 수 있습니다.

위치 투명성이 부족하여 Reactive Programming 기술을 기반으로하는 프로그램을 탄력적으로 적응 적으로 확장 할 수 없으므로 메시지 버스, 데이터 그리드 또는 맞춤형 네트워크 프로토콜과 같은 상단에 추가 도구를 레이어해야합니다. 여기서 Reactive Systems의 Message-Driven 방식은 모든 차원의 스케일에서 프로그래밍 모델과 의미를 유지하는 통신 추상화이므로 시스템 복잡성과인지 오버 헤드를 줄입니다.

콜백 기반 프로그래밍의 일반적으로 언급 된 문제는 그러한 프로그램을 작성하는 것이 비교적 쉽지만 장기적으로 실제 결과를 가져올 수 있다는 것입니다.

예를 들어, 익명 콜백을 기반으로하는 시스템은 사용자가 추론해야 할 때 통찰력을 유지하거나 유지해야하며, 무엇보다도 생산 중단 및 오작동이 발생하는 위치와 이유를 파악해야합니다.

Reactive Systems (예 : Akka 프로젝트 및 Erlang 플랫폼) 용으로 설계된 라이브러리 및 플랫폼은 오래 전부터이 교훈을 얻었으며 미래에 대해 쉽게 추론 할 수있는 수명이 긴 주소 지정 가능 구성 요소에 의존합니다. 오류가 발생하면 구성 요소는 오류의 원인이 된 메시지와 함께 고유하게 식별 할 수 있습니다. 모니터링 솔루션은 구성 요소 모델의 핵심 부분 인 주소 지정 가능성이라는 개념을 통해 전파되는 ID를 활용하여 수집 된 데이터를 제공하는 의미있는 방법을 제공합니다.

주소 지정 기능 및 오류 관리와 같은 기능을 수행하는 좋은 프로그래밍 패러다임의 선택은 실재의 가혹함을 염두에두고 설계 되었기 때문에 생산에서 매우 귀중한 것으로 입증되었습니다. 시도의 실패 원인보다는 오류를 예상하고 받아 들일 수 있습니다. 그것을 막기 위해.

전체적으로 Reactive Programming은 Reactive Architecture에서 사용할 수있는 매우 유용한 구현 기술입니다. 스토리의 한 부분만을 관리하는 데 도움이된다는 점을 기억하십시오. 비동기 및 비 차단 실행을 통한 데이터 흐름 관리 (대개 단일 노드 또는 서비스 내에서만 가능). 여러 개의 노드가 있으면 데이터 일관성, 노드 간 통신, 조정, 버전 관리, 오케스트레이션, 오류 관리, 관심과 책임 분리 등의 일에 열심히 생각해 볼 필요가 있습니다. 시스템 아키텍처.


리액티브 프로그래밍은 단일 노드 또는 서비스 간의 비동기식 비 블로킹 데이터 흐름 관리에 중점을 두지 만 복잡한 리 액티브 시스템 아키텍처는 노드 및 클러스터에 여러 서비스를 성공적으로 배포하는 데 훨씬 더 많은 것을 필요로합니다.


따라서 Reactive Programming의 가치를 극대화하려면 Reactive System을 구성하는 도구 중 하나로 사용하십시오. 리액티브 시스템을 구축하려면 OS 고유의 리소스를 추상화하고 기존의 기존 소프트웨어 스택 위에 비동기 API 및 회로 차단기를 뿌려주는 것 이상을 필요로합니다. 여러 서비스로 구성된 분산 시스템을 구축하는 중입니다. 모든 서비스는 예상대로 작동 할 때뿐만 아니라 예측할 수없는로드 상황에서도 일관적이고 반응이 빠른 경험을 제공해야합니다. .


리액티브 프로그래밍 및 시스템은 빠른 데이터 스트리밍과 어떤 관련이 있습니까?

빠른 데이터 스트리밍 (분산 스트림 처리) 6은 사용자 관점에서 일반적으로 로컬 및 스트림 기반 추상화를 사용하여 이벤트 중심으로 기능적 결합 자 및 콜백과 같은 리 액티브 프로그래밍 구조에 의존하는 최종 사용자 API를 노출합니다.

그런 다음 최종 사용자 API 아래에서 일반적으로 Message-passing 및 스트림 처리 단계의 분산 시스템, 내구성 이벤트 로그, 복제 프로토콜을 지원하는 노드 사이의 Reactive Systems의 원칙을 사용합니다. 이러한 부분은 일반적으로 개발자. 이는 사용자 수준에서 리 액티브 프로그래밍을 사용하고 시스템 수준에서 리 액티브 시스템을 사용하는 좋은 예입니다.


리액티브 프로그래밍 및 시스템은 마이크로 서비스와 어떤 관련이 있습니까?

마이크로 서비스 기반 아키텍처 - Cloud를 지정된 배포 플랫폼으로 사용하는 자율적 인 분산 서비스 시스템을 설계하는 것은 Reactive를 수용하여 제공되는 가치에서 많은 이점을 얻습니다.

지금까지 살펴본 바와 같이, 리액티브 프로그래밍과 리액티브 시스템 설계는 서로 다른 상황에서 서로 다른 이유로 중요합니다.

  • 리액티브 프로그래밍은 단일 마이크로 서비스 내에서 서비스 내부 로직 및 데이터 흐름 관리를 구현하는 데 사용됩니다.
  • 리액티브 시스템 디자인은 마이크로 서비스 사이에서 사용되며 분산 시스템의 규칙에 따라 재생되는 마이크로 서비스 시스템을 만들 수 있습니다.
    메시지 주도로 가능해진 탄력성과 탄력성을 통한 반응성.


리액티브 프로그래밍 및 시스템은 모바일 애플리케이션 및 IoT (Internet of Things)와 어떤 관련이 있습니까?

Internet of Things (IoT) - 연결된 센서, 장치 및 가전 제품의 폭발로 인해 검색, 집계, 분석 및 푸시 아웃해야하는 많은 양의 데이터를 생성하는 동시에 연결된 모든 장치를 처리하는 방법에 문제가 발생합니다. 전체적인 시스템 응답을 유지하면서 모든 장치를 지원합니다. 이러한 과제에는 센서 데이터 수신, 대량 프로세스 (일괄 프로세스 또는 실시간) 처리, 실제 사용 패턴에 대한 값 비싼 시뮬레이션을 통해 트래픽 급증을 관리하는 것이 포함됩니다. 일부 IoT 배포에서는 장치에서 보낸 데이터를 소비하는 것이 아니라 장치를 관리하는 백 엔드 서비스가 필요합니다.

잠재적으로 수백만 개의 연결된 장치가 사용할 수있는 서비스를 구축 할 때 대규모의 정보 흐름에 대처할 수있는 모델이 필요합니다. 장치 고장을 처리하기위한 전략, 정보가 손실되었을 때, 서비스가 실패 할 때를 대비하여 전략이 필요합니다. 이 모든 것을 관리하는 백엔드 시스템은 수요에 맞게 확장하고 완전히 복원력이 있어야합니다. 즉, 리 액티브 시스템이 필요합니다.

많은 양의 센서가 데이터를 생성하고이 데이터가 도착하는 속도를 처리 할 수 ​​없기 때문에 IoT의 백엔드에서 흔히 볼 수있는 문제는 장치 및 센서에 역 압력을 구현할 필요가 있음을 나타냅니다. IoT 시스템의 엔드 투 엔드 데이터 흐름 (수많은 장치) : 서비스를 중단하지 않고도 데이터를 저장하고 정리하고 처리하고 분석을 실행해야하는 필요성 - 비동기식, 비 차단식 역 압력의 흐름이 중요 해지면 리 액티브 프로그래밍 (Reactive Programming)이 실제로 빛을 발합니다.


리액티브 프로그래밍 및 시스템은 전통적인 웹 응용 프로그램과 어떤 관련이 있습니까?

웹 응용 프로그램은 Reactive Programming 스타일 개발의 이점을 크게 누릴 수 있으므로 서비스 호출을 분기하고 비동기 적으로 리소스를 가져 오며 응답을 작성한 후 클라이언트에 마샬링하는 등 요청 / 응답 워크 플로를 구성 할 수 있습니다. 가장 최근에는 Server-Sent 이벤트와 WebSocket이 점점 더 많이 사용되어 왔으며이를 대규모로 수행하면 열려있는 많은 연결을 유지하는 효율적인 방법이 필요합니다. IO가 차단되지 않는 경우 Reactive Programming은 이에 대한 도구를보다 구체적으로 제공합니다 Streams and Futures를 사용하면 비 차단 및 비동기 변환을 수행하고이를 클라이언트에 전달할 수 있습니다. 리 액티브 프로그래밍은 데이터 액세스 계층에서 중요한 역할을합니다. 비효율적 인 드라이버가있는 SQL 또는 NoSQL 데이터베이스를 사용하는 것이 리소스 효율적인 방식으로 데이터를 업데이트하고 쿼리합니다.

또한 웹 애플리케이션은 리액티브 시스템 디자인의 이점을 활용하여 분산 캐싱, 데이터 일관성 및 노드 간 알림을 제공합니다. 전통적인 웹 응용 프로그램은 일반적으로 상태 비 저장 노드를 사용합니다. 그러나 SSE (Server-Sent-Events) 및 웹 소켓을 사용하자 마자 노드는 클라이언트 연결 상태를 유지하고 있으므로 푸시 알림을 그에 따라 라우팅해야하므로 상태가 유지됩니다. 이렇게하려면 효과적으로 반응 형 시스템 디자인이 필요합니다. 메시징을 통해받는 사람을 직접 주소 지정하는 것이 중요한 영역이기 때문입니다.


요약

기업 및 미들웨어 업체는 모두 리액티브를 채택하기 시작했으며 2016 년에는 Reactive 채택에 대한 기업의 관심이 크게 증가했습니다. 이 글에서는 리액티브 시스템을 중요요한 툴 중 하나 인 Reactive Programming과 함께 기업용 멀티 코어, 클라우드 및 모바일 아키텍처의 컨텍스트를 가정하는 최종 목표로 설명했습니다.

Reactive Systems는 내부 논리 및 데이터 흐름 변환을위한 구성 요소 수준에서 성능 및 자원 효율성을 통해 개발자를 위한 생산성을 제공하며 Reactive Systems는 "Cloud Native"를 구축하고 시스템 수준에서 복원력과 탄력성을 통해 Architects 및 DevOps에 생산성을 제공합니다. 다른 대규모 분산 시스템. Reactive Programming의 기술을 Reactive Systems의 설계 원칙에 결합하는 것이 좋습니다.






1 일반적으로 파일 시스템과 같은 기본 OS 기능에 의존하지 않는 대신 일반적으로 구성 가능한 끝점을 사용하여 클라우드와 같은 가상화 된 환경에서 실행할 수 있도록 해주는 응용 프로그램을 가리키는 다소 정의되지 않은 용어입니다.

2 이 프레젠테이션에서 FRP의 발명가 인 Conal Elliott에 따르면.

3 Amdahl의 법칙에 따르면 시스템의 이론적 인 속도 향상은 일련의 부품에 의해 제한되므로 새로운 자원이 추가 될 때 시스템의 수익이 줄어들 수 있습니다.

4 Neil Günter의 범용 확장 성법은 동시 및 분산 시스템에서 경합 및 조정의 효과를 이해하는 데 필수적인 도구이며 새로운 자원이 시스템에 추가 될 때 시스템의 일관성 비용이 부정적인 결과를 초래할 수 있음을 보여줍니다.

5 메시징은 동기식 (발신자와 수신자가 동시에 사용 가능해야 함) 또는 비동기식 (시간 내에 분리 될 수 있음) 중 하나 일 수 있습니다. 의미 론적 차이에 대해 논의하는 것이이 백서의 범위를 벗어납니다.

6 예를 들어 Spark Streaming, Flink, Kafka Streams, Beam 또는 Gearpump를 사용합니다.

7 autonomous라는 단어는 자동을 뜻하는 auto라는 단어에서 비롯된 것이며 law는 법을 의미합니다. 나. 자신의 법에 따라 사는 요원 : 자치와 독립.



Original text

[1] Reactive Programming versus Reactive Systems, LightBend


Leave a Comment

Original text

[1] reactive-streams.org (http://www.reactive-streams.org/)

[2] reactive stream wiki (https://en.wikipedia.org/wiki/Reactive_Streams)


이 글은 위 원본 글을 번역한 글입니다. 오역이 있을 수 있습니다.


리액티브 스트림(Reactive Streams)

리 액티브 스트림은 논블로킹(non blocking) 역압(back pressure)으로 비동기 스트림 처리 표준을 제공하기위한 계획입니다. 여기에는 런타임 환경 (JVM 및 JavaScript)과 네트워크 프로토콜을 위한 노력이 포함됩니다.


문제

데이터의 스트림, 특히 볼륨이 미리 결정되지 않은 "라이브"데이터를 처리하려면 비동기 시스템에서 특별한주의가 필요합니다. 가장 중요한 문제는 빠른 데이터 소스가 스트림 대상을 압도하지 않도록 리소스 소비를 제어해야한다는 것입니다. 비동기성은 컴퓨팅 리소스를 병렬로 사용하거나 네트워크 호스트를 공동 작업하거나 단일 시스템 내의 여러 CPU 코어를 사용할 수 있도록하기 위해 필요합니다.


리액티브 스트림의 주요 목표는 수신 측에서 임의의 양의 데이터를 강제로 버퍼링하지 않도록하면서 비동기 경계를 통과하는 스트림 데이터를 다른 스레드 또는 스레드 풀로 전달하는 것을 제어하는 ​​것입니다. 다시 말해서, 배압은 스레드 사이를 중재하는 큐를 제한 할 수 있도록하기 위해이 모델의 필수적인 부분입니다. 비동기 처리의 이점은 역 압력 통신이 동기 적이면 무효화됩니다 (Reactive Manifesto 참조). 따라서 Reactive Streams 구현의 모든 측면에 대해 비 차단 및 비동기 동작을 수행하도록주의를 기울여야합니다.


규칙을 준수함으로써 스트림 응용 프로그램의 전체 처리 그래프에서 앞서 언급 한 이점 및 특성을 유지하면서 원활하게 상호 운용 할 수있는 많은 구현을 만들 수 있는 것이 사양의 의도입니다.



범위

리액티브 스트림의 범위는 목표를 달성하기 위해 필요한 작업과 엔티티를 설명하는 인터페이스, 메소드 및 프로토콜의 최소 집합을 찾는 것입니다. 논블로킹 백압으로 데이터의 비동기 스트림을 달성합니다.


최종 사용자 DSL 또는 프로토콜 바인딩 API는 잠재적으로 다른 프로그래밍 언어를 사용하여 플랫폼의 관용구에 가능한 한 사실을 유지할 수있는 여러 가지 구현을 장려하고 활성화 할 수 있도록 의도적으로 그 범위를 벗어났습니다.


이 Reactive Streams 사양 및 구현 경험을 수용하면 향후 JDK 릴리스에서의 Java 플랫폼 지원 또는 향후 웹 브라우저에서의 네트워크 프로토콜 지원을 비롯하여 광범위한 통합이 이루어질 것으로 예상됩니다.


워킹 그룹

기본 의미론

기본 의미론은 역류를 통해 흐름 요소의 전달이 조절되는 방법을 정의합니다. 요소가 전송되는 방법, 전송 중 표시 또는 역 압력이 신호되는 방식은이 사양의 일부가 아닙니다.


JVM 인터페이스(완료)

이 워킹 그룹은 공유 메모리 힙을 사용하여 JVM 내의 객체와 스레드간에 스트림을 전달하기 위해 서로 다른 구현 및 언어 바인딩의 상호 운용을 허용하는 것을 주된 목적으로하는 프로그래밍 인터페이스 세트에 기본 의미를 적용합니다.


2015 년 4 월 30 일부터 자바 API, 텍스트 사양, TCK 및 구현 예를 비롯하여 JVM 용 리 액티브 스트림 1.0.0 버전을 출시했습니다. Maven Central에서 해당 코드 아티팩트를 사용할 수 있습니다.


<dependency>
  <groupId>org.reactivestreams</groupId>
  <artifactId>reactive-streams</artifactId>
  <version>1.0.0</version>
</dependency>
<dependency>
  <groupId>org.reactivestreams</groupId>
  <artifactId>reactive-streams-tck</artifactId>
  <version>1.0.0</version>
</dependency>


이 소스 코드는 github에서 사용할 수 있습니다. 피드백을 제공하기 위해 github 문제를 사용하십시오.

모든 아티팩트 및 사양은 Creative Commons Zero에서 공개 도메인으로 공개됩니다.

JVM 용 Reactive Streams 1.0.0에 대한 자세한 내용은 여기를 참조하십시오.


구현 자에 대한 참고 사항

최종 사양을 구현하려면 README 및 Java API 설명서를 읽은 다음 사양을 살펴보고 TCK 및 예제 구현을 살펴 보는 것이 좋습니다. 위의 문제가있는 경우 닫힌 문제를 살펴본 다음 아직 해결되지 않은 경우 새로운 문제를여십시오.


이 작업은 reactive-streams-jvm 저장소에서 수행되었습니다.


JavaScript 인터페이스

이 작업 그룹은 JavaScript 런타임 환경에서 요소 스트림을 관 {하기위한 최소한의 오브젝트 특성 세트를 정의합니다. 목표는 여러 구현이 동일한 런타임 환경 내에서 상호 운용되도록하는 테스트 가능한 스펙을 제공하는 것입니다.


이 작업은 reactive-streams-js 저장소에서 수행됩니다.


네트워크 프로토콜

이 워킹 그룹은 데이터 요소의 직렬화 및 비 직렬화와 관련된 다양한 전송 매체를 통해 반응 스트림을 전달하기위한 네트워크 프로토콜을 정의합니다. 이러한 전송의 예로는 TCP, UDP, HTTP 및 WebSockets가 있습니다.


이 작업은 reactive-streams-io 저장소에서 수행됩니다.



리액티브 스트림 위키 정의

리액티브 스트림은 논블로킹(non blocking) 역압(back pressure)으로 비동기 스트림 처리 표준을 제공하기위한 계획입니다.[1]


리액티브 스트림의 주요 목표는 수신 측에서 임의의 양의 데이터를 강제로 버퍼링하지 않도록하면서 비동기 경계에서 스트림 데이터를 다른 스레드 또는 스레드 풀로 전달하는 것과 같은 스트림 데이터 교환을 제어하는 ​​것입니다. 다시 말해서, 배압은 스레드 사이를 중재하는 큐를 제한 할 수 있도록하기 위해이 모델의 필수적인 부분입니다.


명세의 의도는 많은 준수 구현의 생성을 허용하는 것으로, 규칙을 준수함으로써 스트림 애플리케이션의 전체 처리 그래프에서 언급 된 이점 및 특성을 유지하면서 원활하게 상호 운용 될 수 있습니다.


리액티브 스트림의 범위는 비 차단 백압으로 데이터의 비동기 스트림을 달성하는 데 필요한 작업과 엔티티를 설명하는 인터페이스, 메소드 및 프로토콜의 최소 세트입니다. 최종 사용자 DSL 또는 프로토콜 바인딩 API는 잠재적으로 다른 프로그래밍 언어를 사용하여 플랫폼의 관용구에 가능한 한 사실을 유지할 수있는 여러 가지 구현을 장려하고 활성화 할 수 있도록 의도적으로 그 범위를 벗어났습니다.


리액티브 스트림은 Netflix, Pivotal 및 Typesafe의 엔지니어들 사이에서 2013 년 말에 시작되었습니다. 가장 초기의 토론 중 일부는 Typesafe의 Play 팀과 Akka 팀간에 2013 년에 시작되었습니다. [2] [3] Typesafe는 리 액티브 스트림의 주된 기여자 중 하나입니다. [4] 다른 참여자로는 Red Hat, Oracle, Twitter 및 spray.io가 있습니다. [5] Reactive Streams의 Java 구현을 Java 9의 일부로 만드는 작업이 진행 중입니다. JSR 166의 리더 인 Doug Lea는 Reactive Streams에서 현재 제공하는 인터페이스를 포함하는 새로운 Flow 클래스 [7]를 제안했습니다. [4] ] [8]


JVM을위한 Reactive Streams의 버전 1.0.0은 2015 년 4 월 30 일 Java API, 텍스트 사양, TCK 및 구현 예제를 포함하여 발표되었습니다 [4] [5] [9]. 알파벳 순서로 나열된, 1.0.0 용 TCK에 의해 검증 된 다수의 호환 구현이 제공됩니다 : [9]


  • Akka stream [12] [13]
  • MongoDB [14]
  • Ratpack [15]
  • Reactive Rabbit — driver for RabbitMQ/AMQP
  • Spring and Pivotal Project Reactor[16]
  • Netflix RxJava [17]
  • Slick 3.0. [18] [19]
  • Vert.x 3.0 [20]
  • Cassandra [21]
  • Elasticsearch [22]
  • Apache Kafka [23]
  • Parallel Universe Quasar [24]
  • Play Framework


Spring 5는 Reactive Stream과 호환되는 Reactor Core를 기반으로 제작되었다고 발표되었습니다.



Reference

[1] reactive-streams.org (http://www.reactive-streams.org/)

[2] A Journey into Reactive Streams

[3] Reactive Streams 1.0.0 interview

[4] Reactive Streams Releases First Stable Version for JVM

[5] Reactive Streams 1.0.0 – a new standard in reactive data processing

[6] jdk9 Candidate classes Flow and SubmissionPublisher

[7] java.util.concurrent.Flow

[8] JEP 266: More Concurrency Updates

[9] a b Reactive Streams 1.0.0 is here!

[10] Java API

[11] Reactive Streams for the JVM specification

[12] InfoQ: Reactive Streams with Akka Streams

[13] Design Principles behind Akka Streams

[14] MongoDB Reactive Streams Java Driver

[15] Ratpack: The Reactive Streams API

[16] Reactor 2.0.0.RC1 with native Reactive Streams support now available!

[17] Advanced RxJava: The Reactive-Streams API (part 1)

[18] Slick 3: Reactive Streams for Asynchronous Database Access in Scala

[19] Slick 3.0.0

[20] Vert.x Reactive Streams Integration

[21] Accessing Cassandra in a Reactive Way

[22] elastic4s — Non blocking, type safe DSL and Scala client for Elasticsearch

[23] Reactive Streams for Apache Kafka

[24] Quasar and Reactive Streams

[25] Play Framework — Reactive Streams integration (experimental)

[26] Reactive Spring

[27] reactive stream wiki (https://en.wikipedia.org/wiki/Reactive_Streams)

Leave a Comment

스트림이란 용어가 리액티브와 같이 참 많은 곳에서 사용이 된다.

데이터 스트림이란 용어도, 스트림이란 용어도 있는데 간략하게 알아보자.


데이터 스트림(Data stream)

일단 데이터 스트림이란 무엇일까?

다음과 같이 정의할 수 있다.

  • 데이터가 열을 지어 흐르는 것처럼 입력되는 것
  • 정해진 포맷을 사용하여 문자 또는 바이트 형식으로 송수신되는 데이터 항목의 연속적인 흐름
  • 데이터의 양이 한정되어 있지 않고 지속적으로 생성되고, 시간에 따라 값이 변하는 데이터의 흐름
  • 연속적으로 흘러들어오는 데이터 (예 :  바이트 배열)
  • 예) 주식 가격, 사용자 클릭, IoT, 게임 데이터, 사용자 행동 정보, 채팅 


실시간 처리(Real-time processing)

  • 대량의 데이터를 빠르게 처리하기 위한 데이터 처리의 목표 또는 제약 사항
  • 실시간은 마감시각(deadline)이 있고, 마감시각 내에 주어진 연산을 완료하지 못하면 실패로 처리
  • 마감시각을 놓쳤을 때의 처리 결과에 따라 Hard/Firm/Soft real-time으로 구분
  • 실시간 처리는 목표로 하는 시간 제약이 주어지고 그에 따른 실패 수준이 정해짐


스트림 처리(Stream processing)

  • 대량의 데이터를 빠르게 처리하기 위한 데이터 처리 방식
  • 범위가 한정되지 않고(unbounded) 끊임 없이 흘러가는(stream) 데이터에 대한 처리 방식
  • 잘 설계된 스트림 처리는 배치 처리를 포함한다고 할 수 있음
  • 스트림 처리가 끊임없이 흘러가는 데이터를 처리하다 보니 데이터 처리 결과를 빠르게 받아볼 수 있고 실시간 처리라고 불릴 수 있음


마이크로 배치(micro-batch)

  • 작은 배치 처리를 무한히 하는 방식
  • 스트림 처리에 포함됨


배치 처리(batch processing)

  • 한정된(bounded) 데이터의 처리를 배치 처리(batch processing)
  • unbounded 스트림 처리의 반대


Reference

[1] Spark streaming으로 실시간 처리 (http://readme.skplanet.com/?p=12465)

[2] http://radar.oreilly.com/2015/08/the-world-beyond-batch-streaming-101.html 

Leave a Comment

Reactive쪽으로 파고들면 파고들수록 머리가 아프다.

다른 분의 말대로 정말 이것은 리택티브의 홍수이다.

정리하기가 쉽지 않다.



JVM 환경에서 리액티브 API


• Reactor 2.5

- 4세대이자 리액티브 스트림(Reactive Streams)을 기반으로 함


https://projectreactor.io/

https://github.com/reactor/reactor-core

https://projectreactor.io/docs/core/release/api/



• RxJava 1.x

- 2세대이자 가장 많이 사용되는 구현체

http://reactivex.io/

https://github.com/ReactiveX/RxJava



• Akka Stream 2.x

- 3세대이자 Reactive API 

- 리액티브 스트림 표준을 내부에서 구현함

- 라이트밴드(Lightbend) 회사에서 만듬

http://akka.io/



리액티브 스트림(Reactive Streams)

- 논블로킹 비동기 스트림 처리 표준

- JVM 기반, 자바스크립트와 네트워크 프로토콜을 포함함


- http://www.reactive-streams.org/





 

 No value

 Single value

 Multiple values

 Blocking

 void

 T

 Future<T>

 Iterable<T>

 Collection<T>

 Stream<T>

 Non-blocking

 CompletableFuture<Void>

 CompletableFuture<T>

 CompletableFuture<List<T>>

 Reactive Streams

 Publisher<Void>

 Publisher<T>

 Publisher<T>

 RxJava (ReactiveX)

 Observable<Void>

 Completable (1.1.1)

 Observable<T>

 Single<T> (1.0.13)

 Observable<T>

 Reactor

 Mono<Void>

 Mono<T>

 Flux<T>






Leave a Comment

Java 9 REPL (JShell)

오라클은 쉘과 REPL(Read Evaluate Print Loop)을 위한 새로운 툴인 "JShell"을 소개한다.

이것은 자바 클래스, 인터페이스, 객체 등의 생성을 매우 쉽게 실행하고 테스트하기 위해 사용된다.


프로그래밍 언어를 구현하는 방법 중에서 인터프리터(해석기) 방식이 있다.
사용자가 입력한 프로그램을 읽고 값을 계산한 다음 출력하는 일을 반복한다.
이렇게 읽고(read), 계산하고(evaluate), 출력하는(print) 반복 구조를 REPL(read-eval-print loop)이라고 한다


다운 가능한 곳 : https://jdk9.java.net/download/



G:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )
a value = 10



JShell에 대해 더 잘 알고 싶다면 아래 링크를 참고.




Factory Methods for Immutable List, Set, Map and Map.Entry

불변 List, Set, Map, Map.Entry를 만들어주는 편리한 팩토리 메서드가 제공된다.

그 유틸 메서드들은 비어있거나 비어있지 않은 Collection 객체를 만드는데 사용됩니다.


자바8이나 이전 버전에서 우리는 Collections 클래스의 unmodifiableXXX와 같은 유틸 메서드를 사용해서 불변 Collection 객체를 만들었다.

그러나 그 메서드들을 이용한 방법은 지루하고 장황했다. 그 단점을 없애기 위해서 새로운 팩토리 메서드가 추가되었다.


List와 Set 인터페이스는 불변의 비어있거나 비어있지 않은 List 또는 Set을 만들어주기 위한 "of" 메서드를 갖는다.


Empty List Example

List immutableList = List.of();

Non-Empty List Example

List immutableList = List.of("one","two","three");


Map은 두 개의 메서드를 갖는다.
"of"는 비어있는 불변 맵을, "ofEntires"는 데이터를 추가해준 불변 맵을 만들어준다.

Empty Map Example

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}

Non-Empty Map Example

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}


위 메서드에 대해 더 자세히 알고 싶다면 아래 링크를 참고.




Private methods in Interfaces

Java8에서 Default와 Static 메서드를 이용해서 인터페이스에 구현체를 넣는 방법이 추가되었다.

하지만 private으로 구현체를 추가하는 방법이 없었기 때문에 이번에 추가되었다.

아래 메서드들에 차이는 없다.


public interface Card{

  private Long createCardID(){
    // Method implementation goes here.
  }

  private static void displayCardDetails(){
    // Method implementation goes here.
  }

}

더 알고 싶다면 아래 링크를 참고




Java 9 Module System

자바9의 큰 변화중 하나는 모듈 시스템이다.

직소 프로젝트(Jigsaw project)는 다음과 같은 특징을 갖고 있다.

  • Modular JDK
  • Modular Java Source Code
  • Modular Run-time Images
  • Encapsulate Java Internal APIs
  • Java Platform Module System


자바 SE 9 버전 전에, 우리는 자바 기반 응용 프로그램을 개발할 때 모노리틱 Jar 방식을 사용하고 있었습니다. 

이 아키텍처는 한계와 단점이 많았습니다. 이러한 모든 단점을 방지하기 위해, 자바 SE 9 모듈 시스템이 나왔습니다..


JDK 9는 92 모듈 (최종 릴리스에서 변경 될 수 있습니다)와 함께 오고 있다.

우리는 JDK 모듈을 사용할 수 있고 아래와 같이 우리 자신의 모듈을 만들 수 있습니다 :



Simple Module Example

module com.foo.bar { }


여기에서 우리는 간단한 모듈을 만드는 'module'을 사용하고 있습니다.

각 모듈의 이름, 관련 코드 및 기타 자원을 보유하고 있습니다.




Process API Improvements

자바9에서 프로세스 API를 개선하였다.

다음과 같은 두 커플 형태의 신규 클래스가 추가되었다. (OS 프로세스를 관리 및 컨트롤할 수 있는)


  • java.lang.ProcessHandle
  • java.lang.ProcessHandle.Info


Process API example

 ProcessHandle currentProcess = ProcessHandle.current();
 System.out.println("Current Process Id: = " + currentProcess.getPid());





Try With Resources Improvement

우리는 자바 7에서 새로운 자원 관리 방법(try with resource)이 나온 것을 알고 있다.

이것의 핵심 목표는 자원관리의 보다 나은 자동화이다.  자바9에서는 더 향상된 방법을 제공한다.



Java SE 7 example

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

Java 9 example

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}


더 많은 정보를 원하면 아래 링크를 참고




CompletableFuture API Improvements

자바8에서 CompletableFuture가 가지는 문제점을 개선하였다.



Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

delayedExecutor()은 static 유틸 메서드로 사용된다.

주어진 시간 딜레이 이후에 기본 실행자로 보내진 new Executor를 반환한다.




Reactive Streams

아름다운 혜택들로 애플리케이션을 배포하기 위해 지금 리액티브 프로그래밍은 큰 인기를 끌고 있다.

Scala, Play, Akka 등의 프레임워크는 이미 리액티브 스트림을 구축하고 많은 혜택을 얻고 있다.

오라클은 새로운 리액티브 스트림 API를 소개한다.


자바9의 리액티브 스트림 API는 자바 언어를 이용해서 매우 쉽게 병행성, 확장성, 비동기 애플리케이션을 구현한 Publish / Subscribe 프레임워크이다.


다음은 자바 기반 애플리케이션에서 리액티브 스트림을 개발하기 위한 API이다.


  • java.util.concurrent.Flow
  • java.util.concurrent.Flow.Publisher
  • java.util.concurrent.Flow.Subscriber
  • java.util.concurrent.Flow.Processor




Diamond Operator for Anonymous Inner Class

자바 7에서 다이아몬드 오퍼레이터를 추가했지만, 자바 8에서 익명 내부 클래스 사용시 한계가 있다는 것을 찾게 되었다.

그것을 수정하였고 아래와 같은 예를 들 수 있다. 자세한 타입 파라미터 없이 단순히 "List"만을 사용하였지만 상세한 타입을 알아서 확인해서 읽어준다.



public List getEmployee(String empid){
     // Code to get Employee details from Data Store
     return new List(emp){ };
  }




Optional Class Improvements

Optional 클래스에 신규 메서드를 추가했다.

값이 Optional 객체로 주어질 때 Stream 메서드는 값과 함께 sequential stream을 리턴한다. 값이 비어 있다면 빈 스트림을 리턴한다.


다음은 Optional에서 stream의 사용 형태를 보여준다.


Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)

위 Optional.stream 메서드는 Employee 객체의 Optional 스트림을 Employee 객체 스트림으로 변환해준다.




Stream API Improvements

자바9에서 Stream 인터페이스에 사용 가능한 4개의 메서드가 추가되었다.

Stream은 인터페이스이므로 신규 구현된 메서드는 모두 default 메서드이다.

그 중 두 개는 매우 중요하다. dropWhile과 takeWhile 메서드

takeWhile은 인수로서의 predicate를 취하고 주어진 값의 스트림 서브셋을 리턴합니다.

해당 값을 만족시키는 값이 없으면 빈 스트림을 리턴합니다.



jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4







Enhanced @Deprecated annotation

자바8과 이전 버전에서 @Deprecated 어느테이션은 어느 메서드도 없이 단순히 마커 인터페이스였다.

Java SE 9에서 Oracle Corporation은 @Deprecated 주석을 강화하여 지원 중단 된 API에 대한 자세한 정보를 제공하고 지원 중단 된 API의 정적 사용을 분석하는 도구를 제공합니다.

forRemovalsince가 추가되었고 이 메서드들은 그 정보를 제공합니다.




HTTP 2 Client

HTTP/2 프로토콜과 WebSocket 기능을 지원하기 위해 새로운 HTTP 2 클라이언트 API가 추가된다.

기존 또는 기존 HTTP 클라이언트 API에 많은 문제점이 있으므로, 이 HttpURLConnection API를 새로운 HTTP 클라이언트로 대체하고 있습니다.


"java.net.http" 패키지 아래에 새로운 HTTP 2 클라이언트 API를 도입 할 것입니다.

HTTP / 1.1 및 HTTP / 2 프로토콜을 모두 지원합니다. 그것은 동기화(블로킹 모드)와 비동기 모드를 모두 지원합니다.

WebSocket API를 사용하여 비동기 모드를 지원합니다.


We can see this new API at: http://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html



HTTP 2 Client Example

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> http://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))





Мulti-Resolution Image API

Java SE 9에서 Oracle Corp은 새로운 multi-Resolution Image API를 도입 할 예정입니다.

이 API의 중요한 인터페이스는 MultiResolutionImage입니다.

java.awt.image 패키지로 이용 가능합니다.

MultiResolutionImage는 서로 다른 높이와 너비 (해상도가 다름)의 이미지 세트를 캡슐화하고 우리가 요구 사항을 사용하여 이미지를 쿼리 할 수 있도록합니다.




Miscellaneous Java 9 Features

아래 특징들이 덜 중요한 특징은 아니지만 현재로서는 확실히 나온 정보가 많지 않음


  • GC (Garbage Collector) Improvements
  • Stack-Walking API
  • Filter Incoming Serialization Data
  • Deprecate the Applet API
  • Indify String Concatenation
  • Enhanced Method Handles
  • Java Platform Logging API and Service
  • Compact Strings
  • Parser API for Nashorn
  • Javadoc Search
  • HTML5 Javadoc



Reference

[1] Java9 Feature (http://www.journaldev.com/13121/java-9-features-with-examples)






'Software > 정리 글' 카테고리의 다른 글

Java9 특징  (0) 2016.12.12
DDD와 JPA에 대해서 알아야 하는 이유  (0) 2016.06.24
함수형 프로그래밍이 주목받는 이유  (0) 2016.04.27
적정 스레드 수  (0) 2013.05.20
Qt(Qt Development Frameworks)란 무엇인가?  (0) 2012.04.16
정규식 예제  (0) 2012.03.29
Java에서 JNI를 써서 핑 프로그램을 구현하는 이유  (0) 2012.01.30
버전 관리 & 이슈 관리 시스템  (0) 2011.06.07
C와 Java의 컴파일 과정  (1) 2011.05.27
난수 발생기  (2) 2010.06.23
SnmpWalk  (0) 2010.04.27

Leave a Comment










Reference

[1] Vert.x VS Akka (https://java.libhunt.com/project/vertx/vs/akka)

[2] Why we chose Akka for our cloud device solution(https://techblog.king.com/why-we-choose-akka-for-our-cloud-device-solution/)

[3] Difference in message-passing model of Akka and Vert.x(http://stackoverflow.com/questions/21481238/difference-in-message-passing-model-of-akka-and-vert-x)

[4] Interview with Tim Fox About Vert.x 3, the Original Reactive, Microservice Toolkit for the JVM (https://www.infoq.com/articles/vertx-3-tim-fox)

[5] Akka wiki (https://en.wikipedia.org/wiki/Akka_(toolkit))

[6] Vert.x wiki (https://en.wikipedia.org/wiki/Vert.x)



Leave a Comment

리액티브 프로그래밍이란 무엇입니까? What is reactive programming?

이 글은 영어 글에 대해 번역한 글입니다. 일부 오역이 있을 수 있습니다.


원본 : https://medium.com/reactive-programming/what-is-reactive-programming-bc9fa7f4a7fc#.j3uzfx76t





리액티브 프로그래밍이란 무엇입니까?

Reactive (프로그래밍 패러다임과 그이면의 동기)를 이해하려면 개발자와 기업이 직면한 과제를 단 10년 만에 직면한 과제와 비교하는 것이 도움이됩니다.

개발자와 기업을 위한 두 가지 주요 변화는 다음과 같습니다.

  • 하드웨어의 발전
  • 인터넷

모든 개발자가 직면하게 될 문제를 해결하기 위해서는 직업의 역사를 탐구해야합니다.




왜 지금 상황이 다른가요?

컴퓨팅 분야에서 수십 년 간의 연구 끝에 얻은 풍부한 지식이 있습니다.

리액티브 프로그래밍은 이 지식을 새로운 세대의 소프트웨어에 적용하기 위해 그 지식을 포착하려는 시도입니다.


1999년

  • 인터넷에는 2억 8천만 명의 사용자가 있었음
  • J2EE는 여전히 Sun Microsystems의 꿈이었음
  • 온라인 뱅킹은 초기 단계 (5세)




2005년

  • J2EE, SOA 및 XML이 가장 중요
  • Ruby on Rails는 J2EE의 아픈 컨테이너 기반 배포 모델에 대한 도전으로 탄생


다른 재미있는 사실들 :

  • 인터넷에는 10 억 명의 사용자가 있었습니다.
  • Facebook에는 550 만 명의 사용자가있었습니다.
  • YouTube는 신생아였습니다 (2005 년 2 월).
  • 트위터는 태어나기 전 (2006).
  • Netflix는 아직 비디오 스트리밍 (2007)을 도입하지 않았습니다.



2014년

인터넷 라이브 통계에 따르면 약 2,950,000,000 명의 인터넷 사용자가 있음
중국 만해도 640 만 인터넷 사용자가 있음
미국은 2 억 8000 만명

오늘날 가장 인기있는 웹 사이트 중 두 가지 :
  • 페이스 북 - 13 억 사용자.
  • 트위터 - 2 억 7 천만 명의 사용자.
시대가 바뀌었음.
하나의 웹 사이트가 이제는 10년 이전의 전체 인터넷만큼의 트래픽을 처리합니다.

1995년부터 2015년까지 인터넷, Facebook 및 Twitter의 총 사용자



일상 생활에서 소프트웨어의 규모, 기대 및 중요성과 관련된 문제에 직면하고 있음을 쉽게 알 수 있습니다.
과거의 일부 패러다임은 현재와 미래로 확대되지 않을 수도 있음을 쉽게 알 수 있습니다.



4 가지 리액티브 원리
반응적 응용 프로그램은 네 가지 기본 원칙에 기반합니다.



Reactive 애플리케이션의 핵심 빌딩 블록.
  • 반응형 애플리케이션이 목표입니다.
  • 응답성이 뛰어난 응용 프로그램은 확장 가능하고 탄력적입니다. 응답성은 확장 성 및 복원력 없이는 불가능합니다.
  • 메시지 기반 아키텍처는 확장 가능하고 탄력적이며 궁극적으로 응답성이 뛰어난 시스템의 토대입니다.



즉각 반응 (Responsive)
애플리케이션이 반응적이라고 말할 때 무엇을 의미합니까?

지속적으로 긍정적인 사용자 환경을 보장하기 위해서
환경이 좋을 때나 좋지 않을 때나 (원문에서는 푸른 하늘과 잿빛 하늘이라고 표현하는데 네트워크나 기타 상황에 대한 묘사인 것으로 보임)
반응형 시스템은 모든 사용자에게 신속하게 반응합니다.


신속성과 외부 시스템의 장애 또는 트래픽의 급증과 같은 다양한 조건에서의 긍정적 인 사용자 경험은 반응 애플리케이션의 두 가지 특징 인 복원력 및 확장성에 달려 있습니다. 메시지 기반 아키텍처는 반응 형 시스템의 전반적인 기반을 제공합니다.
메시지 기반 아키텍처가 응답성에 중요한 이유는 무엇입니까?
세상은 비동기 적입니다. 여기에 한 가지 예가 있습니다. 커피 한 잔을 끓이는 것이지만, 크림과 설탕이 부족하다는 것을 깨닫게됩니다.

한 가지 가능한 접근법 :
커피 한잔을 끓이세요.
커피가 끓는 동안 가게에 가세요
크림과 설탕을 사세요.
집으로 돌아오세요
커피를 마시세요
인생을 즐기세요

또 다른 가능한 접근법 :
가게로 가세요
크림과 설탕을 사세요.
집으로 돌아오세요
커피를 끓으세요
조바심내며 커피가 끓고 있는지 확인합니다.
카페인 금단 증상을 경험합니다.
추락합니다.

명확하게 알 수 있듯이, 메시지 중심 아키텍처는 시간과 공간을 차단하는 비동기 경계를 제공합니다. 우리는이 게시물의 나머지 부분에서 비동기 경계 개념을 계속 탐구 할 것입니다.


캐나다 월마트에서의 일관성 (Consistency)
Typesafe에 참여하기 전에 저는 캐나다 월마트의 새로운 전자 상거래 플랫폼을 구축한 Play 및 Scala 팀의 기술 선도자였습니다.
우리의 목표는 다음과 상관없이 긍정적인 사용자 경험의 일관성이었습니다.
  • 데스크탑, 태블릿 또는 모바일 장치 상관 없이 walmart.ca를 검색하는 데 사용 된 실제 장비
  • 현재 피크 트래픽은 강하게 한번 오는 것이든 지속적으로 오는 것이든 상관 없음
  • 전체 데이터 센터의 손실과 같은 주요 인프라 장애.

응답 시간과 전반적인 사용자 경험은 위의 시나리오에 관계없이 일관성을 유지해야했습니다.
현재 당신의 웹 사이트가 당신의 브랜드임을 고려해 볼 때 일관성은 매우 중요합니다. 

온라인에서 겪은 좋지 못한 사용자 경험은 쉽게 잊혀지거나 무시 당하지 않습니다.



Gilt의 반응적인 소매

전자 상거래 도메인의 일관성은 실수로 발생하지 않습니다.

예를 들어 정오에 매일 판매되는 품목을 발표 할 때 매일 트래픽이 급증하는 플래시 판매 사이트인 금트 (Gilt)가 있습니다.

플래시 판매 사이트의 사용자 환경을 고려해 보겠습니다. 11시 58 분에 Gilt를 검색하고 오후 12시 1 분에 다시 방문하면 금테가 정오 이후에 트래픽이 몰려 들었음에도 불구하고 긍정적인 경험을 기대합니다.

Gilt는 지속적으로 긍정적이고 반응이 빠른 경험을 제공하고 Reactive를 통해 이를 달성했습니다.


스칼라 기반 마이크로 서비스 아키텍처 마이그레이션한 방법에 대한 인터뷰
(http://readwrite.com/2014/05/08/gilt-eric-bowman-interview-scala-rails-jvm-reactive-platform/)





탄력성

대부분의 응용 프로그램은 일반적인 상황을 위해 설계 및 개발되었지만 상황이 잘못 될 수 있습니다.

주요 애플리케이션의 오류에 대한 보고가 있거나 해커가 시스템을 중단하여 장애를 겪을 수 있는 것으로 보입니다.


탄력적인 시스템은 일반적인 상황뿐만 아니라 장애 등의 상황에서도 응답성을 보장하기 위해 적절한 설계 및 아키텍처 원칙을 적용합니다.


Java와 JVM은 하나의 응용 프로그램을 여러 운영 체제에 원활하게 배포하는 것과 관련이 있지만 20- 십 (201x)의 상호 연결된 응용 프로그램은 모두 응용 프로그램 수준의 구성, 연결 및 보안에 관한 것입니다.

이제 응용 프로그램은 웹 서비스 및 기타 네트워크 프로토콜을 통해 통합 된 여러 가지 다른 응용 프로그램으로 구성됩니다. 현재 구축 된 응용 프로그램은 신뢰할 수있는 자체 방화벽 외부에서 많은 수의 외부 서비스 (10 개, 20 개 또는 그 이상)에 의존 할 수 있습니다. 또한 많은 수의 외부 클라이언트 (사람과 다른 시스템 모두)에게 서비스를 제공 할 수 있습니다.

이러한 통합의 복잡성을 염두에두고 얼마나 많은 개발자가 :

모든 외부 종속성을 분석하고 모델링 하시겠습니까?

통합 된 각 서비스의 이상적인 응답 시간을 기록하고, 성능 테스트 (피크 및 내구성 모두)를 수행하여 초기 기대치를 온전하게 확인하십시오.

모든 성능, 실패 및 기타 비 기능 요구 사항을 코어 응용 프로그램 논리의 일부로 포함 시키려면 어떻게해야합니까?

각 서비스의 모든 장애 시나리오를 분석하고 테스트하십시오.

외부 시스템과의 통합이 새로운 취약점을 생성한다는 것을 인식하고 외부 종속성의 보안을 분석하십시오.

탄력성은 가장 정교한 응용 프로그램의 가장 약한 링크 중 하나이지만 나중에 고려해야 할 탄력성은 곧 종료됩니다. 최신 응용 프로그램은 이상적인 상황이 아닌 다양한 실제 환경에서 응답 성을 유지하기 위해 핵심에서 복원력이 있어야합니다. 성능, 내구성 및 보안은 모든 측면에서 탄력적입니다. 응용 프로그램은 모든 수준에서 복원력이 있어야합니다.


While Java and the JVM were all about seamlessly deploying a single application to multiple operating systems, the interconnected applications of the twenty-teens (201x) are all about application-level composition, connectivity, and security.

Applications are now composed from a number of other applications, integrated via web services and other network protocols. An application built today may depend on a large number of external services — 10, 20, or even more — outside of its own trusted firewall. It may also serve a large number of external clients, both people and other systems.

With this integration complexity in mind, how many developers:

Analyze and model all external dependencies?

Document ideal response times of each service that’s integrated with, conducting performance tests — both peak and endurance — to sanity-check the initial expectations?

Codify all performance, failure, and other non-functional requirement expectations to be included as part of core application logic?

Analyze and test against all failure scenarios of each service?

Analyze the security of external dependencies, recognizing that integrating with an external system creates new vulnerabilities?

Resiliency is one of the weakest links of even the most sophisticated application, but resiliency as an afterthought will soon end. Modern applications must be resilient at their core in order to stay responsive under a variety of real-world, less than ideal conditions. Performance, endurance, and security are all facets of resiliency. Your applications must be resilient on all levels, not just a few.




메시지 중심 탄력성

메시지 중심의 핵심 요소를 구축하는 것의 장점은 자연스럽게 많은 가치있는 빌딩 블록을 사용하여 작업 할 수 있다는 것입니다.

시스템이 자체 치료할 수있는 격리가 필요합니다. 격리가 이루어지면 장애 위험, 성능 특성, CPU 및 메모리 사용 등과 같은 여러 요소를 기반으로 여러 유형의 작업을 구분할 수 있습니다. 격리 된 하나의 구성 요소에서의 장애는 전체 시스템의 응답성에 영향을 미치지 않으며 실패한 구성 요소에 치유 할 기회를 제공합니다.

위치 투명성은 같은 VM에서 진행되는 것처럼 여러 클러스터 노드에서 서로 다른 프로세스와 상호 작용할 수있는 기능을 제공합니다.

전용 별도의 오류 채널을 사용하면 발신자의 얼굴에 오류 신호를 던지기보다는 오류 신호를 다른 곳으로 리디렉션 할 수 있습니다.

이러한 요소는 강력한 오류 처리 및 내결함성을 응용 프로그램에 통합하는 데 도움이됩니다. 이는 Akka의 감독자 계층 구조와 같은 구현을 통해 실제로 입증됩니다.

메시지 기반 아키텍처가 제공하는 핵심 빌딩 블록은 탄력성에 기여하며, 이는 푸른 하늘 아래뿐만 아니라 다양한 덜 이상적이고 현실적인 상황에서 응답성에 기여합니다.



Message-driven resiliency

The beauty of building on top of a message-driven core is that you naturally get a number of valuable building blocks to work with.

Isolation is needed for a system to self-heal. When isolation is in place, we can separate different types of work based on a number of factors, like the risk of failure, performance characteristics, CPU and memory usage, and so on. Failure in one isolated component won’t impact the responsiveness of the overall system, while also giving the failing component a chance to heal.

Location transparency gives us the ability to interact with different processes on different cluster nodes just like we do in-process on the same VM.

A dedicated separate error channel allows us to redirect an error signal somewhere else rather than just throwing it back in the caller’s face.

These factors help us towards incorporating robust error handling and fault tolerance into our applications. This is demonstrated in action through implementations like Akka’s supervisor hierarchies.

The core building blocks provided by a message-driven architecture contributes to resiliency, which in turn contributes to responsiveness — not only under blue skies, but under a variety of less-than-ideal, real-world conditions.




4 억 4 천만 달러의 탄력성 실수

2012 년 Knight Capital Group이 경험 한 소프트웨어 결함을 생각해보십시오. 소프트웨어 업그레이드 도중에 다른 휴면 통합 응용 프로그램이 우발적으로 가동되어 거래량이 증가하기 시작했습니다.

다음 45 분 동안 일어난 일은 악몽 같은 시나리오였습니다.

Knight의 자동화 된 거래 시스템은 나스닥에 실수로 넘쳐 났으며 수십억 달러 상당의 의도하지 않은 입장에 처하게되었습니다. 회사 측에 4 억 4 천만 달러의 비용이 들었다. 결함이있는 동안 나이트는 나스닥에 범람 한 거래의 범람을 막을 수 없었기 때문에 나스닥은 나이트의 플러그를 뽑아야했습니다. 나이트의 주식은 하루에 63 % 하락한 상태로 회사로 간신히 살아 남았고 재고가 가치를 회복하고 이후 투자자가 인수 한 후에 거기에 매달렸다.

나이트의 시스템은 성능이 좋았지 만 탄력성이 없었습니다. 탄력성이없는 성능은 Knight가 발견 한 문제를 증폭시킬 수 있습니다. Knight는 치명적인 버그가 발생하면 시스템에 플러그를 꽂을 수있는 킬 스위치 메커니즘조차 갖고 있지 않았으므로 회색 하늘 아래에서 자동 거래 시스템이 회사의 전체 자본 보유량을 45 분 내에 고갈 시켰습니다.

이것은 푸른 하늘을위한 설계 및 개발의 정의입니다. 소프트웨어가 우리의 개인 생활과 비즈니스의 핵심 구성 요소가 되었기 때문에 회색 하늘 시나리오는 예상 시간과 예상 시간이 1 시간 이내 인 경우 비용이 많이 듭니다.




The 440 million dollar resiliency mistake

Consider the software glitch experienced by Knight Capital Group in 2012. During a software upgrade, another dormant, integrated application was inadvertently fired up and began amplifying trading volumes.

What happened over the next 45 minutes was a nightmare scenario.

Knight’s automated trading system flooded NASDAQ with erroneous trades and put the company into billions of dollars worth of unintended positions. It cost the company 440 million dollars to reverse. During the glitch Knight couldn’t stop the deluge of trades that flooded NASDAQ, so NASDAQ had to pull the plug on Knight. Knight’s stock slid 63% in a single day and they barely survived as a company, only hanging in there after the stock regained some of its value and after a subsequent takeover by investors.

Knight’s systems were performant, but they were not resilient. Performance without resilience can amplify problems as Knight discovered. Knight didn’t even have a kill-switch mechanism in place to pull the plug on their system should a catastrophic bug occur, so under grey skies their automated trading system depleted the entire capital reserves of the company within 45 minutes.

This is the definition of designing and developing for blue skies. Now that software is such a core component of our personal lives and our businesses, a grey sky scenario can be very costly if it is not expected and designed for, even within an hour.




확장 성

응답 성이 뛰어난 애플리케이션을 지속적으로 생성 할 때 탄력성과 확장 성이 함께 작용합니다.

확장 가능한 시스템은 다양한 부하 조건에서 응답 성을 보장하기 위해 필요할 때 쉽게 업그레이드 할 수 있습니다.

온라인으로 물건을 판매하는 사람은 간단한 사실을 이해합니다. 가장 큰 물건을 팔 때 가장 많은 트래픽이 발생합니다. 대부분의 경우 - 스파이크가 의도적 인 사이버 공격이 아니라면 큰 트래픽이 발생한다는 것은 당신이 옳은 일을한다는 것을 의미합니다. 소통량이 급증한 동안 사람들은 돈을주고 싶어합니다.

그렇다면 트래픽의 꾸준한 증가 또는 꾸준한 증가를 어떻게 처리합니까?

먼저 패러다임을 선택하고 패러다임을 초월하는 언어와 툴킷을 선택하십시오. 너무 자주 개발자는 단순히 언어와 프레임 워크를 선택합니다 ... "때문에". 툴링 결정이 내려지면이를 뒤집기가 어렵 기 때문에 주요 투자와 마찬가지로 의사 결정에 접근하십시오. 원리와 분석을 바탕으로 기술적 인 선택을 내리면 이미 앞설 것입니다.


Scalable

Resiliency and scalability go hand-in-hand when creating consistently responsive applications.

A scalable system is easily upgraded on demand in order to ensure responsiveness under various load conditions.

Anyone who sells things online understands a simple fact: your largest spikes of traffic are when you sell the most stuff. For the most part — unless the spike is a purposeful cyberattack — experiencing a large burst of traffic means you’re doing something right. During a spike of traffic people want to give you money.

So how do you handle a spike — or a steady but significant increase — of traffic?

Choose your paradigm first, and then choose the languages and toolkits that embrace that paradigm second. All too often developers simply pick a language and framework… ”because”. Once tooling decisions are made they’re difficult to reverse, so approach those decisions as you would with any major investment. If you make technical selection decisions based on principles and analysis you’re already well ahead of the pack.



스레드 기반 동시성 제한 사항

기술적 선택 결정의 가장 중요한 측면 중 하나는 프레임 워크의 동시성 모델입니다. 상위 수준에서 두 개의 별개의 동시성 모델이 있습니다.

호출 스택 및 공유 메모리를 기반으로하는 전통적인 스레드 기반 동시성.

메시지 기반 동시성.

Rails와 같은 인기있는 MVC 프레임 워크는 스레드 기반입니다. 이러한 프레임 워크의 다른 전형적인 특징은 다음과 같습니다.

공유 가능한 상태.

요청 당 스레드.

가변 상태 변수 및 객체 인스턴스에 대한 동시 액세스 - 잠금 및 기타 복잡한 동기화 구문으로 관리.

이러한 특성을 Ruby와 같이 동적으로 형식화되고 해석 된 언어와 결합하면 성능 및 확장 성의 상한선에 신속하게 도달 할 수 있습니다. 본질적으로 핵심 인 스크립팅 언어 인 모든 언어에 대해 동일하게 말할 수 있습니다.



Thread-based limitations to concurrency

One of the most critical aspects of technical selection decisions is the concurrency model of a framework. At a high-level, two distinct concurrency models exist:

Traditional thread-based concurrency based on a call stack and shared memory.

Message-driven concurrency.

Some popular MVC frameworks like Rails are thread-based. Other typical characteristics of these frameworks include:

Shared mutable state.

A thread per request.

Concurrent access to mutable state — variables and object-instances — managed with locks and other complicated synchronization constructs.

Combine those traits with a dynamically typed, interpreted language like Ruby and you can quickly reach the upper bounds of performance and scalability. You can say the same for any language that is essentially, at its core, a scripting language.





밖으로 또는 위로?

애플리케이션을 확장하는 여러 가지 방법을 고려해 보겠습니다.

확장에는 단일 CPU / 서버의 자원을 최대화해야하며 종종 강력하고 이국적인 고가의 하드웨어를 구입해야합니다.

스케일 아웃은 저렴한 비용의 상용 하드웨어 (예 : 클라우드)의 클러스터 전반에 컴퓨팅을 분산시키는 것인데, 이는 비용 효율적이지만 시스템이 시간 및 공간의 개념을 기반으로 할 때 달성하기가 매우 어렵습니다. 이전에 언급했듯이 메시지 기반 아키텍처는 시간과 공간에서 분리해야하는 비동기 경계를 제공하여 요구에 맞게 쉽게 확장 할 수있는 기능을 제공합니다 (탄력성이라고도 함). 확장은 이미 사용 가능한 리소스를 효율적으로 사용하는 것과 관련이 있지만 신축성이란 시스템의 요구 사항이 바뀌면 필요에 따라 새로운 리소스를 시스템에 추가하는 것입니다. 요구에 맞게 수평 확장 할 수있는 기능은 Reactive 애플리케이션의 궁극적 인 확장 성 목표입니다.

반응 형 응용 프로그램은 스레드 기반 프레임 워크로 작성하기가 어렵습니다. 공유 가변 상태, 스레드 및 잠금을 기반으로 응용 프로그램을 수평 확장하는 것이 얼마나 어렵 기 때문입니다. 개발자는 단일 시스템에서 여러 코어를 활용할 수 있어야 할뿐만 아니라 개발자가 특정 지점에서 시스템 클러스터를 활용해야합니다. 공유 된 가변 상태는 또한 불가능하지는 않지만, 규모를 늘리는 것을 어렵게 만듭니다. 두 개의 서로 다른 스레드에서 동일한 공유 가변 상태로 작업을 시도한 사용자는 스레드 안전성을 보장하는 복잡한 프로세스가 무엇인지 이해하고 스레드 안전을 위해 오버 엔지니어링과 관련된 성능 저하를 이해합니다.


Out or up?

Let’s consider the different ways to scale an application.

Scaling up involves maximizing the resources of a single CPU/server, often requiring the purchase powerful, exotic, expensive hardware.

Scaling out involves distributing computation across a cluster of cheap commodity hardware (e.g, the cloud) which is cost efficient, but very difficult to accomplish when your system is based around the concepts of time and space. As we mentioned earlier, a message-driven architecture provides the asynchronous boundary needed to decouple from time and space, providing the ability to easily scale out on demand, also known as elasticity. While scaling up is about the efficient use of resources already available, elasticity is about adding new resources to your system on demand as the needs of your system change. The ability to scale out, on demand is the ultimate scalability goal of a Reactive application.

Reactive applications are difficult to build with thread-based frameworks because of how difficult it is to scale out an application based on shared mutable state, threads, and locks. Not only do developers need to be able to take advantage of multiple cores on a single machine, at a certain point developers need to take advantage of clusters of machines. Shared mutable state also makes it difficult, though not impossible, to scale up. Anyone who has attempted to work with the same shared mutable state in two different threads understands what a complicated process ensuring thread safety is, and also understands the performance penalties associated with over-engineering for thread safety.




메시지 중심

메시지 기반 아키텍처는 반응 형 애플리케이션의 기반입니다. 메시지 기반 응용 프로그램은 이벤트 기반, 액터 기반 또는이 둘의 조합 일 수 있습니다.

이벤트 중심 시스템은 0 명 이상의 관찰자가 모니터링하는 이벤트를 기반으로합니다. 호출자는 호출 된 루틴의 응답 대기를 차단할 필요가 없으므로 명령형 프로그래밍과 다릅니다. 이벤트는 특정 주소로 전달되는 것이 아니라 오히려 시청 (또는 듣기)되기 때문에 우리가 더 자세히 논의 할 내용을 포함하고 있습니다.

액터 기반 동시성은 메시지 패싱 아키텍처의 확장이며 메시지는 수신자에게 전달됩니다. 메시지는 스레드 경계를 넘거나 다른 실제 서버의 다른 액터의 메일 함으로 전달 될 수 있습니다. 액터가 네트워크를 통해 배포 될 수 있지만 여전히 동일한 JVM을 공유하는 것처럼 서로 통신 할 수 있으므로 요구에 맞게 확장 할 수 있습니다.

메시지와 이벤트의 주요 차이점은 이벤트가 발생하는 동안 메시지가 전달된다는 것입니다. 0 개 이상의 관찰자가 이벤트를 관찰 할 수있는 반면 메시지의 대상은 명확합니다.

이벤트 중심 및 액터 기반 동시성에 대해 좀 더 자세히 살펴 보겠습니다.



Message-driven

A message-driven architecture is the foundation of Reactive applications. A message-driven application may be event-driven, actor-based, or a combination of the two.

An event-driven system is based on events which are monitored by zero or more observers. This is different than imperative programming because the caller doesn’t need to block waiting for a response from the invoked routine. Events are not directed to a specific address, but rather watched (or listened) for, which has some implications that we’ll discuss further.

Actor-based concurrency is an extension of the message-passing architecture, where messages are directed to a recipient, which happens to be an actor. Messages may cross thread boundaries or be passed to another actor’s mailbox on a different physical server. This enables elasticity — scaling out on demand — as actors can be distributed across the network, yet still communicate with each other as if they were all sharing the same JVM.

The main difference between messages and events is that messages are directed while events happen. Messages have a clear destination while events may be observed by zero or more (0-N) observers.

Let’s explore event-driven and actor-based concurrency in a little more detail.




이벤트 중심 동시성

일반적인 응용 프로그램은 명령형으로 - 순차적 인 작업 순서 - 개발되었으며 호출 스택을 기반으로합니다. 호출 스택의 주요 기능은 주어진 루틴의 호출자를 추적하고 프로세스에서 호출자를 차단하면서 호출 된 루틴을 실행하고 리턴 값으로 호출자에게 제어를 리턴하는 것입니다.

피상적으로, 이벤트 위주의 애플리케이션은 호출 스택에 초점을 맞추지 않고 이벤트를 트리거합니다. 이벤트는 0 이상의 관찰자가 모니터하는 대기열에있는 메시지로 인코딩 될 수 있습니다. 이벤트 중심의 스타일과 명령형의 큰 차이점은 호출자가 응답을 기다리는 동안 스레드를 차단하지 않는다는 것입니다. 이벤트 루프 자체는 단일 스레드 일 수 있지만, 호출 된 루틴이 (때때로 단일 스레드 이벤트 루프가 들어오는 요청을 처리 할 수 ​​있도록하면서) 호출 된 루틴이 비즈니스에 대해 (그리고 IO 자체에서 잠재적으로 차단되면서) 동시성은 여전히 ​​달성됩니다. 완전히 처리되지 않는 한 요청을 차단하는 대신 호출자의 ID가 요청 메시지의 본문과 함께 전달되므로 호출 된 루틴이이를 선택하면 응답자가 호출 할 수 있습니다.

이벤트 중심 아키텍처를 선택하게 된 주된 결과는 콜백 지옥이라는 현상을 겪을 수 있다는 것입니다. 예를 들어 http://callbackhell.com을 참조하십시오. 콜백 지옥은 메시지의 수신자가 주소 지정 가능한 수신자 대신 익명의 콜백이기 때문에 발생합니다. 콜백 지옥에 대한 일반적인 해결책은 순전히 구문 론적 측면, 즉 운명의 피라미드 (Pyramid of Doom)에 초점을 맞추고 코드에서 표현 된 일련의 사건에 대한 추론과 디버깅에서 발생하는 어려움을 무시합니다.


Event-driven concurrency

Typical applications are developed in imperative style — a sequential order of operations — and based around a call stack. The main function of the call stack is to keep track of the caller of a given routine, execute the invoked routine while blocking the caller in the process, and returning control to the caller with a return value (or nothing at all).

Superficially, event-driven applications are not focused on the call stack, but rather on triggering events. Events may be encoded as messages that are placed in a queue that is monitored by zero or more observers. The big difference between event-driven and imperative style is that the caller does not block and hold onto a thread while waiting for a response. The event-loop itself may be single threaded, but concurrency is still achieved while invoked routines go about their business (and potentially block on IO themselves) while allowing the (sometimes single) threaded event-loop to process incoming requests. Instead of blocking on a request unless completely processed, the caller’s identity is passed along with the body of the request message so that — if the invoked routine chooses to do so — the caller can be called back with a response.

The main consequence of choosing an event-driven architecture is that they can suffer from a phenomenon called callback hell — see http://callbackhell.com for examples. Callback hell occurs because the recipients of messages are anonymous callbacks instead of addressable recipients. Common solutions to callback hell focus purely on the syntactic aspect — aka, the Pyramid of Doom — while neglecting the difficulties that arise in reasoning about and debugging the sequence of events expressed in the code.




액터 기반 동시성

액터 기반 애플리케이션은 여러 액터 사이의 비동기 메시지 전달을 중심으로 이루어집니다.

액터는 다음과 같은 속성을 가진 구문입니다.

메시지를 수신하기위한 사서함.

액터의 논리는 패턴 매칭에 의존하여 각 유형의 메시지를 처리하는 방법을 결정합니다.

요청간에 컨텍스트를 저장하기 위해 공유 된 상태가 아닌 격리 된 상태.

이벤트 기반 동시성과 마찬가지로 액터 기반 동시성은 경량 메시지 전달을 위해 호출 스택을 피합니다. 액터는 메시지를 앞뒤로 전달하거나 메시지를 전달할 수 있습니다. 액터는 큐에있는 다른 메시지를 먼저 처리 한 후 장기 실행 요청 처리를 완료하기 위해 메시지를 자신에게 전달할 수 있습니다. 배우 기반 동시성의 큰 이점은 이벤트 중심 아키텍처에서 얻는 이점 외에도 네트워크 경계를 넘어 계산을 확장하는 것이 훨씬 쉽고 메시지가 액터로 전달되기 때문에 콜백 (callback-hell)을 피할 수 있다는 것입니다. 이는 설계, 구축 및 유지 보수가 용이 한 확장 성이 뛰어난 응용 프로그램을 쉽게 만들 수있는 강력한 개념입니다. 시간과 공간 또는 심하게 중첩 된 콜백을 생각하는 대신 액터간에 메시지가 어떻게 전달되는지 생각하면됩니다.

액터 기반 아키텍처의 또 다른 주요 이점은 구성 요소의 느슨한 결합입니다. 호출자는 응답 대기중인 스레드를 차단하지 않으므로 호출자는 다른 작업으로 빠르게 이동할 수 있습니다. 액터에 의해 캡슐화 된 호출 된 루틴은 필요할 경우 호출자에게 다시 호출하면됩니다. 이는 호출 스택이 메모리의 단일 공간에 응용 프로그램을 연결하지 않기 때문에 액터 모델은 프로그래밍 토폴로지가 아닌 배치 토폴로지를 추상화 된 구성 관심사로 만들기 때문에 시스템 클러스터에 루틴을 배포하는 것과 같은 다양한 가능성을 열어줍니다.

Akka는 JVM에서 동시성, 분산 및 내결함성이 높은 액터 기반 응용 프로그램을 구축하기위한 액터 기반 툴킷 및 런타임 (Typesafe Reactive Platform)의 일부입니다. Akka는 탄력성을위한 관리자 계층 구조와 확장 성을위한 분산 된 직원과 같은 Reactive 응용 프로그램을 구축하기위한 여러 가지 놀라운 기능을 제공합니다. Akka에 대한 심층적 인 탐구는이 기사의 범위를 벗어나지 만 Akka 관련 콘텐츠를 더 보려면 Let it Crash 블로그를 방문하는 것이 좋습니다.

또한 Benjamin Erb의 Diploma Thesis, Scalable Web Architectures를위한 동시 프로그래밍 (Concurrent Programming for Scalable Web Architects)을 읽는 것이 좋습니다.이 섹션은이 섹션의 일부로 정보 소스로 사용되었습니다.


Actor-based concurrency

Actor-based applications revolve around asynchronous message passing between multiple actors.

An actor is a construct with the following properties:

A mailbox for receiving messages.

The actor’s logic, which relies on pattern matching to determine how to handle each type of message it receives.

Isolated state — rather than shared state — for storing context between requests.

Like event-driven concurrency, actor-based concurrency eschews the call stack in favour of lightweight message passing. Actors can pass messages back and forth, or even pass messages to themselves; an actor can pass a message to itself in order to finish processing a long-running request after it services other messages in its queue first. A huge benefit of actor-based concurrency is that in addition to the benefits gained by an event-driven architecture, scaling computation out across network boundaries is even easier, and callback-hell is avoided because messages are directed to actors. This is a powerful concept that makes it easy to build hyper-scalable applications that are also easy to design, build, and maintain. Rather than thinking about time and space, or deeply nested callbacks, you only need to think about how messages flow between actors.

Another major benefit of an actor-based architecture is the loose coupling of components. The caller doesn’t block a thread waiting for a response, therefore the caller can quickly move onto other work. The invoked routine, encapsulated by an actor, only needs to call the caller back if necessary. This opens up many possibilities, like distributing routines across a cluster of machines, because the call stack doesn’t couple applications to a single space in memory and the actor-model makes the deployment topology an abstracted away configuration concern rather than a programming concern.

Akka is an actor-based toolkit and runtime — part of the Typesafe Reactive Platform — for building highly concurrent, distributed, and fault tolerant actor-based applications on the JVM. Akka has a number of other incredible features for building Reactive applications, like supervisor hierarchies for resilience and distributed workers for scalability. A deep dive into Akka is beyond the scope of this article, but I highly recommend visiting the Let it Crash blog for more Akka related content.

I also highly recommend reading Benjamin Erb’s Diploma Thesis, Concurrent Programming for Scalable Web Architectures, which was used as a source of information for part of this section.



결론

위의 모든 것들은 오늘날 애플리케이션 개발의 표면을 긁어 내고 리 액티브 프로그래밍은 현대의 소프트웨어 개발자가 배우는 패러다임이 아니라 다른 추세가되는 이유를 제시합니다. 선택한 언어 또는 툴킷에 관계없이 사용자의 기대를 충족시키는 유일한 방법은 응답 성을 얻기 위해 확장 성과 탄력성을 우선적으로 두는 것입니다. 이것은 지나가는 해가 갈수록 중요해질 것입니다.



Conclusion

All of the above scratches the surface of developing applications today, and leads to why Reactive programming isn’t just another trend but rather the paradigm for modern software developers to learn. Regardless of the language or toolkit you choose, putting scalability and resilience first in order to achieve responsiveness is the only way to meet the expectations of users. This will only get more important with each passing year.






Leave a Comment

함수형 프로그래밍(functional programming)이나 리액티브 프로그래밍(reactive programming) 또는 함수형 리액티브 프로그래밍(functional reactive programming)에 대한 관심이 뜨겁다. 이러한 소프트웨어 패러다임에 있어서 늘 나오는 이야기는 비슷하다. 멀티 코어의 시대와 멀티 스레드 프로그래밍의 어려움과 문제점들이 이야기되고 모바일 시대와 IoT로 인해서 늘어나는 트래픽양이 이야기된다.


결론적으로 내가 내린 결론은 이러하다.

이러한 패러다임의 변화는 물론 개발의 편리성이나 이점들도 있지만 결국은 현대의 하드웨어에 맞춰서 소프트웨어의 성능을 최대한으로 끌어내기 위한 것이다. 성능의 중요성은 대형 서비스일수록 매우 중요하다. 페이스북이나 아마존 라인, 트위터에서 받는 트래픽 양을 생각해보아라.


결국 핵심은 멀티코어 하드웨어에서 어떠한 방법으로 소프트웨어의 성능을 최대한으로 끌어낼 것인가인데 여기서 "동시성(Concurrency"과 "병렬성(parallelism]"이 중요하다. 조금 더 구현적으로 상세하게 들어가면 "비동기(asynchronous)" 방식과 "논블로킹(non blocking"방식을 통해서 성능을 높이는 부분이 있고, 스레드의 상태를 공유하지 않고 복사하는 형태로서 멀티 스레드의 근본적인 문제점을 제거하는 형태가 있다.


그 결과물들로 뜨겁게 부상하고 있는 함수형 프로그래밍 스칼라가 있고, 리액티브 프로그래밍에서는 RxJava, Vert.x, Akka, Play framework 등이 있다.

로우 레벨과 하이레벨에 대한 부분을 잘 구별해야 한다. Vert.x의 경우 내부에서 이미 RxJava와 Netty를 사용하고 있다.


결국은 이런 이론적인 부분과 로우 레벨단에 대한 공부를 잔뜩 한 후에 Vert.x나 Akka를 쓰면 끝나는 문제가 아닐까 싶기도 하다.

그래도 Spring 5. 버전에서 리액티브 프로그래밍이 반영이 된다고 하니 리액티브 프로그래밍과 기초적인 내용을 잘 공부해두면 향후에 기술을 고를 때나 사용할 때 많이 유용할 듯 하다.




자극 (Motivation)

2가지 중요한 포인트가 있다. 두 가지 주요 변화는 다음과 같다.

  • 하드웨어의 발전
  • 인터넷


첫번째로 "하드웨어의 발전", 30년간 컴퓨터 성능은 무어의 법칙이 주도하였다.

하지만 무어의 법칙[1]은 깨졌고 현재는 암달[2]의 법칙이 주도하고 있다.


프로그래머가 별다른 노력 없이도 컴퓨터의 성능이 무어의 법칙으로 향상되고 있었는데

무어의 법칙이 깨진 것에 대해서 Herb Sutter라는 사람이 한 말은 유명하다.


공짜 점심은 끝났다
- 어브 써터(Herb Sutter) -


두번째로 인터넷 트래픽의 증가이다. 

스마트폰으로 인하여 모바일 트래픽은엄청나게 증가했다. 그리고 지금은 IoT로 인한 트래픽까지 증가하고 있다.

이 전과 비교하면 인터넷 트래픽이 엄청나게 증가하였고 이에 따라서 성능의 중요성 또한 이전보다 훨씬 중요하게 되었다.




무어의 법칙


무어의 법칙[1]은 반도체 집적회로의 성능이 18개월마다 2배로 증가한다는 법칙

  • 메모리의 용량이나 CPU 속도가 18개월에서 24개월마다 2배씩 향상된다는 '기술 개발 속도에 관한 법칙'
  • 컴퓨팅 성능은 18개월마다 2배씩 향상됨
  • 컴퓨팅 가격은 18개월마다 반으로 떨어짐



암달의 법칙(Amdahl's law)



  • 암달의 저주[2]로도 불림
  • 컴퓨터 시스템의 일부를 개선할 때 전체적으로 얼마만큼의 최대 성능 향상이 있는지 계산하는 데 사용
  • 병렬 컴퓨팅에서 멀티 프로세서를 사용할 때 프로그램의 성능향상은 프로그램의 순차적인 부분에 의해 제한됨
  • 예를 들면, 프로그램의 95%가 병렬화 할 수 있다면 이론적인 최대 성능 향상은 아무리 많은 프로세서를 사용하더라도 최대 20배로 제한됨[3]




인터넷

조금 전에 얘기한대로 인터넷 사용자는 엄청나게 증가를 하였는데 대략적으로 어떤 변화를 보였는지 보자.


1999년

  • 인터넷에는 2억 8천만 명의 사용자가 있었음


2005년

  • J2EE, SOA 및 XML이 가장 중요
  • 인터넷에는 10 억 명의 사용자가 있음
  • Facebook에는 550만 명의 사용자가 있음
  • YouTube는 신생아 (2005 년 2 월).
  • 트위터는 태어나기 전 (2006).
  • Netflix는 아직 비디오 스트리밍 (2007)을 도입하지 않음


2014년
  • 인터넷 라이브 통계에 따르면 약 2,950,000,000 명의 인터넷 사용자가 있음
  • 중국 만해도 640 만 인터넷 사용자가 있음
  • 미국은 2 억 8000 만명

오늘날 가장 인기있는 웹 사이트 중 두 가지 :
  • 페이스 북 - 13 억 사용자.
  • 트위터 - 2 억 7 천만 명의 사용자.
시대가 바뀌었다. 2014년 기준으로 하나의 웹 사이트(페이스북)가 이제는 10년 이전의 전체 인터넷 사용자보다 많은 사용자를 보유하고 있다.

1995년부터 2015년까지 인터넷, Facebook 및 Twitter의 총 사용자




멀티코어 시대

어찌되었든 무어의 법칙이 깨진 이후 CPU 회사들은 컴퓨터의 성능을 높이는 대신에 CPU 숫자를 늘리는 것이 주력하였는데 이것이 우리가 아는 듀얼 코어, 쿼드 코어의 등장이다. 게다가 하이퍼 스레딩[4]이라는 기술을 개발하여 하나의 물리적 CPU를 두 개의 CPU인 것처럼 인식하게 만들어서 코어의 숫자는 더욱 더 늘어나게 되었다.


문제는 이러한 멀티코어 시대에 따라서 소프트웨어 개발자들은 "동시성 프로그래밍, 멀티 스레드 프로그래밍"이라는 당면 과제를 받게 되었다.

하지만 자바 동시성 프로그래밍은 쉽지 않다. 대표적인 것이 자바 개발자들에게 동시성 프로그래밍 바이블 같은 책이었던 "JAVA Concurrency in practice"이다. concurrency인데 왜 번역이 병렬 프로그래밍으로 되었을까 싶은 마음이 들기는 하였는데 아무래도 멀티 코어를 다 사용한다는 점에서 병렬 프로그래밍이라는 이름으로 번역을 한 듯하다. 개인적으로는 "실전 자바 동시성"이라는 이름이 더 맞는듯하다. 참고로 동시성과 병렬성은 다른 뜻이다.



java concurrency in practice에 대한 이미지 검색결과  


동시성 프로그래밍이 왜 어려운지 예를 들 때면 늘 이 책이 나오곤 합니다. 많은 사람들이 추천하지만 그만큼 책 내용은 어렵습니다.

"java.util.concurrent" 패키지쪽 사용 방법에 대해서 많은 설명이 되어있는데 사용을 하는 법은 어렵지 않으나 동시성 프로그래밍의 어려운 점이나 문제가 생기는 구간, 원인 그리고 해결방법에 대한 원론적인 문제들은 사실 많이 골치 아프고 생각을 많이 해보게 만든다. 그리고 그런 점이 이 책이 어렵다고 많이들 이야기하는 이유이기도 하다.


자바에서 벗어나면 다음과 같은 책이 또 있다.

동시성 관련하여 유명한 책인데 나는 번역본을 보았다. 이 책 또한 정말 머리깨지는 이야기인데 "Java concurrency in practice"는 JAVA라는 언어에 국한되어 설명하기 때문에 이 책이 더 좋고 추천할만하다. 하지만 이 책도 만만치 않게 어렵다. (어쩌면 더)

"Java concurrency in practice"에서 다룬 내용은 이 책에서 동시성 모델 중 하나인 "스레드와 잠금장치"에 해당한다. 



  7가지 동시성 모델에 대한 이미지 검색결과





현재 패러다임

조금 전 살펴본 동시성 프로그래밍에서 Thead는 큰 문제를 갖고 있다. 예측이 불가능한 상황이 만들어지고 테스트가 어렵고 프로그밍하기 어렵다는 문제이다.


“Thread를 사용하는 대부분의 프로그램 들은 버그로 가득 차 있다.”
- Havoc Pennington -


처음에는 이러한 어려움과 문제에 대해서 원래 그런 것이고 이 어려운 것을 잘 해내는 사람이 잘하는 것이고 고수라는 생각을 갖고 있었지만 이제는 달라지고 있다. 이 고질적인 문제를 근본적으로 해결하려 하는 것이 요즘 많이 뜨고 있는 "함수형 프로그래밍(Functional programming"이고 동시성 프로그래밍 분야에서 큰 각광을 받고 있는 것이 "반응형 프로그래밍(Reactive programming"이다. 

 그리고 이 둘의 장점을 합친 "함수형 반응형 프로그래밍(Functional reactive programming"이 유행인데 아직 국내에서는 이렇다 할 큰 사례는 없는듯하다.

하지만 이러한 리액티브와 같은 부분은 Spring 5에서도 도입이 된다고 할만큼 큰 추세이니 알아두면 향후에 큰 도움이 될 것이다.




Reference

[1] 무어의 법칙 한글 위키 (https://ko.wikipedia.org/wiki/%EB%AC%B4%EC%96%B4%EC%9D%98_%EB%B2%95%EC%B9%99)

[2] 암달의 법칙 한글 위키 (https://ko.wikipedia.org/wiki/%EC%95%94%EB%8B%AC%EC%9D%98_%EB%B2%95%EC%B9%99)

[3] 암달의 법칙 영문 위키 (https://en.wikipedia.org/wiki/Amdahl%27s_law)

[4] 하이퍼 스레딩(https://ko.wikipedia.org/wiki/%ED%95%98%EC%9D%B4%ED%8D%BC%EC%8A%A4%EB%A0%88%EB%94%A9)

[5] what is reactive programming (https://medium.com/reactive-programming/what-is-reactive-programming-bc9fa7f4a7fc#.j3uzfx76t)



Leave a Comment


to Top