WSO2 API 管理器对 Store rest API 的查询速度慢 SQL 导致性能不佳 UI
WSO2 API Manager slow SQL query on Store rest API causing bad UI performance
部署如下:
Mgr 节点:默认 (Store+Pub),Gateway-Manager。
工作节点:GW-Workers,Key-Managers
我们使用 MySQL NDB 作为我们的 API Manager 数据库。在商店 UI 上观察到非常慢的 API 加载时间。使用 Chrome Dev-Tools,我看到单击 API 打开时(使用登录会话)将调用以下 API:
http://{host/port}/store/apis/info?name={api-name}&version={v}&provider={provider}
手动调用 API(包括 cookie)在我们的负载平衡器 (504) 上超时。
查看 Store Jaggery 文件,我发现 API 它似乎调用 (../repository/deplyement/server/jaggeryapps/store/modules/api/api.jag),但我无法将其与实际的 API Impl 联系起来。使用常识,我认为 API 和相关的元数据需要从数据库中检索。
启用慢速查询日志(25 秒)产生了以下查询,当我尝试打开 API:
时会记录该查询
SELECT
ICA.CONSUMER_KEY AS CONSUMER_KEY,
ICA.CONSUMER_SECRET AS CONSUMER_SECRET,
IAT.ACCESS_TOKEN AS ACCESS_TOKEN,
IAT.VALIDITY_PERIOD AS VALIDITY_PERIOD,
ISAT.TOKEN_SCOPE AS TOKEN_SCOPE,
AKM.KEY_TYPE AS TOKEN_TYPE,
AKM.STATE AS STATE
FROM
AM_APPLICATION_KEY_MAPPING AKM,
IDN_OAUTH2_ACCESS_TOKEN IAT,
IDN_OAUTH2_ACCESS_TOKEN_SCOPE ISAT,
IDN_OAUTH_CONSUMER_APPS ICA
WHERE AKM.APPLICATION_ID = 149
AND IAT.USER_TYPE = 'APPLICATION'
AND ICA.CONSUMER_KEY = AKM.CONSUMER_KEY
AND IAT.CONSUMER_KEY_ID = ICA.ID
AND IAT.TOKEN_ID = ISAT.TOKEN_ID
AND AKM.KEY_TYPE = 'PRODUCTION'
AND (
IAT.TOKEN_STATE = 'ACTIVE'
OR IAT.TOKEN_STATE = 'EXPIRED'
OR IAT.TOKEN_STATE = 'REVOKED'
)
ORDER BY IAT.TIME_CREATED DESC;
此查询平均执行时间为 80 秒,返回约 33000 行。查询写得不好,因为没有连接,它的以下优化版本 returns 在 < 3 秒内得到相同的结果集:
SELECT
`api_am_dev_1`.`ICA`.`CONSUMER_KEY` AS `CONSUMER_KEY`,
`api_am_dev_1`.`ICA`.`CONSUMER_SECRET` AS `CONSUMER_SECRET`,
`api_am_dev_1`.`IAT`.`ACCESS_TOKEN` AS `ACCESS_TOKEN`,
`api_am_dev_1`.`IAT`.`VALIDITY_PERIOD` AS `VALIDITY_PERIOD`,
`api_am_dev_1`.`ISAT`.`TOKEN_SCOPE` AS `TOKEN_SCOPE`,
`api_am_dev_1`.`AKM`.`KEY_TYPE` AS `TOKEN_TYPE`,
`api_am_dev_1`.`AKM`.`STATE` AS `STATE`
FROM
`api_am_dev_1`.`AM_APPLICATION_KEY_MAPPING` `AKM`
JOIN `api_am_dev_1`.`IDN_OAUTH2_ACCESS_TOKEN` `IAT`
JOIN `api_am_dev_1`.`IDN_OAUTH2_ACCESS_TOKEN_SCOPE` `ISAT`
JOIN `api_am_dev_1`.`IDN_OAUTH_CONSUMER_APPS` `ICA`
WHERE (
(
`api_am_dev_1`.`AKM`.`KEY_TYPE` = 'PRODUCTION'
)
AND (
`api_am_dev_1`.`ISAT`.`TOKEN_ID` = `api_am_dev_1`.`IAT`.`TOKEN_ID`
)
AND (
`api_am_dev_1`.`IAT`.`CONSUMER_KEY_ID` = `api_am_dev_1`.`ICA`.`ID`
)
AND (
`api_am_dev_1`.`ICA`.`CONSUMER_KEY` = `api_am_dev_1`.`AKM`.`CONSUMER_KEY`
)
AND (
`api_am_dev_1`.`IAT`.`USER_TYPE` = 'APPLICATION'
)
AND (
`api_am_dev_1`.`AKM`.`APPLICATION_ID` = 149
)
AND (
(
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'ACTIVE'
)
OR (
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'EXPIRED'
)
OR (
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'REVOKED'
)
)
)
ORDER BY `api_am_dev_1`.`IAT`.`TIME_CREATED` DESC
添加索引似乎对解决问题没有帮助。我们 运行 每周清理一次代币,所以数据库中总共只有大约 20 000 个代币 ~ 我们的 QA 非常忙。
问题:查询是由Hibernate生成的,是创建补丁的唯一选项吗?
WSO2 商店是一个很棒的开发人员门户,但这破坏了我们许多用户的体验。
编辑:
API 管理器版本 = 2.1.0
答案是否定的,查询不是由 hibernate 或任何其他抽象框架生成的。所有查询都作为字符串常量存储在 java class 文件中,所以是的,如果您发现需要更改基础查询,则必须更改查询并构建补丁。
我们 运行 遇到了同样的问题,但是添加以下索引在单击 API 以显着检索其信息时提高了商店性能:
数据库:apimgt
Table: IDN_OAUTH2_ACCESS_TOKEN
列:USER_TYPE、CONSUMER_KEY_ID、TOKEN_ID、TOKEN_STATE
部署如下:
Mgr 节点:默认 (Store+Pub),Gateway-Manager。
工作节点:GW-Workers,Key-Managers
我们使用 MySQL NDB 作为我们的 API Manager 数据库。在商店 UI 上观察到非常慢的 API 加载时间。使用 Chrome Dev-Tools,我看到单击 API 打开时(使用登录会话)将调用以下 API:
http://{host/port}/store/apis/info?name={api-name}&version={v}&provider={provider}
手动调用 API(包括 cookie)在我们的负载平衡器 (504) 上超时。 查看 Store Jaggery 文件,我发现 API 它似乎调用 (../repository/deplyement/server/jaggeryapps/store/modules/api/api.jag),但我无法将其与实际的 API Impl 联系起来。使用常识,我认为 API 和相关的元数据需要从数据库中检索。
启用慢速查询日志(25 秒)产生了以下查询,当我尝试打开 API:
时会记录该查询SELECT
ICA.CONSUMER_KEY AS CONSUMER_KEY,
ICA.CONSUMER_SECRET AS CONSUMER_SECRET,
IAT.ACCESS_TOKEN AS ACCESS_TOKEN,
IAT.VALIDITY_PERIOD AS VALIDITY_PERIOD,
ISAT.TOKEN_SCOPE AS TOKEN_SCOPE,
AKM.KEY_TYPE AS TOKEN_TYPE,
AKM.STATE AS STATE
FROM
AM_APPLICATION_KEY_MAPPING AKM,
IDN_OAUTH2_ACCESS_TOKEN IAT,
IDN_OAUTH2_ACCESS_TOKEN_SCOPE ISAT,
IDN_OAUTH_CONSUMER_APPS ICA
WHERE AKM.APPLICATION_ID = 149
AND IAT.USER_TYPE = 'APPLICATION'
AND ICA.CONSUMER_KEY = AKM.CONSUMER_KEY
AND IAT.CONSUMER_KEY_ID = ICA.ID
AND IAT.TOKEN_ID = ISAT.TOKEN_ID
AND AKM.KEY_TYPE = 'PRODUCTION'
AND (
IAT.TOKEN_STATE = 'ACTIVE'
OR IAT.TOKEN_STATE = 'EXPIRED'
OR IAT.TOKEN_STATE = 'REVOKED'
)
ORDER BY IAT.TIME_CREATED DESC;
此查询平均执行时间为 80 秒,返回约 33000 行。查询写得不好,因为没有连接,它的以下优化版本 returns 在 < 3 秒内得到相同的结果集:
SELECT
`api_am_dev_1`.`ICA`.`CONSUMER_KEY` AS `CONSUMER_KEY`,
`api_am_dev_1`.`ICA`.`CONSUMER_SECRET` AS `CONSUMER_SECRET`,
`api_am_dev_1`.`IAT`.`ACCESS_TOKEN` AS `ACCESS_TOKEN`,
`api_am_dev_1`.`IAT`.`VALIDITY_PERIOD` AS `VALIDITY_PERIOD`,
`api_am_dev_1`.`ISAT`.`TOKEN_SCOPE` AS `TOKEN_SCOPE`,
`api_am_dev_1`.`AKM`.`KEY_TYPE` AS `TOKEN_TYPE`,
`api_am_dev_1`.`AKM`.`STATE` AS `STATE`
FROM
`api_am_dev_1`.`AM_APPLICATION_KEY_MAPPING` `AKM`
JOIN `api_am_dev_1`.`IDN_OAUTH2_ACCESS_TOKEN` `IAT`
JOIN `api_am_dev_1`.`IDN_OAUTH2_ACCESS_TOKEN_SCOPE` `ISAT`
JOIN `api_am_dev_1`.`IDN_OAUTH_CONSUMER_APPS` `ICA`
WHERE (
(
`api_am_dev_1`.`AKM`.`KEY_TYPE` = 'PRODUCTION'
)
AND (
`api_am_dev_1`.`ISAT`.`TOKEN_ID` = `api_am_dev_1`.`IAT`.`TOKEN_ID`
)
AND (
`api_am_dev_1`.`IAT`.`CONSUMER_KEY_ID` = `api_am_dev_1`.`ICA`.`ID`
)
AND (
`api_am_dev_1`.`ICA`.`CONSUMER_KEY` = `api_am_dev_1`.`AKM`.`CONSUMER_KEY`
)
AND (
`api_am_dev_1`.`IAT`.`USER_TYPE` = 'APPLICATION'
)
AND (
`api_am_dev_1`.`AKM`.`APPLICATION_ID` = 149
)
AND (
(
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'ACTIVE'
)
OR (
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'EXPIRED'
)
OR (
`api_am_dev_1`.`IAT`.`TOKEN_STATE` = 'REVOKED'
)
)
)
ORDER BY `api_am_dev_1`.`IAT`.`TIME_CREATED` DESC
添加索引似乎对解决问题没有帮助。我们 运行 每周清理一次代币,所以数据库中总共只有大约 20 000 个代币 ~ 我们的 QA 非常忙。
问题:查询是由Hibernate生成的,是创建补丁的唯一选项吗?
WSO2 商店是一个很棒的开发人员门户,但这破坏了我们许多用户的体验。
编辑:
API 管理器版本 = 2.1.0
答案是否定的,查询不是由 hibernate 或任何其他抽象框架生成的。所有查询都作为字符串常量存储在 java class 文件中,所以是的,如果您发现需要更改基础查询,则必须更改查询并构建补丁。
我们 运行 遇到了同样的问题,但是添加以下索引在单击 API 以显着检索其信息时提高了商店性能:
数据库:apimgt
Table: IDN_OAUTH2_ACCESS_TOKEN
列:USER_TYPE、CONSUMER_KEY_ID、TOKEN_ID、TOKEN_STATE