• OpenStack协同并发 eventlet


    今天听easystack一哥们讲nova协同并发,结合自己之前的认识。回顾一下openstack eventlet。

    OpenStack作为热门的开源云平台,本身代码当然得支持高并发。

    首先讲讲python的并发,python中的并发有:进程、线程、协程(Coroutines)。

    进程和线程大家都比较清楚了,那什么是协程,协程介绍如下:

    • 协程和线程比较像,每个协程都有⾃己的私有stack和局部变量
    • 一个线程内可以有很多个协程
    • 多个线程可以同时运行。但在一个线程内,同一时间只有一个协程在运行,无须对某些共享变量加锁
    • 协程之间的执行顺序,完全由程序来控制
    • 除非自己放弃执行,否则一直执行到结束
    • 协程是一种概念,非操作系统可见,在多种语言中实现,如go、ruby等。eventlet是Python中实现之一

    进程、线程、协程之间的关系可以用下图表示:

    eventlet是对greenlet的封装,先了解下greenlet,下面是一个官方给出的例子:

     1 from greenlet import greenlet
     2 
     3 def test1():
     4     print 12
     5     gr2.switch()
     6     print 34
     7 
     8 def test2():
     9     print 56
    10     gr1.switch()
    11     print 78
    12 
    13 gr1 = greenlet(test1)
    14 gr2 = greenlet(test2)
    15 gr1.switch()

    执行结果是:

    12
    56
    34

    程序很简单,定义两个协程,最后一行g1.switch()跳转到 test1() ,它打印12,然后跳转到 test2() ,打印56,然后跳转回 test1() ,打印34,然后 test1() 就结束,gr1死掉,回到父greenlet,不会再切换到test2,所以不会打印78。在上面的例子中main greenlet就是它们的父greenlet。

    greenlet使用虽然简单,但是需要程序员显式的写代码在不同的协程之间切换,对于OpenStack这样的大项目显然是不现实的。

    于是eventlet封装了greenlet,以下是eventlet的介绍:

    • 由second life开源的高性能网络库
    • 基于greenlet
    • 通过patch标准模块实现协程
    • 对greenlet封装,提供GreenThread
    • 内部使用timer实现greenlet调度器
    • 内部main loop 循环通过最小堆查找应该执行的greenlet

    python 2.x 原生是不支持协程的,eventlet通过对标准库打patch实现协程,例如在Nova项目中 nova/cmd/__init__.py

    import eventlet
    from nova import debugger
    
    if debugger.enabled():
        # turn off thread patching to enable the remote debugger
        eventlet.monkey_patch(os=False, thread=False)
    else:
        eventlet.monkey_patch(os=False)

    其中eventlet.monkey_patch()就是对标准库打patch。

    在调试Nova代码时,有时会因为协程导致调试不方便,可以把else语句里面的eventlet.monkey_patch(os=False)改为eventlet.monkey_patch(os=False, thread=False)

    eventlet的文档中有关于eventlet的使用,主要包含以下几个接口:

    (1) spawn(func, *args, **kw)
    启动一个greenthread来调用func函数,args和kw都是传递给func的参数。返回值是greenthread.GreenThread对象

    (2) spawn_n(func, *args, **kw)
    除了没有返回值,其他跟spawn一样

    (3) spawn_after(seconds, func, *args, **kw)
    在seconds秒之后启动

    (4) sleep(seconds=0) 
    暂停当前greenthread,给其它greenthread执行的机会

     

    参加资料:

    http://greenlet.readthedocs.org/en/latest/

    http://eventlet.net/doc/basic_usage.html

    http://blog.csdn.net/hackerain/article/details/7836993

    http://www.choudan.net/2013/08/18/OpenStack-eventlet%E5%88%86%E6%9E%90(%E4%B8%80).html

     

  • 相关阅读:
    Spring Boot Sample 033之swagger3.0
    Spring Boot Sample 025之spring-boot-security-oauth2
    Spring Boot Sample 024之spring-boot-data-influxdb
    docker 安装redis /mysql/rabbitmq
    发布视频文件,并配置vtt格式的字幕文件
    Windows控制台用copy命令合并二进制文件
    Solaris修改IP地址
    为java程序配置网络访问代理
    apache2 httpd.conf 反向代理设置实例
    Apache配置正向代理与反向代理
  • 原文地址:https://www.cnblogs.com/gorlf/p/4246659.html
Copyright © 2020-2023  润新知