在 ColdFusion 中使用缓存限制对 Api 的调用速率

发布于 2024-08-30 02:56:11 字数 1030 浏览 4 评论 0原文

您好,我正在使用 ColdFusion 调用 last.fm api,使用源自 此处 的 cfc 包。

我担心是否会超过请求限制,即每个原始 IP 地址每秒 5 个请求,平均在 5 分钟内发生。

cfc 包有一个中央组件,它调用所有其他组件,这些组件被分为“艺术家”、“曲目”等部分......这个中央组件“lastFmApi.cfc”。在我的应用程序中启动,并在应用程序的生命周期中持续存在

// Application.cfc example
    <cffunction name="onApplicationStart">
        <cfset var apiKey = '[your api key here]' />
        <cfset var apiSecret = '[your api secret here]' />

        <cfset application.lastFm = CreateObject('component', 'org.FrankFusion.lastFm.lastFmApi').init(apiKey, apiSecret) />
    </cffunction>

现在,如果我想通过处理程序/控制器调用 api,例如我的艺术家处理程序...我可以这样做,

<cffunction name="artistPage" cache="5 mins">
 <cfset qAlbums = application.lastFm.user.getArtist(url.artistName) />
</cffunction>

我对缓存有点困惑,但是我在此处理程序中缓存对 api 的每次调用 5 分钟,但这有什么区别吗,因为每次有人点击新的艺术家页面时,这仍然算作对 api 的新点击吗?

想知道如何最好地解决这个问题

谢谢

Hi I am using ColdFusion to call the last.fm api, using a cfc bundle sourced from here.

I am concerned about going over the request limit, which is 5 requests per originating IP address per second, averaged over a 5 minute period.

The cfc bundle has a central component which calls all the other components, which are split up into sections like "artist", "track" etc...This central component "lastFmApi.cfc." is initiated in my application, and persisted for the lifespan of the application

// Application.cfc example
    <cffunction name="onApplicationStart">
        <cfset var apiKey = '[your api key here]' />
        <cfset var apiSecret = '[your api secret here]' />

        <cfset application.lastFm = CreateObject('component', 'org.FrankFusion.lastFm.lastFmApi').init(apiKey, apiSecret) />
    </cffunction>

Now if I want to call the api through a handler/controller, for example my artist handler...I can do this

<cffunction name="artistPage" cache="5 mins">
 <cfset qAlbums = application.lastFm.user.getArtist(url.artistName) />
</cffunction>

I am a bit confused towards caching, but am caching each call to the api in this handler for 5 mins, but does this make any difference, because each time someone hits a new artist page wont this still count as a fresh hit against the api?

Wondering how best to tackle this

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

栖迟 2024-09-06 02:56:11

由于它是简单的数据模型,我不会使用自定义缓存引擎使事情变得复杂。我将简单的结构/查询:searchTerm/结果、时间戳放在某处。在那里你可以这样做:

<cffunction name="artistPage" cache="5 mins">
    <cfargument name="artistName" type="string" required="true"/>
    <cfif structKeyExists(application.artistCache, arguments.artistName) and structfindkey(application.artistCache, arguments.artistName)>
        <cfif (gettickcount() - application.artistCache[arguments.artistName].timestamp ) lte 5000 >

        <cfset result = application.artistCache[arguments.artistName].result >
    <cfelse>
        <cfset qAlbums = application.lastFm.user.getArtist(arguments.artistName) />
        <cfset tempStruct = structnew()>
        <cfset structNew.result = qAlbums >
        <cfset structNew.timestamp = getTickCount() >
        <cfset structInsert(application.artistCache, arguments.artistName, tempstruct, true) >

        <cfset result = qAlbums >

    </cfif>

    <cfreturn result >
</cffunction>

编辑:是的,你应该在某个地方放置一个方法,该方法将删除时间戳差异大于你的缓存有效期的结构键。

建议使用外观模式,以便将来可以更改。

抱歉,有错别字:)

Since it's simple data model I'd not complicate things with custom cache engines. I'd put simple struct/query : searchTerm/result,timestamp somewhere. There you could do this:

<cffunction name="artistPage" cache="5 mins">
    <cfargument name="artistName" type="string" required="true"/>
    <cfif structKeyExists(application.artistCache, arguments.artistName) and structfindkey(application.artistCache, arguments.artistName)>
        <cfif (gettickcount() - application.artistCache[arguments.artistName].timestamp ) lte 5000 >

        <cfset result = application.artistCache[arguments.artistName].result >
    <cfelse>
        <cfset qAlbums = application.lastFm.user.getArtist(arguments.artistName) />
        <cfset tempStruct = structnew()>
        <cfset structNew.result = qAlbums >
        <cfset structNew.timestamp = getTickCount() >
        <cfset structInsert(application.artistCache, arguments.artistName, tempstruct, true) >

        <cfset result = qAlbums >

    </cfif>

    <cfreturn result >
</cffunction>

EDIT: yes, you should put somewhere also method which would remove struct keys where timestamp difference is gt then your cache validity period.

Facade pattern is recommended in order to make this changeable in future.

Sorry for typos :)

眼波传意 2024-09-06 02:56:11

我会尝试自定义缓存。

它可以是一个结构,其中键是艺术家姓名或条目的其他唯一标识符。

如果您使用 CF9 或 Railo 3.1.2+,您可以使用内置缓存(CachePut、CacheGet 等函数),它可以为您处理超时等问题。

否则,您可以将缓存存储到应用程序范围中,但需要在每个条目中包含时间戳,并在缓存事件(获取/放置/删除)甚至每个请求上检查它。

I would try the custom cache.

It can be a structure where keys are artist names or other unique identifiers of your entries.

If you are using CF9 or Railo 3.1.2+ you can use built-in caching (functions CachePut, CacheGet etc), it can handle for you the timeouts and stuff.

Otherwise you can store the cache into Application scope, but will need to include timestamp with each entry and check it on cache events (get/put/remove) or even on each request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文