Tornado本身的设计目标是单线程异步非阻塞,要想很好的发挥它的性能最好使用异步IO,并且Tornado本身也提供了异步的AsyncHttpClient的实现,配合gen.coroutine和yield,可以让请求异步执行从而不阻塞当前线程,对于单线程服务器来说,阻塞(blocking)和同步的sleep这种会挂起线程的动作都是服务器的噩梦,因为只有一个线程,所以任何等待都会影响服务器对于其他请求的处理。
异步非阻塞对于第三方IO是http请求的情况还好,毕竟可以使用Tornado提供的异步实现,但是对于有些数据库的IO,则需要异步库的支持,比如针对MongoDB的Motor等。但是第三方异步库的质量也是参差不齐,在实际的工程中
继续阅读 »
文/Robin
据 Dune Analytics 数据显示,以太坊隐私协议 Tornado Cash 美元存款量已超 1 亿美金。当前 Tornado Cash 内 ETH 存款量近 32 万枚,约 31.82 万枚。DAI、cDAI、USDC、USDT 等美元稳定币存款总量约为 1.03 亿美金。
默认情况下,你在以太坊上所有的交易历史和余额都是公开的。通过诸如 Etherscan 这样的区块浏览器可以查看所有的交易,某人但凡知道了你的地址,就可以轻轻松松获取你的支付记录、跟踪你的资金来源、计算你的持仓、甚至分析你的链上活动。
Tornado.cash 是如何在以太坊上实现隐私的?主要思路就是打破收款人和资金目标地址之间
继续阅读 »
重新翻看看ioloop的源码, 以前只读到ioloop是tornado所有网络服务的基础,比如tcpserver, iostream都是将自己对应的callback通过ioloop挂载在对应的epoll事件上,
以达到非阻塞的效果。
这里总结下ioloop类的构建过程。
ioloop它有一个基类: Configurable定义在util.py文件内,这个Configurable类重定义了new工厂函数, 据源码里的描述是为了形成一个使用new函数来作为构造函数基类,
看这个new方法代码:
继续阅读 »
源码里的结构:
tornado
├── auth.py
├── autoreload.py
├── ca-certificates.crt
├── curl_httpclient.py
├── database.py
├── escape.py
├── gen.py
├── httpclient.py
├── httpserver.py
├── httputil.py
├── init.py
├── ioloop.py
├── iostream.py
├── locale.py
├── netutil.py
├── options.py
├── platform
│ ├── auto.py
│ ├── common.py
继续阅读 »
这里的blocking signal里的blocking并不是传统意义上的针对IO的blocking, 尽管这可能是引起ioloop阻塞的一个原因之一。在这里,blocking指的是ioloop在epoll返回之后开始依次处理各监听文件句柄上的IO事件时,直到下一次进入epoll调用的这段时间的ioloop的状态。我们知道Tornado是单线程的,在处理完某次epoll调用返回的读写就绪事件之前,Tornado无法启动下次epoll监听,所以这段时间理论上是越短越好,这样,ioloop可以充分及时的获取就绪文件句柄,不会影响整体IO性能。然而在实际的使用过程中,难免会出现某次处理时间过长,从而导致ioloop的blocking时间过
继续阅读 »
交错
tornado session 管理
我们在用到的tornado的session方法, 是一个开源的session代码
继续阅读 »
Memcached作为高性能的分布式内存对象缓存系统,在web服务里应用较广,和高性能的异步非阻塞服务器Tornado搭配起来可以大幅提高服务端的性能。
应用Memcached缓存热点请求结果
我们给客户端提供api,通过json来返回http请求的结果,一般Web服务都是如此。由于用的是Tornado,所以逻辑上大概长这样:
一个请求对应一个RequestHandler对象,RequestHandler类通过定义get/post方法来处理http请求,结果会通过write方法写到一个write_buffer里,最终有flush方法负责将write_buffer里的结果返回给客户端。
缓存的话,我们一般是这样:
从Torn
继续阅读 »
同步IO
Linux IO的两阶段
同步, 异步, 阻塞, 非阻塞, 是网络IO中经常被提到的概念, 刚接触Tornado服务器的时候也知道Tornado是异步非阻塞的高性能web服务器, 直到最近看了一些资料才对同步异步的概念有了一些自己的想法。
HTTP协议是构建在TCP协议上的, TCP通信的底层本质上是socket的IO, 在Linux上, 以读socket为例, 数据首先到达的是内核缓冲区, 其次才会从内核缓冲区拷贝到用户进程, 所以负责通信的进程去读写socket的时候(也即recvfrom调用), 一般是两个阶段:
等待数据准备好, 此时数据暂存在内核缓冲区
数据准备好, 从内核缓冲区拷贝到用户进程
以上的两阶
继续阅读 »
three girls
tornado tcp server流程
tornado除去外层httpserver的封装后, 底下都是教给tcpserver, 因此才可以很容易将http协议的tornado app改造成兼容tcp协议的app.
tcpserver的使用doc:
继续阅读 »
最不喜欢在Tornado中使用任何同步阻塞型的东西,不想让ioloop阻塞在某个IO调用上,因为单线程的东西任何阻塞都是代价很高的,除非你的数据库被优化的性能很好,速度很快。除了之前的线程池之外,直接使用异步库也是不错的选择,Motor就是Tornado里可以用的很好的异步库,它兼容Tornado的gen.coroutine式的异步调用形式,主要使用了greenlet来巧妙的封装PyMongo的同步API, 把底层的socketIO进行了异步化的处理,化同步为异步。
从使用的例子来分析Motor是如何把PyMongo的API异步化的:
client = motor.MotorClient(...)
db = client['te
继续阅读 »