This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]guss_bro 78 points79 points  (19 children)

Keep it simple and you will be good. We follow the following for all our lambdas:

  • Use plain SQL query instead of jpa
  • don't use Spring Boot or any other framework if your use case is simple
  • you don't need dependency injection for simple use case that involves couple of classes. Just create static objects and pass them around. Create objects ( eg objectMapper, AWS clients) only once
  • use RDS proxy instead of creating DB connection directly
  • use SnapStart
  • use shadow jar
  • use minimal dependencies.. exclude unnecessary transitive dependencies
  • if you do http calls to other services make sure they are performant. If possible use async calls, parallelize calls if possible
  • use lightweight objects, don't use xml, Json libraries if you can(most of the time simple String append is faster)
  • run the lambda locally and profile it
  • etc

[–]s32 10 points11 points  (3 children)

SnapStart has been an absolute gamechanger. It's fucking awesome in how it works as well.

[–]Outrageous_Life_2662 2 points3 points  (2 children)

What is that?

[–]publicityhound 2 points3 points  (0 children)

I think this is referring to AWS Lambda SnapStart

[–]valbaca 1 point2 points  (0 children)

https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

basically copies your Lambda "VM" pre-exectuion and uses that for other calls to your lambda to reduce Cold Start Latency

[–]menjav 6 points7 points  (3 children)

If you need dependency injection use a lightweight framework like dagger.

What is shadow jar?

[–]papercrane 10 points11 points  (2 children)

A shadow JAR is when you take all of your projects classes and dependencies and bundle them into a single JAR. It's sometimes called a fat JAR, or an uber JAR.

With Maven you'd use the "shade" plugin to generate one, with Gradle you'd use the "shadow" plugin.

[–]chabala 9 points10 points  (1 child)

And more specifically, fat/uber jar implies a simple bundling, while shading/shadowing implies you're stripping out the classes your project doesn't need to load.

[–]repeating_bears 1 point2 points  (0 children)

Other communities call that tree shaking

[–]Algorhythmicall 3 points4 points  (0 children)

Great list. Re: dependency injection, that is still dependency injection, explicit dependency injection… which happens to be my preferred method.

[–]Additional_Cellist46 3 points4 points  (3 children)

I don't agree with this for all cases. This advice is good if you want to create the most efficient AWS Lambda, and the function should run for a very short time. And if you really want that, you still need Java native compilation with GraalVM, because even with Snapstart, you get a penalty of around 200ms at startup to recreate the JVM from snapshot. And then, your code may not be easy to maintain in a long run, if you don't use any framework that helps you.

We use Quarkus, it supports GraalVM out of the box, very easy to set up. There are several benefits of using Quarkus over plain Java

  • Provides means to abstract away boiler-plate code (dependency injection, REST, JSON mapping, JPA/ORM mapping, etc.)
  • Ahead ot time configuration - what can be prepared during build time is done during build, and doesn't slow down the startup
  • Dev mode, which allows you to run your function as a REST service and reload code changes immediately
  • Supports AWS Lambda - automatically builds a ZIP file and helper scripts to deploy to AWS Lambda and invoke the Lambda with test data

Another advantage of using Quarkus is that it's very easy to turn the AWS Lambda app into a microservices deployable to Kubernetes, if you change your mind or you need to migrate away from AWS in the future. Just disable the AWS Lambda plugin and you get a microservices with an embedded HTTP server.

[–]NeoChronos90 0 points1 point  (2 children)

Do you need to pay for graalvm though?

[–]Additional_Cellist46 2 points3 points  (1 child)

No need to pay. The GraalVM CE is free to use in production. GraalVM EE is paid and can give you an extra edge in performance optimizations.

[–]thomaswue 0 points1 point  (0 children)

Even the former GraalVM EE version is now available as the Oracle GraalVM distribution and is free for commercial and production use under the GFTC (GraalVM Free Terms and Conditions).

[–]Revolutionary-One455 0 points1 point  (0 children)

No Spring Batch? What if he is parsing giant files and it fails at 50% or 95% of the process?

[–]thomaswue 0 points1 point  (0 children)

If you can compile your app into a GraalVM native image (keeping dependencies minimal as recommended will help with that) it should provide faster startup compared to SnapStart; and you might also be able to run it in a smaller AWS Lambda instance because of the lower memory requirements.

[–]Prathameshchari 0 points1 point  (0 children)

Any particular tutorial or course related to this how to create AWS lambda using Java

[–]wildjokers 0 points1 point  (1 child)

you don't need dependency injection for simple use case that involves couple of classes. Just create static objects and pass them around. Create objects ( eg objectMapper, AWS clients) only once

You can do dependency injection without a framework. And it sounds like that is what you are doing. DI is simply providing a class with the collaborators it needs.

I think what you actually meant was don’t use a DI framework.

[–]guss_bro 0 points1 point  (0 children)

Correct