0%

翻译自:Asynchronous programming with Tornado

对于初学者来说异步编程很令人迷惑,因此我觉得有必要介绍一些有用的基本概念来帮助初学者避免一些常见的陷阱。如果希望理解通用的异步编程模型,可以查看以下这些网络资源,Introduction to Asynchronous ProgrammingTwisted Introduction。在这篇文章中我将会着眼于如何使用 Tornado 进行异步编程。

来自Tornado主页的一段话:

FriendFeed’s web server is a relatively simple, non-blocking web server written in Python. The FriendFeed application is written using a web framework that looks a bit like web.py or Google’s webapp, but with additional tools and optimizations to take advantage of the non-blocking web server and tools. Tornado is an open source version of this web server and some of the tools we use most often at FriendFeed. The framework is distinct from most mainstream web server frameworks (and certainly most Python frameworks) because it is non-blocking and reasonably fast. Because it is non-blocking and uses epoll or kqueue, it can handle thousands of simultaneous standing connections, which means the framework is ideal for real-time web services. We built the web server specifically to handle FriendFeed’s real-time features every active user of FriendFeed maintains an open connection to the FriendFeed servers. (For more information on scaling servers to support thousands of clients, see The C10K problem.)

对于初学者首先需要认清的是自己是否真的需要异步操作。异步编程比同步编程复杂得多,因此有人说:异步编程是不适合人类大脑的。

Read more »

先来看一段十分简单的使用stl的c++代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
using namespace std;

int main(void) {
vector<int> vec;
int len = 5;
for (int i = 1; i <= len; ++i)
vec.push_back(i);
make_heap(vec.begin(), vec.end());
for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) {
cout << *iter << " ";
}
cout << endl;
return 0;
}

发现在 xcode 中运行和在 mac terminal 中利用 g++ 编译运行结果不一样,分别为:

1
2
xcode-default : 5 4 2 1 3
terminal-g++ : 5 4 3 1 2
Read more »

Tornado的web框架在web.py中实现,主要包括RequestHandler类(本质为对http请求处理的封装)和Application类(是一些列请求处理的集合,构成的一个web-application,源代码注释不翻译更容易理解:A collection of request handlers that make up a web application)。

RequestHandler分析

RequestHandler提供了一个针对http请求处理的基类封装,方法比较多,主要有以下功能:

  1. 提供了GET/HEAD/POST/DELETE/PATCH/PUT/OPTIONS等方法的功能接口,具体开发时RequestHandler的子类重写这些方法以支持不同需求的请求处理。

  2. 提供对http请求的处理方法,包括对headers,页面元素,cookie的处理。

  3. 提供对请求响应的一些列功能,包括redirect,write(将数据写入输出缓冲区),渲染模板(render, reander_string)等

  4. 其他的一些辅助功能,如结束请求/响应,刷新输出缓冲区,对用户授权相关处理等。

Read more »

用惯了crontab,希望在自己的Android手机上完成定时执行一些脚本的任务。google一下找到了 android应用实现定时打电话 这样一篇文章,正好满足我的需求。下面做一个简单的总结。

安装的软件

  • SL4A(Scripting Layer for Android),Andriod系统下运行脚本的环境,可以在终端、后台或Locale中运行,现阶段支持Python, Perl, JRuby, Lua, BeanShell, JavaScript, Tcl和shell脚本。

  • Py4A,SL4A的python插件,安装之后就可以运行python脚本。

  • TaskBomb task scheduler,一个可以执行计划任务的app,类似于Unix中的crontab。

  • SL4A Script Launcher,TaskBomb可以通过此app执行SL4A脚本。

Read more »

IOStream对socket读写进行了封装,分别提供读、写缓冲区实现对socket的异步读写。当socket被accept之后HTTPServer的_handle_connection会被回调并初始化IOStream对象,进一步通过IOStream提供的功能接口完成socket的读写。文章接下来将关注IOStream实现读写的细节。

IOStream的初始化

IOStream初始化过程中主要完成以下操作:

  1. 绑定对应的socket
  2. 绑定ioloop
  3. 创建读缓冲区_read_buffer,一个python deque容器
  4. 创建写缓冲区_write_buffer,同样也是一个python deque容器
Read more »

注:在分割线之前是基于 Tornado2.4 的分析。在Tornado3.0+以后IOLoop发生了一些改动,分割线之后有相应的介绍。

IOLoop是基于epoll实现的底层网络I/O的核心调度模块,用于处理socket相关的连接、响应、异步读写等网络事件。每个Tornado进程都会初始化一个全局唯一的IOLoop实例,在IOLoop中通过静态方法instance()进行封装,获取IOLoop实例直接调用此方法即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
@staticmethod
def instance():
"""
class MyClass(object):
def __init__(self, io_loop=None):
self.io_loop = io_loop or IOLoop.instance()
"""
if not hasattr(IOLoop, "_instance"):
with IOLoop._instance_lock:
if not hasattr(IOLoop, "_instance"):
# New instance after double check
IOLoop._instance = IOLoop()
return IOLoop._instance
Read more »

httpserver.py中给出了一个简单的http服务器的demo,代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
from tornado import httpserver
from tornado import ioloop

def handle_request(request):
message = "You requested %s\n" % request.uri
request.write("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s" % (
len(message), message))
request.finish()

http_server = httpserver.HTTPServer(handle_request)
http_server.bind(8888)
http_server.start()
ioloop.IOLoop.instance().start()

该http服务器主要使用到IOLoop, IOStream, HTTPServer, HTTPConnection几大模块,分别在代码ioloop.py, iostream.py, httpserver.py中实现。工作的流程如下图所示:

Read more »

引言

Tornado是FriendFeed最早使用的一款由python编写的轻量级、无阻塞式Web服务器,还包括一些相关的工具和优化。现已由Facebook开源在github。得益于无阻塞IO和epoll(or kqueue in FreeBSD, Mac OS X)的使用,Tornado每秒可以处理大量/数千的客户端连接,适用于实时的Web服务(详细可以参阅The C10K problem)。

接下来几篇文章将会从Web服务器框架设计、代码实现细节等角度介绍我对Tornado源码的分析。这篇文章作为概述,首先介绍Tornado的模块按功能分类,同时提供后续文章的结构目录。

Read more »

今天研究apache ab这个测试工具,在网上看到压力测试shell脚本一文介绍了一个封装的bash脚本,用于多次测试返回requests per second的平均值,对脚本进行了简单的改写,将所有的测试输出进行记录。改写脚本在文章的最后。

改写过程中发现这样一个问题,比如写下面的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

result=""
cat abtest_temp.log | while read LINE
do
result=`echo $LINE | grep 'Requests per second:'`
if [ "$result" != "" ]
then
break
fi
done
echo "result is "${result}
Read more »

系统环境Mac OS X 10.8.2,这个博客主要通过jekyll生成静态页面,使用ruby提供的一些扩展插件,比如按月份进行归档等,配置环境的过程如下。

安装ruby,rubygems

1
2
3
4
sudo port ruby
sudo port install rb-rubygems
sudo gem install rubygems-update
sudo gem update --system

安装bundle

1
sudo gem install bundler
Read more »