Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >距离 Java 开发者玩转 Serverless,到底还有多远?

距离 Java 开发者玩转 Serverless,到底还有多远?

作者头像
程序猿DD
发布于 2023-04-04 07:25:14
发布于 2023-04-04 07:25:14
87800
代码可运行
举报
文章被收录于专栏:程序猿DD程序猿DD
运行总次数:0
代码可运行

本文摘自 Spring Cloud Alibaba 开源项目创始团队成员方剑撰写的 《深入理解 Spring Cloud 与实战》 一书,主要讲述了 Java 微服务框架 Spring Boot/Cloud 这个事实标准下如何应对 FaaS 场景。

Serverless & FaaS

2019 年,O'Reilly 对 1500 名 IT 专业人员的调查中,有 40% 的受访者在采用 Serverless 架构的组织中工作。2020 年DataDog 调查显示,现在有超过 50% 的 AWS 用户正在使用 Serverless 架构的 AWS Lambda。

Serverless 正在成为主流,于是就诞生了下面这幅图,从单体应用的管理到微服务应用的管理再到函数的管理。

Serverless 到目前为止还没有一个精准定义。Martin Fowler 在个人博客上有一篇《Serverless Architectures》文章,其对 Serverless 的的定义分成了 BaaS 或 FaaS 。

Baas 是全称是 Backend-as-a-Service,后端即服务,FaaS 的全称是 Function-as-a-Service,函数即服务。

今天我们来聊聊 FaaS。这是维基百科对 FaaS 的定义:

函数即服务(FaaS)是一类云计算服务,它提供了一个平台,使客户可以开发,运行和管理应用程序功能,而无需构建和维护通常与开发和启动应用程序相关的基础架构。遵循此模型构建应用程序是实现 Serverless 架构的一种方法,通常在构建微服务应用程序时使用。

对于 Python、JavaScript 这种天生支持 Lambda 的开发语言,和 FaaS 简直是完美结合。Serverless Framework 的调研报告也很好地说明了这一点。NodeJS、Python 是 FaaS 使用率前二的语言。

我们知道,因为 JVM 占用的内存比较大,所以 Java 应用的启动会有点慢,不太适合 FaaS 这个场景,这也是 Java 在使用率上偏低的原因。

另外,对 Java 开发者来说 Spring Boot/Cloud 已经成为了事实标准,依赖注入是 Spring Framework 的核心,Spring Boot/Cloud 这个事实标准应对 FaaS 这个场景,会碰撞出怎么样的火花呢?这就是今天我们要聊的 Spring Cloud Function。

Java Function

在对 Spring Cloud Function 介绍之前,我们先来看 Java 里的核心函数定义。

JDK 1.8 推出了新特性 Lambda 表达式,java.util.function 包下面提供了很多的函数。这 3 个函数尤为重要:

1. java.util.function.Function: 需要一个参数,得到另一个结果。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@FunctionalInterface
public interface Function<T, R> {   
    R apply(T t);
}

比如通过 Stream API 里的 map 方法可以通过 Function 把字符串从小写变成大写:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Stream.of("a", "b", "c").map(String::toUpperCase);

这里的 map 方法需要一个 Function 参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
2. java.util.function.Consumer: 需要一个参数进行操作,无返回值。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@FunctionalInterface
public interface Consumer<T> {    
    void accept(T t);
}

比如通过 Stream API 里的 forEach 方法遍历每个元素,做对应的业务逻辑处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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());
});
3. java.util.function.Supplier: 得到一个结果,无输入参数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@FunctionalInterface
public interface Supplier<T> { 
    T get();
}

比如自定义 Supplier 可以返回随机数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Random random = new Random();

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

System.out.println(supplier100.get());
System.out.println(supplier1000.get());

Spring Cloud Function

Java Function 的编程模型非常简单,本质上就是这 3 个核心函数:

  • Supplier
  • Function<I, O>
  • Consumer<I>

Spring Cloud Function 是 Spring 生态跟 Serverless(FaaS) 相关的一个项目。它出现的目的是增强 Java Function,主要体现在这几点:

  • 统一云厂商的 FaaS 编程模型: Spring Cloud Function 的口号是 "Write Once, Run Anywhere"。我们写的 Spring Cloud Function 代码可以运行在本地、各个云厂商(AWS Lambda, GCP Cloud Functions, Azure Functions)。
  • 自动类型转换: 理解过 Spring MVC 或者 Spring Cloud Stream 的同学肯定对 HttpMessageConverter 或者 MessageConverter 模型,这个转换器的作用是将 HTTP BODY(或者 Message Payload)、HTTP Query Parameter、HTTP HEADER(或者 Message Header)自动转换成对应的 POJO。有了这个特性后,我们就无需关注函数的入参和返回值,用 String 参数就可以获取原始的入参信息,用 User 这个 POJO 参数就可以将原始的入参参数自动转换成 User 对象。
  • 函数组合: 可以让多个函数之间进行组合操作。
  • 函数管理: 新增 FunctionCatalog、FunctionRegistry 接口用于 Function 的管理。管理 ApplicationContext 内的 Function,动态注册 Function 等操作。
  • Reactive 支持: Spring Cloud Function 新增比如 FluxFunction、FluxSupplier、FunctionConsumer 这种 Reactive 函数。
  • 自动跟 Spring 生态内部原有的组件进行深度集成:
    • Spring Web/Spring WebFlux: 一次 HTTP 请求是一次函数调用。
    • Spring Cloud Task: 一次任务执行是一次函数调用。
    • Spring Cloud Stream: 一次消息消费/生产/转换是一次函数调用。

这里再多介绍统一云厂商的 FaaS 编程模型,让大家对 Spring Cloud Function 更有体感。

AWS Lambda 是第一个是提供 FaaS 服务的云厂商,RequestStreamHandler 是 AWS 提供的针对 Java 开发者的接口,需要实现这个接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class HandlerStream implements RequestStreamHandler {  
  @Override  
  public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException
  {    ...

Azure Functions 针对 Java 开发者提供了 @HttpTrigger 注解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Function {    
  public String echo(@HttpTrigger(name = "req",       
  methods = {HttpMethod.POST},  authLevel = AuthorizationLevel.ANONYMOUS)         String req, ExecutionContext context) { 
  ...    
  }
}

从这两段代码可以看出,不同的云厂商要编写不同的代码。如果要变换云厂商,这个过程会很痛苦。

另外,无论是 AWS、Azure 或者 GCP 提供的接口或注解,他们没有任何 Spring 上下文相关的初始化逻辑。如果我们是一个 Spring Boot/Cloud 应用迁移到 FaaS 平台,需要添加 Spring 上下文初始化逻辑等改动量。

Spring Cloud Function 的出现就是为了解决这些问题。

Spring Cloud Function 的使用

Spring Cloud Function & Spring Web:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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();    
  }
}

访问对应的 Endpoint:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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}

Spring Cloud Function & Spring Cloud Stream:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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;   
  }
}

加上 function 相关的配置(针对 input-topic 上的每个消息,payload 转换大写后再加上 prefix- 前缀,再写到 output-topic 上):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

Spring Cloud Function & Spring Cloud Task:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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); 
      };   
  }
}

加上 function 相关的配置(Supplier 模拟任务的输入源,Function 模拟对任务输入源的处理,Consumer 模拟处理对 Function 处理输入源后的数据):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.cloud.function.task.function=function
spring.cloud.function.task.supplier=supplier
spring.cloud.function.task.consumer=consumer

(完)

作者简介

方剑,花名洛夜,Spring Cloud Alibaba 开源项目负责人/创始人之一。Apache RocketMQ Committer,Alibaba Nacos Committer。目前就职于阿里巴巴集团。

曾在个人博客上编写过《Spring MVC源码分析系列》、《Spring Boot源码分析系列》文章。目前,关注微服务、云原生Kubernetes

图书推荐

▊《深入理解Spring Cloud与实战》

方剑 编著

  • Spring Cloud Alibaba创始人倾力打造
  • 理论与实践相结合,核心知识点辅以案例讲解

这是一本深入剖析 Spring Cloud 全家桶的书籍,主要介绍Spring Cloud各个核心组件的设计原理,以及目前流行的Spring Cloud Alibaba和 Netflix组件,并且剖析Spring Cloud对流处理、批处理,以及目前业界流行的Serverless的支持。在介绍各部分内容时,本书将理论与实践相结合,对每个核心知识点都给出了具体的案例应用,以帮助读者掌握核心组件的设计理念。

抽奖赠书

截止时间:2021年2月1日 17:00

如何抽奖:扫描下方二维码,关注公众号,回复关键词 :20210127

下次你更希望我们送哪本书呢?

留言告诉我们!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿DD 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Serverless安全研究 — Serverless概述
在“云”的概念还没有产生之前,开发者购买物理机,并在其上部署应用程序,企业将购买的机器放置数据中心,其网络、安全配置均需要专业的技术人员管理,在这种高成本运营模式下,虚拟化技术应运而生。
绿盟科技研究通讯
2020/09/08
2.2K0
深入浅出Serverless:3 Serverless的实现
AWS Lambda、Microsoft Azure Functions及Google Cloud Functions支持的开发语言
yeedomliu
2019/09/27
3.6K0
当我们在聊Serverless时你应该知道这些
作者:竹涧 原文地址:https://yq.aliyun.com/articles/574222
Nealyang
2019/10/24
1.2K0
当我们在聊Serverless时你应该知道这些
玩转Java8 Stream流
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/08/31
5420
玩转Java8 Stream流
CloudBluePrint-Chapter 1.7 : 云上应用技术架构-函数计算、Serverless、小程序
FaaS(函数即服务)、Serverless、小程序和弹性云计算的诞生可以归因于云计算发展的趋势和应用架构的演变。
行者深蓝
2023/09/01
4650
Serverless简介
Serverless的全称是Serverless computing无服务器运算,又被称为函数即服务(Function-as-a-Service,缩写为 FaaS),是云计算的一种模型。以平台即服务(PaaS)为基础,无服务器运算提供一个微型的架构,终端客户不需要部署、配置或管理服务器服务,代码运行所需要的服务器服务皆由云端平台来提供。 国内外比较出名的产品有Tencent Serverless、AWS Lambda、Microsoft Azure Functions 等。
xiangzhihong
2020/12/21
2.6K0
Serverless当打之年
当前大多数公司在运营应用产品时,无论是选择公有云还是自建的数据中心,都会面临服务器数量预估、存储容量规划和数据库的选型等问题。同时需要在基础设施之上部署依赖软件,以运行应用程序。当前是否存在一种简单的架构模型能够满足我们这种应用场景?当然,这个架构已经存在许久,它就是今天软件架构世界中很热门的一个话题——Serverless。
zouyee
2021/02/01
6880
Serverless当打之年
使用 Node.js 快速开启 ServerLess Functions:入门实践指南
近一年来我在很多地方看到 ServerLess 这一词出现,概念介绍的相对比较多,但是真正实践的还是很少,也是出于对新技术的好奇,所以我打算进一步的对 ServerLess 做一个了解,以便体验到 ServerLess 能给我们带来什么便捷,最好的例子还是先从一个 Hello World 开始。
五月君
2020/02/11
2.8K0
使用 Node.js 快速开启 ServerLess Functions:入门实践指南
【Web技术】244-Serverless掀起新的前端技术变革
最近关于 Serverless 的讨论越来越多。看似与前端关系不大的 Serverless,其实早已和前端有了渊源,并且将对前端开发模式产生变革性的影响。本文来自阿里云前端工程师蒋航在 QCon 北京 2019 的分享,他从前端开发模式的演进、基于 Serverless 的前端开发案例以及 Serverless 开发最佳实践等方面,与大家探讨 Serverless 中的前端开发模式。
pingan8787
2019/07/25
9500
【Web技术】244-Serverless掀起新的前端技术变革
入门 Serverless:如何实现 Hello World?
近年来,IT 技术的更新迭代速度非常快,每个时间点都有典型的代表名词以及概念,就目前而言,人工智能领域中的机器学习、深度学习、强化学习等名词和概念就非常热,同时区块链、物联网等技术发展也是异常火热。在云计算领域,有这样一个技术被众多云厂商认为是“风口项目”,甚至可以颠覆现有云计算中的某些格局,为此包括 AWS、谷歌以及腾讯云、阿里云等在内的云厂商,都为此投入了重大人力以及精力进行相关产品建设,它就是 Serverless 技术。 自 2006 年 8 月 9 日,Google 首席执行官埃里克·施密特(E
腾讯云serverless团队
2020/04/09
2.1K1
突发!Spring Cloud 也沦陷了。。。
点击关注公众号,Java干货及时送达 大家好,我是栈长。 相信大家看到了昨天的 Spring 漏洞,严重级别仅为中等,不必慌张, 栈长没想到的是,自这个月初 Spring Cloud Gateway 突发高危漏洞,现在 Spring Cloud 另外一个 Spring Cloud Function 模块也沦陷了。。。 来看最新昨天 Spring 官方博客发布的漏洞声明: 漏洞描述: 在使用路由功能时,用户可以制作特制的 SpEL 表达式作为路由表达式,从而导致用户可以 访问本地资源 的漏洞。 严重级别
Java技术栈
2022/03/31
7490
突发!Spring Cloud 也沦陷了。。。
深入浅出Serverless:2 Serverless与相关技术
介绍 作为一个热门词汇,Serverless并不孤单,和它一起受到广泛关注的还有诸如微服务(Microservice)、容器(Container)和云等。其实这些技术之间有着很强的关联关系。正确地理解Serverless和其他技术的关系,是正确理解Serverless架构的一个重要基础。要深入理解Serverless,需要结合当下业界发展的整个大环境和趋势进行思考。 云计算 从私有数据中心到云 按所管控的计算资源的范围来划分,云计算模式可以分为基础架构即服务(Infrastructure as a Serv
yeedomliu
2019/09/29
1.1K0
What is Serverless Web Application Development?
What is Serverless Web Application Development? Serverless web application development is an emergin
用户4822892
2019/08/20
6090
What is Serverless Web Application Development?
Java的函数式接口以及Lambda表达式
在java中,大家肯定使用过lambda表达式吧,这是适用于函数式接口的一种便捷写法。
半月无霜
2023/03/03
4820
Java的函数式接口以及Lambda表达式
【玩转腾讯云】基于Serverless搭建WordPress
在《Serverless Architectures》中对 Serverless 是这样子定义的:
落雨
2021/04/26
76.9K0
java8新特性整理
官方文档:http://docs.oracle.com/javase/specs/jls/se8/html/index.html
pollyduan
2019/11/04
1.2K0
从aws lambda谈serverless
一、基于aws lambda构建监控告警的思考二、什么是serverless?三、serverless解决了什么问题四、常见serverless应用场景五、为什么serverless淡出视野?六、参考
叔牙
2023/06/21
4210
从aws lambda谈serverless
Serverless 的前景和机会 |社区精选文章
本文为 Serverless 社区成员撰稿。作者谢扬,蒸汽记忆创始人,SoLiD 中文社区(learnsolid.cn)发起人。目前聚焦研发一款 IDaaS 身份即服务产品 Authing。供稿请戳~ Serverless 正在改变未来软件开发的模式和流程,对于大多数应用而言,借助 Serverless 服务,开发者可以将绝大多数精力投入在业务逻辑的开发整合上,大大缩短开发周期,降低运维成本。本文将探讨 Serverless 生态中缺少的工具以及潜在的创业机会。 我们目前创业做的事情跟 Serverles
腾讯云serverless团队
2020/03/04
1.4K0
Serverless 的前景和机会 |社区精选文章
Java8新特性
Jdk8提供了java.util.function包,提供了常用的函数式功能接口。
牧晗
2020/06/05
1.1K0
Java8新特性
Lambda表达式可以看成是匿名内部类,使用Lambda表达式时,接口必须是函数式接口
shimeath
2020/07/30
6300
Java8新特性
相关推荐
Serverless安全研究 — Serverless概述
更多 >
加入讨论
的问答专区 >
1KOL擅长5个领域
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    本文部分代码块支持一键运行,欢迎体验
    本文部分代码块支持一键运行,欢迎体验