是否可以向Invoke-RestMethod添加速率限制?

时间:2019-05-15 22:52:13

标签: rest powershell powerbi

每次尝试运行此脚本时,服务器都会遇到429错误(速率限制)。如何减慢速度或降低速度以免遇到此错误?

这用于通过PowerBI API将数据流传输到PowerBI服务。我试图查看是否可以找到有关如何结合Invoke-RestMethod实施速率限制的任何信息,但我找不到任何东西。我不确定是否有可能,或者是否应该完全使用其他方法。我在PowerBI文档中找不到任何可以暗示Invoke-RestMethod以外的其他替代方法来向API端点发送数据的信息。

while($true) 
{
    Clear-Host;

    $SysDateTime = Get-Date -DisplayHint DateTime -Format F

    $SqlServer = 'nt-sql-db';
    $SqlDatabase = 'stream-db';

    $SqlConnectionString = 'Data Source={0};Initial Catalog={1};Integrated Security=SSPI' -f $SqlServer, $SqlDatabase;
    $SqlQuery = "SELECT * FROM dbo.streamTable;";

    $SqlCommand = New-Object -TypeName System.Data.SqlClient.SqlCommand;
    $SqlCommand.CommandText = $SqlQuery;
    $SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $SqlConnectionString;
    $SqlCommand.Connection = $SqlConnection;

    $SqlConnection.Open();
    $SqlDataReader = $SqlCommand.ExecuteReader();

    ## identify the API endpoint
    $endpoint = "https://api.powerbi.com/beta/1234567890"

    ## structure the JSON payload
    while ($SqlDataReader.Read()) {
        $payload =  @{
            "name" =$SqlDataReader['name']                                         
            "queueTime" = $SqlDataReader['queueTime']                                    
            "promisedTime" =$SqlDataReader['promisedTime']                                   
            "sys_datetime" = $SysDateTime
            } 
        Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))
    }

    $SqlConnection.Close();

    $SqlConnection.Dispose();

    Start-Sleep -Seconds 30;
}

我在这里有一个循环,其目的是查询网络上的SQL Server并一次又一次地将数据传输到API端点,以便Power BI应用程序准实时显示数据。

该脚本似乎正在运行,但是很快就收到服务器的429响应。由于某种原因,直到Power BI中的“历史数据分析”选项被检查后,这似乎才开始发生,尽管我不确定我是否了解其影响以及该选项将如何影响此脚本的功能。

1 个答案:

答案 0 :(得分:1)

在您的代码中,您正在读取表中的所有行,并将它们逐一推送,这是一个无限循环。如果表中的行数超过60,您将按limit每分钟进行POST行请求。限制如下:

  • 最多75列
  • 最多75张桌子
  • 每个单独的POST行请求
  • 最多10,000行
  • 每个数据集每小时增加
  • 1,000,000行
  • 每个数据集
  • 最多5个待处理的POST行请求
  • 每个数据集每分钟120个POST行请求
  • 如果表有250,000或更多行,则每个数据集每小时120个POST行请求
  • 每个表
  • 在FIFO数据集中最多存储200,000行
  • 在“无保留策略”数据集中,每个表最多
  • 存储5,000,000行
  • POST行操作中的字符串列,每个值
  • 每个字符4,000个字符

这意味着您每分钟最多只能发出120个端口请求,但是您可以在一个帖子中最多添加1万行,因此只需更改代码即可读取表中的所有行(假设它们是少于10K),并通过单个发布请求将其推送到流数据集。这样,您每分钟只会发出2个请求,而不会得到429个响应。

除非启用历史数据分析,否则数据集将仅保留最后一小时的行。如果启用它,行数将继续增长,并且如果行数超过250K,则每分钟120个帖子的限制将降低为每小时 120个帖子,因此即使存在在表中有2行。因此,这可以解释差异。

要一次推送数据集中的所有行,您需要在循环后将调用移至API。使用循环来初始化包含所有行的数组,然后将此数组推送到服务。将循环更改为如下所示:

## structure the JSON payload
$AllRows = @()
while ($SqlDataReader.Read()) {
    $CurrentRow =  @{
        "name" =$SqlDataReader['name']                                         
        "queueTime" = $SqlDataReader['queueTime']                                    
        "promisedTime" =$SqlDataReader['promisedTime']                                   
        "sys_datetime" = $SysDateTime
        } 
    $AllRows += $CurrentRow
}
Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json $AllRows)