V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ri0day
V2EX  ›  Python

关于python 的non-blocking IO的一些疑问。以及我正在做的一个小工具的中遇到的一些问题。求解惑

  •  
  •   ri0day ·
    ri0day · 2011-11-02 11:37:59 +08:00 · 5453 次点击
    这是一个创建于 4802 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一直没有系统的学过python,但是每次都是网上看一些现成资料。写一些小脚本。不知道自己入没入门。一直时断时续的看一些基础语法。现在想通过做一个东西让自己熟悉一些。所以有如下疑问:

    1.怎么判断一个socket server中的操作是阻塞或者是非阻塞的。如何用简单明了的代码测试出来阻塞与非阻塞的明显区别。这样非常直观的让我理解这个机制
    有这种示例代码么。我在网上找了很久也没有。我说的是使用原生python编写 不是利用第三方已经写好的异步或者non-blocking模块

    2.我在做一个带健康检查的DNS服务,其实就是一个python socket 脚本。我对他的规划是 一个主体的DNS socket server 的脚本。然后 一些check的脚本。这些check的脚本去检测我checklist的一些服务。然后判断他是否能对外界服务。最后check脚本返回一组可用服务的IP。而我在DNS socket server
    中 import 这些check模块。按照返回的ip列表 随机返回一个IP响应外部的解析请求。这样既做到了健康检查。而且可以很智能调度访问.又可以做到负载均衡.

    但是。有一个bug 。我测试时候故意停掉后端一个服务。发现DNS还是返回了后端正常时的IP列表。后来到网上查了一下发现 import 模块里边定义的变量的值是一直不会改变的。除非重新import. 但是我脚本里不可能这么写。 现在需要实现这个值能跟随每次检查而变动。而且能体现在我主体的DNS SOCKET server里。这样就能动态的增删后端节点

    第二个问题是。我这个服务如果check模块变多以后。会影响响应的速度。我如何实现一个高效率的checker,是使用线程,还是进程,还是异步。哪个比较好一点。我想要实现这些checker是非阻塞的我这个服务才快得起来。

    最后贴上已经实现的代码吧 :(请勿在饭后阅读):
    DNS-SERVER :
    https://gist.github.com/1332783

    check_ping:
    https://gist.github.com/1332789

    请大家给我些建议。
    8 条回复    1970-01-01 08:00:00 +08:00
    clino
        1
    clino  
       2011-11-04 21:44:26 +08:00
    "后来到网上查了一下发现 import 模块里边定义的变量的值是一直不会改变的。"这种还是用配置文件来做比较合适,例如用 ini (dict4ini) 或者 json 之类的.

    "我如何实现一个高效率的checker,是使用线程,还是进程,还是异步。哪个比较好一点。"
    要是我会选择进程,这样程序可以用同步的方式写,比较简单.
    fcicq
        2
    fcicq  
       2011-11-04 22:07:23 +08:00
    1 对于默认 socket, 没有 gevent / stackless python 这类的修改, 就全部是阻塞的.
    tornado / twisted 是自己实现了一套, 没有暴露原始的 socket.

    2 你不理解 DNS.
    DNS 的结果会被缓存比较长的一段时间, 不要以为 DNS 上不返回失效的 IP, 就不会有人访问了. 用这个做负载均衡虽说是可以的, 但不要把 checker 和 DNS 联系到一起. 高可用的正常做法是 LVS 或者硬件负载均衡器, 而不是你山寨的玩意.
    CMGS
        3
    CMGS  
       2011-11-04 22:16:57 +08:00
    @fcicq 2.6+之后python 在select包里面提供了epoll等,理论上不跨平台还是能写出原生non-blocking。。tornado的回调太让人菊花疼了。。
    fcicq
        4
    fcicq  
       2011-11-04 22:20:51 +08:00
    @CMGS 这个会有人这样写吗? 和 C 写法也很接近了... 提供了也没用.
    elden
        5
    elden  
       2011-11-04 22:55:55 +08:00
    判断阻塞/非阻塞,可以分别写一个简单的listener(server)和client,一方向另一方写小量数据,如果另一方没读就直接返回,那么就说明是非阻塞的。
    est
        6
    est  
       2011-11-04 23:35:36 +08:00
    @fcicq 同意。建议用gevent
    ri0day
        7
    ri0day  
    OP
       2011-11-04 23:55:51 +08:00
    @fcicq 现在那个bug 已经 消灭了。由于是新手对yield理解不对。后来用return的 方式 解决了这个反回失效后端的IP BUG.
    至于说还是会调度到失效的后端这个问题我没有发现有这个情况。我这个DNS 是给内网用的。用于一些配置文件里面。好让程序透明访问资源。而这个checker的脚本也可以做一些比较智能的调度。比如说根据后端服务器负载,或者数据库的繁忙程度等等。
    这个东西确实比较山寨。性能也肯定不怎么好。我新人拿来练手用的。呵呵。 不过我会尝试大家推荐的一些异步的库。比如gevent 什么的。
    CMGS
        8
    CMGS  
       2011-11-06 02:27:36 +08:00
    @fcicq 有example,没人用是因为。。gevent之流实在是。。太方便了。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   975 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:07 · PVG 05:07 · LAX 13:07 · JFK 16:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.