Go Micro: a standard library for distributed systems development
github.com
github.com
go-micro seems like it does a bit too much, like service discovery and balancing within the framework when that's likely better handled by an Envoy/Istio.
Sidecar proxies also have the fatal flaw that they can't propagate a distributed trace, so if incoming RPC call triggers outgoing calls (common in microservices, for better or for worse), then you lose the link between them. To do that, your application has to remember the trace ID and pass it along from the server to the client. For reasons like that, I'm kind of bearish on premade service meshes. But, they are OK for mTLS.
gRPC has added a lot of code in recent years to support xDS, which lets clients discover endpoints, load assignments, locality, etc. and lets your app do the right thing without an intermediate proxy. It can just connect directly to the control plane and make the same routing decisions a proxy would. That's the ideal situation to me.
I've also seen it cause a lot of pain during upgrades since upgrading the service framework is implicitly upgrading so many other components and the framework is probably not being diligent about only improving one component (ex. Auth) per release. Sometimes that leads to basically never upgrading to avoid the risk.
It's true you need to do propagation for tracing but open telemetry has pretty broad support these days. That cost seems worth the stability and control.
Netflix eventually moved away from HTTP+JSON to gRPC for backend services, and also started to expose internal DNS-based service discovery. This removed the need for that sidecar from _most_ places, since you could just generate code from protobufs, but it created other problems. Specifically, it was hard to apply the same resiliency patterns across multiple languages when calling those APIs, and so that would then contribute to weird incidents.
I'm not there anymore, but last context I have is that things are moving to an Envoy-based model now. The idea is that everything will use the sidecar, and resiliency patterns will be baked in at that layer. I suspect that'll be a better architecture in the long run.
> also started to expose internal DNS-based service discovery. Then this is similar to Consul-based service discovery. In that case, do you know how Netflix continued to support their client-defined routing rules, like selecting a specific set of nodes of a given service to route traffic to? I'd imagine that the number of IP addresses in an ARecord is limited too, so a service won't retrieve the entire list of IPs from a DNS record?
This is common even in xDS implementations; client services don't need to know every possible endpoint.
~25 direct dependencies is too many
Firstly it's a security problem: not only have to vet this code, but also all the dependencies, and all their dependencies. It's going to be be quicker to just write the bits of this lib that I need (especially if I can copy/paste the tricky bits from here).
Secondly, it shows that the maintainer wasn't being careful about their deps. That when they see a problem, they hunt for a solution that looks like it fits rather than really trying to dig in to the problem and grok it and work out the best solution. I'm all for not re-inventing the wheel, but you have to understand your load, your road surface, your motive force and your steering mechanism before deciding on a wheel design. Adding a cartwheel to a Formula 1 race car is not going to bring the happy faces. Too many dependencies is a sign of lazy thinking
Sounds like a big red flag of unnecessary depedency bloat.
Or see also: https://medium.com/code-zen/why-i-don-t-use-go-web-framework... (or any of the dozens of blogs of people indicating why you dont need a framework for go)
Further it turns some straight forward business logic in to some cultish bulshittery of endless packages, classes, annotations and so on. But hey, there is no xml config now, so it all is super modern stuff.
Just yesterday, I had to look into perf issue of Spring based project. It has probably 500 line of core business logic. But it is littered in tens of packages and dozens of java source files.
So it is standardization for sure but it does not seem to be leading to better results. It is however giving a great cover for bad stuff because now code follows all best practices as per Spring framework.
I emphasize the age of Go because I don't think this is a virtue of the language per se (considered as a bag of features), or because the developers were super geniuses who could see what nobody else could. It's just that net/http was able to be spec'd and put into the standard library based on the decades of experiences other languages had. I would expect any other upcoming languages to be able to pull off a similar trick, as long as they try.
I certainly don't sit down with every Go web app I write with literally nothing but the standard library. I do have some non-trivial code written that way, but it isn't something I seek out as a terminal goal. It just isn't necessary to go commit to "Spring" or "Ruby on Rails" or some other framework just to get access to anything at all. I'm already in the Go ecosystem just by using net/http, you're not obligated to commit to a "framework"'s ecosystem just to get access to basic functionality because you're all but already tied in to a framework's ecosystem just by using Go, and there are many options for that basic functionality.
And to be clear, I'm more agreeing with you than disagreeing with you; I'm trying to explain the divergence between your understanding and what the Go ecosystem has because I consider it a worthy question to ask, and there is legitimately an interesting question to consider here based on experience from many other languages.
You can often use package reflect to hack up something approximating a solution to this class of problems, true. But, like package unsafe, package reflect sidesteps a bunch of language assumptions, conventions, idioms, etc. which means any code that uses reflection is going to be subtle, brittle. It's a tool of last resort, really, an escape hatch. Not something that you should consider part of your tool set.
This is all by design, I think. Go tries to ensure that a straight-line reading of the code accurately represents the execution flow. So you can't really implement the inversion of control patterns that frameworks usually rely on without fighting the language.
Last post of that URL was 8 months ago according to https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
Seems reasonable.
I'm not really sure what that is beyond a lot of popup ads. The HN admin may have replaced and reposted based on the request of the original poster.
See https://github.com/go-micro/go-micro instead.
Are you affiliated with this repository? How is it related to yours?