前言随着技术的发展,我们实现业务逻辑的选择越来越多。Serverless作为当今的前沿技术,是否也能探索微服务架构的新可能?这篇文章是对我近期使用serverless落地SpringBoot微服务项目的一些探索成果的总结。什么是Serverless,什么是微服务,什么是springBoot,已经不需要我解释了。那么什么是无服务器?根据CNCF的定义,Serverless是指构建和运行不需要服务器管理的应用程序的概念。Serverless并不是说没有服务器就可以进行计算,而是开发者或者企业可以在不了解和管理底层服务器的情况下进行计算。通俗的说,Serverless是对底层的计算资源进行了封装,你只需要提供运行它的函数即可。这里要提到的另一个概念是FaaS(FunctionasaService),功能即服务。我们通常在Serverless上运行的逻辑是函数级别的粒度。所以对于微服务来说,使用Serverless是非常合适的,拆分粒度控制合理。Serverless对微服务的价值每个微服务调用API的频率不同,使用Serverless可以精确管理成本和弹性。不用担心因为大量的API调用而需要扩展整个服务。Serverless可以自动向上和向下扩展。不需要运维每个服务后面部署多少容器和服务器,也不需要做负载均衡。屏蔽了K8S等容器编排的复杂学习成本。Serverless的无状态特性也非常符合微服务使用RestfulAPI的特性。初步实践首先需要准备一个SpringBoot工程,可以通过start.spring.io快速创建。在业务开发上,Serverless与传统的微服务开发没有区别。于是赶紧写了一个todo后端服务,完成了增删改查功能。示例代码在这里。那么使用Serverless的真正区别在哪里呢?如果单纯想部署单个服务,主要区别在于两个方面:部署方式、启动方式、部署方式。由于我们无法接触到服务器,因此部署方式发生了很大变化。传统微服务部署通常直接部署在虚拟机上运行,??或者使用K8S进行容器化调度。传统的部署关系大致如下图所示。如果我们使用Serverless,我们一般会要求我们的微服务被拆分成更细的粒度,以实现FaaS。所以使用Serverless部署微服务的关系大致如下图所示。Serverless只需要提供代码,因为Serverless有自己的运行环境,所以在Serverless中部署微服务通常有两种方式:代码包上传部署镜像部署第一种方式与传统部署的区别最大。需要我们把写好的代码打包上传。并且需要指定入口函数或者指定监听端口。第二种方法和传统的方法差不多,就是把完成的镜像上传到我们的镜像仓库。然后在serverless平台部署时选择对应的镜像。启动方式是因为serverless在使用的时候创建对应的实例,不用的时候销毁实例,体现了serverless按量计费的特点。所以serverless在第一次调用的时候有一个冷启动过程。所谓冷启动,是指需要平台分配计算资源,加载并启动代码。因此,根据运行环境和代码的不同,可能会有不同的冷启动时间。作为一种静态语言,Java的启动速度一直为人诟病。不过还是有比较慢的,就是spring的启动时间,这是有目共睹的。因此,java+spring的强强联合造就了树懒般的启动速度。这可能会导致第一次调用该服务的等待时间很长。不过不用担心,spring已经提供了两种缩短启动时间的方案。一个是SpringFu,一个是SpringNative。SpringFuSpringFu是JaFu(JavaDSL)和KoFu(KotlinDSL)的孵化器,以声明方式使用代码显式配置SpringBoot,由于自动完成功能,具有很高的可发现性。它提供快速启动(比最小SpringMVC应用程序的常规自动配置快40%)、低内存消耗,并且由于其(几乎)无反射方法而非常GraalVM原生。如果配合GraalVM编译器,应用启动速度可以直线下降到原来的1%左右。但是,SpringFu还处于非常早期的阶段,在使用过程中存在很多问题。另外,使用SpringFu会有很大的代码改造成本,因为它把所有的注解都干掉了,所以这次我没有使用SpringFu。SpringNativeSpringNative使用GraalVM本机图像编译器将Spring应用程序编译成本机可执行文件,以提供打包在轻量级容器中的本机部署选项。SpringNative的目标是在这个新平台上支持SpringBoot应用程序,几乎没有代码转换成本。所以我选择了Spring原生,因为它不需要修改代码,只需要添加一些插件和依赖就可以实现原生镜像。本机映像有几个优点:未使用的代码在构建时从类路径中删除没有类被延迟加载:可执行文件中的所有内容在启动时加载到内存中并在构建时运行一些代码基于这些特性,因此它可以使程序的启动时间要快得多。我将在下一篇文章中解释如何使用它。详细教程可以查看这个官方教程。我也遵循了本教程。先说一下我的测试对比结果吧。我在本地部署测试了编译好的镜像,腾讯云serverless云函数和AWSserverlesslambda。规格SpringBoot冷启动时间SpringNative冷启动时间本地16G内存Mac1秒79毫秒腾讯云Serverless256M内存13秒300毫秒AWSServerless256M内存21秒1秒从测试结果来看,SpringNative在启动速度上有很大提升。增加serverless规范可以进一步提高速度。如果Serverless的冷启动速度控制在1秒以内,那么大部分业务是可以接受的。并且只有第一次请求时才会冷启动,其他请求的响应时间和普通微服务一样。此外,目前各大平台的Serverless都支持预配置实例,即在访问到达之前提前创建实例,以减少冷启动时间。为业务带来更高的响应时间。综上所述,Serverless作为目前比较先进的技术,给我们带来了很多好处。自动伸缩和细粒度资源分配的弹性和并发松耦合,免运维。然而,无服务器并不完美。当我们尝试在微服务领域使用它时,我们仍然可以看到有很多问题有待解决。难以监控和调试这是目前公认的痛点冷启动可能会更多当我们拆分微服务以适应功能粒度时,我们也分散了每个功能的调用时间,导致每个功能调用的频率较低,导致更多的冷启动开始。函数之间的交互会更加复杂。由于功能的粒度更细,在大型微服务项目中,本来就错综复杂的微服务会变得更加错综复杂。综上所述,要想完全取代传统虚拟机,Serverless在微服务的道路上还有很长的路要走。下一步,我会继续探索Serverless和微服务的实践。在接下来的文章中,我将讨论以下主题:无服务器中的服务间调用无服务器服务中的数据库访问无服务器服务中的注册和发现无服务器服务中的熔断和降级无服务器中的拆分
