介绍:SpringBootServerless实战系列第四篇来了。本文将介绍如何对Serverless应用进行性能调优。SpringBoot是一个基于JavaSpring框架的套件。它预装了一系列Spring组件,允许开发人员使用很少的配置创建独立的应用程序。在云原生的世界里,可以运行SpringBoot应用的平台有很多,比如虚拟机、容器等,但其中最吸引人的还是以Serverless的方式运行SpringBoot应用。通过系列文章,我将从架构、部署、监控、性能、安全五个方面来分析在Serverless平台上运行SpringBoot应用的优缺点。为了让分析更具有代表性,我选择了github上50k以上star的电商应用商城作为例子。这是系列文章中的第四篇文章,向您展示如何调优Serverless应用程序的性能。实例启动速度优化在之前的文章实战教程中,相信大家都能感受到Serverless的便捷与美好。只需上传代码包和镜像,即可轻松启动弹性高可用的Web应用。但是,它在第??一次启动时仍然存在“冷启动延迟”的问题。商城应用实例的启动大约需要30秒,用户会经历很长的冷启动延迟。在这个“即时时代”,应用程序响应会有些慢。瑕不掩瑜。(“冷启动”指的是函数正在为特定的调用请求服务时的状态,当一段时间没有请求时,Serverless平台会回收函数实例;下次有请求时,系统会再次实时拉起实例。这个过程称为冷启动。)在优化冷启动之前,我们首先要分析冷启动各个阶段的耗时。首先,在函数计算(FC)控制台的服务配置界面开启链路追踪功能。向mall-admin服务发起请求,成功后查看FC控制台,我们可以看到相应的请求信息。确保关闭“仅查看功能错误”,以便显示所有请求。指标监控和调用链路数据采集会有一定的延迟。如果没有显示,请稍等片刻再刷新。找到冷启动标记的请求,单击“更多”下的“请求详细信息”。调用环节会显示冷启动各个环节的耗时。冷启动包括以下步骤:代码准备(PrepareCode):主要是下载代码包或图片。由于我们启用了图片加速功能,所以不需要下载所有图片,所以这一步的延迟很短。运行时初始化(RuntimeInitialization):从函数启动开始,直到函数计算(FC)系统检测到应用端口就绪。这包括应用程序启动时间。在命令行执行small-adminlogs查看对应的日志时间,我们也可以看到SpringBoot应用的启动耗时比较长。应用初始化(Initialization):函数计算提供了Initializer接口,用户可以在initializer中执行一些初始化逻辑。调用延迟(Invocation):处理请求的延迟,很短。从上面的linktrace图可以看出,实例启动时间是瓶颈,我们可以通过多种方式对其进行优化。1.1.使用保留实例的Java类应用程序通常启动缓慢。应用在初始化的时候,还需要和很多外部服务进行交互,耗时较长。这类流程是业务逻辑需要的,延迟很难优化。因此,函数计算提供了预留实例功能。预留实例的启停由用户控制,即使没有请求也会一直停留,不会出现冷启动问题。当然,用户需要为整个实例的运行付费,即使该实例不处理任何请求。在函数计算控制台中,我们可以在“弹性伸缩”页面为函数设置预留实例。用户在控制台中配置最小和最大实例数。平台将预留实例数最少的实例,最大实例数是指该功能下的实例数上限。用户还可以设置定时预约和按度量预约的规则。创建预留规则时,将创建预留实例。当预留实例就绪后,我们再次访问该函数时就不会冷启动了。1.2.优化实例启动速度延迟初始化在SpringBoot2.2及之后的版本中,可以开启一个全局的延迟初始化标志。这将提高启动速度,但代价是可能会有更长的首次请求延迟,因为它会等待组件首次初始化。相关应用可以在s.yaml中配置如下环境变量SPRING_MAIN_LAZY_INITIATIALIZATION=true关闭优化编译JVM默认有多个阶段的JIT编译。虽然这些阶段可以逐步提高应用程序的效率,但它们也会增加内存使用的开销并增加启动时间。对于短期运行的无服务器应用程序,请考虑关闭此优化以牺牲长期效率来换取更快的启动时间。s.yaml中可以为相关应用配置如下环境变量:JAVA_TOOL_OPTIONS="-XX:+TieredCompilation-XX:TieredStopAtLevel=1"s.yaml中设置环境变量示例:如下图,配置环境对于mall-admin函数变量。然后执行sudo-Esmall-admindeploy进行部署。登录实例查看环境变量配置是否正确。在控制台功能详情页面的请求列表中找到对应的请求,点击更多中的“实例详情链接”。在实例详情页面点击“登录实例”。在shell界面执行echo命令,查看相应的环境变量是否设置正确。注意:对于非预留实例,函数计算会在一段时间没有请求后自动回收实例。此时无法再登录实例(在上面的实例详情页面中,登录实例按钮会变灰)。所以请在调用后尽快登录,在实例被回收之前。配置合理的实例参数我们在选择应用实例规格时,比如2C4G或者4C8G,都想知道一个实例能处理多少个请求,从而充分利用资源,保证性能。当处理的请求超过限制时,系统可以快速弹出实例以确保应用性能流畅。如何衡量实例过载有多个维度,比如qps超过某个阈值,或者实例CPU/Memory/Network/Load等指标超过阈值等等。函数计算以实例并发(InstanceConcurrency)作为实例负载的衡量标准和实例伸缩的依据。实例并发是指一个实例可以同时执行的请求数。例如,将实例并发设置为20,表示一个实例在任何时刻最多可以同时执行20个请求。注意:请区分实例并发和QPS的区别。使用实例并发度来衡量负载有以下好处:系统可以快速统计实例并发度指标值进行伸缩。CPU/Memory/Network/Load等实例级指标通常在后台统计,需要几十秒的时间收集指标再进行伸缩,难以满足在线应用的弹性伸缩需求。在各种条件下,实例并发指标能够稳定地反映系统负载的高低。如果以请求延迟作为指标,系统很难区分是实例过载导致延迟增加,还是下游服务成为瓶颈导致延迟增加。例如,典型的Web应用程序通常访问MySQL数据库。如果数据库成为瓶颈,请求延迟变大,此时扩容不仅没有意义,还会压垮数据库,让情况变得更糟。QPS与请求延迟有关,也会出现上述问题。虽然以实例并发作为伸缩的基础,虽然具有以上优点,但用户往往不知道实例并发应该设置多少。我推荐按照下面的流程来确定一个合理的并发度:将应用函数的最大实例数设置为1,保证在压力下测试单个实例的性能。使用负载压测工具对应用进行测试,查看tps、请求延迟等指标,逐步提高实例并发。如果表现还不错,继续增加;如果性能没有达到预期,降低并发度。原文链接本文为阿里云原创内容,未经许可不得转载。
