Hacker News new | past | comments | ask | show | jobs | submit login

Will someone enlighten me as to why a microservice should have no dependent services? Seems reasonable to me.



Service dependencies indicate that you're domain is not properly broken down, or that the services are communicating incorrectly. They can share information, but probably better to do so via events and data copy.

For example, you have a centralized security service. It handles the things related to accounts, profiles and group membership. You have a recipe service. It handles things like finding recipes, adding them to "books", etc. The recipes need to be guarded. They are shown only to members of certain groups.

You could have the recipe service call the security service each time to get the caller's groups. Then compare those groups to the allowed groups. If that user service goes down, you're borked.

If you use events instead, you'd keep a copy of the profile and its groups in the recipes. Every time that changes, it gets an event with the details. Now they've decoupled by sharing data async. It is not a perfect system. It can be possible that the recipes service doesn't update. Now a user that should get the data can't.

The trade off with events is that you can upgrade and redeploy services more easily. If you find a bug in the user profile service, bring it down, update and restart. No other service goes down with it.


Thank you for the answer.

All of this makes sense but also seems unavoidable to some degree. Seems like a set of tradeoffs you make by going microservies that you should be weary of.

Having services fully state-decoupled via unified log is interesting. I’ve considered this but it seemed a bit complicated in terms of then being able to scale the services that need, say, local copies of user profiles.


It can be, heck it is difficult if you think about service having to have access to a full profile. If it is the case, that service should probably be part of the profile containing service. But you might not need the full profile.

Here's two examples. Provided you don't get much churn in key profile data, you might be able to use JWT to store group membership for example. All services can read the the token. The token provides the groups necessary for the access operation.

Another example is only copying parts of the data. My current project has profiles and memberships. Interestingly the app side code doesn't actually use that information directly. A copy of group membership is held in the DB. When the user executes any operation, the queries themselves check for rights. When a use wants to read a list of recipes, part of the query is "and has read permission". The same is true of updates. The system queries for the resource to update. Only those that the user has an explicit right to modify are found.


I prefer that the advice not to be dogmatic about saying “no” but rather to be wary of the costs. The big benefit of microservices is being able to easily reason about or scale services, but adding dependencies usually sacrifices those benefits. I’ve seen that done poorly in the various iterations of this cycle and the worst failure modes mean that debugging requires you to understand how to get & interpret state from many locations, making even simple problems challenging.

That might mean that you still take that cost willingly but engineer in the extra tooling to make things easier to manage – i.e. simplifying tracing load or errors across service boundaries back to the source – but it might also be a cue for you raise to reconsider whether the service divisions are in the right place or whether all of the services are appropriately sized. If you find yourself needed distributed transactions, retries, etc. that’s often a good time to pause and reconsider.


> The big benefit of microservices is being able to easily reason about or scale services, but adding dependencies usually sacrifices those benefits.

Thank you that makes sense.


I wouldn't say it should never happen, but if you end up with tons of dependent services you're going to be in dependency hell rather quickly. Where, only some versions of some services can be installed along side others, and when you update one component you may end up having up update almost all of them to keep the dependencies correct.


That’s right but kubernetes and helm make it easy to launch entire service stacks at a new version. That’s been my approach. Launch a new application and change DNS or ingress, etc. When satisfied, trash the old application.


I mean there's no reason you can't do that, I think that's a fine approach personally. I'm not really sure you gain much from focusing on developing tons of microservices at that point though. In general it's going to add complexity to your project, and at the end of the day you're still deploying it as one big single service so I'm not really sure you gain much from the added complexity. That said, I'm not really huge on microservices to being with, so I may not be the best one to talk to about them ;)


Definitely a good approach, I'd like to update the article to mention this as a recipe for success. The only challenge I've seen is when the old app is still doing work behind the scenes, such as running crons or dequeuing messages or whatever.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: