這篇文章主要講解了“Java中的Serverless怎么使用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Java中的Serverless怎么使用”吧!
創(chuàng)新互聯(lián)憑借專業(yè)的設(shè)計(jì)團(tuán)隊(duì)扎實(shí)的技術(shù)支持、優(yōu)質(zhì)高效的服務(wù)意識(shí)和豐厚的資源優(yōu)勢(shì),提供專業(yè)的網(wǎng)站策劃、成都網(wǎng)站制作、成都做網(wǎng)站、網(wǎng)站優(yōu)化、軟件開(kāi)發(fā)、網(wǎng)站改版等服務(wù),在成都十載的網(wǎng)站建設(shè)設(shè)計(jì)經(jīng)驗(yàn),為成都上1000家中小型企業(yè)策劃設(shè)計(jì)了網(wǎng)站。
2019 年,O'Reilly 對(duì) 1500 名 IT 專業(yè)人員的調(diào)查中,有 40% 的受訪者在采用 Serverless 架構(gòu)的組織中工作。2020 年 DataDog 調(diào)查顯示,現(xiàn)在有超過(guò) 50% 的 AWS 用戶正在使用 Serverless 架構(gòu)的 AWS Lambda。
Serverless 正在成為主流,于是就誕生了下面這幅圖,從單體應(yīng)用的管理到微服務(wù)應(yīng)用的管理再到函數(shù)的管理。
Serverless 到目前為止還沒(méi)有一個(gè)精準(zhǔn)定義。
Baas 是全稱是 Backend-as-a-Service,后端即服務(wù),F(xiàn)aaS 的全稱是 Function-as-a-Service,函數(shù)即服務(wù)。
今天我們來(lái)聊聊 FaaS。這是維基百科對(duì) FaaS 的定義:
函數(shù)即服務(wù)(FaaS)是一類云計(jì)算服務(wù),它提供了一個(gè)平臺(tái),使客戶可以開(kāi)發(fā),運(yùn)行和管理應(yīng)用程序功能,而無(wú)需構(gòu)建和維護(hù)通常與開(kāi)發(fā)和啟動(dòng)應(yīng)用程序相關(guān)的基礎(chǔ)架構(gòu)。遵循此模型構(gòu)建應(yīng)用程序是實(shí)現(xiàn) Serverless 架構(gòu)的一種方法,通常在構(gòu)建微服務(wù)應(yīng)用程序時(shí)使用。
對(duì)于 Python、JavaScript 這種天生支持 Lambda 的開(kāi)發(fā)語(yǔ)言,和 FaaS 簡(jiǎn)直是完美結(jié)合。Serverless Framework 的調(diào)研報(bào)告也很好地說(shuō)明了這一點(diǎn)。NodeJS、Python 是 FaaS 使用率前二的語(yǔ)言。
我們知道,因?yàn)?JVM 占用的內(nèi)存比較大,所以 Java 應(yīng)用的啟動(dòng)會(huì)有點(diǎn)慢,不太適合 FaaS 這個(gè)場(chǎng)景,這也是 Java 在使用率上偏低的原因。
另外,對(duì) Java 開(kāi)發(fā)者來(lái)說(shuō) Spring Boot/Cloud 已經(jīng)成為了事實(shí)標(biāo)準(zhǔn),依賴注入是 Spring Framework 的核心,Spring Boot/Cloud 這個(gè)事實(shí)標(biāo)準(zhǔn)應(yīng)對(duì) FaaS 這個(gè)場(chǎng)景,會(huì)碰撞出怎么樣的火花呢?這就是今天我們要聊的 Spring Cloud Function。
在對(duì) Spring Cloud Function 介紹之前,我們先來(lái)看 Java 里的核心函數(shù)定義。
JDK 1.8 推出了新特性 Lambda 表達(dá)式,java.util.function 包下面提供了很多的函數(shù)。這 3 個(gè)函數(shù)尤為重要:
1. java.util.function.Function: 需要一個(gè)參數(shù),得到另一個(gè)結(jié)果.
@FunctionalInterface public interface Function{ R apply(T t); }
比如通過(guò) Stream API 里的 map 方法可以通過(guò) Function 把字符串從小寫(xiě)變成大寫(xiě):
Stream.of("a", "b", "c").map(String::toUpperCase);
這里的 map 方法需要一個(gè) Function 參數(shù):
Stream map(Function super T, ? extends R> mapper);
2. java.util.function.Consumer: 需要一個(gè)參數(shù)進(jìn)行操作,無(wú)返回值。
@FunctionalInterface public interface Consumer{ void accept(T t); }
比如通過(guò) Stream API 里的 forEach 方法遍歷每個(gè)元素,做對(duì)應(yīng)的業(yè)務(wù)邏輯處理:
RestTemplate restTemplate = new RestTemplate(); Stream.of("200", "201", "202").forEach(code -> { ResponseEntityresponseEntity = restTemplate.getForEntity("http://httpbin.org/status/" + code, String.class); System.out.println(responseEntity.getStatusCode()); });
3. java.util.function.Supplier: 得到一個(gè)結(jié)果,無(wú)輸入?yún)?shù)。
@FunctionalInterface public interface Supplier{ T get(); }
比如自定義 Supplier 可以返回隨機(jī)數(shù):
Random random = new Random(); Supplier supplier100 = () -> random.nextInt(100); Supplier supplier1000 = () -> random.nextInt(1000); System.out.println(supplier100.get()); System.out.println(supplier1000.get());
Java Function 的編程模型非常簡(jiǎn)單,本質(zhì)上就是這 3 個(gè)核心函數(shù):
Supplier
Function
Consumer
Spring Cloud Function 是 Spring 生態(tài)跟 Serverless(FaaS) 相關(guān)的一個(gè)項(xiàng)目。它出現(xiàn)的目的是增強(qiáng) Java Function,主要體現(xiàn)在這幾點(diǎn):
統(tǒng)一云廠商的 FaaS 編程模型: Spring Cloud Function 的口號(hào)是 "Write Once, Run Anywhere"。我們寫(xiě)的 Spring Cloud Function 代碼可以運(yùn)行在本地、各個(gè)云廠商(AWS Lambda, GCP Cloud Functions, Azure Functions)。
自動(dòng)類型轉(zhuǎn)換: 理解過(guò) Spring MVC 或者 Spring Cloud Stream 的同學(xué)肯定對(duì) HttpMessageConverter 或者 MessageConverter 模型,這個(gè)轉(zhuǎn)換器的作用是將 HTTP BODY(或者 Message Payload)、HTTP Query Parameter、HTTP HEADER(或者 Message Header)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的 POJO。有了這個(gè)特性后,我們就無(wú)需關(guān)注函數(shù)的入?yún)⒑头祷刂?,?String 參數(shù)就可以獲取原始的入?yún)⑿畔ⅲ?User 這個(gè) POJO 參數(shù)就可以將原始的入?yún)?shù)自動(dòng)轉(zhuǎn)換成 User 對(duì)象。
函數(shù)組合: 可以讓多個(gè)函數(shù)之間進(jìn)行組合操作。
函數(shù)管理: 新增 FunctionCatalog、FunctionRegistry 接口用于 Function 的管理。管理 ApplicationContext 內(nèi)的 Function,動(dòng)態(tài)注冊(cè) Function 等操作。
Reactive 支持: Spring Cloud Function 新增比如 FluxFunction、FluxSupplier、FunctionConsumer 這種 Reactive 函數(shù)。
自動(dòng)跟 Spring 生態(tài)內(nèi)部原有的組件進(jìn)行深度集成:Spring Web/Spring WebFlux: 一次 HTTP 請(qǐng)求是一次函數(shù)調(diào)用。Spring Cloud Task: 一次任務(wù)執(zhí)行是一次函數(shù)調(diào)用。Spring Cloud Stream: 一次消息消費(fèi)/生產(chǎn)/轉(zhuǎn)換是一次函數(shù)調(diào)用。
這里再多介紹統(tǒng)一云廠商的 FaaS 編程模型,讓大家對(duì) Spring Cloud Function 更有體感。
AWS Lambda 是第一個(gè)是提供 FaaS 服務(wù)的云廠商,RequestStreamHandler 是 AWS 提供的針對(duì) Java 開(kāi)發(fā)者的接口,需要實(shí)現(xiàn)這個(gè)接口:
public class HandlerStream implements RequestStreamHandler { @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { ...
Azure Functions 針對(duì) Java 開(kāi)發(fā)者提供了 @HttpTrigger 注解:
public class Function { public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) { ... } }
從這兩段代碼可以看出,不同的云廠商要編寫(xiě)不同的代碼。如果要變換云廠商,這個(gè)過(guò)程會(huì)很痛苦。
另外,無(wú)論是 AWS、Azure 或者 GCP 提供的接口或注解,他們沒(méi)有任何 Spring 上下文相關(guān)的初始化邏輯。如果我們是一個(gè) Spring Boot/Cloud 應(yīng)用遷移到 FaaS 平臺(tái),需要添加 Spring 上下文初始化邏輯等改動(dòng)量。
Spring Cloud Function 的出現(xiàn)就是為了解決這些問(wèn)題。
Spring Cloud Function & Spring Web:
@SpringBootApplication public class SpringCloudFunctionWebApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionWebApplication.class, args); } @Bean public FunctionupperCase() { return s -> s.toUpperCase(); } @Bean public Function user() { return user -> user.toString(); } }
訪問(wèn)對(duì)應(yīng)的 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}
Spring Cloud Function & Spring Cloud Stream:
@SpringBootApplication public class SpringCloudFunctionStreamApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionStreamApplication.class, args); } @Bean public Functionuppercase() { return x -> x.toUpperCase(); } @Bean public Function prefix() { return x -> "prefix-" + x; } }
加上 function 相關(guān)的配置(針對(duì) input-topic 上的每個(gè)消息,payload 轉(zhuǎn)換大寫(xiě)后再加上 prefix- 前綴,再寫(xiě)到 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
Spring Cloud Function & Spring Cloud Task:
@SpringBootApplication public class SpringCloudFunctionTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFunctionTaskApplication.class, args); } @Bean public Supplier> supplier() { return () -> Arrays.asList("200", "201", "202"); } @Bean public Function
, List
> function() { return (list) -> list.stream().map( item -> "prefix-" + item).collect(Collectors.toList()); } @Bean public Consumer > consumer() { return (list) -> { list.stream().forEach(System.out::println); }; } }
加上 function 相關(guān)的配置(Supplier 模擬任務(wù)的輸入源,F(xiàn)unction 模擬對(duì)任務(wù)輸入源的處理,Consumer 模擬處理對(duì) Function 處理輸入源后的數(shù)據(jù)):
spring.cloud.function.task.function=function spring.cloud.function.task.supplier=supplier spring.cloud.function.task.consumer=consumer
感謝各位的閱讀,以上就是“Java中的Serverless怎么使用”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Java中的Serverless怎么使用這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!