리액티브 프로그래밍이란 무엇입니까? 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)을 도입하지 않았습니다.
- 페이스 북 - 13 억 사용자.
- 트위터 - 2 억 7 천만 명의 사용자.
- 반응형 애플리케이션이 목표입니다.
- 응답성이 뛰어난 응용 프로그램은 확장 가능하고 탄력적입니다. 응답성은 확장 성 및 복원력 없이는 불가능합니다.
- 메시지 기반 아키텍처는 확장 가능하고 탄력적이며 궁극적으로 응답성이 뛰어난 시스템의 토대입니다.
지속적으로 긍정적인 사용자 환경을 보장하기 위해서
환경이 좋을 때나 좋지 않을 때나 (원문에서는 푸른 하늘과 잿빛 하늘이라고 표현하는데 네트워크나 기타 상황에 대한 묘사인 것으로 보임)
반응형 시스템은 모든 사용자에게 신속하게 반응합니다.
- 데스크탑, 태블릿 또는 모바일 장치 상관 없이 walmart.ca를 검색하는 데 사용 된 실제 장비
- 현재 피크 트래픽은 강하게 한번 오는 것이든 지속적으로 오는 것이든 상관 없음
- 전체 데이터 센터의 손실과 같은 주요 인프라 장애.
전자 상거래 도메인의 일관성은 실수로 발생하지 않습니다.
예를 들어 정오에 매일 판매되는 품목을 발표 할 때 매일 트래픽이 급증하는 플래시 판매 사이트인 금트 (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.
'Devlopment > Reactive, Concurrency' 카테고리의 다른 글
리액티브란 무엇인가? (What's in a Name : Reactive) (0) | 2017.01.10 |
---|---|
리액티브 프로그래밍 대 리액티브 시스템 (Reactive Programming vs Reactive Systems) (0) | 2017.01.09 |
리액티브 스트림(Reactive Streams) (0) | 2017.01.04 |
데이터 스트림 (0) | 2016.12.29 |
동시성 관련 분류 (0) | 2016.12.27 |
vert.x VS Akka (0) | 2016.11.22 |
1. 소프트웨어 패러다임 - 성능 그리고 동시성 (0) | 2016.11.17 |
동시성(Concurrency) vs 병렬성(Parallelism) (0) | 2016.11.17 |
synchronous, asynchronous, blocking, non-blocking (0) | 2016.10.31 |
Rx-Java와 Java8에서의 반응형 프로그래밍 (Reactive Programming in Java 8 with Rx-Java) (0) | 2016.10.31 |