News for hackers. Stuff that matters.
Re:Why Segment Went Back to a Monolith by kkapelon on Wednesday April 29, 2020 @06:38AM (#23017615)
>Shared libraries were created to provide behavior that was similar for all workers. However, this created a new bottleneck, where changes to the shared code could require a week of developer effort, mostly due to testing constraints.

That is a big red flag. Microservices that suffer from shared code changes are not really microservices, but a distributed monolith instead.

Re:Why Segment Went Back to a Monolith by pjc50 on Wednesday April 29, 2020 @07:01AM (#23017767)
This is really a time-of-binding argument; the difference between a "library" and a "service" is that one is in-process and accessed over function calls, and the other is out-process and accessed over RPC.

If you change code that other services are using, you can break those other services. No way round that.

Re:Why Segment Went Back to a Monolith by zzbzq on Wednesday April 29, 2020 @02:14PM (#23022343)
There are circumstances where they are equivalent, but they're very different overall. Namely, if you use a service, you update it once and see the new behavior everywhere. If you use a shared library, you have to update and redeploy every service. Libraries are strictly inferior in that scenario. This sounded, to me, like it was Segment's problem. They were updating shared libraries all over the place all the time.

I generally avoid creating shared libraries, they're a trap. They have a very narrow band of usefulness squeezed in between the more palatable solutions of creating new services or just copy & pasting code and allowing it to diverge for each different use-case.

Re:Why Segment Went Back to a Monolith by Autowired on Wednesday April 29, 2020 @09:06AM (#23018618)
While that is true, a microservices architecture can (and in my opinion should) rely on messaging and account for message schema evolution. Dependencies between services should be way less coupling than dependencies between an application and a library.
Re:Why Segment Went Back to a Monolith by caust1c on Wednesday April 29, 2020 @10:07AM (#23019380)
Schema evolution is just as big of a dependency hell as managing direct library dependencies. With a monolithic architecture, a lot of those concerns are contained within the context of a single repo, and can be tested much more easily than with many repos.
Re:Why Segment Went Back to a Monolith by marcosdumay on Wednesday April 29, 2020 @10:46AM (#23019885)
A library API can rely on versioning and account for schema evolution too. Even different versions can coexist if you decide that's important from the beginning (what is the same requirement as with services).

The only real difference is that services have a slow serialized network interface that fails 4 or 5 orders of magnitude more often than libraries, but can migrate over memory domains.

Re:Why Segment Went Back to a Monolith by barrkel on Wednesday April 29, 2020 @07:31AM (#23017937)
Sharing code or reinventing the wheel repeatedly is inevitable once you have more than one concern by which you can divide services.

For example: let's say you have lots of integrations, and you need to scale compute, and parse and generate common data sent to and from the integrations.

You can either have a monolithic integration service which you scale out on load; or you can have integration-specific services that scale out on load and share your data parsing & generation library. Due to multiple concerns, there's no "best slice".

FWIW, scaling out compute is a stronger argument to me for a service boundary than responsibility segregation. Scaling out requires distribution; scaling up complexity doesn't, though it can help for other reasons, like CI/CD. I prefer FaaS architectural patterns with the freedom to share libraries in different functions (images) to services, especially if long-running state is not needed.

Re:Why Segment Went Back to a Monolith by kkapelon on Wednesday April 29, 2020 @11:13AM (#23020205)
Sorry for not being clear.

Having a shared library is not a bad thing on its own. Making the library a bottleneck is the anti-pattern.

If you wish to have a shared-library of microservices you should be prepared to have multiple versions of it running at the same time without any pressure to update everything at once.

If your shared library is the bottleneck, it means that your microservices are tighly coupled (hence the distributed monolith)

Re:Why Segment Went Back to a Monolith by jmilloy on Wednesday April 29, 2020 @09:40AM (#23018992)
That just sounds like the shared libraries needed to make breaking changes less often. If you're going to make changes to core code, it's going to take time to get everything up to date no matter how your code is organized. In other words, shared code needs to be treated just like a third-party library/service (both from the developers and users points of view).
Re:Why Segment Went Back to a Monolith by gowld on Wednesday April 29, 2020 @12:12PM (#23020869)
One view is that the difference between a service and a microservice is that a microservice can be sketched between being a local library or wrapped in an RPC server.
Re:Why Segment Went Back to a Monolith by jmilloy on Wednesday April 29, 2020 @12:16PM (#23020911)
> can be sketched

What does that mean?

Re:Why Segment Went Back to a Monolith by dx034 on Wednesday April 29, 2020 @06:52AM (#23017708)
Reinventing all parts for every microservice sounds wasteful to me. Especially if they handle the same data and/or use the similar business logic.
Re:Why Segment Went Back to a Monolith by kminehart on Wednesday April 29, 2020 @08:37AM (#23018341)
A common practice is to introduce services that handle shared functionality.

One common example is, instead of having a shared library that reads & verifies JWTs, use a gateway service that handles this before requests reach the upstream service.

This means changes to your organization's JWT code will only require a redeployment of one service, the JWT Auth service.

Re:Why Segment Went Back to a Monolith by dx034 on Wednesday April 29, 2020 @12:22PM (#23020981)
But that also for input handling, formatting or simple business libraries? Sure you could implement that as services but that would probably result in up to a hundred service calls for one customer interaction. Maybe it looks clean from an architecture perspective but I can't imagine how that'll result in a good user experience.
Re:Why Segment Went Back to a Monolith by kkapelon on Wednesday April 29, 2020 @11:15AM (#23020228)
Let me clarify because I wasn't clear in the parent comment.

Microservices using shared libraries -> ok

Microservices "suffering" from shared libraries -> not ok.

Re:Why Segment Went Back to a Monolith by MaxBarraclough on Wednesday April 29, 2020 @06:43AM (#23017644)
That sounds like an overly broad generalisation.

They might well all share the same basic framework code, of course. Why not share code for recurring concerns like auth?

Re:Why Segment Went Back to a Monolith by bauerd on Wednesday April 29, 2020 @06:53AM (#23017709)
Idea is that you have a service that authorizes transactions
Re:Why Segment Went Back to a Monolith by klohto on Wednesday April 29, 2020 @06:54AM (#23017726)
Because if you share something (like auth for example), you should have microservice for that. The question is not about duplicate code, but about duplicate libraries that handle the same thing. Decoupling the auth process into separate microservice removes the bottleneck.
Re:Why Segment Went Back to a Monolith by alkonaut on Wednesday April 29, 2020 @07:01AM (#23017763)
Eventually you'll have a service to format phone numbers in the format that the company needs to be standard across all services.

If you don't want to do that, then you need a simple shared library for that.

The problem is that there is no easy way to draw the line between "this is obviously a trivial library function we should just link into our code" and "this is something we can't share because it would create friction or break our isolation".

Auth is obviously a "service" but phone number formatting as a service seems extreme.

Re:Why Segment Went Back to a Monolith by curryst on Wednesday April 29, 2020 @11:13AM (#23020195)
One of the lines is going to be acceptable performance. Your phone number formatting microservice is going to be orders of magnitude slower than a client library.

The auth service will likely have to hit a DB anyways. Assuming the microservice call has roughly the same network latency as the DB call and the DB has 0 response time, it would double the total time to perform the auth. It only gets more favorable as DB response times go up.

More generally, I think microservices make sense in scenarios where the time to process the request is longer than the network latency incurred by making it a microservice. Things that have to hit a DB are generally okay. Pure functional things that just compute on CPU and RAM are generally not, unless they're very computationally expensive like running a simulation or something like that.

Re:Why Segment Went Back to a Monolith by jmt_ on Wednesday April 29, 2020 @12:14PM (#23020886)
I'm reminded of the classic problem of static utility classes, where you have functions for say formatting phone numbers, or computing a commonly occurring simple mathematical function. It can be difficult to figure out how to better modularize the functionality provided by this class, the motivation typically being having a large static utility class often violates the principle of a class having a clear, single responsibility. Breaking up a large static class into other static classes that better encapsulate some functionality/concept can help but isn't always the best solution.

So lets say we have shared code for doing something like phone formatting. My question for more experienced microservice practitioners is -- does it make sense to create a microservice for preprocessing data in general? Phone number-formating-as-a-service is excessive but creating a microservice for processing data where phone number formatting is just one aspect of this service makes sense to me. All other services can throw data at the data processing service and get data back in some sort of standard and expected way conforming to whatever business logic/processing rules required.

Re:Why Segment Went Back to a Monolith by gridlockd on Wednesday April 29, 2020 @09:37AM (#23018926)
> Auth is obviously a "service" but phone number formatting as a service seems extreme.

You clearly haven't finished drinking your Kool-Aid yet.

Re:Why Segment Went Back to a Monolith by NewEntryHN on Wednesday April 29, 2020 @06:09PM (#23025046)
If you have zero coupling, it means you have multiple products.
Re:Why Segment Went Back to a Monolith by gitgud on Wednesday April 29, 2020 @08:44AM (#23018406)
A good architecture is orthogonal, meaning parts can scale independently...

Shared code shackles everything together, like global variables...

Re:Why Segment Went Back to a Monolith by gridlockd on Wednesday April 29, 2020 @07:13AM (#23017829)
> Microservices that suffer from shared code changes are not really microservices, but a distributed monolith instead.

In other words, if you can share a lot of code between services, a monolith is actually an appropriate architecture.