GatewayTimeout问题在逻辑应用程序中运行存储过程

时间:2020-06-29 07:21:19

标签: azure stored-procedures azure-logic-apps bad-gateway

我们面临使用Azure Logic Apps服务和SQL数据库一起运行三个存储过程(SP)的问题。

无论SP的运行顺序如何,该问题总是出现在运行的第一个SP中。

处理过程最初需要花费几秒钟才能成功运行和执行,但是我们注意到执行时间和所需的DTU(数据库吞吐量单位)每天都在增加。

其中一个SP使用按日期过滤表TABLE1的变量,并仅显示TABLE2中的“当前日期”数据。过滤器变量(在SP中使用)在Logic App中定义为SUBSTRING(startOfDay(utcNow()), 0, 10),它返回当前日期值。

我们的代码包括仅过滤当天的TABLE1的值,将其放入TABLE2,对其进行一些计算并将结果存储回TABLE1中。 SP代码内部使用了WITHLast_ValueFirst_ValueINSERT函数。 INSERT函数用于将结果行插入TABLE1(约74行)中。

TABLE1中记录的数据行数每天都在增加,但是TABLE2中的数据行数是恒定的,因为它是过滤“当前日期”的结果,因此它仅显示当前日期值。

使用SQL Server Management Studio,可以无问题地手动执行SP。

起初,当我们的数据库DTU设置为400时,第一个SP的Logic App的执行时间不到10分钟,而其余两个SP分别花费了几秒钟。

最近第一个SP无法执行,给出了GatewayTimeout错误,并且Logic Apps执行失败:

enter image description here

enter image description here

当我们将DTU增加到800时,逻辑应用程序可以成功运行,但是我们仍然会收到GatewayTimeout的警告。

enter image description here

检查了与数据库的连接,测试了每个SP的手动执行,将过滤器变量数据类型从datetime更改为varchar(以与Logic Apps参数匹配)已经做出来了,但是问题一直在发生。

如果不解决此问题,此问题将再次发生。有什么建议吗?

谢谢。

更新

这是一个SP的代码:

WITH enTotTable 
AS 
  (
    SELECT --TOP(100)
        se.id
        , se.gatewayName
        , se.deviceId
        , se.ts
        , se.pointNameId

        , case 
            when se.presentValue < 0 then 0 else se.presentValue end as presentValue
        , DATEPART(hh,se.ts) as hTs
    FROM dbo.SolarEnergyTable se
    WHERE se.gatewayName IN ('DPJW', 'DAN1') and se.pointNameId = 7 and not se.presentValue = 0 and se.ts >= @tsFilter
  ) 


, calculationTable AS
  (

    SELECT distinct
            FORMAT ( tot.ts , 'yyyy-MM-dd' ) as dayTs
            ,tot.deviceId
            ,tot.gatewayName

            , CASE 
                WHEN  Last_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
                    ORDER by tot.hTs ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 
                    - FIRST_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
                    ORDER by tot.hTs ) >=12 
                then 1 
                Else NULL end as ifAllDay

            , CASE 
                WHEN  Last_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
                    ORDER by tot.hTs ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 
                    - FIRST_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
                    ORDER by tot.hTs ) >=12 
                then (LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                        ORDER by tot.deviceId desc, tot.ts
                        ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 
                    - FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                        ORDER by tot.deviceId desc, tot.ts) )
                else NULL 
                end as enTdy

            ,case 
                when LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                    ORDER by tot.deviceId desc, tot.ts
                    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) < 0 then NULL

                else  
                    LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                    ORDER by tot.deviceId desc, tot.ts
                    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 
                end as lastPvalueDay
            , case 
                when FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                    ORDER by tot.deviceId desc, tot.ts
                    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) < 0 then NULL

                else 
                    FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
                    ORDER by tot.deviceId desc, tot.ts) 
                end as firstPvalueDay            
    FROM enTotTable tot 
    WHERE not tot.presentValue = 0 
  )

, plantAndTdyTable 
AS
(   
    SELECT 
        tdy.gatewayName
        ,tdy.dayTs as ts
        ,CAST(2 as INT) as deviceId
        , CAST(20 as INT) as pointNameId
        , Case When 
            tdy.ifAllDay = 1 
            then SUM(tdy.lastPvalueDay)-SUM(tdy.firstPvalueDay)
            else NULL end as presentValue
    FROM calculationTable tdy
    GROUP BY tdy.dayTs ,tdy.ifAllDay, tdy.gatewayName
 UNION

    SELECT 
        tdy.gatewayName
        ,tdy.dayTs as ts
        ,CAST(2 as INT) as deviceId
        , CAST(17 as INT) as pointNameId
        ,SUM(tdy.lastPvalueDay) as presentValue
    FROM calculationTable tdy
    GROUP BY tdy.dayTs, tdy.gatewayName
 UNION


    SELECT 
        tdy.gatewayName
        , tdy.dayTs as ts
        , tdy.deviceId
        , CAST(6 as INT) as pointNameId
        , tdy.enTDY as presentValue
  From calculationTable tdy
  
)


INSERT INTO [dbo].[SolarEnergyTable]
SELECT 
    pt.gatewayName
    ,pt.ts
    ,pt.deviceId
    ,pt.pointNameId
    ,pt.presentValue
FROM plantAndTdyTable pt



-- SELECT *
-- From
-- plantAndTdyTable
-- -- calculationTable
-- -- enTotTable

2 个答案:

答案 0 :(得分:0)

请查看以下答案here

enter image description here

我使用azure logic app stored procedure taking too long找到了它。

答案 1 :(得分:0)

我终于改变了运行SP的体系结构。为了避免Logic应用程序需要连接到数据库时的GatewayTimeout,我使用了Azure自动帐户。我创建了一个PowerShell脚本来运行我的SP,并使用Logic App来运行PowerShell脚本。就我而言,效果更好。