Ask HN: What's your biggest struggle with Microservices?
I'm working on a book about microservices and want to know what questions and topics you'd like to see covered.
What were your biggest hurdles when first adopting microservices? Was it hard for your team to determine service boundaries? Did you struggle with developing and managing them?
76 comments
[ 3.3 ms ] story [ 137 ms ] threadThis involved creating a mutually agreed upon definition of what we actually meant by "microservices". I literally repurposed paragraphs out of Sam Newman's book to do this.
As a small team, I also didn't have examples to support my argument that microservices would benefit us.
My sense is that for a small team a microservices architecture might be more trouble than it's worth, but I can definitely see how some kinds of applications - or even kinds of teams - it could be a good fit.
Handling service discovery, API gateway in ever-changing kubernetes ecosystem.
You have to start out with a monolith and only if you realise along the way that some components might work better as a service (micro or not) you should extract those. Until then, commonplace modularisation will serve you just fine.
Once you have more than 1 microservice running infrastructure becomes a huge problem. There's no real turnkey solution for deploying and running internal / on-premises microservices yet. You basically have to build monitoring, orchestration and logging infrastructure yourself.
I'm lucky that the project that I'm working on has support to use JHipster (https://jhipster.github.io/) with microservices deployed to OpenShift (https://www.openshift.com/). I used MiniShift to test my deployments, metrics, monitoring, orchestration, and logging locally. This was mostly for a proof-of-concept.
I had a system where the main running cost was MySQL. It turned out that I needed to provision a lot of MySQL capacity because there was one table that had a high rate of selects and updates.
The hot table did not use many MySQL features and could easily be handled by a key-value store with highly tuned data structures. That's a place where a "microservice" which has it's own address space, if not machine, makes it possible to scale parts of the system that need to be scaled without scaling the rest.
One table is small in terms of data but involves an interactive service that might generate 50 updates/sec at peak times.
With the "hot" service implemented on top of a key-value store, the database is the ultimate commodity, I have many choices such as in-memory with logging, off-heap storage, distributed key-value stores, etc.
The service is not "in front" of MySQL, but is on the side of it so far as the app is concerned.
The number of different services is close to the number of people on the team.
This is working very well for us, and it provides us with some welcome isolation when there are problems with one of the microservices. Maybe we can go into read-only mode or stop processing batch jobs for a while, depending on what services have problems.
But we also have good infrastructure support, which makes this a lot easier.
Just for every team that I see that has a good use case for micro services, and does the hard work of instrumentation and deployment, I see 8 teams that go with microservices because they think it's a magic bullet. Then they don't spend the time and effort necessary to get instrumentation and orchestration up and running. They don't aggregate logs, they don't spend the time to create defined contracts between the services, they don't make services robust to the failure of other services. They just complicate their debugging, deployment, uptime, and performance scenario without getting any of the benefits.
It's also a lot easier to prioritize process scheduling than it is to prioritize thread scheduling.
That statement assumes this picture:
I'm curious, what happens to the message being sent from ServiceA if Network or ServiceB is down?Testing of individual microservices in isolation is insufficient. Interaction between services has to be tested as well (because real APIs never work exactly as documented/mocked). Proper integration tests aren't any easier than testing a monolith.
There was so much fragmentation between each autonomous team that we were forced to standardize on a common framework (think of build/integration pipelines and common modules) which could almost never be changed or refactored.
The upside was that there was way more automated testing and flexibility in deployment, so overall it was a net gain.
Still, the actual ergonomics of working with the build/release system was so painful it made me leave to work somewhere where I could do actual innovation.
There was so much waste that was already 'baked into the system' and the other teams finished their work so if you had struggles with it it was your problem
That definitely does not sound like an overall net gain.
They were doing even worse before. They upgraded to a CD style pipeline to AWS instead of monolithic java apps. It was better but nobody realized there were deep and very wrong tech debt. The complacency around this was a big factor in causing me to seek new challenges.
The biggest pain points were always not the OSS stuff that was adopted, it was all the “NIH” innovations that were developed because the OSS stuff wasn’t quite right, stuff that “worked” but had no support or allowances for improvement.
1- You first mistake is wanna to (be a bomb defuser) use micro-services.
Don't
2- You second mistake is (getting close to the bomb) start building a micro-service infrastructure.
Not.
3- You third and worst mistake is believe (you can defuse the bomb safely) you can build a microservice solution correctly.
The only reason to (be a bomb-defuser) use microservices is (you are part of the police or army and somebody must do this) you ALREADY HAVE SOLVED THE MAIN THINGS FOR YOUR APP and now are in the hostile territory where micro-service truly make sense. You are facebook-alike.
Or is it better to deal with that complexity up front and then adding new services/functionality will be easy as time goes on?
When we started switching over to microservices, originally we were going to have some sort of standardized message format, which would include all of the info that service would need to do its job.
However, there were too many people building it too quickly, and it's since devolved into a spaghetti pile where almost every microservice has about 3-4 others on which it is dependent (and a handful on which those are dependent) - to query for some bit of data, set off an async task, etc. This obviously complicates the development environment significantly.
When I want to add a feature to a service it can take hours trying to bring up the correct dependencies, update their configuration, fix the errors that they're returning due to their dependencies being down, and set up the necessary databases and ssh tunnels.