The author | jian fang (night) Spring Cloud Alibaba, one of the founders of open source project/source | Alibaba Cloud native public number

Takeaway: This article is excerpted from the book In-depth Understanding of Spring Cloud and Practice written by Fang Jian, a member of the founding team of Spring Cloud Alibaba open source project. It focuses on how to deal with FaaS scenarios under the de facto standard of The Java microservices framework Spring Boot/Cloud.

Serverless & FaaS

In a 2019 O’Reilly survey of 1,500 IT professionals, 40% of respondents worked in organizations that adopted the Serverless architecture. The 2020 DataDog survey shows that more than 50% of AWS users are now using AWS Lambda with the Serverless architecture.

Serverless is becoming mainstream, and this is where the following chart comes in, from singleton application management to microservice application management to function management.

There is no precise definition of Serverless so far. Martin Fowler has a Serverless Architectures article on his blog, which defines Serverless as BaaS or FaaS.

Baas is the full name of backend-as-a-service, and the Backend is a Service. FaaS is the full name of function-as-a-service.

Today we are going to talk about FaaS. Here’s how Wikipedia defines FaaS:

Function as a Service (FaaS) is a class of cloud computing services that provide a platform that enables customers to develop, run, and manage application functionality without building and maintaining the infrastructure typically associated with developing and launching applications. Building applications following this model is one way to implement the Serverless architecture, which is typically used when building microservice applications.

For development languages like Python and JavaScript, which inherently support Lambda, FaaS is a perfect match. The Serverless Framework research report also illustrates this very well. NodeJS and Python are the top two languages used by FaaS.

As we know, Java applications are slow to start because of the large memory footprint of the JVM, which is not suitable for the FaaS scenario, and this is why Java usage is low.

In addition, Spring Boot/Cloud has become a de facto standard for Java developers. Dependency injection is the core of the Spring Framework. How will Spring Boot/Cloud, a de facto standard, react to the FaaS scenario? This is the Spring Cloud Function we are talking about today.

Java Function

Before introducing Spring Cloud Function, let’s look at the core Function definitions in Java.

JDK 1.8 introduced a new feature called Lambda expressions, and the java.util.function package provides many functions. These three functions are particularly important:

1. Java. Util. The function. The function: the need for a parameter, get another result.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}
Copy the code

For example, the map method in the Stream API can use Function to write a string from small to uppercase:

Stream.of("a", "b", "c").map(String::toUpperCase);
Copy the code

The map method here takes a Function argument:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Copy the code

2. Java. Util. Function. Consumer: need a parameter, there is no return value.

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}
Copy the code

For example, the Stream API forEach method iterates through each element to do the corresponding business logic:

RestTemplate restTemplate = new RestTemplate();
Stream.of("200", "201", "202").forEach(code -> {
    ResponseEntity<String> responseEntity =
        restTemplate.getForEntity("http://httpbin.org/status/" + code, String.class);
    System.out.println(responseEntity.getStatusCode());
});
Copy the code

3. Java. Util. Function. : Supplier: get a result, there is no input parameters.

@FunctionalInterface
public interface Supplier<T> {
    T get();
}
Copy the code

For example, a custom Supplier can return a random number:

Random random = new Random();

Supplier supplier100 = () -> random.nextInt(100);
Supplier supplier1000 = () -> random.nextInt(1000);

System.out.println(supplier100.get());
System.out.println(supplier1000.get());
Copy the code

Spring Cloud Function

The Java Function programming model is very simple, essentially consisting of these three core functions:

  • Supplier
  • Function<I, O>
  • Consumer

Spring Cloud Function is a project of the Spring ecosystem related to Serverless(FaaS). It appears to enhance Java Function in the following ways:

  • FaaS programming model for unified Cloud vendors: The slogan of Spring Cloud Function is “Write Once, Run Anywhere”. We wrote Spring Cloud Function code that runs locally, across Cloud vendors (AWS Lambda, GCP Cloud Functions, Azure Functions).

  • Automatic type conversion: Those of you who understand Spring MVC or Spring Cloud Stream are probably familiar with HttpMessageConverter or the MessageConverter model This converter automatically converts HTTP BODY(or Message Payload), HTTP Query Parameter, HTTP HEADER(or Message HEADER) into the corresponding POJO. With this feature, we don’t need to worry about the function’s input and return values. We use the String argument to get the original input parameter information, and use the User POJO argument to automatically convert the original input parameter into a User object.

  • Function composition: You can combine operations between multiple functions.

  • Function management: Add FunctionCatalog and FunctionRegistry interfaces for Function management. Manage functions within ApplicationContext, dynamically register functions, and so on.

  • Reactive: Spring Cloud Function adds functions such as FluxFunction, FluxSupplier, and FunctionConsumer.

  • Automatic deep integration with existing components within the Spring ecosystem:

    • Spring Web/Spring WebFlux: An HTTP request is a function call.
    • Spring Cloud Task: A Task execution is a function call.
    • Spring Cloud Stream: A message consumption/production/transformation is a function call.

Here we will introduce the FaaS programming model of unified Cloud vendors to give you a better sense of Spring Cloud Function.

AWS Lambda is the first cloud vendor to provide FaaS services. RequestStreamHandler is an interface provided by AWS for Java developers that needs to be implemented:

public class HandlerStream implements RequestStreamHandler {
  @Override
  public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException
  {
    ...
Copy the code

Azure Functions provides the @httpTrigger annotation for Java developers:

public class Function { public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) { ... }}Copy the code

As you can see from these two pieces of code, different cloud vendors write different code. If you have to change cloud vendors, the process can be painful.

Also, whether AWS, Azure, or GCP provide interfaces or annotations, they don’t have any Spring context-specific initialization logic. If we are a Spring Boot/Cloud application migrating to the FaaS platform, we need to add Spring context initialization logic and so on.

Spring Cloud Function is designed to solve these problems.

Use of Spring Cloud Function

Spring Cloud Function & Spring Web:

@SpringBootApplication public class SpringCloudFunctionWebApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionWebApplication.class, args); } @Bean public Function<String, String> upperCase() { return s -> s.toUpperCase(); } @Bean public Function<User, String> user() { return user -> user.toString(); }}Copy the code

Access the corresponding Endpoint:

$ curl -XPOST -H "Content-Type: text/plain" localhost:8080/upperCase -d hello
HELLO
$ curl -XPOST -H "Content-Type: text/plain" localhost:8080/user -d '{"name":"hello SCF"}'
User{name\u003d\u0027hello SCF\u0027}
Copy the code

Spring Cloud Function & Spring Cloud Stream:

@SpringBootApplication public class SpringCloudFunctionStreamApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionStreamApplication.class, args); } @Bean public Function<String, String> uppercase() { return x -> x.toUpperCase(); } @Bean public Function<String, String> prefix() { return x -> "prefix-" + x; }}Copy the code

The payload is capitalized for every message on the input-topic, and the payload is written to the output-topic.

spring.cloud.stream.bindings.input.destination=input-topic
spring.cloud.stream.bindings.input.group=scf-group

spring.cloud.stream.bindings.output.destination=output-topic

spring.cloud.stream.function.definition=uppercase|prefix
Copy the code

Spring Cloud Function & Spring Cloud Task:

@SpringBootApplication public class SpringCloudFunctionTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionTaskApplication.class, args); } @Bean public Supplier<List<String>> supplier() { return () -> Arrays.asList("200", "201", "202"); } @Bean public Function<List<String>, List<String>> function() { return (list) -> list.stream().map( item -> "prefix-" + item).collect(Collectors.toList()); } @Bean public Consumer<List<String>> consumer() { return (list) -> { list.stream().forEach(System.out::println); }; }}Copy the code

Add function-related configurations (Supplier emulates the input source of the task, function emulates processing of the input source of the task, and Consumer emulates processing of the data after function processes the input source):

spring.cloud.function.task.function=function
spring.cloud.function.task.supplier=supplier
spring.cloud.function.task.consumer=consumer
Copy the code

The book “Deep Understanding of Spring Cloud and Practice” is officially available for pre-order. It is an in-depth analysis of the Spring Cloud family barrel book, covering the following topics:

  • Spring Boot core features
  • Spring Cloud service registration/service discovery principle analysis
  • The case of Eureka migration to Nacos is completed by dual registration and dual subscription model
  • Load balancing: Spring Cloud LoadBalancer and Netflix Ribbon
  • Dubbo Spring Cloud: A fusion of Spring Cloud and Apache Dubbo
  • Spring Cloud grayscale publishing case
  • Spring system configuration, dynamic refresh loading principle analysis
  • Spring Cloud Circuit Breaker abstract and Sentinel, Hystrix, Resilience4j fuse comparison
  • Spring architecture message programming model analysis
  • Spring Cloud Data Flow completes batch and stream processing tasks
  • The Spring Cloud Gateway is analyzed
  • Convergence of Spring and Serverless

Click to learn more and have a chance to win a free book!

Author’s brief introduction

Fang Jian is the open source project leader/co-founder of Spring Cloud Alibaba. Author, Apache RocketMQ Committer, Alibaba Nacos Committer I have written “SpringMVC source analysis series” and “SpringBoot source Analysis series” articles on my personal blog. At present, I focus on micro services, cloud native and Kubernetes.

Fang Jian, the author of “In-depth Understanding of Spring Cloud and Practice”, will attend Spring Cloud Alibaba Shanghai on January 9th. There will also be interactive book giveaways. Welcome to meet the author on site. Click the link to participate in activities to sign up: www.huodongxing.com/event/25765…