Using Spring Cloud Function with Spring Cloud AWS - aws-lambda

I've been looking into Spring-Cloud-Function and Spring-Cloud-AWS recently and all of the capabilities that the Spring modules provide, however, one thing I'm not too clear on is really whether the two properly go together.
I can see Spring Cloud function and maybe S3 being used together but there is no support for AWS' serverless DB, DynamoDB.
Would it be good or bad practice to use Spring Cloud Function (AWS Lambda) with RDS? Is the fact that DynamoDB is a non-blocking DBS a better fit for Lambda's and their billing structure?

I have created a sample Spring Cloud Function for AWS Lambda on my github. It uses AWS Java SDK to request for S3 objects. I have also written another sample with integration with AWS SQS.
So, I think it will be easy to integrate with DynamoDB as there is also Java sdk available for DynamoDb (although I have not personally used it before)
IMHO, I think because AWS Lambda charges by execution time, and initiating the connection to the RDS might also take up some time (same for shutting down).
Besides that, for scaling purposes, if your Lambda function was triggered in high frequency within a short period. Each of the lambda function will try to establish sql connection to the RDS and might eventually cause an overhead to the RDS.
What I did for my project is that I exposed an API endpoint on the web application and direct the traffic from lambda to the endpoint. Since SQL connection can be reused within the web app, I guess it is more efficient.
Ps. I have yet to use DynamoDB. So I cant comment much on that.

I would say Spring Cloud Function with the Spring eco system behind is a good basis for accessing DynamoDB from a Lambda function.
There is a community-supported Spring Data module for DynamoDB.
You might have a look at my article, where I'm using Spring Cloud Function with Spring Data DynamoDB.

Related

Spring Boot Microservices load balancing vs cloud load balancing

I am new to Microservices. (Learning phase). I have a question. We deploy microservices at cloud. (e.g. AWS). Cloud already provide load balancing and logs. And We also implement Load Balancing(Ribbon) and logs(Rabbit MQ and Zipkin) in Spring Boot.
What is the difference in these two implementation? Do we need both?
Can some answer these questions.
Thanks in advance.
Ribbon is a client side load balancer which means there is no any other hop in between your client and service. Basically you keep and maintain a list of service on your client.
In AWS load balancer case you need to make another hop in between the client and server.
Both have advanges and disadvantages. Former has the advantage of not having any dependency to any specific external solution. Basically with ribbon and service discovery like eureka you can deploy your product to any cloud provider or on-premise setup without additional effort. Latter has advantage of not needing an extra component of service discovery or keeping the cache of service list on client. But it has that additional hop which might be an issue if you are trying to run an very high-load system.
Although I don't have much experience with AWS CloudWatch what I know is it helps you to collect logs to a central place from different AWS components. And that is what you are trying to do with your solution.

How is state handled in the go cloud?

In terraform we get a state file, and CloudFormation also has a notion of a working state. How does go cloud handle the state, do we have to create it ourselves?
For more info on Go Cloud
https://github.com/google/go-cloud
https://godoc.org/github.com/google/go-cloud
Terraform wants to solve the problem of managing and provisioning Cloud services.
Go Cloud wants to solve the problem of using Cloud services in application code.
So, they work well together. For example, the Go Cloud sample guestbook app (https://github.com/google/go-cloud/tree/master/samples/guestbook) uses Terraform to provision the resources needed to run the app on various Cloud providers; the application code in the sample has a small amount of provider-specific setup code, but the application logic itself is provider-agnostic.
go-cloud:
The Go Cloud Project is an initiative that will allow application developers to seamlessly deploy cloud applications on any combination of cloud providers. It does this by providing stable, idiomatic interfaces for common uses like storage and databases. Think database/sql for cloud products.
Terraform:
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.
So with go-cloud you could create a tool like terraform that, for now can provide generic APIs for:
Unstructured binary (blob) storage
Variables that change at runtime (configuration)
Connecting to MySQL databases
Server startup and diagnostics: request logging, tracing, and health checking

Checkpointing with Spring AWS Integration

According to Spring release notes, spring-integration-aws.1.1.0.M1 does not include DynamoDB MetaDataStore implementation. There is still ConcurrentMetadataStore class which is a key-value based store and based on implementation I suppose it maps streams with latest sequence number read. But it does not use any data store as to retrieve checkpoints.
I am using spring integration for kinesis consuming and need to implement checkpointing. I am wondering if I need to do it manually by connecting to DynamoDB and always update checkpoints or there is another way of doing it using spring framework?
P.S: I can't use Spring Cloud KinesisBinderConfiguration as I dynamically consume events from a list of configurable streams.
Thank you
If you are not talking about Spring Cloud Stream and the AWS Kinesis Binder implementation, then I don't see any blockers for you to upgrade your solution to the Spring Integration AWS 2.0 and go ahead with already provided DynamoDbMetaDataStore.
Or if that is so hard for you to move to the Spring Integration 5.0, then you simply can consider to copy/paste an implementation to your own class and inject it into the KinesisMessageDrivenChannelAdapter: https://github.com/spring-projects/spring-integration-aws/blob/master/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetaDataStore.java
Although it is really available in the 1.1.0.RELEASE - I don't see reason for your to stick with the 1.1.0.M1: https://spring.io/blog/2017/11/27/spring-integration-for-aws-1-1-ga-available

Azure alternative to spring cloud dataflow process

I'm looking for the azure alternative for the Data flow model of Data Source-processor-sink.
I want the three entities to be separate microservices. I want to use messaging as a link between these three.
Basically, Source app takes the data from another service and sends it to processor while processor app acts on it and sends relevant notification/alert to sink.
I'm aware I can use rabbitmq for the messaging but I need to know which one will be better in azure - service bus topics or eventhub? and how can I use them?
At the moment, there isn't a Spring Cloud Stream binder implementation for Azure Event Hubs.
Unless we have this, the out-of-the-box or the custom apps cannot be built as a messaging-microservice app, where Spring Cloud Stream provides the programming model and Spring Cloud Data Flow lets you orchestrate the individual microserivces in to a data pipeline (i.e., source-processor-sink) via the DSL/Drag-and-Drop GUI.
Microsoft was exploring the binder implementation in the past; possibly it would end up in Azure Spring Boot project. Feel free to drop an issue on their backlog.

Is Spring Compatible with Serverless Computing

I've seen this post here: https://dzone.com/articles/making-spring-boot-application-run-serverless-with which gives an example of how to use Spring in a Serverless scenario, but I believe that this still involves creating the Spring context, an expensive thing to do every time a request comes in. And I am wondering if Spring, but also the traditional web application frameworks are even truely compatible with the severless model, as they all tend to assume the server is only going to initialise on start, and then not again till the server is restarted, as opposed to being immediately ready to handle a request and not needing to initialize a Spring context for instance. So then these frameworks tend to do allot of stuff in the start up phase, which is not good I believe when you don't have a server per-say, and you effectively need to start up every time your would call what would be a lambda in AWS.
So my question is are these traditional web frameworks, such as Spring, which perform allot of compute when starting up still applicable in the Serverless model, for instance: AWS lambda.
Spring can indeed be applicable with the Serverless model, but as you suggest, IMHO it is not suitable for all use cases.
For the reasons that you mention (comparatively long start up times for a "cold" Lambda), I would advise against using Spring when implementing a web app that is deployed to an AWS Lambda function behind an API Gateway as the response times will suffer.
However, there are scenarios when the long start up time of a JVM based function handler implementation in a cold AWS Lambda function is less of a headache and where you may consider this option. One example is as a consumer of a Kinesis stream. The cold start will still be as bad as in the previous case, but if you have a steady stream of events the cold start will only occur once per shard. Another difference is that when using Kinesis you have already chosen an asynchronous application flow. In other words, the event producer can continue its work as soon as the event has been put on the stream without waiting for the event to be processed.
There are some Spring sub-projects that try to deal with this scenario, like Spring Cloud Function:
https://spring.io/blog/2017/07/05/introducing-spring-cloud-function
The deployment profiles even extend into the realm of Serverless (a.k.a. Functions-as-a-Service) providers, such as AWS Lambda and Apache OpenWhisk (as well as Azure Functions and Google Cloud Functions once they provide support for Java)
However, context initialization is still needed, so I guess is up to the developer to make it as small as possible to guarantee a quick startup.
EDIT: Today, I was on a talk given by Dave Syer in the Spring I/O Conference, and he presented some solutions to make Spring Boot more suitable for serveless computing:
Spring Boot Mini Applications: They are SB application but with reduced contexts:
https://github.com/dsyer/spring-boot-thin-launcher
Spring Boot thin launcher:
https://github.com/dsyer/spring-boot-thin-launcher
Some benchmarks on how long does it take to launch several configurations:
https://github.com/dsyer/spring-boot-startup-bench

Resources