构建 API 服务器时,无论使用何种技术,您都会面临一系列基本问题。大多数问题都可以避免,但我仍然看到拥有数十年经验的专业工程师年复一年地在做着同样的工作。
让我们一起走进数据库性能陷阱的花园。我们将讨论您可能会犯哪些错误、如何发现这些错误、如何解决这些错误以及我们是否可以采取预防措施。
错误 #1:查询不变的信息
当我构建Avalara AvaTax REST API时,我必须允许用户发送地址。由于他数据库性能们的数据很乱,有时他们会发送 ISO 国家代码,或者可能是国家名称,也可能是别名。我可以处理这个问题,因为 GitHub 上有很多具有宽松许可证的国家 数据 源,但最终我选择付费购买官方 ISO 3166 国家代码列表。
下一步是让我的 API 服务器在启动时加载这些数据。代码不必太数据库性能复杂——这里有一些类似 C# 的伪代码,大致显示了如何使其工作:
为什么要这样做?幸运的数据库性能是,新国家/地区并不经常创建。如果国家/地区列表要更改,我们会在每月的应用程序部署期间发送 SQL 脚本来添加新记录。
我的 C# API 服务器不是查询数据库中的表,而是将这些数据库性能数据保存在单例中。它会在输入或输出时查找正确的名称。数据只占用几千字节,为了方便起见,我有多个散列的不区分大小写的字典。
您可能有几十个这样的静态数据集。查找数据集、原因数据库性能代码、配置标志 — 将它们存储在静态单例中!如果您忘记了,您可能会发现您的系统每秒对永远不会改变的数据进行数千次不必要的查询。
错误#2:状态页面检查过度使用数据库
您的 API 服务器需要一个健康数据库性能检查系统。它数据库性能以是一个页面或一个 API,但它应该执行一系列基本功能测试,以确保机器能够正常工作。典型的测试包括:
- 我有正确的配置文件吗?
- 我是否可以联系我需要的外部服务,或者是否有防火墙阻止我?
- 我的服务器是否以正确的凭据和权限运行?
- 我的数据库连接字符串有效吗?
这些类型的状态检查对于启动作为自动扩展组一部分的服务器或使用容器数据库性能化启动模板是必不可少的。在部署服务器之前,彻底测试所有内容非常重要——启动缺少数据库连接字符串的机器会很糟糕。
这些状态检查的一个副作用是,它们通常也用于监控部署后的服务器整体数据库性能健康状况。一些云服务会每分钟多次调用此状态页面,如果服务器无法响应,则会将其从负载平衡器中移除。如果您的状态页面在此测试中执行查询,这可能会迅速消耗您的数据库。
可以想象,在数据库性能启动时测试数据库 房主数据库 连接至关重要。但是,一旦服务器成功部署,有效的数据库连接以后突然变为无效的可能性就很小。我发现最好将成功的结果缓存一小段时间,比如 30 秒。
错误#3:API身份验证查询过多
大多数重度 API 用户会数据库性能迅速发出大量请求。对于每个请求,服务器需要检查用户是否经过身份验证,以及他们是否有权执行他们请求的工作。许多这些检查都需要从数据库中提取数据:
- 检索用户和账户的状态
- 检查用户的权限
- 检索配置或首选项
对每个请求都这样做似乎很自然,但 什么是商业报价 数据库性能这些信息可能会浪费大量时间。幸运的是,有一种方法可以解决缓慢的身份验证数据库查询问题:如果调用者发出请求,您可以在短时间内缓存他们的凭据。
缓存授权可能看起来很可怕,因为更改不是即时的,但在实践中,“即时”很难定义。如果在撤销访问权限之前 API 调用正在进行中,则用户可能会或可能不会被允许根据随机运气发出请求 — 无论 API 调用是否在撤销之前到达。
如果我们更新文档,说“更改数据库性能用户权限后,请等待 5 分钟,所有服务器才会更新新权限”——那么您就可以规划性能了!这里的技巧是对 API 调用的承载令牌及其 IP 地址进行哈希处理,然后在缓存中查找所有身份验证和授权数据:
- 首先检查服务器内数据库性能存中的哈 cl 列表 希表。实际上,这将花费 。
- 如果持有者令牌不在服务器的内存缓存中,请检查 REDIS 或其他等效的键值对服务器。这将需要 1-2 毫秒。
- 如果在任一缓存中都找不到该值,则创建一个承诺来数据库性能获取必要的数据。如果该承诺已存在,则加入该承诺,这样您就不会同时发出多个请求。
- 如果身份验证数据超过特定年龄,则启动一个新的承诺来再次重新获取数据,以便在旧数据从缓存中过期时数据就可以准备就绪。
要了解详细信息,请阅读我关于身份验证缓存技数据库性能术的博客文章- 其中还有很多难以正确理解的额外细节。
错误 #4:循环查询的对象关系映射器
Entity Framework 等现代技术使得访问数据库性能数据库变得极其简单。事实上,这非常容易,以至于我们经常可以编写一个方法来执行数据库调用 — 然后发现人们在使用这个方法时并没有数据库性能意识到它接触了数据库。
一个简单的数据库性能例子可能是这样的:
这段代数据库性能码可能看起来微不足道,但如果该方法CountUsersPerItem
联系数据库,可能是为了获取一个标志或查询一个子表,您可能会发现看似一个查询变成了数百或数千个查询。
更糟糕的是,此功能的性能在开发人员的桌面上可能看起来不错,但当现实世界的客户面临同样的情况时,可能会突然下降。
错误#5:因为查询速度快而忽略它
这个问题非数据库性能数据库性能常隐蔽。现代数据库技术非常强大,简单的数据库查询通常可以与 REDIS 查询一样快甚至更快。在本地工作的开发人员通常会看到非常好的性能,因为他们的应用程序和数据库服务器之间没有延迟,两者都在笔记本电脑上的容器中运行。
即使您的 SQL Server 或 Postgres 实例可以在一毫秒内做出响应,这些毫秒数据库性能也会累积起来。如果您的 API 请求发出十个一毫秒的查询,则可能会使您的 API 延迟增加十毫秒 — 当平均预期时间少于一百毫秒时,这是一个不可忽略的量。
这里的关数据库性能键教训是,在 API 设计中,每个数据库查数据库性能询都数据库性能很重要。注意它们,你的 API 就会快速且实用。