You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Functions结合Azure Cosmos DB或SQL数据库时负载测试性能异常排查求助

从你的描述和代码来看,每次请求都重新初始化Cosmos Client是导致负载下响应变慢的核心原因,这也是Azure Functions + Cosmos DB场景中常见的性能陷阱。下面给你具体的排查方向和优化方案:

1. 修复Cosmos Client的初始化方式

你的代码里,每次处理/postcode_cosmosdb请求时都会新建一个CosmosClient实例,而Cosmos Client的初始化是相对重的操作——它会建立连接池、初始化认证等。在高负载下,频繁创建销毁客户端会导致大量的连接开销,直接拖慢响应时间。

Cosmos Client是线程安全且设计为复用的,应该把它的初始化移到函数的全局作用域(模块级别),这样整个函数实例的所有请求都会复用同一个客户端和连接池。修改后的代码如下:

import azure.functions as func
import os
from azure.functions import AsgiMiddleware
from fastapi import Query
from typing import Optional
from api_app import app
import azure.cosmos.documents as documents
import azure.cosmos.cosmos_client as cosmos_client
import azure.cosmos.exceptions as exceptions
from azure.cosmos.partition_key import PartitionKey

# 全局初始化Cosmos Client,仅在函数实例启动时执行一次
settings = {
    'host': os.environ.get('ACCOUNT_HOST', 'XXXXXX'),
    'master_key': os.environ.get('ACCOUNT_KEY', 'XXXXXX'),
    'database_id': os.environ.get('COSMOS_DATABASE', 'WoningAdressen'),
    'container_id': os.environ.get('COSMOS_CONTAINER', 'AdressenLight'),
}
HOST = settings['host']
MASTER_KEY = settings['master_key']
DATABASE_ID = settings['database_id']
CONTAINER_ID = settings['container_id']

# 全局客户端实例,复用连接池
client = cosmos_client.CosmosClient(HOST, {'masterKey': MASTER_KEY}, user_agent="CosmosDBPythonQuickstart", user_agent_overwrite=True)
db = client.get_database_client(DATABASE_ID)
container = db.get_container_client(CONTAINER_ID)

@app.get("/status")
def get_status():    
    return ({"status": 200})

@app.get("/postcode_cosmosdb/{postcode}/{huisnummer}")
async def postcode_cosmosdb(postcode: str, huisnummer: int):    
    items = list(container.query_items(
        query="SELECT l.postcode, l.huisnummer, l.huisletter, l.nummeraanduiding_id as bagid, l.gemeente FROM AdressenLight as l WHERE l.postcode=@postcode AND l.huisnummer=@huisnummer",
        parameters=[
            { "name":"@postcode", "value": postcode },
            { "name":"@huisnummer", "value": huisnummer }
        ]
    ))    
    return items

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:    
    return AsgiMiddleware(app).handle(req, context)

2. 排查数据库连接池与资源限制

  • Cosmos DB侧:检查你的容器是否有足够的请求单位(RU)。虽然CPU内存正常,但如果负载下RU使用率接近100%,会导致请求被节流(Cosmos会自动重试,但会增加耗时)。可以在Azure Portal查看Cosmos DB的Total Request Units指标。
  • Azure Functions侧:如果使用的是Consumption计划,函数实例会自动扩展,但每个实例的并发请求数默认是100。你可以在host.json中调整maxConcurrentRequests参数,比如:
    {
      "version": "2.0",
      "functionTimeout": "00:05:00",
      "extensions": {
        "http": {
          "maxConcurrentRequests": 100
        }
      }
    }
    
    如果是Premium计划,还可以调整实例的数量和规格,获得更稳定的性能。

3. 优化查询性能

即使数据库资源正常,查询本身也可能存在优化空间:

  • 检查分区键:如果你的Cosmos容器分区键不是postcode或postcode+huisnummer,那么当前的查询会是跨分区查询,这会消耗更多RU且变慢。建议将分区键设置为查询中频繁使用的字段组合,比如postcode。
  • 创建覆盖索引:确保你的查询用到的字段(postcode、huisnummer)有索引,并且投影的字段(huisletter、bagid、gemeente)也被包含在索引中,避免Cosmos进行全表扫描。

4. 用监控工具定位瓶颈

  • 使用Application Insights追踪每个请求的详细耗时,看数据库调用的阶段是否在负载下明显变长,这能帮你确认是连接问题还是查询本身的问题。
  • 在Azure Monitor中查看函数的Connections指标,看是否有连接数飙升的情况;同时查看Cosmos DB的Connection Pool Size指标,确认连接池是否被有效复用。

按照这个顺序排查,先解决客户端初始化的问题,应该能大幅改善负载下的响应时间。

内容的提问来源于stack exchange,提问作者Joey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:18:12