<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Design Patterns on Brave New Geek</title><link>https://bravenewgeek.com/category/design-patterns/</link><description>Recent content in Design Patterns on Brave New Geek</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 03 Jan 2020 14:18:10 -0600</lastBuildDate><atom:link href="https://bravenewgeek.com/category/design-patterns/index.xml" rel="self" type="application/rss+xml"/><item><title>Microservice Observability, Part 2: Evolutionary Patterns for Solving Observability Problems</title><link>https://bravenewgeek.com/microservice-observability-part-2-evolutionary-patterns-for-solving-observability-problems/</link><pubDate>Fri, 03 Jan 2020 14:18:10 -0600</pubDate><guid>https://bravenewgeek.com/microservice-observability-part-2-evolutionary-patterns-for-solving-observability-problems/</guid><description>&lt;p&gt;In &lt;a href="https://bravenewgeek.com/microservice-observability-part-1-disambiguating-observability-and-monitoring/"&gt;part one&lt;/a&gt; of this series, I described the difference between monitoring and observability and why the latter starts to become more important when dealing with microservices. Next, we’ll discuss some strategies and patterns for &lt;em&gt;implementing&lt;/em&gt; better observability. Specifically, we’ll look at the idea of an &lt;a href="https://bravenewgeek.com/the-observability-pipeline/"&gt;observability pipeline&lt;/a&gt; and how we can start to iteratively improve observability in our systems.&lt;/p&gt;
&lt;p&gt;To recap, observability can be described simply as the ability to ask questions of your systems without knowing those questions in advance. This requires capturing a variety of signals such as logs, metrics, and traces as well as tools for interpreting those signals like log analysis, SIEM, data warehouses, and time-series databases. A number of challenges surface as a result of this. &lt;a href="https://twitter.com/clintsharp"&gt;Clint Sharp&lt;/a&gt; does a great job &lt;a href="https://cribl.io/blog/the-observability-pipeline/"&gt;discussing&lt;/a&gt; the key problems, which I’ll summarize below along with some of my own observations.&lt;/p&gt;</description></item><item><title>The Observability Pipeline</title><link>https://bravenewgeek.com/the-observability-pipeline/</link><pubDate>Wed, 12 Sep 2018 11:37:24 -0500</pubDate><guid>https://bravenewgeek.com/the-observability-pipeline/</guid><description>&lt;p&gt;The rise of cloud and containers has led to systems that are much more distributed and dynamic in nature. Highly elastic microservice and serverless architectures mean containers spin up on demand and scale to zero when that demand goes away. In this world, servers are very much cattle, not pets. This shift has exposed deficiencies in some of the tools and practices we used in the world of servers-as-pets. It has also led to new tools and services created to help us support our systems.&lt;/p&gt;</description></item><item><title>Building a Distributed Log from Scratch, Part 5: Sketching a New System</title><link>https://bravenewgeek.com/building-a-distributed-log-from-scratch-part-5-sketching-a-new-system/</link><pubDate>Tue, 23 Jan 2018 12:08:53 -0600</pubDate><guid>https://bravenewgeek.com/building-a-distributed-log-from-scratch-part-5-sketching-a-new-system/</guid><description>&lt;p&gt;In &lt;a href="https://bravenewgeek.com/building-a-distributed-log-from-scratch-part-4-trade-offs-and-lessons-learned/"&gt;part four&lt;/a&gt; of this series we looked at some key trade-offs involved with a distributed log implementation and discussed a few lessons learned while building NATS Streaming. In this fifth and final installment, we’ll conclude by outlining the design for a new log-based system that draws from the previous entries in the series.&lt;/p&gt;
&lt;h3 id="the-context"&gt;The Context&lt;/h3&gt;
&lt;p&gt;For context, &lt;a href="https://nats.io/"&gt;NATS&lt;/a&gt; and &lt;a href="https://nats.io/documentation/streaming/nats-streaming-intro/"&gt;NATS Streaming&lt;/a&gt; are two different things. NATS Streaming is a log-based streaming system built on top of NATS, and NATS is a lightweight pub/sub messaging system. NATS was originally built (and then open sourced) as the control plane for Cloud Foundry. NATS Streaming was built in response to the community’s ask for higher-level guarantees—durability, at-least-once delivery, and so forth—beyond what NATS provided. It was built as a separate layer on top of NATS. I tend to describe NATS as a dial tone—ubiquitous and always on—perfect for “online” communications. NATS Streaming is the voicemail—leave a message after the beep and someone will get to it later. There are, of course, more nuances than this, but that’s the gist.&lt;/p&gt;</description></item><item><title>Take It to the Limit: Considerations for Building Reliable Systems</title><link>https://bravenewgeek.com/take-it-to-the-limit-considerations-for-building-reliable-systems/</link><pubDate>Tue, 20 Dec 2016 19:55:52 -0600</pubDate><guid>https://bravenewgeek.com/take-it-to-the-limit-considerations-for-building-reliable-systems/</guid><description>&lt;p&gt;Complex systems usually operate in failure mode. This is because a complex system typically consists of many discrete pieces, each of which can fail in isolation (or in concert). In a microservice architecture where a given function potentially comprises several independent service calls, &lt;em&gt;high&lt;/em&gt; availability hinges on the ability to be &lt;em&gt;partially&lt;/em&gt; available. This is a core tenet behind resilience engineering. If a function depends on three services, each with a reliability of 90%, 95%, and 99%, respectively, partial availability could be the difference between 99.995% reliability and 84% reliability (assuming failures are independent). Resilience engineering means designing with failure as the normal.&lt;/p&gt;</description></item><item><title>Iris Decentralized Cloud Messaging</title><link>https://bravenewgeek.com/iris-decentralized-cloud-messaging/</link><pubDate>Tue, 22 Jul 2014 22:34:31 -0600</pubDate><guid>https://bravenewgeek.com/iris-decentralized-cloud-messaging/</guid><description>&lt;p&gt;A couple weeks ago, I published a rather extensive &lt;a href="http://www.bravenewgeek.com/dissecting-message-queues/"&gt;analysis&lt;/a&gt; of numerous message queues, both brokered and brokerless. Brokerless messaging is really just another name for peer-to-peer communication. As we saw, the difference in message latency and throughput between peer-to-peer systems and brokered ones is several orders of magnitude. ZeroMQ and nanomsg are able to reliably transmit &lt;em&gt;millions&lt;/em&gt; of messages per second at the expense of guaranteed delivery.&lt;/p&gt;
&lt;p&gt;Peer-to-peer messaging is decentralized, scalable, and fast, but it brings with it an inherent complexity. There is a dichotomy between how brokerless messaging is conceptualized and how distributed systems are actually &lt;em&gt;built&lt;/em&gt;. Distributed systems are composed of services like applications, databases, caches, etc. Services are composed of instances or nodes—individually addressable hosts, either physical or virtual. The key observation is that, conceptually, the unit of interaction lies at the &lt;em&gt;service level&lt;/em&gt;, not the instance level. We don’t care about &lt;em&gt;which&lt;/em&gt; database server we interact with, we just want to talk to &lt;em&gt;a&lt;/em&gt; database server (or perhaps multiple). We’re concerned with logical groups of nodes.&lt;/p&gt;</description></item><item><title>A Look at Nanomsg and Scalability Protocols (Why ZeroMQ Shouldn’t Be Your First Choice)</title><link>https://bravenewgeek.com/a-look-at-nanomsg-and-scalability-protocols/</link><pubDate>Sun, 29 Jun 2014 20:44:34 -0600</pubDate><guid>https://bravenewgeek.com/a-look-at-nanomsg-and-scalability-protocols/</guid><description>&lt;p&gt;Earlier this month, I &lt;a href="http://www.bravenewgeek.com/distributed-messaging-with-zeromq/" title="Distributed Messaging with ZeroMQ"&gt;explored ZeroMQ&lt;/a&gt; and how it proves to be a promising solution for building fast, high-throughput, and scalable distributed systems. Despite lending itself quite well to these types of problems, ZeroMQ is not without its flaws. Its creators have attempted to rectify many of these shortcomings through spiritual successors &lt;a href="https://github.com/crossroads-io/libxs"&gt;Crossroads I/O&lt;/a&gt; and &lt;a href="http://nanomsg.org/"&gt;nanomsg&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The now-defunct Crossroads I/O is a proper fork of ZeroMQ with the true intention being to build a viable commercial ecosystem around it. Nanomsg, however, is a &lt;em&gt;reimagining&lt;/em&gt; of ZeroMQ—a complete rewrite in C ((The author &lt;a href="http://250bpm.com/blog:4"&gt;explains why&lt;/a&gt; he should have originally written ZeroMQ in C instead of C++.)). It builds upon ZeroMQ’s rock-solid performance characteristics while providing several vital improvements, both internal and external. It also attempts to address many of the strange behaviors that ZeroMQ can often exhibit. Today, I’ll take a look at what differentiates nanomsg from its predecessor and implement a use case for it in the form of service discovery.&lt;/p&gt;</description></item><item><title>Distributed Messaging with ZeroMQ</title><link>https://bravenewgeek.com/distributed-messaging-with-zeromq/</link><pubDate>Wed, 11 Jun 2014 16:56:03 -0600</pubDate><guid>https://bravenewgeek.com/distributed-messaging-with-zeromq/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“A distributed system is one in which the failure of a computer you didn’t even know existed can render your own computer unusable.” -Leslie Lamport&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the increased prevalence and accessibility of cloud computing, distributed systems architecture has largely supplanted more monolithic constructs. The implication of using a service-oriented architecture, of course, is that you now have to deal with a myriad of difficulties that previously never existed, such as fault tolerance, availability, and horizontal scaling. Another interesting layer of complexity is providing consistency across nodes, which itself is a problem surrounded with endless research. Algorithms like &lt;a href="http://en.wikipedia.org/wiki/Paxos_(computer_science)"&gt;Paxos&lt;/a&gt; and &lt;a href="https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf"&gt;Raft&lt;/a&gt; attempt to provide solutions for managing replicated data, while other solutions offer eventual consistency.&lt;/p&gt;</description></item><item><title>Modularizing Infinitum: A Postmortem</title><link>https://bravenewgeek.com/modularizing-infinitum-a-postmortem/</link><pubDate>Thu, 27 Dec 2012 16:04:16 -0600</pubDate><guid>https://bravenewgeek.com/modularizing-infinitum-a-postmortem/</guid><description>&lt;p&gt;In addition to getting the code migrated from &lt;a href="https://code.google.com/p/infinitum-framework/"&gt;Google Code&lt;/a&gt; to &lt;a href="https://github.com/infinitumframework"&gt;GitHub&lt;/a&gt;, one of my projects over the holidays was to modularize the Infinitum Android framework I’ve been working on for the past year.&lt;/p&gt;
&lt;p&gt;Infinitum began as a SQLite ORM and quickly grew to include a REST ORM implementation,  REST client, logging wrapper, DI framework, AOP module, and, of course, all of the framework tools needed to support these various functionalities. It evolved as I added more and more features in a semi-haphazard way. In my defense, the code was organized. It was logical. It made &lt;em&gt;sense&lt;/em&gt;. There was no method, but there also was no madness. Everything was in an appropriately named package. Everything was coded to an interface. There was no duplicated code. However, modularity — in terms of minimizing framework dependencies — wasn’t really in mind at the time, and the code was all in a single project.&lt;/p&gt;</description></item><item><title>The Importance of Being Idle</title><link>https://bravenewgeek.com/the-importance-of-being-idle/</link><pubDate>Wed, 19 Dec 2012 19:12:36 -0600</pubDate><guid>https://bravenewgeek.com/the-importance-of-being-idle/</guid><description>&lt;p&gt;&lt;em&gt;“Practice not-doing and everything will fall into place.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It’s good to be lazy. Sometimes, in programming, it can also be hard to be lazy. It’s this paradox that I will explore today — The Art of Being Lazy. Specifically, I’m going to dive into a design pattern known as lazy loading by discussing why it’s used, the different flavors it comes in, and how it can be implemented.&lt;/p&gt;
&lt;p&gt;Lazy loading is a pretty simple concept: don’t load something until you really need it. However, the philosophy can be generalized further: don’t do something until you need to do it. It’s this line of thinking that has helped lead to processes like &lt;a href="http://en.wikipedia.org/wiki/Kanban_(development)"&gt;Kanban&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Lean_software_development"&gt;lean software development&lt;/a&gt; (and also probably got you through high school). Notwithstanding, this tenet goes beyond the organizational level. It’s about optimizing efficiency and minimizing waste. There’s a lot to be said about optimizing efficiency in a computer program, which is why The Art of Being Lazy is an exceedingly relevant principle.&lt;/p&gt;</description></item><item><title>Proxies: Why They’re Useful and How They’re Implemented</title><link>https://bravenewgeek.com/proxies-why-theyre-useful-and-how-theyre-implemented/</link><pubDate>Mon, 17 Dec 2012 17:22:52 -0600</pubDate><guid>https://bravenewgeek.com/proxies-why-theyre-useful-and-how-theyre-implemented/</guid><description>&lt;p&gt;I wanted to write about lazy loading, but doing so requires some background on proxies. Proxies are such an interesting and useful concept that I decided it would be worthwhile to write a separate post discussing them. I’ve talked about them in the past, for instance on &lt;a href="http://stackoverflow.com/a/10239705/210070"&gt;StackOverflow&lt;/a&gt;, so this will be a bit of a rehash, but I will go into a little more depth here.&lt;/p&gt;
&lt;p&gt;What is a proxy? Fundamentally, it’s a broker, or mediator, between an object and that object’s user, which I will refer to as its client. Specifically, a proxy intercepts calls to the object, performs some logic, and then (typically) passes the call on to the object itself. I say &lt;em&gt;typically&lt;/em&gt; because the proxy could simply intercept without ever calling the object.&lt;/p&gt;</description></item><item><title>Solving the Referential Integrity Problem</title><link>https://bravenewgeek.com/solving-the-referential-integrity-problem/</link><pubDate>Sat, 01 Dec 2012 13:37:46 -0600</pubDate><guid>https://bravenewgeek.com/solving-the-referential-integrity-problem/</guid><description>&lt;p&gt;&lt;em&gt;“A man with a watch knows what time it is. A man with two watches is never sure.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I’ve been developing my open source Android framework, &lt;a href="http://code.google.com/p/infinitum-framework/"&gt;Infinitum&lt;/a&gt;, for the better part of 10 months now. It has brought about some really interesting problems that I’ve had to tackle, which is one of the many reasons I enjoy working on it so much.&lt;/p&gt;
&lt;h3 id="chicken-or-the-egg"&gt;Chicken or the Egg&lt;/h3&gt;
&lt;p&gt;Although it’s much more now, Infinitum began as an object-relational mapper which was loosely modeled after &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;. One of the first major issues I faced while developing the ORM component was loading object graphs. To illustrate what I mean by this, suppose we’re developing some software for a department store. The domain model for this software might look something like this:&lt;/p&gt;</description></item></channel></rss>