27:42” 重构¶
根据文档, SAE 目前的服务基本覆盖了所有Web应用所需要的功能,包括:
- MySQL (分布式数据库服务,通过RDC提供)
- Memcache (分布式缓存服务)
- Storage(分布式文件存储服务)
- KVDB(分布式key-value持久化存储)
- Cron(分布式定时服务)
- Image(分布式图像处理服务)
- FetchURL(分布式网页抓取服务)
- Mail(分布式邮件服务)
- TaskQueue(异步轻量级任务队列)
- DeferredJob(异步大任务延迟队列)
- Counter(分布式计数器服务)
- Rank(实时排行榜服务)
...
当前小应用服务的加速需求其实就是:
每次来的查询,以查询的网址为键,在 SAE 中保存金山云查询结果
下次,再有查询,先检查,是否被查询过:
- 如果有,立即本地搜索出来,返回请求
- 如果没有,向金山云查询,并同樣保存一份儿
简单的説,就是个 键-值 对的本地数据库
对照一下,立即识别出 KVDB 就是对口的专门服务!
KVDB¶
SAE Python 开发文档 中的示例代码 很简洁:
import sae.kvdb
kv = sae.kvdb.KVClient()
k = 'foo'
kv.set(k, 2)
kv.delete(k)
kv.add(k, 3)
kv.get(k)
kv.replace(k, 4)
kv.get(k)
print kv.get_info()
但是:
- kv.get_info() 吐出的都是什么含义?
- KVDB 中的键,有什么约定? 可以使用 url 嘛?
...
都没有进一步交待了,,, 好在通过 Python 可以快速完成探查,增补好功能!
调试¶
根据示例代码,快速拼出一个功能函式: qchk
@app.route('/qchk', method="POST")
def qchk():
url = request.forms.get('uri').split("/")
if 1 == len(url):
uri = url[0]
else:
uri = url[2]
k = uri
import sae.kvdb
kv = sae.kvdb.KVClient()
v = kv.get(k)
print "kv.get(uri)~ type=%s var=%s"%(type(v),v)
return "debugging..."
主要目标是想印证 KVDB 的使用,是否是自个儿想象的那样儿...
但是, dev_server 本地运行时, 一提交到 localhost:8080/qchk/ 就囧掉:
Traceback (most recent call last):
File "/usr/local/bin/bottle.py", line 737, in _handle
return route.call(**args)
File "/usr/local/bin/bottle.py", line 1454, in wrapper
rv = callback(*a, **ka)
File "index.wsgi", line 57, in qchk
import sae.kvdb
ImportError: No module named kvdb
127.0.0.1 - - [26/Apr/2012 11:42:28] "POST /qchk/ HTTP/1.1" 500 -
很明显, dev_server 中没有包含 KVDB 的模拟,,,
好吧,只有回到原始的调试过程:修订->部署->对真实服务进行测试
但是,真实运行中的服务,是跑在 SAE 中的,怎么看到为了调试,进行的 print 标准输出?
服务端日志¶
好在 SAE 毕竟是商用 PaaS 服务! 当然有渠道可以观察的!

插图 2-1 配合后台日志中心进行调试
如截屏所示...
- 每个版本的应用,都有具专用的日志收集渠道
- 日志的收集等级也详细分成5级
- 代码中的 print 调试信息,收集在 debug 级别日志通道中,,,
print "kv.get(uri)~ type=%s var=%s"%(type(v),v)
| |
| +------------------------------------+
+------------------------------+ |
V V
[26/Apr/2012:14:31:56 +0800] kv.get(uri)~ type=<type 'NoneType'> var=None yf34
对照调试代码,立即可以知道, .get() 在没有获取键值时,返回的是 None
那么立即就可以增进代码为完整的功能逻辑:
@app.route('/qchk', method="POST")
def qchk():
url = request.forms.get('uri').split("/")
if 1 == len(url):
uri = url[0]
else:
uri = url[2]
k = uri
print k
import sae.kvdb
print "kv.get_info() %s"% kv.get_info()
kv = sae.kvdb.KVClient()
v = kv.get(k)
print "kv.get(uri)~ type=%s var=%s"%(type(v),v)
if None == v:
result = _askCloud(cfg.APITYPE, uri)
kv.add(k, result)
return "/qchk(KSC)::\t %s" % cfg.PHISHTYPE[str(result)]
else:
return "/qchk(KVDB)::\t %s" % cfg.PHISHTYPE[str(v)]
即: - 没有查到,说明是首次查询,那么正常的去问金山云 - 否则,就直接返回记录中的值
将代码部署上去后,自然的使用 cURL 从本地发出请求,如: 插图 2-2 使用curl发送调试请求 :

插图 2-2 使用curl发送调试请求
对应的刷新日志页面, 情景如: 插图 2-3 调试请求的对应日志截屏

插图 2-3 调试请求的对应日志截屏
BINGO!
42:01” 小结¶
~ 这一处增强,纯粹是根据文档配合后台日志,尝试几个回和而已,一刻钟,整出来不难吧?
- 但是,过程中的心理冲突,绝对不轻
- 比如,文档中未言明的各种细节, 是否重要? 怎么测试确认?
- 怎么设计 print 点输出的格式,以便从后台日志中明确的识别出?
- 等等,都需要补课,老实查阅文档,认真领悟,大胆尝试,建立靠谱的思路和反应,,,
不过,整体上,只要思路明确,方向正确,真心只是个轻松的过程而已,,,