Recent Posts
Archives

Posts Tagged ‘ReactiveSystems’

PostHeaderIcon [DevoxxPL2019] Reactive for the Impatient: A Gentle Introduction to Reactive Programming and Systems

Lecturer

Mary Grygleski serves as a developer advocate at IBM, based in Chicago. She organizes the Chicago Java Users Group (CJUG) and leads IBM-sponsored meetups on topics like reactive systems and cloud technologies. Her background includes promoting community engagement and advancing Java-based reactive frameworks.

Abstract

This article provides an in-depth exploration of reactive programming and systems, emphasizing their emergence to address modern computing demands for responsiveness and scalability. It delineates core principles from the Reactive Manifesto, differentiates reactive paradigms, and surveys key Java libraries: RxJava, Spring Reactor, Akka, and Vert.x. Analytical insights into patterns, methodologies, and real-world applications underscore the significance of asynchronicity, elasticity, and fault tolerance in building impatient-user-friendly systems.

Emergence and Principles of Reactive Systems

The surge in reactive methodologies arises from hardware advancements, such as multi-core CPUs and cloud virtualization, coupled with escalating user expectations for instantaneous responses. Mary traces reactive roots to the 1980s actor model in Erlang for real-time telecommunications, now adapted to handle proliferating devices and concurrent requests. Human impatience drives this evolution, mirroring family dynamics where multiple demands require asynchronous handling.

The Reactive Manifesto, led by Lightbend (creators of Akka), outlines four pillars: responsiveness, elasticity, resiliency, and message-driven architecture. Responsiveness ensures timely replies, even in failures, forming the usability foundation. Elasticity scales resources dynamically under varying loads, maintaining throughput. Resiliency employs replication and isolation for fault containment, preventing systemic collapses. Message-driven mechanics enable the others, facilitating asynchronous, non-blocking communication akin to event-driven systems but with addressed destinations.

Mary clarifies distinctions: reactive programming propagates changes via event streams, functional reactive programming advances via execution threads, and reactive systems orchestrate isolated components cohesively. Event-driven emits unaddressed events for observers, while message-driven specifies recipients, enhancing coordination.

Patterns and Terminologies in Reactive Programming

Reactive programming revolves around responding to external stimuli through event propagation. Streams represent sequential data elements, fundamental to reactivity. Observables emit event streams, observed by subscribers, drawing from design patterns like observer, composite, and iterator.

Using marble diagrams, Mary illustrates streams: empty timelines await events, marbles denote data, vertical lines signal completion. Backpressure management prevents overwhelming consumers. Reactive extensions (Rx) standardize these, with RxJava implementing them in Java.

A noodle shop analogy piques interest: ordering mimics reactive flows, where requests (events) trigger preparations (responses) asynchronously, handling multiple patrons without blocking.

Survey of Java Reactive Libraries: RxJava and Spring Reactor

RxJava, Netflix’s 2013 port of Microsoft’s Reactive Extensions, supports Java 6+ with backpressure in version 2 (2016). It enables declarative, functional-style programming for asynchronous data streams.

Code sample for a simple observable:

import io.reactivex.Flowable;

public class HelloWorld {
    public static void main(String[] args) {
        Flowable.fromArray(args).subscribe(System.out::println);
    }
}

This pipelines arguments into a flowable, subscribing for output.

Spring Reactor, from Pivotal, leverages Java 8 streams for cleaner APIs, fully supporting reactive streams. It integrates with Kafka, Netty, and others.

Comparative example:

// Traditional Spring MVC (blocking)
@GetMapping("/products")
public List<Product> getProducts() {
    System.out.println("Traditional way started");
    List<Product> products = productService.getProducts();
    System.out.println("Traditional way completed");
    return products;
}

// Reactive WebFlux (non-blocking)
@GetMapping(value = "/product-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Product> getProductStream() {
    System.out.println("Reactive way using Flux started");
    Flux<Product> productFlux = productService.getProductStream();
    System.out.println("Reactive way using Flux completed");
    return productFlux;
}

The reactive version returns a Flux (ticket) immediately, processing asynchronously.

RxJava partially supports reactive streams; Reactor fully, with Reactor favoring Java 8+ for elegance.

Advanced Frameworks: Akka and Vert.x

Akka, from Lightbend, embodies the actor model for event-driven, location-transparent systems. Actors handle functions isolately, with supervisors managing failures for resiliency.

Java Akka hello world:

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class HelloWorld extends AbstractActor {
    @Override
    public void preStart() {
        final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter");
        greeter.tell(Greeter.Msg.GREET, getSelf());
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals(Greeter.Msg.DONE, msg -> getContext().stop(getSelf()))
                .build();
    }
}

Scala variant condenses this, leveraging functional conciseness.

Vert.x, from Eclipse, is polyglot, supporting mixed languages. Verticles (actor-like) execute on events, with an event bus for communication.

Vert.x HTTP server:

import io.vertx.core.Vertx;

public class HelloWorldServer {
    public static void main(String[] args) {
        Vertx.vertx().createHttpServer()
                .requestHandler(req -> req.response().end("Hello World"))
                .listen(8080);
    }
}

Vert.x’s lightweight, non-container-bound nature suits diverse integrations.

Implications for Modern Software Development

Reactive approaches mitigate blocking I/O pitfalls, though database engines lag in full reactivity (e.g., R2DBC offers non-blocking connectivity, but underlying engines remain blocking). Mary advocates community participation, like her reactive meetup group, to foster learning.

In conclusion, reactive paradigms empower scalable, responsive systems, aligning software with hardware and user demands. Frameworks like RxJava, Reactor, Akka, and Vert.x provide tools for implementation, promising flexible, fault-tolerant architectures.

Links:

PostHeaderIcon [ScalaDaysNewYork2016] Perfect Scalability: Architecting Limitless Systems

Michael Nash, co-author of Applied Akka Patterns, delivered an insightful exploration of scalability at Scala Days New York 2016, distinguishing it from performance and outlining strategies to achieve near-linear scalability using the Lightbend ecosystem. Michael’s presentation delved into architectural principles, real-world patterns, and tools that enable systems to handle increasing loads without failure.

Scalability vs. Performance

Michael Nash clarified that scalability is the ability to handle greater loads without breaking, distinct from performance, which focuses on processing the same load faster. Using a simple graph, Michael illustrated how performance improvements shift response times downward, while scalability extends the system’s capacity to handle more requests. He cautioned that poorly designed systems hit scalability limits, leading to errors or degraded performance, emphasizing the need for architectures that avoid these bottlenecks.

Avoiding Scalability Pitfalls

Michael identified key enemies of scalability, such as shared databases, synchronous communication, and sequential IDs. He advocated for denormalized, isolated data stores per microservice, using event sourcing and CQRS to decouple systems. For instance, an inventory service can update based on events from a customer service without direct database access, enhancing scalability. Michael also warned against overusing Akka cluster sharding, which introduces overhead, recommending it only when consistency is critical.

Leveraging the Lightbend Ecosystem

The Lightbend ecosystem, including Scala, Akka, and Spark, provides robust tools for scalability, Michael explained. Akka’s actor model supports asynchronous messaging, ideal for distributed systems, while Spark handles large-scale data processing. Tools like Docker, Mesos, and Lightbend’s ConductR streamline deployment and orchestration, enabling rolling upgrades without downtime. Michael emphasized integrating these tools with continuous delivery and deep monitoring to maintain system health under high loads.

Real-World Applications and DevOps

Michael shared case studies from IoT wearables to high-finance systems, highlighting common patterns like event-driven architectures and microservices. He stressed the importance of DevOps in scalable systems, advocating for automated deployment pipelines and monitoring to detect issues early. By embracing failure as inevitable and designing for resilience, systems can scale across data centers, as seen in continent-spanning applications. Michael’s practical advice included starting deployment planning early to avoid scalability bottlenecks.

Links:

PostHeaderIcon [ScalaDaysNewYork2016] Lightbend Lagom: Crafting Microservices with Precision

Microservices have become a cornerstone of modern software architecture, yet their complexity often poses challenges. At Scala Days New York 2016, Mirco Dotta, a software engineer at Lightbend, introduced Lagom, an open-source framework designed to simplify the creation of reactive microservices. Mirco showcased how Lagom, meaning “just right” in Swedish, balances developer productivity with adherence to reactive principles, offering a seamless experience from development to production.

The Philosophy of Lagom

Mirco emphasized that Lagom prioritizes appropriately sized services over the “micro” aspect of microservices. By focusing on clear boundaries and isolation, Lagom ensures services are neither too small nor overly complex, aligning with the Swedish concept of sufficiency. Built on Play Framework and Akka, Lagom is inherently asynchronous and non-blocking, promoting scalability and resilience. Mirco highlighted its opinionated approach, which standardizes service structures to enhance consistency across teams, allowing developers to focus on domain logic rather than infrastructure.

Development Environment Efficiency

Lagom’s development environment, inspired by Play Framework, is a standout feature. Mirco demonstrated this with a sample application called Cheerer, a Twitter-like service. Using a single SBT command, runAll, developers can launch all services, including an embedded Cassandra server, service locator, and gateway, within one JVM. The environment supports hot reloading, automatically recompiling and restarting services upon code changes. This streamlined setup, consistent across different machines, frees developers from managing complex scripts, enhancing productivity and collaboration.

Service and Persistence APIs

Lagom’s service API is defined through a descriptor method, specifying endpoints and metadata for inter-service communication. Mirco showcased a “Hello World” service, illustrating how services expose endpoints that other services can call, facilitated by the service locator. For persistence, Lagom defaults to Cassandra, leveraging its scalability and resilience, but allows flexibility for other data stores. Mirco advocated for event sourcing and CQRS (Command Query Responsibility Segregation), noting their suitability for microservices. These patterns enable immutable event logs and optimized read views, simplifying data management and scalability.

Production-Ready Features

Transitioning to production is seamless with Lagom, as Mirco demonstrated through its integration with SBT Native Packager, supporting formats like Docker images and RPMs. Lightbend Conductor, available for free in development, simplifies orchestration, offering features like rolling upgrades and circuit breakers for fault tolerance. Mirco highlighted ongoing work to support other orchestration tools like Kubernetes, encouraging community contributions to expand Lagom’s ecosystem. Circuit breakers and monitoring capabilities further ensure service reliability in production environments.

Links: