4 ms·
I don't think this is particularly good advice, he makes some valid points, but doesn't really consider the costs of the alternatives that he is suggesting. So
by WatchDog 5y ago
I don't think this is particularly good advice, he makes some valid points, but doesn't really consider the costs of the alternatives that he is suggesting.
Some counterpoints:
1. Micro-lambdas
How many routes does your application have 3, 30?
Trying to maintain 30 different codebases and deployments would be a nightmare.
Package size.
Package size is unlikely to be much different by adding a little extra code, especially if the code for each route uses the same set of libraries(which will make up the bulk of the package size).
Least privilege.
If it makes sense to limit a routes privileges, you can simply deploy the same lambda code separately, with a different role.
Upgrading.
On the contrary, upgrading a lambda that uses a single codebase, is much simpler than having to deploy multiple systems and deal with the issues of interoperability and compatibility between versions.
Reusing code.
Also much much simpler with a monolithic codebase, the code is right there, ready to use.
Testing.
Testing a monolithic app is very straight-forward, you don't need to setup a complex integration test environment, all the functionality can be tested locally.
4. Lambdas calling lambas
I tend to agree with this one, at least for synchronous calls, but you can also call another lambda asynchronously, actually this is something you tend to find yourself doing if you go down the path of breaking down a monolithic lambda.
5. Synchronous waiting.
Yes, from a cost perspective, you should minimize the amount of time your lambda is spending waiting on external IO.
However, from an application complexity perspective, you should make things as simple as possible, building overly complex event based lambda flows, can make it really difficult to debug and maintain your application.
- jackpeterfletch 5y agoYou can solve alot of these with multi-module projects, at least in Kotlin/Java. You have a single codebase, with modules for each route, and modules for shared infra/domain code. Maven builds a JAR for each Route with only the resources that route needs, you deploy a single lambda for each JAR - but - you deploy them all together as part of the same build pipeline. Then you have, non-monolithic lambdas, that can easily be performance tuned and privileged individually, but a single codebase that represents a whole 'microservice' application in one place, with shared code, that can be upgraded and kept consistant.
- bko 5y agoI use serverless to orchestrate my lambdas. They help out with the tradeoff between micro-lambdas and monolith. I get a single code base where I can reuse code, write tests and deploy all at once and serverless packages it up into individual lambdas. You can also manage other resources there in a single serverless file including iam permissioning, databases, or any other aws service. So your entire app is in that config file. Sometimes it bites you in the ass though and you get cryptic errors when trying to update the app in cloudfront, but overall I think its worth it. [0] https://www.serverless.com/ https://www.serverless.com/
- joshstrange 5y agoThis is my approach and it worked really well for a side(ish)-project. I liked having each endpoint be it's own file but also the code could share common 1st and 3rd party libs. I was also able to easily add some top-level checks/handling by adding a wrapper function that could handle certain types of errors and inject stuff like DataDog (though I will not be using them going forward, way too expensive, even with 0 traffic they were causing almost $75 worth of Cloudwatch requests a month, on top of their costs).
- wodenokoto 5y ago> Package size is unlikely to be much different by adding a little extra code, I was surprised to learn that Google Cloud Functions deploy a 1.5gb docker image. After that I was like fuck it, I don’t need to think about saving a few megabytes payload here and there.
- dodobirdlord 5y agoPresumably though that involves image layers and an image-layer-aware filesystem so that they don’t actually have to have more than one copy of the common image per execution machine, and just have to send around the customer’s overlay diff? Maybe they don’t bother and just pass the whole thing around, but this is a solved problem in the wider world for distributing a large number of large OCI images that are substantially similar.
- skipants 5y agoYour counter-points to (1) don't seem any different to the monolith vs. microservice debate. Much of your critiques are not so much problems as they are trade-offs. And they've been talked about ad nauseam.
- goostavos 5y ago>doesn't really consider the costs of the alternatives I loathe blog post "anti-patterns" for this reason. Our job as engineers is largely about managing tradeoffs. And trade-offs don't come pre-packaged in a blog of dos and donts, they're specific to the constraints at hand. Just about all of these "anti-patterns" are actually freaking awesome when what they offer (and do not offer!) lines up with what you need. 1. monoliths are awesome when that's all you need. Simple to write, maintain, and deploy. 2. Orchestration lambdas are A-OK when it's all you need and your workload fits comfortably in Lambda's constraints. I swear, the 'cloud' is rotting people's brains. There's a complexity threshold where Step Functions start to pay off. It's fairly high imo. The complexities in testing and debugging it introduces are huge compared to just dropping a break point in your control script. 3. This one is sane 4. Calling this an anti-pattern is again wrong imo. Goodness of fit depends on context. Lambdas calling other lambdas can squeeze a helluva lot of burst CPU performance for not a lot of money. There are a lot of workloads for which this makes sense. 5. This one is stepping over dollars to pick up pennies. I agree with your take entirely. Whatever minuscule amount is saved on idle CPU time with be dwarfed by the additional dev time spent writing, deploying, instrumenting, and debugging. Classic Solutions Architect wankery.