Spring Cloud Function – What is it? Why do people use it or not use it?

My dad likes to say “Don’t tell me how to build a watch, just tell me the time” to express his point that he doesn’t want to know any details; he only wants the outcome. That’s the gist of a Function. A watch to my dad is a Function, with an input question “what time is it” and an output result: the actual time. He doesn’t care how the watch is built or if it is an Omega watch or an Apple watch, he just cares about the business value it provides: it tells the time.

Function as a service or Serverless has a similar concept. Instead of managing long running components as the server side applications, let’s run ephemeral function instances. Each function contains one business logic and provides one business value with well defined inputs and/or outputs.

Raised Value Line

Before we drill down to the technical details of a Function, let’s back up a bit and talk about the value line again. It’s a very popular topic. People always say that you want to stay above the value line so you can be the most productive. Nobody cares about infrastructure that is below the value line. That’s one of the big reasons why the cloud business is so hot today. At the end of the year, your CIO is not going to pat your shoulder and say “great job on successfully patching that server” and give you an extra bonus. That will never happen. Instead, it’s all about what’s above the value line, whether that’s a new software you developed per the business’ request or an enhancement you put in that generated massive revenue.

So where is the value line? At the bottom, there are bare metal servers. Things have to be running somewhere eventually, and those are the servers. Even if you move your workload to Cloud, you’re moving your own data center somewhere else whether it is on Amazon or Google. Next is the Virtual Machine layer. Nowadays VM has become a standard. On top of VM is the operating system and middlewares. All the maintenance work including upgrading and security patching are important, but developers shouldn’t care. Also there’s this container layer. The container topic (such as Docker) gets really hot. Consequently, Open Container Initiative was launched in June 2015. Deploying applications in dockers, in my opinion, is adding a bottleneck and more risks to the development to deployment process. Developers really don’t want to write docker files and run docker build as their daily practices and they don’t want to have the admin access to the production OS environment, which unfortunately is what Docker does. It gives operators headaches to manage containers as well because they have to maintain different applications that are running in containers with different versions of middlewares. Cloud Foundry came along with buildpacks where all the libraries, frameworks and runtimes are within, so developers can truly do what they love to do, which is writing software.

Cloud Foundry is very good, so developers can focus on applications. But applications don’t necessarily represent business logics. If a majority of your time is spent dealing with integrations, connecting to services, or handling concurrent incoming requests, authentications, security, you are still not writing business logics. This is where FaaS comes in. It abstracts away all these glues. So Serverless or FaaS is an abstraction, which raised the value line.

Spring Cloud Function Implementation

As a developer, all I care about a very simple function that can do one execution with an input and an output, and maybe some business transformation in between. I put my function on a Serverless platform and it just runs. Popular Serverless platforms include Amazon Lambda, Google Cloud Function, Azure Function, IBM OpenWhisk, Fission, Kubeless etc. The language support includes NodeJS, Python, and JVM languages such as Java, Scala and Clojure. As a Function developer, I shouldn’t need to know the details of each language and framework. Just the basic syntax that can allow me to write business logics should be enough. Spring Cloud Function serves this purpose.

Spring Boot is designed for developers to spin up a production-ready, spring-powered application quickly. It’s naturally a suitable language for Function developers through which they can truly focus on business logics. Everything else is wired for you. You don’t need to know Spring, such as ComponentScan or Annotations. Take a look at the Java Util Function that Spring Cloud Function provides:

Java Util Function

public interface Function<T, R> {
R apply(T t);
}
public interface Consumer<T> {
void accept(T t);
}
public interface Supplier<T> {
T get();
}
Simple! If you would like to transform from T to R, you call the apply function. If you just want to accept the input, you can implement the Consumer interface. Or if you want to get a list of items, you can implement Supplier. Of course you still want to test your code. It is very easily testable, and you can run it on your local laptop then ship to any function platforms such as Amazon Lambda or Google Compute. The idea is for you to have a very fast turnaround for prototyping, then quickly turn that prototype to production code.

Characteristics

Event Driven

Obviously, functions are triggered by event types defined by the providers. With Amazon, triggers can be http calls, S3 file updates, scheduled tasks or messages added to a messaging queue. In Spring Cloud Function, we can easily configure the trigger to be http web endpoint or a message coming into the stream. You can also expose functions via other handlers that can be easily implemented.

Stateless

Functions are totally stateless. You can kill a function anytime, it’s going to come back up and it’s going to continue to serve the incoming requests. This puts significant restrictions on coding local states. You must assume that for any given invocation of a function, none of the in-process or host state will be available to any subsequent invocation. This includes memory/cache state or disk state.

Java Support

Amazon Lambda and IBM OpenWhisk support Java natively. Other vendors use a JRE launcher to run a Spring Cloud Function.

Auto Scaling

Horizontal scaling is completely automated, elastic and managed by provider. Your function only needs to coded to handle one incoming request. If the system needs to process 100 concurrent incoming requests, the provider will handle it. Your functions are ephemeral and the provider provision and destroy them purely based on the runtime need.

Billed by execution

The billing model is per execution. This really changes the way you build your functions. If your function is not often billed, maybe it is time to change it so it can be important and consumed more frequently.

Comparison with Paas

You probably have realized that the characteristics listed above are a lot like 12-factor app design principles. That is correct! From the development perspective, Faas functions are a lot like microservices, except for the fact that functions are in a more granular scale so they are like nano-services. We advocate that we should be running microservices on Paas, so can we run functions on Paas? Technically you can. However, you wouldn’t want to.

First of all, the billing model is different. For example, Pivotal Cloud Foundry bills applications by each application instance (AI). As long as your application instance is up and running, it doesn’t matter if there is any incoming request, you will be billed. Therefore, the billing model of Function providers can be more cost efficient.

Secondly, Paas still requires operators to configure the underlying resource allocation (how many EC2 instances on AWS for instance), scalability, logging, monitoring, alerting etc. On the contrary, Faas providers just deploy, run, and scale functional components and operation is completely transparent to functions. Therefore, Faas can save a lot of operation headaches.

Both Faas functions and microservices have their own place in the market. A function seems to be a better choice for an event driven, light weight component, whereas a microservice may be more suitable for a multientry point, more complex application that is in line with the capability of a business unit.

Benefits and Drawbacks

We have mentioned many benefits including reduced operational cost, scaling cost, easier deployment and shorter time-to-market, even more so than Paas. The drawbacks, however, are worth noting before considering to adopt Faas.

The number one problem is the vendor lock-in. You will be stuck with Amazon Lamda or Google Cloud Function or any other vendors. It wouldn’t be easy for you to switch vendors. You will almost certainly need to update your deployment tools, code, and architecture designs to be able to do so.

Execution duration limit is another concern. If your function runs longer than 5 mins, Amazon Lambda will terminate your running function. A lot of variables can impact how long your function runs on a Faas platform. This arbitrary limit may cause unnecessary system outages. Moreover, startup latency is especially noticeable with a JRE function, which in our case is Spring Cloud Function. This will further consume the time that is needed for running the function.

Last but not least, the distributed computing problems faced by microservices exist with functions as well. How are they going to discover each other? How do we configure them effectively? How do we control versions? With microservices, Spring Cloud provided toolings to address these concerns. However, in the Faas world, we don’t have matured patterns yet.

Next Steps

Serverless or Faas is a great idea. But it’s not for everybody. It is still at an early stage where more toolings, patterns, and platform improvements are needed. We hope that the Serverless community will work toward the direction where the drawbacks can be mitigated and Faas can be more widely adopted.

Leave a Reply

Your email address will not be published. Required fields are marked *