Sample cloud-native application with microservices
github.com
github.com
Istio mesh is a good example.
This kind of architecture is not unreasonable for larger companies with many teams, which is where the technology itself becomes useful as well. So in that context, this architecture is entirely reasonable.
so, i would think the percentage is larger than 1%.
Quantity itself is not an issue - it's great to have options. Incompatibility, segmentation and uncertainity about the future are issues, though. E.g. ksonnet and Forge are dying. Some say Helm isn't particularly healthy, too - is it just speculations or would it die in next year or two, leaving all those charts repos a dead code for archeologists?
Maybe that's just me, but modern DevOps feels like JavaScript world from a few years ago. Things are born in abundance, promise lots, and die before they're even v1.0.
By some people from k8s: https://docs.google.com/spreadsheets/d/1FCgqz1Ci7_VCz_wdh8vB...
By me: https://github.com/dhall-lang/dhall-kubernetes/issues/10
Have to imagine some k8s-controller/git server that enables git deployments to k8s with just a node size config is the optimal end state.
I’ve mentioned this before in related threads: app devs want heroku. They want a managed platform where they type “git push” and they have an application with all the fixings. Heroku got the UX right long ago, and the rest of the ecosystem is still playing catchup
However, there is https://gitkube.sh/ that looks somewhat similar. Can't vouch for or against - haven't used it at all.
There are some review issues in the main upstream Helm Chart repo, but that's due to volume (which is now higher than ever).
I was more specifically asking Jeff which similar tools are cleaner, and why? Are there any helm drop-in replacements that anyone would recommend? Or is it really a shift to other ways of deploying, like these hosted solutions, or is everyone building their own k8s operators now...? Or something else?
Only being slightly tongue-in-cheek.
Give it time it'll mature and people will be burnt out from all the changes
Things are simpler now, not more complex. The tools are better, more standardized, and way more broadly available. It's up to you whether you need or want them or not.
The pieces are largely the same, but in a lot of ways, the tooling has _enabled_ more complexity than is necessary. Things have become specialized in incongruent ways that makes things harder. Simplicity is a constant struggle and a quality all of its own. Sometimes you have it by accident, where it then occupies the unknown known quadrant.
To me all of this sounds like crazy complexity vs a basic Kubernetes cluster. It all depends on what you are comfortable with I guess.
https://www.independent.co.uk/life-style/gadgets-and-tech/33...
Didn't Facebook also start in Harvard's dorms?
(Disclosure: I run it.)
All companies had their own way of hacking and making their system worked. But they didn't share it. Twenty years agoes, what big company shares their infrastructure knowledges as open sources?
Now things are being shared and learned together.
One of the main benefits of decoupling a monolithic application is getting the freedom to release, scale and manage different components separately. Each team becomes empowered to define their own practices, procedures and policies that are appropriate to their business requirements.
Have a mission-critical component that needs 5 9s reliability (auth or billing)? Great, release that carefully over multiple days with canarying across failure zones. Working on an experimental API for a new mobile app? Awesome, ship every commit.
The common quote "if you have four groups working on a compiler, you’ll get a four-pass compiler" clearly has architecture following from organizational structure.
I think your original comment was unclear, if not misstated. I had read the "like" in "[a]rchitect your microservices like your org chart" as something like "to resemble", and the rest of the comment seems to follow just fine. Other readings seem possible but I don't see one that gives the sense you want without what feels like some serious contortion.
In any case, no worries, we're clearly on the same page now - just trying to figure out what went wrong.
Similarly, if you run a website that does batch processing of images for example, the image processor application would be a microservice since that would scale independent of website load. It could be that you would need to process 100 or even 1000 images for each user, on average, and it doesn't make sense to scale your whole application when a bulk of the application processing is for image processing.
When deployment and coordination become an issue, that is when _deployment_ needs to get split up. But given our current RPC mechanisms, deployment and invocation are over-coupled so we have to consciously make these decisions when they could be made by the runtime.
In either case, the best time to do it would be when you feel the increased speed and agility is outweighed by the added overhead. The speed and agility comes from small teams being able to operate mostly independently.
There are of course a ton of exceptions to this. For example, if you're using AWS Lambda or Google cloud functions, they do a lot of that 25% for you, as long as you're willing to do it their way, so now you have an incentive to go microservices sooner. Also, going microservices will probably allow you to scale up faster if you've done it right. So if you expect a huge spike in traffic, that's a good time to go microservices.
There is lots of good material on the pros and cons of microservices, but when to actually make the switch, or if you should start out at microservices, is a very situation specific question and relies on a lot of external factors.
The best I can say is look at the pros and cons and figure out what that costs or gains you in your particular situation.
I would say, don't use Microservices unless you have 100 or more employees.
You will learn about how to model complex domain models and how to decompose them into Aggregate's. The Aggregate is the key to where to create new microservices, as each aggregate should only contain domain objects that relate to itself.
Payments is a great example of an Aggregate.
#anecdata
The other heuristic to follow is how your company is organized. If you have a separate team working on a major feature then perhaps that could be its own service so they can own the full-stack.
Otherwise, stick to the monolith for the best results.
- independent deployment of this service
- independent scaling of this service
- independent implementation stack for this service
- security - minimize privilege escalation and access to infrastructure
- scalability - different workloads need different metrics to scale(CPU bounds vs connection bound)
- dependencies - why burden devs with all dependencies especially some that are more difficult to setup dev environments for
- service per backend dbs/etc (overlaps with the above)
- domain - can place domain specific skills on a team
kafka ->process message -> kafka
You're right they could have... beefed up the soda can, so to speak, but I don't blame the (presumably) DevRel folks who put this together for hand-waving it, "now imagine a mountain here".
I would very much agree with that. Although I'm not against microservices, they are by no means a quick or efficient way to get things done. Hedging against future theoretical scaling concerns comes at a high cost - a cost that's very much worth it if true scale is achieved, but a high cost nonetheless.
I'd be interested in some resources around this topic if you know of any.
https://www.slideshare.net/TriNimbus/chris-munns-devops-amaz...
There are comments arguing these architectures create a ridiculous amount of overhead for what would be a simple application traditionally, and others countering that the point is to show the underlying tech in the context of a "simple" problem. I think there's a large amount of truth for both sides.
It feels like there's a great paradigm shift on the horizon, and hopefully a good set of abstractions to build with. We're programming in machine-specific assembly languages, waiting for a high-level language to come along so we don't worry about things like calling conventions anymore.
[1] https://github.com/dotnet-architecture/eShopOnContainers
I'd love to say this is overcomplicated and to just use Docker Compose, but I don't think Docker Compose is the way to go.
The next thing I'd like to see is how to get this integrated with vscode or Atom to provide autocomplete without installing everything locally.
.proto(s) -> language code -> language binary/package
Completely automated and ready for an import into a project.https://docs.bazel.build/versions/master/be/protocol-buffer....
We use it at work to build a web app whose backend is written in Go and frontend in Typescript. All of the code gets built and placed in a Docker image using these rules:
As your json payloads evolve, you're going to encounter pain trying to keep your services in sync, whether it comes in the form of writing parsing code to crack open payloads and do conditional error checking based on the version (and expected fields), or whether it comes operationally in how you actually deploy updates to running services.
It’s helpful for casual observers to understand all the pieces of the stack. You can get an immediate feel if the approach is right for you and your team.
And it’s helpful for engineers to have examples to reference copy when implementing the patterns themselves.
I’ve been working on project similar to this for go, gRPC and Envoy:
https://github.com/nzoschke/gomesh
My project doesn’t go into deployment or K8. If I needed to figure that out I’d look at the OP project.
I also have a project that demonstrates Go and Lambda:
https://github.com/nzoschke/gofaas
If these help even a few engineers learn to be successful with the tools it’s a win.
That's not satire, that's trying to show you how to make classes and factories in that language.
This is showing you how to build a full website with microservices on GCE/Kube.
It's obviously overbuilt for what it does, that's not the point. The point is to show you how to build something complicated with simple examples.
This is an example of an extreme opposite. Almost destructive.
Google has enormous mindshare amongst developers; and when they put something like this out there, people will actually see it as an example to follow.
Where is the blinking warning sign saying "do not try this at home"?
This is nothing like creating too many factories in a Java application.
When I look at this I think, "Man what a cute little architecture, but at least it shows some of the basics of a large scale website".
Software evolves to spaghetti over time unless one makes an effort for it not to happen.
It makes no sense to start with spaghetti.
I know hn don’t like one line questions like that which may be read as an insult. But I honestly cannot tell.
It is obviously a lot of work. But the technology mix and design is just absurd. The choice of web shop with hipster products is tongue in the cheek but so was the pet store of year 2000.
Sending emails is a one-liner in Django. Am I a sucker for not building my own email sending service?!
Of course being a Google demo they have to include the obligatory ad server service, in Java no less. Nonsense like this is why I'm steering my kids away from considering software development as a career.
An example of an email sending service is Sendgrid, who have built an entire company around this service.
They are alive because they take the spam blame for you.
It's still a one-liner once you've configured your async task handler. Which makes the example custom email sending microservice even more ridiculous when it can be done trivially by configuring proven off-the-shelf components and third party email delivery services.
I wasn’t sure how ready rq was for prime time, but I’ve hit far too many celery bugs and the maintenance hasn’t been great for awhile.
Django-RQ's job decorator is basically a drop-in replacement for Celery's task decorator. Django-RQ's built-in Django admin app is very nice.
My Celery usage was pretty simple (mostly background email sending and PDF generation) but for those use-cases Django-RQ has been a very good replacement. Your mileage may vary of course.
Most software projects are long lasting, and have unpredictable and constantly changing requirements.
Agile is currently the best software development methodology under these constraints.
Effective Agile teams should not be larger than 10 people total, minus the PO and Scrum Master leaves 8 devs.
Its not possible to run a large scale, high traffic web application with only 8 devs.
Therefore, it makes sense to split large applications up into chunks small enough for a 10 person team to manage autonomously.
Since the application had to be split up, we now have to solve the communication issue. Now we need networking, DNS, TLS, have to consider latency and bandwidth, etc... We also have other issues if we’re running at scale: redundancy, monitoring, separate environments for testing and production, having a local dev environment similar to the production environment. There is a huge list of things that are not important to for an early stage startup to think about, but are very important and very difficult for most large enterprises to get right if they want to consistently and reliably deliver good software.
Google is a large enterprise that operates large scale web services that has proven they know how to get this stuff right.
This repo is a reference architecture, from Google, on how to run micro services at scale using modern tools and methodologies. If you think this is over engineered I think you're just not the target audience, and something like Heroku is much better suited for your scale.
Also, no persistent data storage (no data to the store owner)? (I guess for easier example)
https://kubernetes.io/docs/concepts/services-networking/serv...
We deliberately wanted to leave state out as it complicates things by quite a bit, but doesn’t add much value in terms of the technologies we wanted to showcase.
Now, there should be a reverse-proxy that first call the authentication, if correct, calls authorization, if correct call the execution. But, how do people do that?
Why get the full web stack in the picture?
The way I see it, I'd rather have it. Took maybe 30 seconds to write, eliminated a whole class of bugs, and if I don't like it, I will write that plugin to hide it.
Imagine writing Java, and wrapping every function call in a try/catch block, and inspecting the exception if one was caught, and then handling it or re-throwing it. That's kind of what we do in Go. There are no "unexpected errors" because it is clear where all errors originate and how they are to be handled.
Go2 will improve on this if err != nil syntax, possibly with some function-scoped error handler and a new language level handle/check concept. Check it out
https://dev.to/deanveloper/go-2-draft-error-handling-3loo https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback
Forcing every intermediate layer in the call stack to catch and rethrow that exception (check and propagate an error code) sounds like a good thing for explicit error handling, but actually in practice introduces a lot of boilerplate code that just provides more opportunities for mistakes (like errors being silently swallowed, or logged multiple times creating confusing log files).
How many times in a code review do you see `if err != nil { return err }` and ask yourself if what it is doing is actually appropriate? Most people just mentally mask out that kind of boilerplate over time.
But it is very verbose error handling.
It's not that they are inherently bad so much as it requiring discipline to stop things from getting out of hand, and that's just something you want to avoid in larger projects. If you need to be disciplined you might as well just check the return error value.
And there's a new class of bugs: forgetting to check for an error. In Rust, the compiler won't let you forget. With exceptions, forgetting to handle an exception will result in a somewhat controlled termination process. In Go, execution will just continue in a bad state.
Go2 will fix this btw