在ColdFusion中调用远程API偶尔会导致超时

时间:2009-06-09 14:52:54

标签: coldfusion

我的公司网站中有一个功能,它使用cgi.remote_host变量来调用hostip.info提供的API并返回orgin的国家/地区。这应该是这样的:

  • 该函数从API中找到国家/地区
  • 对我们的本地数据库运行查询,以确定我们要转发的站点 用户,和
  • 将用户重定向到相应的站点。

如果出于任何原因,我们无法将国家/地区与我们的某个地区相关联,我们会将用户重定向到默认网站。

实际发生的是,偶尔我们的服务器找不到API,我们会收到超时错误。

这是我们要求获取领土的功能的代理:

<cffunction name="getGeoInfo" access="public" output="true" returntype="any" hint="call getGeoIP API and check country against DB">
    <cfargument name="IPAddress" required="yes" type="string" />

    <!--- Calling hostip API to get our Geo IP information --->
    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" method="get" result="geoIP" />

    <!--- Try to parse the file, if it can't parse, we don't create the variable --->
    <cftry>
        <cfset geoIPXML = xmlParse(geoIP.fileContent) />
    <cfcatch type="any" />
    </cftry>

    <!--- If variable was created, perform the function to get territory info --->
    <cfif isDefined("geoIPXML")>
        <cfset countryAbbrev = geoIPXML.HostipLookupResultSet['gml:featureMember']['hostip']['countryabbrev'].xmlText />

        <cfquery name="theTerritory" datasource="#request.dsource#">
            SELECT territory
            FROM countries
            WHERE countryCode = <cfqueryparam value="#countryAbbrev#" cfsqltype="cf_sql_varchar" />
        </cfquery>

        <!--- If no record was found, set locale to default --->
        <cfif theTerritory.recordcount EQ 0>
            <cfset returnLocale = "default" />
        <cfelse>
            <!--- Otherwise set it to territory found in DB --->
            <cfset returnLocale = theTerritory.territory />
        </cfif>
    <cfelse>
    <!--- if no XML file was returned, set locale to default --->
        <cfset returnLocale="default" />
    </cfif>

    <cfreturn returnLocale />
</cffunction>

我在这里缺少什么?我应该如何更改此功能,以便如果http请求超时,我仍然会返回我的默认值?

3 个答案:

答案 0 :(得分:6)

<cfhttp>来电换入<cftry>

另外,我会让catch块返回defaultLocale而不是什么都不做,然后检查是否存在geoIPXML。

<cftry>

    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" 
            method="get" 
            result="geoIP"
            throwOnError="yes" />
    <cfset geoIPXML = xmlParse(geoIP.fileContent) />

<cfcatch type="any">
   <cfreturn "default">
</cfcatch>

</cftry>

答案 1 :(得分:2)

我不太确定您的超时是仅针对http呼叫,还是针对整个页面。 CFHTTP具有超时属性。如果您的http呼叫超时,您可以使用它来阻止您的页面超时。

使用try / catch(如Patrick所示)返回默认结果。

答案 2 :(得分:2)

这两种方法都可行,但您可以设置

,而不是将您的调用包装在try catch块中
throwOnTimeout="false"
&lt; cfhttp&gt;上的

属性调用,而不必对您的代码进行任何其他修改。返回cfhttp结构并包含“fileContent”变量,但将填充“Connection Timeout”。尝试xmlParse它将失败,然后执行将命中你的catch块。我建议帕特里克做&lt; cfreturn“默认”/&gt;在你的catch块中,这样你的其余程序就不必随意执行。