Live data from Hacker News

Starting with microservices

arnoldgalovics.com

61–70 of 139 posts

Re: Starting with microservices

#61

I've come to the conclusion that microservices as usually implemented are simply a Conway's law concern. We haven't had a great track record defining the semantics of component boundaries, but http is both simple enough that it constricts code flow in a particular way leaving a lot of misunderstandings and bike shedding discussions off of the table, and is the ligua franca for external services owned by other orgs so…

Spot on. Microservices is a way of scaling people. There are other ways of scaling systems.

I would suggest that http not be the go-to mechanism for communicating between microservices. Each should be able to operate to some degree without hard dependencies. If you build using microservices with RPC over http or what-have-you replacing function calls, you've done it wrong. You can usually tell if your 'bounded context' is of the form noun-service or adjective-noun-service. Usually the context boundary should be a process (workflow kind) that serves a user type. Reliable one-way async datastreams are more useful for keeping microservices fed with the information it needs, and it can decide how to utilize that information in a way that makes sense for that service. If you have core 'source of truth' services used by many others, you have a distributed monolith.

Re: Starting with microservices

#62
Companies that aren’t B2D have a hard time with monolithic architecture. They simply have too many disparate needs, teams, vendors, and timelines to try to force everyone to share a codebase, unit of deployment, and set of endpoints. The supply side and demand side of any business has vastly different objectives, SLAs and priorities. Should we have to wait two weeks to deploy a minor patch to the Purchase Order portal because there is a risky ecommerce deployment that needs to be finalized first? Do we need to scale up the web servers to batch process some nightly data?

Surely there are excesses in the realm of microservice architecture… “every library is a microservice…” is advice I’ve read in the past. Service discovery / routing isn’t easy. Naming things is hard.

Personally I prefer the term Service and try to make no prescriptions as to what size it will end up being.

Re: Starting with microservices

#63
The example given, of adding new instances of a session service that consumes from a Kafka topic, is completely wrong.

Kafka producers use a partition key of your choice, so the UserLoggedInEvent and UserActivityEvent that relate to the same userId will always be written to same partition. This is how horizontal scaling of Kafka consumers works, without ordering problems. Anyone that isn't aware of this has very limited experience with Kafka and event-driven microservices.

I respect the author's attempt to give some balance, but I think some parts aren't well informed.

It's important to understand the benefits of microservices AND the costs. Small focused projects have small, fast test suites, can be wholly owned and developed by a single team amongst many, can be released and deployed without fear of breaking unrelated features across a vast platform, can be retired easily when obsolete. They also introduce the complexity of communication across many systems to complete an end-to-end journey, and require incredibly careful design and carefully chosen boundaries and responsibilities if you want to allow each one to evolve independently. This takes time and experience, and many organisations get themselves into a big mess with no governance, consistency or cohesion across a confusing sea of services and teams.

There's no free lunch, but let's get beyond fashion-driven lurching from one extreme to another. This cycle of having a few years where the costs of an approach aren't acknowledged, to a few years where the benefits aren't acknowledged, is very lame.

Re: Starting with microservices

#64
post #19

I have done the full theme park ride on monolith->microservices->monolith. Both have ups and downs. The most important thing I learned is that "microservices" in absolutely no way necessitates "bullshit spread across multiple cloud vendors and other scenarios involving more than 1 computer". What part of microservices says things must be separated by way of an arbitrary wire protocol? We now have a "monolith" (proces…

Pretty clearly the pros and cons come down to the application and necessary stability. Need ultra stable? More and smaller microservices usually better. Need fairly stable? Bigger services is fine. Need it to work generally? Build it however you can.

> Need ultra stable? More and smaller microservices usually better.

I don't think I agree with this statement. "More and smaller" also means potentially more routing and communication paths, thus increased latency and complexity.

Re: Starting with microservices

#65
post #53

Earlier quoted context omitted.

Pretty sure microservices will be remembered as a horribly convoluted stop gap once we have better language modularization. They encourage modular patterns which is usually good, but all that plumbing will eventually become unnecessary. I can’t help but remember building 6 versions of each class in the old ejb days whenever I hear microservices hype.

Example of better language modularization? Who is working on this?

Perhaps some idea and abstractions from Erlang could be interesting to explore in more mainstream languages?

Re: Starting with microservices

#66
post #35
post #10

I have a theory that auto-wired Dependency Injection in a single DI container is partly to blame for monolith spaghetti. Once an app reaches a certain size and anything can depend on anything else, reasoning about the whole can become difficult. I think there is value in wiring a monolith together in such a way that each course grained subcomponent exposes a constrained interface into the rest of the system (payments…

I notice there's a lot of comments here saying this exact same thing, and it's also what seems most sensible to me. Yet microservices are getting all the hype. Should be hype a thorough modular design more?

Yes, but microservices maximize cloud vendors' revenue compared to monoliths.

Re: Starting with microservices

#67
I’m going to be the contrarian in this discussion. I think microservices are awesome and I’ve deployed architectures in anger in both Java and Go. 100% would (and will) do it again.

Most of the problems people are talking about seem to be around using microservices inappropriately, without sufficient preparation, or when an application is not complex enough to benefit from it.

Microservices are not a panacea any more than any other architecture. Properly implemented, they have significant strengths vs monoliths, but require experience to get right.

Properly implemented monoliths built by experienced developers are likely to strongly resemble microservices but without some of the advantages that I enjoy.

As others have said, it’s not all or nothing, one or the other, but I don’t get the hate for microservices here.

Re: Starting with microservices

#68
post #19

I have done the full theme park ride on monolith->microservices->monolith. Both have ups and downs. The most important thing I learned is that "microservices" in absolutely no way necessitates "bullshit spread across multiple cloud vendors and other scenarios involving more than 1 computer". What part of microservices says things must be separated by way of an arbitrary wire protocol? We now have a "monolith" (proces…

Currently at my day job, we have a monolithic code base with multiple entry points. If you update a library, you have to update the client or keep the changes backwards compatible. I really prefer this over multiple micro services.

I’ve done monoliths and microservices. Having a monolithic codebase with many entry points is my preferred.

Re: Starting with microservices

#69
post #48
post #10

I have a theory that auto-wired Dependency Injection in a single DI container is partly to blame for monolith spaghetti. Once an app reaches a certain size and anything can depend on anything else, reasoning about the whole can become difficult. I think there is value in wiring a monolith together in such a way that each course grained subcomponent exposes a constrained interface into the rest of the system (payments…

In theory it all sounds great and makes total sense but when the company grows to a billion dollar firm and hires engineers to work on the said monolith thats when things breakdown. The founding team was a closet knit team and ensure there is no spaghetti code but the moment you move on from that closely knit group its hard to enforce constraints. Have worked at multiple companies that started out as a monolith and a…

[deleted]

Re: Starting with microservices

#70
post #19

I have done the full theme park ride on monolith->microservices->monolith. Both have ups and downs. The most important thing I learned is that "microservices" in absolutely no way necessitates "bullshit spread across multiple cloud vendors and other scenarios involving more than 1 computer". What part of microservices says things must be separated by way of an arbitrary wire protocol? We now have a "monolith" (proces…

Yeah, the biggest problem that people get into with microservices is that they allow the communication structure to dictate the app structure. A monolith gives you some refactorability because you can run what would have been "integration" tests locally, as you massage your module boundaries to match the problem that you're solving. So a monolith can become a clean monolith, and then a clean monolith can maybe become microservices if you need the scale attributes.

The basic problem is that before you know where the module boundary is, you cannot have a clear module boundary. So three popular approaches emerge:

(a) DDD "milliservices". Basically define the different sorts of users, come up with a clustering of the different sorts of people that you think will be using your app. People are considered to be in the same cluster if they use the same jargon to refer to things, or different clusters if they both use some word but they both mean subtly different things by it.

(b) Gut-feeling microservices that become feature microservices. I should probably have an "auth service," I don't know what it does but I'm going to be doing auth so that's probably a service. I need to import a git library to contact GitHub, probably there should be a "git service" that handles all communication to GitHub or other git repos. Each of these things exposes some swagger/openAPI docs, maybe we should have a docs service? -- that sort of thing. The danger is that the things that are easy to break off are usually not the core competency of the product, and so there emerges some sort of "core services," one or two big honkers that basically are monoliths. People are aware that they aren't supposed to keep adding to the core services and so new services emerge named after feature requests, hello "sharing service," hello "wallet service." Except the core usually is tightly coupled to these new feature services and they all kind of connect to each other. The idea of splitting the core services into other services to fit the newfound module boundaries becomes complicated by all these ties to nearby features, you are not actually loosely coupled because you do RPCs and you probably code in the expectation of success into these RPCs like method calls.

(c) Every noun becomes a "nanoservice". This is a service that watches just one or two tables (or NoSQL document types or what have you) and exposes a CRUD API for that noun, plus a couple auxiliary verbs to do actual business needs with those nouns. So if you were implementing Git there would be a file service, a tree service, a branch service, a commit service, probably a working tree service... But you just have to "know" that logs and rebases and cherrypicks live in CommitService while diffing for some reason lives in TreeService and adding a file to your working tree requires first creating it in FileService and then handing that link off to the WorkingTreeService which will make needed calls to TreeService, creating your own tree is exposed via TreeService's CRUD but the developers tell you that down that road There Be Dragons and you should not have been messing with that.

Any of these three can be successful but only insofar as you can create new module boundaries and move module boundaries and test to make sure that your users will not notice any performance regressions. Of them I would only recommend option (a), because it gives a really nice place for these tests to live and an intuition that each test should document a user journey for the system.

Post reply on HN