9 ms·
Modern-Day Architecture Design Patterns for Software Professionals
- progre 6y agoAnother great one is "Service Consolidation": When you notice that some of your microservices spends most of their time chattering with each other, it's time to clump them togeather into a regular old service.
- yeswecatan 6y agoI've spent a lot of time over the past couple of months thinking about how it would be great to move to microservice architecture to help with the "ball of mud" our codebase has turned into. The benefits seem really great, but it's such a daunting hill to climb. You can't just have a couple different services and boom everything works. You need to worry about consistency, efficiency (e.g. no database joins), and so many other things. Then there's a question of how do you handle things that used to be simple-- i.e. a POST request maybe used to return an id but now it just returns 201 and that's it since you have event sourcing and the instance is eventually created. In the end, I wonder how many companies really need microservices. What if boundaries between apps were actually enforced?
- progre 6y agoYou can still have isolation of responibilities between modules, like "this module only reads and writes to that database schema". Modules combined with appropiate glue then makes a service that is "fat" in responibilities but lean in network latencies. Code reviews that also checks that module seperation is maintained really helps.
- jzoch 6y agoId go a lot further and say you should invest a ton in enforcing module boundaries automatically. Shopify's approach to writing their own package manager comes to mind - you cannot rely on code review to keep code clean. Entropy will naturally lead to boundaries broken down. If you want the separation of microservices with a network to enforce it you need robust tooling to enforce that.
- lifeisstillgood 6y agodo you have any links re that shopify package manager - google seems to confuse software and postal wrapping...
- grncdr 6y agoI believe GP is referring to https://engineering.shopify.com/blogs/engineering/enforcing-modularity-rails-apps-packwerk https://engineering.shopify.com/blogs/engineering/enforcing-... Previous discussion: https://news.ycombinator.com/item?id=24571423 https://news.ycombinator.com/item?id=24571423
- swsieber 6y agoIn java land, I have found multi-projevt gradle builds and copious tests have gotten us pretty far without needing to resort to a custom package manager.
- Tainnor 6y agomulti project gradle builds are a god-send
- Cthulhu_ 6y agoI think it's not really microservices you pine for, but it's being able to untangle said ball of mud into discrete and - more importantly - manageable codebases. 100K LOC is hard to work with, but 10K is manageable. I do think that's why developers idealize the microservices architecture; they don't want to have to keep 100K LOC in their head, or work with 10 other developers; they want to tend to their own 10K LOC garden, they want to isolate a problem space and focus on that, instead of the big picture which is too much for any one person to deal with.
- hackerfromthefu 6y agoI absolutely agree, and that's delivered by simple modular architecture over well designed interfaces. Adding runtime networking and server management complexity to that is a completely different things though!
- yeswecatan 6y agoYou're absolutely right.
- hackerfromthefu 6y agoHave a look at "refactoring legacy code" by michael feathers I think it was. The book is a bit old, about process not fad technology and the age has affected it not at all. It's describes the accurate and correct process to fix the problem you describe.
- mamcx 6y ago> efficiency (e.g. no database joins) This is WRONG. I was in a team that somehow think that could make a decent software without using postgresql as-is. Is wrong: How many devs know how implement, CORRECTLY, ACID? ALL OF ACID? Then if "remove" for "efficiency" the single piece of software that ACTUALLY implement it, CORRECTLY, what exactly them expect? Well, them were running in circles, avoiding ACID, being very efficient running 12 docker images (!) and not implementing actual features. I left because I point to this and was deemed not good fit. With relation to microservices and all their past selves (n-tiers variations) the best advice is: Use a rdbms, properly Maybe, add a cache as redis. End. This is all you need for the vast majority of apps. And it will scale, and will perform very well. If it NOT scale and not perform very well, then is MORE likely that the app code is wrong than PostgreSQL/Redis to be wrong. MORE.
- tmd83 6y agoExactly this. Even if I forgot all the complexity of distributed architecture, tons of new failure. condition, the conversion to microservice what about the efficiencies. I have quite a few core objects/tables that everyone use that anyone can join or use in their ORM mapping and what happens if they are all in a separate schema and microservice.
- decebalus1 6y agohttps://archive.is/g8bFM https://archive.is/g8bFM
- dnpp123 6y agoor, you know, https://github.com/iamadamdev/bypass-paywalls-chrome https://github.com/iamadamdev/bypass-paywalls-chrome :)
- Spearchucker 6y agoCircuit breaker is a design pattern, not an architecture pattern. Event sourcing is badly written. I'm guessing that one is supposed to look at a seperate event log instead of querying the data directly. Not understanding the Sidecar pattern either. Does L4/L7 imply L4, 5 6 and 7, or just L4 (transport layer) and L7 (application layer)? Does sidecar then simply suggest seperating application logic from cross-cutting concerns (communication, security, logging etc.)?
- anon73044 6y agoI've only ever seen the sidecar pattern described with containers. https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar https://docs.microsoft.com/en-us/azure/architecture/patterns...
- deleted 6y ago[deleted]
- legerdemain 6y agoYes, basically as you guessed. Applications receive input, manage local resources, and produce output. The sidecar proxy is their interface with the world. The proxy handles cross-cutting infrastructure concerns: service discovery, federation, distributed tracing, and so on. Blog posts about Envoy proxy as a sidecar in a service mesh context should offer plenty of examples.
- andrewstuart2 6y agoHas anybody legitimately had good experiences with microservices these days? Especially if you're not starting with a monolith that has done well? My experience at several companies, several projects, has been that what was actually just a poorly built, inflexible, monolithic application becomes a poorly built, distributed, networked, polyglot application that is now 100x less flexible. Sure you can reimplement any microservice interface any time you want and drop in the replacement, but good luck figuring out where that was being called and how many unique and interesting ways it might break if you don't implement the edge cases in the same way. Microservices and patterns like the ones in this article really add a serious amount of cost in the form of complexity, and you had better understand much better than this article explains the actual ways that your new and distributed system might fail. What happens when this circuit breaker opens and you stop creating accounts, but your transaction circuit breaker hasn't opened and because you're CQRS, you've already told your client "201 Accepted"? Be ready to deal with that. In my experience, you're much better off knowing how to build and iterate on a scalable monolithic architecture first. Built something that's good and that you can iterate on pretty easily. Figure out how to profile monolithic applications for performance and squeeze more throughput out of your system before you try your hand at splitting that architecture up and adding the myriad of distributed systems problems on top of the essential complexity. Don't underestimate the value of a compiler error or a right-click-to-refactor IDE. You don't get those when suddenly everything is loosely coupled microservices over a service mesh. There is plenty of tech to master to manage a half decent networked monolith without adding your own accidental complexity to the equation. Just to add a reference to a primary inspiration, on top of my anecdotes: https://www.martinfowler.com/bliki/MonolithFirst.html https://www.martinfowler.com/bliki/MonolithFirst.html
- kid_atticus 6y agoAt my previous workplaces: no it has always been an unmitigated disaster. And in one case I think moving from the original monolith to microservice based architecture killed the business. At my current workplace: yes! We have about a dozen separate "microservices" and it works pretty well actually. The main difference I can see is that the boundary layers are extremely well defined and completely asynchronous. There are no synchronous REST or RPC calls between services at all. And it actually works! I think the key is loose coupling in the extreme.
- legulere 6y ago> Many modern-day applications need to be built at an enterprise scale, sometimes even at an internet scale. I would argue the contrary: most applications don’t need to be built to scale. Building distributed systems (which is what scaling is about) costs a lot of effort and therefore money. Throwing more hardware at it and traditional optimization are enough for 99% of projects (you do that after a project turns out to be taking off)
- hackerfromthefu 6y agoYes, that modern day scaling is generally of aspirations rather than applications!
- nhumrich 6y agoWhat the article calls CQRS is just read replication (Its still very valid, and common), its just not called CQRS, CQRS is about actually different data representations on query and read, and is an orthogonal concept to read replicas. source: https://www.martinfowler.com/bliki/CQRS.html https://www.martinfowler.com/bliki/CQRS.html
- hackerfromthefu 6y agoFor another reference on CQRS that goes deeper than Mr Fowlers wonderful wiki, Udi Dahan did a lot of practical work and then education regarding CQRS systems
- zmmmmm 6y agoI think one of the more useful ones not mentioned would be idempotency. That is, ensure for any given message, processing it multiple times will be at least tolerated, but ideally yield identical state. This eases so many complexities of dealing with failures (it's always safe to to retry, even if the receipient may have processed your first attempt), coherency, etc etc.
- lincpa 6y agothe Grand Unified Architecture -- The Pure Function Pipeline Data Flow with Warehouse/Workshop Model https://github.com/linpengcheng/PurefunctionPipelineDataflow https://github.com/linpengcheng/PurefunctionPipelineDataflow
- _0o6v 6y agoThe "Strangler" pattern _is_ the facade pattern?
- hackerfromthefu 6y agoYes I would largely agree. One useful distinction is about the scale or context of applying the base idea - Facade is typically a code class level pattern, whereas Strangler as described here is an application or service pattern. At a scale in the middle is the DTO pattern, representing a facade on the data objects internal/external to a service.
- asim 6y agoI used to write articles like this. And I used to relish in the details of building distributed systems. No more. The reality is that monolith everyone loves to rage on about as the grand opposition to microservices is actually built on an operating system that abstracts away the details programmers before us had to deal with. And I imagine they too talked of the tradeoffs in design between design patterns. If an architecture and operating environment promotes distributed systems development then these problems go away and actually you find it's a fundamentally better experience. Unix pipes were written in a single day and they became the thing that redefined how programs were written. Imagine all your favourite tools like ls, grep, ps we're just one monolith. Holy heck no. I think microservices are waiting for the distributed operating system and development environment that makes life as easy as Unix did with C programming and bash. All these things in the article. You shouldn't have to care about.
- bibabaloo 6y ago> Imagine all your favourite tools like ls, grep, ps we're just one monolith Like BusyBox? :-)
- JackMorgan 6y agoI very much agree. Have you seen Unison, the language written by a prominent Scala author? Do you think that it provides enough abstractions for distributing processing to push it over the "tipping point"? https://www.unisonweb.org/ https://www.unisonweb.org/
- asim 6y agoFirst I'm seeing of unison, will have a look thanks. My primary language became Go when that came out, and I don't foresee myself moving to another language until there's a paradigm shift. Meaning, I think the majority of services we need will be written in Go and be exposed as very standard consumable APIs much like unix tools were with text. The shift beyond that, I think is to a language that understands a live environment of these services as opposed to yet another language that looks to replace existing languages. Basically I think Go is the last language needed on the backend for the way we write software today much as C reached its pinnacle 10-15 years ago. C program moved to Java or dynamic scripting languages for different platforms. Go dominates the Cloud and I think the platforms we program for beyond that might be something higher level. Maybe voice. Maybe something visual, who knows.
- 02020202 6y agomy 2c: when you are doing event sourcing, do it only if you push events outside of your domain. if you are within your own domain, i suggest you just store snapshots of the entity after each change, including "before" version and schema version. otherwise it is just ton of unnecessary work jsut for the sake of es. as for cqrs - if you are using es or snapshoting, you can use cqrs within single db to build "views" for various data that would otherwise require complicated queries. you just need to create schema and hook a reactor into entity post-save "event". it works incredibly well and with this ans es mentioned above, you only need to keep the "events" table(or in this case snapshots table) and you can change and rebuild your db schema any time in the future without any loss of data whatsoever.
- thatjamesdude 6y agoI am just shy of 10 years professional experience now and I have learned 1 very important lesson: You can safely ignore the opinion of anyone/anything that claims there's a "golden solution". That goes for ALL aspects of programming. EVERYTHING has a tradeoff, and it concerns me how often that pro vs con analysis is just never done. I've worked in all the flavors here: * Well designed, easy to use interfaces in a massive monolith * Poorly designed monoliths with litanies of gotchas and edge cases * Super fast microservices that "just work" * Garbage applications tightly coupled across a network layer What it all comes down to is the strength and ability of the design phase. Good engineers = good products. This shouldn't need to be said but the comments also appear to sidestep that problem with a few proclaiming "golden solutions". Be weary :)