动态生成KML的故障排除
我在使用动态生成的KML文件,但它偶尔会出问题,似乎是因为和谷歌服务器的“时机问题”。上次检查时它是正常的,但这感觉像是巧合。我是否应该设置一个定时任务,每5分钟访问一次这个页面,以保持数据在内存中是最新的?服务器端的KML生成器是:
class KMLHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Cache-Control'] = 'public,max-age=%s' \
% 86400
start = datetime.datetime.now() - timedelta(days=60)
from google.appengine.api import memcache
memcache_key = 'ads'
data = memcache.get(memcache_key)
if data is None:
a = Ad.all().filter('modified >',
start).filter('published =',
True).order('-modified').fetch(1000)
memcache.set('ads', a)
else:
a = data
dispatch = 'templates/kml.html'
template_values = {'a': a, 'request': self.request,
'host': os.environ.get('HTTP_HOST',
os.environ['SERVER_NAME'])}
path = os.path.join(os.path.dirname(__file__), dispatch)
output = template.render(path, template_values)
self.response.headers['Content-Type'] = \
'application/vnd.google-earth.kml+xml'
self.response.headers['Content-Length'] = len(output)
self.response.out.write(output)
--
模板文件是:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
{% for ad in a %}
{% if ad.geopt %}
<Placemark><name></name><description>
<![CDATA[{% if ad.uri2view %}<img src="{{ ad.uri2view }}">{% endif %}<a href="http://www.koolbusiness.com/vi/{{ad.key.id}}"> {{ ad.title }} </a><br/>{{ad.text|truncatewords:20}}]]></description><Point><coordinates>{{ad.geopt.lon|floatformat:2}},{{ad.geopt.lat|floatformat:2}}</coordinates></Point></Placemark>{% endif %}{% endfor %}</Document></kml>
--
我还用KML验证器检查过输出,以确保它是正确的。这个KML是动态生成的,我也尝试过缓存它。但它就是偶尔会出问题,原因不明。我用Python生成KML,代码也检查过,应该是没问题的。我看不出程序哪里出错了?我可以把我的脚本输出保存为一个静态的KML文件,这样是可以正常工作的,而且KML也是有效的,所以看起来在动态生成时,传给谷歌的时候出现了“时机问题”。但我该如何进一步排查这个问题呢?我可以考虑换成使用JSON,但那会需要很多重新编码,我觉得我离解决这个问题不远了。
我想到的三种策略是:
- 换成Jinja2模板
- 用JSON代替KML
- 写一个定时任务,每5分钟访问一次文件,以保持数据在内存缓存中

1 个回答
2
我怀疑你的KML文件生成得太慢,导致谷歌放弃了。我测试了这个链接几次,每次加载都要几秒钟,有时候甚至超过5秒。下载和显示这些KML文件的服务器如果加载速度太慢,就会超时或者放弃加载。这种情况通常会导致文件有时无法加载,或者缓存(当文件加载成功时)过期。
如果生成KML文件的过程无法改进,你应该缓存你生成的实际文件数据,这样将来可以更快地返回这些数据。你可以使用任务队列API或定时任务,每隔N分钟运行一次重建任务,保持缓存的最新状态。