category
本文提供了在单个区域中在Azure App Service上运行web应用程序的基线体系结构。它详细介绍了在Azure上设计安全、区域冗余和高可用的web应用程序的指导。该体系结构通过具有Web应用程序防火墙的Azure应用程序网关公开公共端点。它通过私有链接将请求路由到Azure应用程序服务。应用程序服务应用程序使用虚拟网络集成和专用链接与Azure PaaS服务(如Azure密钥库和Azure SQL数据库)进行安全通信。
重要的
GitHub徽标该指南由一个示例实现支持,该示例展示了Azure上的基线应用服务实现。此实现可以作为您迈向生产的第一步中进一步开发解决方案的基础。
架构
Figure 1: Baseline Azure App Service architecture
组件
- Microsoft Entra ID是一种基于云的身份和访问管理服务。它提供了一个单一的身份控制平面来管理访问web应用程序的用户的权限和角色。它与应用程序服务集成,简化了web应用程序的身份验证和授权。
- 应用程序网关是一个第7层(HTTP/S)负载均衡器和web流量管理器。它使用基于URL路径的路由在可用性区域之间分配传入流量,并卸载加密以提高应用程序性能。
- Web应用程序防火墙(WAF)是一种云原生服务,可保护Web应用程序免受SQL注入和跨站点脚本等常见漏洞的攻击。WAF提供了web应用程序的流量可见性,使您能够监控和保护您的应用程序。
- App Service是一个完全管理的平台,用于构建、部署和扩展web应用程序。
- Azure密钥库是一种安全存储和管理机密、加密密钥和证书的服务。它集中管理敏感信息。
- Azure Monitor是一种监控服务,用于在整个部署中收集、分析遥测数据并对其采取行动。
- Azure虚拟网络是一种服务,使您能够在Azure中创建隔离且安全的专用虚拟网络。对于应用程序服务上的web应用程序,您需要一个虚拟网络子网来使用专用端点进行资源之间的网络安全通信。
- 私有链接使客户端可以直接从私有虚拟网络访问Azure平台即服务(PaaS)服务,而无需使用公共IP地址。
- Azure DNS是DNS域的托管服务,使用Microsoft Azure基础架构提供名称解析。专用DNS区域提供了一种将服务的完全限定域名(FQDN)映射到专用端点的IP地址的方法。
- Azure SQL数据库是用于关系数据的托管关系数据库服务。
网络
网络安全是应用服务基线架构的核心(见图2)。从高层来看,网络体系结构可确保以下内容:
- 客户端流量的单一安全入口点
- 已过滤网络流量
- 传输中的数据使用TLS进行端到端加密
- 通过使用私有链接保持Azure中的流量,最大限度地减少了数据泄露
- 网络资源通过网络分割进行逻辑分组并相互隔离
网络流量
Figure 2: Network architecture of the baseline Azure App Service application
以下是到应用程序服务实例的互联网流量的入站流以及从应用程序服务到Azure服务的流的描述。
入站流量
- 用户向应用程序网关公共IP发出请求。
- 评估WAF规则。WAF规则通过防止各种攻击(如跨站点脚本(XSS)和SQL注入),对系统的可靠性产生积极影响。如果违反WAF规则并停止处理,Azure应用程序网关将向请求者返回错误。如果没有违反WAF规则,应用程序网关会将请求路由到后端池,在本例中,后端池是应用程序服务的默认域。
- 专用DNS区域privatelink.azurewebsites.net链接到虚拟网络。DNS区域有一个A记录,该记录将应用服务默认域映射到应用服务专用终结点的专用IP地址。此链接的专用DNS区域允许Azure DNS将默认域解析为专用终结点IP地址。
- 该请求通过专用端点路由到应用程序服务实例。
应用服务到Azure PaaS服务流
- 应用程序服务向所需Azure服务的DNS名称发出请求。请求可以是到Azure密钥库以获取机密,到Azure存储以获取发布zip文件,到Azure SQL数据库,或到任何其他支持私有链接的Azure服务。应用程序服务虚拟网络集成功能通过虚拟网络路由请求。
- 与入站流中的步骤3类似,链接的专用DNS区域有一个A记录,该记录将Azure服务的域映射到专用端点的专用IP地址。同样,此链接的专用DNS区域允许Azure DNS将域解析为服务的专用端点IP地址。
- 请求通过专用端点路由到服务。
Ingress到应用程序服务
应用程序网关是一种区域资源,可满足此基线体系结构的要求。Application Gateway是一个可扩展的区域性第7层负载均衡器,支持web应用程序防火墙和TLS卸载等功能。在实现应用程序网关以进入Azure应用程序服务时,请考虑以下几点。
- 部署应用程序网关并使用Microsoft管理的规则集配置WAF策略。使用“预防”模式来减轻可能导致源服务(体系结构中的应用程序服务)不可用的web攻击。
- 实现端到端TLS加密。
- 使用专用终结点实现对应用程序服务的入站专用访问。
- 考虑为应用程序网关实现自动缩放,以便随时适应动态流量。
- 考虑使用不少于三个的最小规模实例数,并始终使用您所在地区支持的所有可用性区域。虽然应用程序网关是以高可用性的方式部署的,但即使是对于单个规模的实例,在出现故障时创建新实例也可能需要长达7分钟的时间。跨可用性区域部署多个实例有助于确保在出现故障时,在创建新实例的同时,实例仍在运行。
- 禁用应用程序服务上的公共网络访问以确保网络隔离。在Bicep中,这是通过在properties/siteConfig下设置publicNetworkAccess:“Disabled”来实现的。
从应用程序服务流向Azure服务
此架构为应用程序服务使用虚拟网络集成,特别是通过虚拟网络将流量路由到专用端点。基线架构不允许所有流量路由强制所有出站流量通过虚拟网络,只有内部流量,例如绑定到专用端点的流量。
不需要从公共互联网访问的Azure服务应启用私有端点,禁用公共端点。通过允许您的应用程序服务直接从您的专用虚拟网络连接到专用链接服务,而无需使用公共IP地址,在整个体系结构中使用专用端点来提高安全性。
在此体系结构中,Azure SQL数据库、Azure存储和密钥保管库都禁用了公共端点。Azure服务防火墙仅用于允许来自其他授权Azure服务的流量。您应该使用私有端点配置其他Azure服务,如Azure Cosmos DB和Azure Redis Cache。在这个体系结构中,Azure Monitor不使用私有端点,但它可以。
基线体系结构为每个服务实现一个专用DNS区域。专用DNS区域包含一个A记录,该记录在服务的完全限定域名和专用端点专用IP地址之间进行映射。区域链接到虚拟网络。专用DNS区域组确保自动创建和更新专用链接DNS记录。
在实现虚拟网络集成和专用端点时,请考虑以下几点。
- 使用Azure服务DNS区域配置指南命名专用DNS区域。
- 配置服务防火墙以确保存储帐户、密钥保管库、SQL数据库和其他Azure服务只能私下连接。
- 设置存储帐户默认网络访问规则以拒绝所有流量。
- 为专用链接启用密钥保管库。
- 拒绝对Azure SQL的公共网络访问。
虚拟网络分割与安全
此体系结构中的网络具有用于应用程序网关、应用程序服务集成组件和专用端点的独立子网。每个子网都有一个网络安全组,该组将这些子网的入站和出站流量限制为所需流量。下表显示了基线添加到每个子网的NSG规则的简化视图。该表提供了规则名称和函数。
Subnet | Inbound | Outbound |
---|---|---|
snet-AppGateway | AppGw.In.Allow.ControlPlane : Allow inbound control plane accessAppGw.In.Allow443.Internet : Allow inbound internet HTTPS access |
AppGw.Out.Allow.AppServices : Allow outbound access to AppServicesSubnetAppGw.Out.Allow.PrivateEndpoints : Allow outbound access to PrivateEndpointsSubnetAppPlan.Out.Allow.AzureMonitor : Allow outbound access to Azure Monitor |
snet-PrivateEndpoints | Default rules: Allow inbound from virtual network | Default rules: Allow outbound to virtual network |
snet-AppService | Default rules: Allow inbound from vnet | AppPlan.Out.Allow.PrivateEndpoints : Allow outbound access to PrivateEndpointsSubnetAppPlan.Out.Allow.AzureMonitor : Allow outbound access to Azure Monitor |
在实现虚拟网络分段和安全性时,请考虑以下几点。
- 为具有子网的虚拟网络启用DDoS保护,该子网是具有公共IP的应用程序网关的一部分。
- 尽可能在每个子网中添加一个NSG。您应该使用最严格的规则来启用完整的解决方案功能。
- 使用应用程序安全组。应用程序安全组允许您对NSG进行分组,从而使复杂环境中的规则创建更加容易。
虚拟子网架构的示例可能是:
Type | Name | Address Range |
---|---|---|
Virtual Network | Address Prefix | 10.0.0.0/16 |
Subnet | GatewaySubnet | 10.0.1.0/24 |
Subnet | AppServicesSubnet | 10.0.0.0/24 |
Subnet | PrivateEndpointsSubnet | 10.0.2.0/27 |
Subnet | AgentsSubject | 10.0.2.32/27 |
Reference Azure-Samples\app-service-baseline-implementation
可靠性
基线应用程序服务架构侧重于关键区域服务的区域冗余。可用性区域是一个区域内物理上独立的位置。当两个或多个实例部署在支持区域中时,它们为支持服务提供区域冗余。当一个区域出现停机时,其他区域可能仍然不受影响。
该体系结构还确保有足够的Azure服务实例来满足需求。以下各节为体系结构中的关键服务提供可靠性指导。通过这种方式,可用性区域通过提供高可用性和容错性来帮助您实现可靠性。
应用程序网关
在区域冗余配置中部署Azure Application Gateway v2。考虑使用不少于三个的最小规模实例计数,以避免在出现故障时应用程序网关实例的启动时间为六到七分钟。
应用程序服务
至少部署三个具有可用性区域支持的应用程序服务实例。
在应用程序中实现健康检查终结点,并配置应用程序服务健康检查功能以将请求从不健康的实例中重新路由。有关应用程序服务运行状况检查的更多信息,请参阅使用运行状况检查监控应用程序服务实例。有关在ASP。NET应用程序,请参阅ASP中的健康检查。NET核心。
提供的容量过大,无法处理区域故障。
SQL数据库
在启用区域冗余的情况下部署Azure SQL DB通用、高级或关键业务。通用、高级和关键业务层支持Azure SQL DB中的区域冗余。
将SQL DB备份配置为使用区域冗余存储(ZRS)或地理区域冗余存储。
Blob存储
Azure?Zone Redundant Storage?(ZRS)在该地区的三个可用区域同步复制您的数据。创建标准ZRS或标准GZRS存储帐户,以确保跨可用性区域复制数据。
为部署、web资产和其他数据创建单独的存储帐户,以便您可以单独管理和配置这些帐户。
可扩展性
可扩展性使应用程序能够处理需求的增加和减少,同时优化性能和成本。以下部分将讨论此体系结构中关键组件的可伸缩性。
应用程序网关
实现应用程序网关的自动缩放,以放大或缩小以满足需求。
将最大实例计数设置为高于预期需要的数字。您将只收取您使用的容量单位的费用。
设置可以处理流量小峰值的最小实例计数。您可以使用平均计算单元使用率来计算您的最小实例计数。
请遵循有关调整应用程序网关子网大小的指导。
应用程序服务
将标准或更高的计划与三个或更多工作实例一起使用,以获得高可用性。
启用“自动缩放”以确保可以向上和向下缩放以满足需求。
如果您的应用程序服务始终使用最大实例数的一半,请考虑打开支持票证,将最大工作人员数增加到实例数的两倍。对于高级应用程序服务计划,最大实例数默认为30个,对于标准计划,默认为10个。
当您的应用程序服务开始达到上限时,请考虑部署应用程序的多个印记。
选择符合您工作负载要求的正确Azure应用程序服务计划。
将Azure CDN添加到Azure应用程序服务以提供静态内容。
如果邻居有噪音,请考虑应用程序服务环境。
SQL Server
扩展数据库资源是一个超出此体系结构范围的复杂主题。在扩展数据库时,请考虑以下资源,
以最少的停机时间动态扩展数据库资源
使用Azure SQL数据库扩展
使用只读副本卸载只读查询工作负载
其他可扩展性指南
审查订阅限制和配额,以确保服务能够按需扩展。
考虑缓存以下类型的数据以提高性能和可扩展性:
半静态事务数据。
会话状态。
HTML输出。这在呈现复杂HTML输出的应用程序中非常有用。
安全
基线应用程序服务体系结构侧重于为您的web应用程序提供基本的安全建议。了解加密和身份在每一层的工作方式对于保护您的工作负载至关重要。
应用程序服务
禁用FTP和SCM站点部署的本地身份验证方法
关闭远程调试。
使用最新的TLS版本。
为应用程序服务启用Microsoft Defender。
使用支持的平台、编程语言、协议和框架的最新版本。
如果您需要更高的隔离或安全的网络访问,请考虑应用程序服务环境。
加密
生产web应用程序需要使用HTTPS加密传输中的数据。HTTPS协议依赖于传输层安全性(TLS),并使用公钥和私钥进行加密。您必须将证书(X.509)存储在密钥保管库中,并允许应用程序网关检索私钥。对于静止的数据,一些服务会自动加密数据,而另一些则允许您进行自定义。
传输中的数据
在基线架构中,从用户到应用程序服务中的web应用程序的传输数据是加密的。以下工作流程描述了加密如何在高级别上工作。
- 用户向web应用程序发送HTTPS请求。
- HTTPS请求到达应用程序网关。
- 应用程序网关使用密钥库中的证书(X.509)来创建与用户的web浏览器的安全TLS连接。应用程序网关解密HTTPS请求,以便web应用程序防火墙可以对其进行检查。
- 应用程序网关创建与应用程序服务的TLS连接,以重新加密用户请求。应用程序服务提供HTTPS的本机支持,因此您不需要向应用程序服务添加证书。应用网关将加密流量发送到应用服务。应用程序服务解密流量,web应用程序处理请求。
配置传输中数据加密时,请考虑以下建议。
- 创建证书或将证书上载到密钥保管库。HTTPS加密需要证书(X.509)。您需要来自自定义域的受信任证书颁发机构的证书。
将证书的私钥存储在密钥保管库中。 - 遵循“向应用程序授予访问Azure密钥库的权限”中的指导,使用Azure RBAC和Azure资源的托管身份为应用程序网关提供对证书私钥的访问。不要使用密钥保管库访问策略来提供访问权限。访问策略只允许您授予广泛的权限,而不仅仅是授予特定的值。
- 启用端到端加密。应用程序服务是应用程序网关的后端池。当您为后端池配置后端设置时,请通过后端端口443使用HTTPS协议。
静止数据
使用透明数据加密对Azure SQL数据库中的敏感数据进行加密。透明数据对整个数据库、备份和事务日志文件进行加密,不需要对web应用程序进行任何更改。
最大限度地减少数据库加密延迟。为了最大限度地减少加密延迟,请将需要保护的数据放在其自己的数据库中,并且只对该数据库启用加密。
了解内置加密支持。Azure Storage使用服务器端加密(256位AES)自动对静止的数据进行加密。Azure Monitor使用Microsoft托管密钥(MMK)自动加密静止的数据。
身份和访问管理
应用程序服务基线为用户身份(用户)和工作负载身份(Azure资源)配置身份验证和授权,并实现最小权限原则。
用户标识
- 使用应用程序服务的集成身份验证机制(“EasyAuth”)。EasyAuth简化了将身份提供者集成到web应用程序中的过程。它处理web应用程序之外的身份验证,因此您不必对代码进行重大更改。
- 配置自定义域的回复URL。您必须将web应用重定向到https://<applicationgateway-endpoint>/.auth/login/<provider>/recallback。将<applicationgatewayendpoint>替换为与应用程序网关关联的公共IP地址或自定义域名。将<provider>替换为您正在使用的身份验证提供程序,例如Microsoft Entra ID的“aad”。您可以使用Azure Front文档通过应用程序网关或设置应用程序网关设置此流。
工作负载标识
- 将托管标识用于工作负载标识。托管身份消除了开发人员管理身份验证凭据的需要。
- 使用用户分配的托管标识。系统分配的标识可能会导致基础结构作为代码部署根据竞争条件和操作顺序而失败。您可以使用用户分配的托管标识来避免出现某些部署错误情况。有关更多信息,请参阅托管身份。
部署
- 基线应用程序服务应用程序的部署遵循CI/CD中针对带有Azure管道的Azure Web应用程序的指导。除此指导外,应用程序服务基线体系结构还考虑到应用程序和部署存储帐户是网络安全的。该体系结构拒绝公众访问应用程序服务。这意味着您不能从虚拟网络外部进行部署。基线显示了如何使用自托管部署代理在虚拟网络中部署应用程序代码。以下部署指南侧重于部署应用程序代码,而不是部署基础结构或数据库更改。
Figure 3: Deploying Azure App Service applications
部署流程
作为发布管道的一部分,管道为作业队列中的自托管代理发布作业请求。作业请求是代理将发布zip文件构建项目上载到Azure存储帐户。- 自托管部署代理通过轮询获取新作业请求。它下载作业和构建工件。
- 自托管部署代理通过存储帐户的专用端点将zip文件上载到存储帐户。
-
管道将继续,托管代理将接下一个作业。托管代理进行CLI调用,以将appSetting WEBSITE_RUN_FROM_PACKAGE更新为临时插槽的新发布zip文件的名称。
az webapp config appsettings set -g MyResourceGroupName -n MyUniqueApp --slot staging --settings WEBSITE_RUN_FROM_PACKAGE=UriToNewZip
- Azure应用程序服务通过存储帐户专用终结点从存储中提取新的发布zip文件。由于WEBSITE_RUN_FROM_package被设置为不同的文件名,临时实例将使用新包重新启动。
管道恢复并运行任何烟雾测试或等待批准。如果测试通过或获得批准,管道将交换暂存和生产插槽。
部署指南
以下重点介绍了基线体系结构的关键部署指南。
- 使用从包运行可避免部署冲突。当您直接从Azure app Service中的包运行应用程序时,包中的文件不会复制到wwwroot目录。相反,ZIP包本身直接作为只读wwwroot目录挂载。这消除了部署和运行时之间的文件锁定冲突,并确保任何时候都只有完全部署的应用程序在运行
- 在已部署的软件包zip文件中包括版本号。将WEBSITE_RUN_FROM_PACKAGE appSetting更新到具有不同文件名的部署包会导致应用程序服务自动获取新版本并重新启动服务。
- 使用部署槽进行弹性代码部署。
- 考虑混合使用托管代理和自托管代理。
- 使用自托管代理通过专用端点将包zip文件上载到存储帐户。代理通过轮询启动与管道的通信,因此不需要为入站呼叫打开网络。
- 对管道中的其他作业使用托管代理。
- 使用“基础架构即代码”(IaC)自动化基础架构部署。
- 使用Azure负载测试和Azure Chaos Studio等服务不断验证工作负载,以测试整个解决方案的性能和弹性。
配置
应用程序需要配置值和机密。使用以下指南进行配置和机密管理。
- 永远不要将密码或访问密钥等机密检查到源代码管理中。
- 使用Azure密钥库存储机密。
- 使用应用程序服务配置进行应用程序配置。如果您需要从应用程序配置中外部化配置,或者需要功能标志支持,请考虑使用Azure应用程序配置。
- 在应用程序服务配置中使用密钥库参考,以安全地暴露应用程序中的机密。
- 创建应用程序设置,这些设置可以固定在一个插槽中,如果您需要不同的生产和暂存设置,则不会被交换。交换部署插槽时,默认情况下会交换应用程序设置。
- 为本地开发设置本地环境变量或利用应用程序平台功能。应用程序服务配置将应用程序设置公开为环境变量。例如,Visual Studio允许您在启动配置文件中设置环境变量。它还允许您使用“应用程序设置”和用户机密来存储本地应用程序设置和机密。
监控
- 监控是从IT系统中收集和分析数据。监控的目标是在多个层面上的可观察性,以跟踪web应用程序的运行状况和安全性。可观察性是基线应用程序服务体系结构的一个关键方面。
- 要监控您的web应用程序,您需要从应用程序代码、基础结构(运行时)和平台(Azure资源)中收集和分析指标和日志。有关详细信息,请参阅Azure活动日志、Azure资源日志和应用程序日志。
监控平台
平台监控是从您的体系结构中的Azure服务收集数据。请考虑以下有关平台监控的指导。
- 为每个Azure资源添加诊断设置。每个Azure服务都有一组不同的日志和度量,您可以捕获这些日志和度量。使用下表计算出要收集的指标和日志。
Azure resource | Metrics and logs descriptions |
---|---|
Application Gateway | Application Gateway metrics and logs descriptions |
Web Application Firewall | Web application firewall metrics and logs descriptions |
App Service | App Service metrics and logs descriptions |
Azure SQL Database | Azure SQL Database metrics and logs description |
CosmosDB | Azure Cosmos DB metrics and logs descriptions |
Key Vault | Key Vault metrics and logs descriptions |
Blob Storage | Azure Blob Storage metrics and logs descriptions |
Application Insights | Application Insights metrics and logs descriptions |
Public IP address | Public IP address metrics and logs descriptions |
- 了解收集指标和日志的成本。一般来说,收集的指标和日志越多,成本就越高。有关更多信息,请参阅日志分析成本计算和选项以及日志分析工作区的定价。
- 创建警报。您应该为体系结构中的所有Azure资源创建警报,并配置“操作”以修正问题。选择常用和推荐的警报规则以开始使用,并根据需要随时间进行修改。有关更多信息,请参阅:
- Azure Monitor警报概述
- 应用程序网关警报
- 应用程序服务警报
- Azure SQL数据库警报
- Blob存储警报
- 密钥保管库警报
应用程序网关
应用程序网关监视其后端池中资源的运行状况。使用应用程序网关访问日志来收集时间戳、HTTP响应代码和URL路径等信息。有关更多信息,请参阅应用程序网关默认运行状况探测以及后端运行状况和诊断日志。
应用程序服务
App Service具有内置和集成的监控工具,您应该启用这些工具以提高可观察性。如果您的web应用程序已经具有遥测和监控功能(“进程内检测”),它应该继续在应用程序服务上工作。
- 启用自动检测。应用程序服务有一个检测扩展,您可以在不更改代码的情况下启用它。您可以获得应用程序性能监视(APM)的可见性。有关详细信息,请参阅监控Azure应用程序服务性能。
- 启用分布式跟踪。自动检测提供了一种通过分布式跟踪和性能探查器监视分布式云系统的方法。
- 使用基于代码的仪器进行自定义遥测。Azure Application Insights还支持用于自定义应用程序遥测的基于代码的检测。将Application Insights SDK添加到代码中,并使用Application Insightsneneneba API。
- 启用应用程序服务日志。应用程序服务平台支持四个额外的日志,您应该启用这些日志来支持故障排除。这些日志包括应用程序日志、web服务器日志、详细的错误消息和失败的请求跟踪。
- 使用结构化日志记录。将结构化日志库添加到应用程序代码中。更新您的代码以使用键值对,并在应用程序服务中启用应用程序日志以将这些日志存储在日志分析工作区中。
- 打开应用程序服务运行状况检查。运行状况检查会重新路由不正常实例的请求,并替换不正常实例。您的应用程序服务计划需要使用两个或多个实例才能进行健康检查。
数据库
用户数据库洞察。对于Azure SQL数据库,您应该在Azure Monitor中配置SQL Insights。Database Insights使用动态管理视图来公开监视运行状况、诊断问题和调整性能所需的数据。有关详细信息,请参阅使用Azure Monitor监视Azure SQL数据库。- 如果您的体系结构包括Cosmos DB,则无需启用或配置任何内容即可使用Cosmos DB见解。
统治
Web应用程序通过强制执行体系结构和安全决策而受益于Azure策略。Azure策略可以使其(1)无法部署(拒绝)或(2)易于检测(审核)与您首选的所需状态的配置漂移。这有助于您了解偏离商定架构的基础架构即代码(IaC)部署或Azure门户更改。您应该将架构中的所有资源置于Azure策略治理之下。在可能的情况下,使用内置策略或策略计划来强制执行基本的网络拓扑、服务功能、安全性和监控决策,例如:
- 应用程序服务应禁用公共网络访问
- 应用服务应使用虚拟网络集成
- 应用程序服务应使用Azure专用链接连接到PaaS服务
- 应用程序服务应禁用FTP和SCM站点部署的本地身份验证方法
- 应用程序服务应关闭远程调试
- 应用程序服务应用程序应使用最新的TLS版本
- 应启用Microsoft Defender for App Service
- 应为应用程序网关启用Web应用程序防火墙(WAF)
查看关键服务的更多内置策略,如应用程序网关和网络组件、应用程序服务、密钥库和监控。如果内置策略不能完全满足您的需求,则可以创建自定义策略或使用社区策略(如从Azure着陆区)。当内置策略可用时,首选这些策略。
Next steps
Related resources
- 登录 发表评论
- 11 次浏览
最新内容
- 1 week 5 days ago
- 2 weeks 6 days ago
- 3 weeks 2 days ago
- 3 weeks 2 days ago
- 3 weeks 5 days ago
- 3 weeks 6 days ago
- 4 weeks ago
- 4 weeks 1 day ago
- 4 weeks 1 day ago
- 4 weeks 1 day ago