Skip to content

Commit 579d30c

Browse files
author
serverless-devs
committed
commit by Serverless devs docs 4-19-2022 13:30:38
1 parent 13f58e3 commit 579d30c

5 files changed

+491
-1
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
title: Springboot Serverless 实战 - 性能调优
3+
description: 'Springboot Serverless 实战 - 性能调优'
4+
position: 14
5+
category: 'FC_Blog'
6+
---
7+
8+
作者 | 西流
9+
10+
[SpringBoot](https://spring.io/projects/spring-boot) 是基于 Java Spring 框架的套件,它预装了 Spring 的一系列组件,让开发者只需要很少的配置就可以创建独立运行的应用程序。在云原生的世界,有大量的平台可以运行 SpringBoot 应用,例如虚拟机,容器等。但其中最有吸引力的,是以 Serverless 的方式运行 SpringBoot 应用。我将通过一系列文章,从架构,部署,监控、性能、安全等5个方面来分析 Serverless 平台运行 SpringBoot 应用的优劣。为了让分析更有代表性,我选择了 github 上 star 数超过 50k 的电商应用 [mall](https://github.com/macrozheng/mall) 作为示例。这是系列文章的第四篇, 向大家展示如何对 Serverless 应用性能调优。
11+
12+
## 1. 实例启动速度优化
13+
14+
在之前的教程中,相信大家都感受到 Serverless 的快捷,上传代码包和镜像,就上线了一个弹性高可用的 Web 应用。但其中一个不好的点是首次启动会很慢,因为一段时间没有请求后,Serverless 平台会回收函数实例。下一次再有请求,系统会实时拉起实例,这个过程称之为冷启动。Mall 应用实例的启动大约 30 秒左右,用户会感受较长时间的冷启动延时。
15+
16+
在优化冷启动之前,我们首先分析清楚冷启动各个阶段的耗时。在函数计算(FC) 控制台的服务配置界面,开启链路追踪功能。
17+
18+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1636529127016-4d7c8676-164f-4830-a42f-fa5f4c1e3ad8.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=P0e5T&originHeight=798&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
19+
20+
对 mall-admin 服务发起请求,成功后查看 FC 控制台,我们能看到相应的请求信息。注意关闭“仅查看函数错误”,这样才会显示所有请求。指标监控和调用链路数据收集有一定延时,如果没有显示,请等待一会再刷新。找到冷启动标记的请求,点击 “更多” 下的 “请求详情”。
21+
22+
![](https://cdn.nlark.com/yuque/0/2022/png/995498/1641283516964-1e17dc64-1011-4a40-bb57-ea7370269e3e.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=nyZEH&originHeight=721&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
23+
24+
调用链路会显示冷启动各个环节的耗时。冷启动包含以下几个环节:
25+
26+
- 代码准备(PrepareCode):主要是下载代码包或者镜像。由于我们已经启用了镜像加速功能,不需要下载全部的镜像,因此这一步的延时非常短
27+
- 运行时初始化(RuntimeInitialization):从启动函数开始,到函数计算(FC)系统探测到应用端口就绪为止。这中间包含了应用启动时间。在命令行执行 `s mall-admin logs`查看相应的日志时间,我们也能看到 SpringBoot 应用的启动需要花大量的时间
28+
- 应用初始化(Initialization):函数计算提供了 Initializer 接口,用户可以将一些初始化逻辑放在 initializer 中执行
29+
- 调用延时(Invocation):处理请求的延时,这个延时非常短
30+
31+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1636532656418-6570b6e9-b3ab-4923-b064-2ce8a408672e.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=zWAMb&originHeight=390&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
32+
33+
从上述链路追踪图来看,实例启动时间是瓶颈,我们可以采取多种方式来优化。
34+
35+
### 1.1. 使用预留实例
36+
37+
Java 类应用普遍启动较慢。应用在初始化时,也需要和很多外部服务交互,耗时较长。这类流程是业务逻辑需要的,很难优化延时。因此函数计算提供了预留实例功能。预留实例的起停由用户自己控制,没有请求也会常驻在那,因此不会有冷启动的问题,当然用户需要为整个实例的运行付费,即便实例没有处理任何请求。
38+
39+
在函数计算控制台,我们可以在“弹性伸缩”页面为函数设置预留实例。
40+
41+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1636616176229-bde75cec-bad6-4801-a61d-6346ed0b1ea4.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=OYNx0&originHeight=470&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
42+
43+
用户在控制台中配置最小和最大实例数。平台会预留最小实例数目的实例,最大实例是指该函数下实例的上限。用户也可以设置定时预留和按指标预留的规则。
44+
45+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1636616934812-6d21f0c2-2586-430d-89c1-6d8023d195d0.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=nk1Hf&originHeight=618&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
46+
47+
创建预留规则后,系统就会创建预留实例。当预留实例就绪后,我们再访问函数就不会有冷启动。
48+
49+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1636618290293-d4c58351-6b1d-49c7-9826-67a46a28bea4.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=BQCdJ&originHeight=469&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
50+
51+
### 1.2. 优化实例启动速度
52+
53+
#### 延迟初始化
54+
55+
在 Spring Boot 2.2 及更高版本中,可以开启一个全局延迟初始化标志。这将提高启动速度,但代价是第一个请求的延迟时间可能变长,因为需要等待组件首次初始化。
56+
57+
可在 s.yaml 中为相关应用配置以下环境变量
58+
59+
```shell
60+
SPRING_MAIN_LAZY_INITIATIALIZATION=true
61+
```
62+
63+
#### 关闭优化编译器
64+
65+
默认情况下,JVM 有多个阶段的 JIT 编译。虽然这些阶段可以逐渐提高应用的效率,但它们也会增加内存使用的开销,并增加启动时间。对于短期运行的 serverless 应用,请考虑关闭此优化,以牺牲长期效率换取更短的启动时间。
66+
67+
可在 s.yaml 中为相关应用配置以下环境变量:
68+
69+
```shell
70+
JAVA_TOOL_OPTIONS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
71+
```
72+
73+
#### s.yaml 中设置环境变量示例:
74+
75+
如下图所示,对 mall-admin 函数配置环境变量。然后执行 `sudo -E s mall-admin deploy` 部署。
76+
77+
![](https://cdn.nlark.com/yuque/0/2022/png/995498/1642384597670-93d52126-1392-4077-add5-42e619a617a8.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=aPGAW&originHeight=1433&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
78+
79+
#### 登录实例检查环境变量是否配置正确
80+
81+
在控制台函数详情页的请求列表中找到对应的请求,点击`更多`中的`实例详情`链接。
82+
83+
![](https://cdn.nlark.com/yuque/0/2022/png/995498/1642384850027-aac7716b-9bde-4866-841d-675ac6726a9c.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=fNr3T&originHeight=700&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
84+
85+
在实例详情页中点击`登录实例`
86+
87+
![](https://cdn.nlark.com/yuque/0/2022/png/995498/1642385045445-625b2fbc-3ff1-48a1-9de8-61c7f760a7a6.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0#crop=0&crop=0&crop=1&crop=1&id=IAPjf&originHeight=740&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
88+
89+
在 shell 界面中执行 echo 命令,查看对应的环境变量是否设置正确。
90+
91+
> 注意:对于非预留实例,一段时间没有请求后,函数计算系统会自动回收实例。此时无法再登入实例(上面的`实例详情`页面中的`登录实例`按钮会变灰)。所以请执行调用后,在实例被回收之前尽快登录。
92+
93+
94+
![](https://cdn.nlark.com/yuque/0/2022/png/995498/1642385572234-8531e14c-0fe7-4a74-892b-d1885c40c1a5.png#crop=0&crop=0&crop=1&crop=1&id=fbrgA&originHeight=980&originWidth=2840&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
95+
96+
## 2. 配置合理的实例参数
97+
98+
当我们选择了应用实例规格,比如 2C4G 或者 4C8G,接下来我们希望知道一个实例处理多少请求是合适的,既能充分利用资源又能保证性能。当处理的请求超过一个限制后,系统能够快速弹出实例,保证应用性能平滑。如何度量实例过载有多个维度,例如 qps 超过一定阈值,或者实例 CPU/Memory/Network/Load 等指标超过阈值等等。函数计算使用实例并发度(Instance Concurrency)来作为实例负载的度量和实例伸缩的依据。实例并发度(Instance Concurrency)是指一个实例能同时执行的请求数。例如将实例并发度设置为20,则意味着一个实例在任意时刻最大能**同时**执行20个请求。
99+
100+
> 注意:请区分实例并发度和 QPS 的区别。
101+
102+
103+
使用实例并发度来度量负载有如下优势:
104+
105+
- 系统能够迅速统计实例并发度指标值进行扩缩容。CPU/Memory/Network/Load 等实例级别的指标通常是后台统计,需要花费数十秒的指标统计后才能进行伸缩,难以满足在线应用的弹性伸缩要求
106+
- 在各种条件下,实例并发度指标都能够稳定的反映系统负载高低。如果以请求延时作为指标,系统难以区分是实例过载导致延时变大,还是下游服务成为瓶颈导致延时变大。例如一个典型的 Web 应用,通常会访问 MySQL 数据库。如果数据库成为瓶颈,请求延时变大,此时扩容不但毫无意义,而且会压垮数据库,让情况更加恶化。QPS 和请求延时相关,也会有上述问题
107+
108+
实例并发度作为伸缩依据虽然有上述优点,但用户常常并不知道该设置多大的实例并发度。推荐按照下述流程确定合理的并发度:
109+
110+
1. 将应用函数的最大实例数设置为1,确保压测到单个实例的性能。
111+
1. 使用负载压测工具对应用进行压测,查看 tps 和请求延时等指标
112+
1. 逐步调大实例并发度,如果性能仍然良好,则继续调大;如果性能不符合预期,则调小并发度。
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Springboot Serverless 实战 - 架构
3+
description: 'Springboot Serverless 实战 - 架构'
4+
position: 11
5+
category: 'FC_Blog'
6+
---
7+
8+
作者 | 西流
9+
10+
[SpringBoot](https://spring.io/projects/spring-boot) 是基于 Java Spring 框架的套件,它预装了 Spring 的一系列组件,让开发者只需要很少的配置就可以创建独立运行的应用程序。在云原生的世界,有大量的平台可以运行 SpringBoot 应用,例如虚拟机,容器等。但其中最有吸引力的,是以 Serverless 的方式运行 SpringBoot 应用。我将通过一系列文章,从架构,部署,监控、性能、安全等5个方面来分析 Serverless 平台运行 SpringBoot 应用的优劣。为了让分析更有代表性,我选择了 github 上 star 数超过 50k 的电商应用 [mall](https://github.com/macrozheng/mall) 作为示例。这是系列文章的第一篇,首先从架构角度分析 SpringBoot 应用的 Serverless 化。
11+
12+
## Mall 架构简介
13+
14+
Mall 是一套电商系统,包括前台商城系统及后台管理系统,基于 SpringBoot + MyBatis 实现。前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。
15+
16+
Mall 的架构如下图所示,分为网关层,应用层,数据存储层。请求首先通过网关到达 SpringBoot 应用服务。网关实现负载均衡,流量控制等功能。应用层包含3个 SpringBoot 应用和1个前端应用:
17+
18+
- mall-admin:后台商城管理系统
19+
- mall-portal:前台商城系统
20+
- mall-search:于Elasticsearch的商品搜索系统
21+
- Mall-admin-web:mall-admin 的前端展示,基于 Vue+Element 实现
22+
23+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1635518177477-9483f633-440d-4015-9d4a-7b9d32e1efc3.png#id=hFSCs&originHeight=665&originWidth=1744&originalType=binary&ratio=1&status=done&style=none)
24+
25+
Mall 使用了 MySQL,Redis,MongoDB,ElaisticSearch 等多种数据库。主要业务数据存储在 MySQL,缓存数据存储在 Redis,用户行为分析数据存储在 MongoDB,搜索数据存储在 ElasticSearch 中。SpringBoot 应用服务间使用 RabbitMQ 实现异步通信。
26+
27+
## Serverless 计算平台-函数计算简介
28+
29+
Serverless 是指用户上传代码包或者容器镜像,平台会负责申请资源,可靠的运行代码。[函数计算](https://help.aliyun.com/product/50980.html)(Function as a Service,FaaS)是 Serverless 的一种计算模式,最突出的特点是内置了网关层能力,能够实现缩容到0,快速的自动伸缩。函数计算也提供了全面的可观测和问题诊断能力。函数计算这些特点,使其很适合 SpringBoot 这类 Web 应用。使用函数计算,开发者只需要专注于 SpringBoot 应用逻辑的实现,而不再费心应用运行环境的搭建、部署、监控等无差别的工作。
30+
31+
## Mall 应用 Serverless 架构总览
32+
33+
Mall 是一个非常标准的 3 层架构 Web 应用,改造为 Serverless 架构非常容易,架构如下所示。由于函数计算内置了网关服务,自动拉起实例运行应用,因此开发者只需要上传应用代码即可。
34+
35+
应用实例在函数计算平台上运行,能够自由的访问其他服务,因此和 MySQL,Redis,RabbitMQ 等服务的访问方式不变。
36+
37+
函数计算内置了日志收集和展示能力。开发者为函数计算指定[阿里云日志服务](https://help.aliyun.com/product/28958.html)的 LogStore,打到标准输出的日志会自动收集到日志服务查询、展示。开发者也可将日志投递到自己的日志处理系统中,但需要做一些额外的配置。在本示例中,我们采用阿里云日志服务来处理应用日志。
38+
39+
函数计算也提供了一系列工具,帮助开发者通过 Jenkins CICD 工具发布应用。我们将在后续的文章中一一展示。
40+
41+
![](https://cdn.nlark.com/yuque/0/2021/png/995498/1635558315375-5d5ea2dd-abcb-4473-8477-e22817184a5c.png#id=nOX6T&originHeight=734&originWidth=1744&originalType=binary&ratio=1&status=done&style=none)
42+
43+
## 在函数计算平台运行 SpringBoot 应用
44+
45+
在阿里云函数计算平台上运行 Web 应用,需要了解以下几个概念:
46+
47+
- [服务](https://help.aliyun.com/document_detail/74925.htm):函数计算的服务资源对应微服务。一个服务下可以创建多个函数,这些函数共享服务级别的配置,包括日志、权限、VPC 网络访问配置等等。一般来说,开发者根据业务场景设计微服务架构,然后为每一个微服务创建函数计算的服务。然后再根据需求,将微服务实现为更细粒度的函数。比如有些逻辑是计算密集型的,可以将它拆分为另一个函数,配置不同的实例规格,既满足性能要求,又优化了成本。按照微服务的理念,一个服务下的函数个数不宜太多
48+
- [函数](https://help.aliyun.com/document_detail/52077.html):函数是运行开发者代码的基本单位。函数的粒度可以很细,比如对应 1 个 API,也可以较粗,对应一组 API。不同的函数配置不同的实例规格。函数计算提供了各种语言的运行时,也提供 custom runtime/custom container 和语言无关的运行时。如果只是用函数计算实现片段代码,可以使用相关语言的运行时。在我们的场景下,因为要无缝迁移 SpringBoot 应用,我们选择 custom container 运行时。Mall 项目已经支持了将 mall 应用自动打包为容器镜像,因此只需要将镜像上传至阿里云容器镜像仓库,并在函数上指定相关信息即可
49+
- [HTTP 触发器](https://help.aliyun.com/document_detail/71229.html):为函数配置 HTTP 触发器后,函数可通过 HTTP 请求的方式调用。函数计算配套的 Serverless Devs 工具会为 HTTP 触发器生成测试域名,开发者可以方便的调试和运行 Web 应用
50+
51+
在了解了这些基本概念后,我们就可以开始构建和部署 Serverless 架构的 mall 应用了。请参考 SpringBoot on FC - 部署篇。

0 commit comments

Comments
 (0)