반응형

2012 OpenStack Folsom Design Summit 이 San Francisco 에서 열렸습니다.

클라우드 시스템을 구축하는 입장에서 현지에서 우리의 현위치와 방향을 잡을 수 있는 기회였습니다.


이번 디자인서밋의 주요 화두는 Software 기반의 Virtual Network 와 관련된 Quantum 입니다.

거의 이틀에 거쳐서 Quantum 세션을 full 로 잡은 것을 보면 그 중요도도 알 수 있을 것입니다.


Quantum 이 왜 필요한지는 Flat Network 나 VLan 모드를 사용하여 클라우드 시스템을 구축하였다면 다들 몸으로 느끼고 있으실 겁니다. (적어도 저는..)


또 다른 하나는 Hybrid Cloud 입니다.

특히 구축이 거의 불가능할 거 같은 Hybrid Cloud Bursting 에 대한 기본 아키텍처 윤곽이 나왔다는 겁니다.

이 곳에서 여러 회사를 만나면서 힌트를 얻게 되는 군요.


아직 Hybrid Cloud 에 대해서 논의되지는 않았지만 아마도 올 하반기 디자인서밋에서 대두될 것 같습니다.

채택이 안된다면 제가 강력히 주장해야 겠습니다. ^^


디자인서밋은 클라우드 구축을 시작하는 회사도 방향을 잡는 부분에서 도움이 될 것이고, 어느 정도 지식이 있는 상태에서 디자인서밋에 참석하는 회사는 더 많은 것을 얻어갈 거라 생각이 듭니다.





반응형
Posted by seungkyua@gmail.com
,
반응형

파이썬에서 eventlet 모듈로 쓰레드를 사용하고 싶다면 세가지 방법이 있습니다.


1. eventlet.tpool 을 사용

    - 가장 간단한 방법으로 eventlet.tpool.execute(function(), ...) 방식으로 쓰레드를 생성하여 호출.

      pool 을 사용하며 쓰레드 20개가 기본.

      pool 사이즈를 늘릴려면 환경변수 EVENTLET_THREADPOOL_SIZE 의 값을 변경


2. eventlet 을 사용

    - eventlet.spawn(function(), ...) 을 사용하여 쓰레드를 생성하여 호출

      리턴값으로 eventlet.greenthread.GreenThread 가 리턴됨.

      pool 을 사용할 수 없음


3. eventlet.greenpool 을 사용

    - eventlet.greenpool.GreenPool.spawn(function(), ...) 을 사용하여 쓰레드를 생성하여 호출

      리턴값으로 eventlet.greenthread.GreenThread 가 리턴됨.

      pool 사용이 가능



반응형
Posted by seungkyua@gmail.com
,
반응형

며칠동안 생고생을 하면서 알아낸 방법입니다.

VMWare fusion4 에서 아무리 환경 설정에서 vt-x 를 활성화 해서 Ubuntu 를 설치해 봤자 vmx 가 활성화 안됩니다.

결국 nova 의 compute 데몬이 실행이 안되지요..

해결방법은 게스트 OS 의 vmx 파일에서 아래의 내용을 추가하면 됩니다.

vhv.enable = "TRUE"
반응형
Posted by seungkyua@gmail.com
,
반응형
먼저 이 글은 대기업이나 중소기업의 의미가 아니라 순수 프로젝트에서 PL 의 입장으로 쓴 글입니다.
그 외의 다른 어떤 의도도 없으니 오해 마시길 바랍니다.

또한, 이 글을 인사담당자나 PM, 혹은 그 윗분들이 읽기를 바라면서...

1. 빠지는 인력이 있다면 다른 인력을 대체 투입하면 된다.(?)
   - 소프트웨어는 살아있는 유기체와도 같습니다. 살기 위해서는 최소한의 Atomic 기준의 인력이 필요합니다.
     5명이 Atomic 한 기준이 되는 소프트웨어를 만드는 프로젝트에서 한 명을 대체하는 것은
     달리기 운동선수의 한쪽 다리를 의족으로 대체하는 것과 같습니다.
   - 의족이 잘 맞을지 안맞을지도 모릅니다. 잘 안맞는다면 다시 걸을 수 있는 확율은 거의 없습니다.
   - 의족이 잘 맞는다 하더라도 현재의 기술로는 제대로 걷는데 몇 달의 필요합니다.
     의족을 종아리 아래 부분만 하면 된다면(소프트웨어 자체가 특별한 기술을 필요로 하거나,
     실력이 좋은 인력 투입) 좀 더 빨리 걸을 것이고,
     의족을 허벅지 아래 부분을 다 한다면(소프트웨어 자체가 일반적인 기술을 쓰거나,
     실력이 없는 인력) 좀 더 오래 걸릴 것입니다.
   - 결국 몇 달 동안 걸었다고 해서 다시 뛰기 까지는 더 많은 노력과 시간이 필요합니다.

2. 텅키 방식으로 일부 기능을 떼어 주면 된다.(?)
   - 일반적으로 치수를 제대로 쟀다고 해서 의족이 바로 자신에게 맞기는 어렵습니다.
     그걸 맞추기 위해서는 생각했던 것 보다 더 오래 걸릴 수 도 있습니다.
     또한, 텅키 업체의 기술자가 바뀌거나 회사 자체가 없어진다면 또 시간이 필요합니다.
   - 허벅지 부분은 우리가 만들고 종아리 부분은 텅키로 주고 서로 무릎을 맞춘다고 가정하면
     위의 설명이 조금 도움이 될려나요?
   - 결국 같이 매일 같이 얼굴 맞대면서 기술자들이 서로의 의견을 교환해 가면서 만드는 것이
     매일 특정시간만 각 업체의 PL 들이 만나서 의견교환하면서 개발하는 것보다 훨씬 진행이 빠를 것입니다.
     그렇다 하더라도 기술자나 회사가 바뀌면 똑같은 첫번째 문제가 발생합니다.

3. 인력을 추가로 투입하면 된다.(?)
   - 여기에는 여러 가지 비유가 있더군요. 대표적으로 보면,
      아기를 낳을 때 10명이 모이면 1달에 낳을 수 있느냐?
   - 겨우 특정한 운동선수의 의족을 그에 맞게 시행착오로 적응해서 만들기 시작했는데,
      다른 기술자나 신입이 들어와서 그 적응 기간없이 만들 수 있을까요?
      아니면 하나의 나사를 둘이서 조인다고 빨리 조일 수 있을까요?

대체 인력을 줬다고, 텅키로 업체를 구했다고, 추가로 인력을 투입했다고 프로젝트가 납기 기간내에 성공할 거라고 논리를 세우는 인사조직이나 PM, 그 윗분님들.. 제발 쫌~~~    
반응형
Posted by seungkyua@gmail.com
,

Nova 소스 위치

OpenStack/Nova 2011. 12. 20. 10:14
반응형
소스 원본 : /usr/share/pyshared/nova
링       크 : /usr/lib/python2.7/dist-packages/nova



반응형
Posted by seungkyua@gmail.com
,

Nova Boot 순서

OpenStack/Nova 2011. 11. 4. 18:00
반응형

nova 에서 instance 를 생성할 때 호출되는 Sequence 흐름을 표현한다.
모듈별 흐름으로 보면 다음과 같다.

API -> COMPUTE -> RabbitMQ -> SCHEDULER -> RabbitMQ -> COMPUTE

1. api/openstack/servers.py -> create()
     1-1. api/openstack/create_instance_helper.py -> create_instance()
            - request 로 넘어온 값을 추출
            - glance Image 서버에 접근할 수 있는 객체 생성
            - glance 로 부터 image id, kernel id, ramdisk id 를 조회
            1-1-1. compute/instance_types.py -> get_instance_type_by_flavor_id()
                      - db로 부터 instance type 을 조회
            1-1-2. compute/api.py -> create()
                      - 넘어온 파라미터에 대한 체크
                      1-1-2-1. create_db_entry_for_new_instance()
                                   1-1-2-1-1. self.db.security_group_get_by_name()
                                                   - db에서 security group name 으로 id를 조회
                                   1-1-2-1-2. self.db.instance_create()
                                                   - instance 테이블에 기본 값만 추가하여 instance id 를 생성
                                   1-1-2-1-3. self.db.instance_add_security_group()
                                                   - security_group_instance_association 테이블에 값을 추가
                                   1-1-2-1-4. self._update_image_block_device_mapping()
                                                   - glance 에서 가져온 image 메타데이터 mappings 정보를 이용
                                                   1-1-2-1-4-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-5. self._update_block_device_mapping()
                                                   - glance 에서 가져온 image 메타데이터 block_device_mappings
                                                      정보를 이용
                                                   1-1-2-1-5-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-6. self._update_block_device_mapping()
                                                   - 파라미터로 넘어온 mappings 정보를 이용
                                                   1-1-2-1-6-1. self.db.block_device_mapping_update_or_create()
                                                                      - 파라미터로 넘어온 mappings 값이 있으면
                                                                         block_device_mapping 테이블에 저장
                                   1-1-2-1-7. self.update()
                                                   1-1-2-1-7-1. self.db.instance_update()
                                                                      - instances 테이블에 vm_state 와 task_state 값을
                                                                        BUILDING, SCHEDULING 으로 수정

                      1-1-2-2. _ask_scheduler_to_create_instance()
                                   1-1-2-2-1. rpc.cast(context,
                                                               FLAGS.scheduler_topic,
                                                               {"method": "run_instance",
                                                                    "args": {"topic": FLAGS.compute_topic,
                                                                                "instance_id": instance_id,
                                                                                "request_spec": request_spec,
                                                                                "availability_zone": availability_zone,
                                                                                "admin_password": admin_password,
                                                                                "injected_files": injected_files,
                                                                                "requested_networks": requested_networks}})
                                                   - rpc.cast 로 scheduler 의 run_instance 메소드를 호출 

2. scheduler/manager.py.SchedulerManager -> __getattr__()
    - run_instance 메소드가 없으니 __getattr__ 메소드가 호출됨
    2-1. _schedule()
           2-1-1. scheduler/multi.py -> __getattr__()
                     - schedule_run_instance 메소드가 없으니 __getattr__ 메소드가 호출
                     2-1-1-1. scheduler/chance.py.ChanceScheduler -> schedule_run_instance()
                                  - schedule_run_instance() 가 없어 AttributeError exception 이 발생
           2-1-2. scheduler/multi.py -> schedule()
                     2-1-2-1.  scheduler/chance.py.ChanceScheduler -> schedule()
           2-1-3. rpc.cast(context,
                                  db.queue_get_for(context, topic, host),
                                  {"method": method,
                                    "args": kwargs})
                     - rpc.cast 로 compute 의 run_instance 메소드를 호출  

3. compute/manager.py.ComputeManager -> run_instance()
    3-1. self._run_instance()
           3-1-1. self.db.instance_get()
                     - db 에서 instance 정보를 조회함
           3-1-2. virt/libvirt/connection.py.LibvirtConnection -> list_instances()
                     - libvirt 를 이용하여 kvm 에서 기동중인 instance vm id 를 조회
                     - instance['name'] 이 kvm 에서 조회되는 vm id 임
           3-1-3. self.db.instance_update()
                     - instances 테이블에 vm_state 와 task_state 를 BUILDING, NETWORKING 으로 변경
           - FLAGS.stub_network 이 False 이면
           3-1-3. network/api.py.API -> allocate_for_instance()
                  3-1-3-1. rpc.call(context, FLAGS.network_topic,
                                    {'method': 'allocate_for_instance',
                                     'args': args})
           3-1-4. self._instance_update()
                     3-1-4-1. self.db.instance_update()
                                  - instances 테이블에 vm_state 와 task_state 를 BUILDING,
                                     BLOCK_DEVICE_MAPPING으로 변경
           3-1-5. self._setup_block_device_mapping() 
                      3-1-5-1. self.db.block_device_mapping_get_all_by_instance()
                                   - instances 테이블과 block_device_mapping 테이블을 조인하여 조회
                                   - snapshot_id 값이 있고, volume_id 값이 없으면 아래가 호출됨
                      3-1-5-2. volume/apy.py.API -> create()
                                   3-1-5-2-1. self.db.snapshot_get()
                                   3-1-5-2-2. quota.py -> allowed_volumes()
                                   3-1-5-2-3. self.db.volume_create()
                                                   - volumes 테이블에 추가, status, attach_status 는 creating,
                                                      detached 로 세팅 
                                   3-1-5-2-4. rpc.cast(context,
                                                               FLAGS.scheduler_topic,
                                                               {"method": "create_volume",
                                                                "args": {"topic": FLAGS.volume_topic,
                                                                            "volume_id": volume['id'],
                                                                            "snapshot_id": snapshot_id}})
                                                  - rpc.cast 로 Volume 을 호출
 
                       3-1-5-3. volume/manager.py.VolumeManager -> create_volume()
                                    3-1-5-3-1. self.db.volume_get()
                                                    - volumes 테이블 정보 조회
                                    3-1-5-3-2. self.db.volume_update()
                                                    - volumes 테이블 host colume 에 떠있는 host 값 저장
                                    - snapshot_id 가 없으면 아래가 호출
                                    3-1-5-3-3. volume.san.py.HpSanISCSIDriver -> create_volume()
                                    - snapshot_id 가 있으면 아래가 호출
                                    3-1-5-3-4. self.db.snapshot_get() 
                                    3-1-5-3-5. volume.san.py.HpSanISCSIDriver ->
                                                                                              create_volume_from_snapshot()
                                    - iSCSI 를 노출
                                    3-1-5-3-6. volume.san.py.HpSanISCSIDriver -> create_export()
                                    3-1-5-3-7. self.db.volume_update()
                                                    - volumes 테이블의 status, launched_at 을 available,
                                                       utils.py -> utcnow() 로 수정

                       3-1-5-4. volume/apy.py.API -> wait_creation()
                                    - greenthread.sleep(1) 을 호출하여 volumes 테이블의 status 를 체킹
                       3-1-5-5. self.db.block_device_mapping_update()
                                    - block_device_mapping 테이블의 volume_id 값을 volumes 테이블의 id 로 세팅
                       3-1-5-6. volume/apy.py.API -> check_attach()
                                    - volumes 테이블을 조회하여 status 가 available 인지 체크
                       3-1-5-7. self._attach_volume_boot()
                                   3-1-5-7-1. volume/apy.py.API -> check_attach()
                                   3-1-5-7-2. volume/manager.py.VolumeManager -> setup_compute_volume()
                                                   - volumes 테이블을 조회하여 host 값이 현재의 host 와 같고
                                                      FLAGS.use_local_volumes 값이 True 이면
                                                   3-1-5-7-2-1. volume.san.py.HpSanISCSIDriver -> local_path()
                                                   - 아니면
                                                   3-1-5-7-2-2. volume.driver.py.ISCSIDriver -> discover_volume()
                                                                      3-1-5-7-2-2-1. self._get_iscsi_properties()
                                                                                            - self._execute('iscsiadm', '-m',
                                                                                                                  'discovery',
                                                                                                                  '-t', 'sendtargets',
                                                                                                                  '-p', volume['host'],
                                                                                                                   run_as_root=True)
                                                                                             - mount_device = ("/dev/disk/by-path/ip-
                                                                                                                       %s-iscsi-%s-lun-0" %
                                                                                                           (iscsi_properties['target_portal'],
                                                                                                            iscsi_properties['target_iqn']))
                                                                                             - export 가 안되면
                                                                                               FLAGS.num_iscsi_scan_tries만큼 반복
                                                   3-1-5-7-2-3. self.db.volume_attached()
                                                                      - volumes 테이블의 status, mountpoint, attach_status 값을
                                                                         in-use, device_name, attached 로 변경 
           3-1-6. self._instance_update()
                     3-1-6-1. self.db.instance_update()
                                  - instances 테이블에 vm_state 와 task_state 를 BUILDING, SPAWNING 으로 변경
           3-1-7. virt/libvirt/connection.py.LibvirtConnection -> spawn()
                     3-1-7-1. self.to_xml()
                                  3-1-7-1-1. self._prepare_xml_info()
                                                  3-1-7-1-1-1. virt/driver.py -> block_device_info_get_mapping()
                                                  3-1-7-1-1-2. virt/libvirt/vif.py.LibvirtBridgeDriver -> plug()
                                                                     - multi_host 가 False 이고 should_create_bridge 가 True
                                                                        - should_create_vlan 이 True 이면
                                                                           3-1-7-1-1-2-1. network/linux_net.py.
                                                                                                     LinuxBridgeInterfaceDriver
                                                                                                            -> ensure_vlan_bridge()
                                                                        - should_create_vlan 이 False 이면
                                                                           3-1-7-1-1-2-2. network/linux_net.py.
                                                                                                     LinuxBridgeInterfaceDriver 
                                                                                                            -> ensure_bridge()
                                                                     3-1-7-1-1-2-3. self._get_configurations()
                                                  3-1-7-1-1-3. compute/instance_types.py -> get_instance.type()
                                                  3-1-7-1-1-4. self._volume_in_mapping()
                                                  3-1-7-1-1-5. virt/driver.py -> block_device_info_get_ephemerals()
                                                  3-1-7-1-1-6. virt/driver.py -> block_device_info_get_root()
                                                  - root_device_name 이 있다면 그대로 데이터를 이용
                                                  - root_device_name 이 없다면
                                                  3-1-7-1-1-7. db.instance_update()
                                                  - local_device 가 True 라면
                                                  3-1-7-1-1-8. db.instance_update()
                                                  3-1-7-1-1-9. virt/driver.py -> block_device_info_get_swap()
                                                  - FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc', 'uml') 라면
                                                     xml_info['vncserver_host'] 및 xml_info['vnc_keymap'] 에 세팅
                     3-1-7-2. virt/libvirt/firewall.py.IptablesFirewallDriver -> setup_basic_filtering() 
                                  3-1-7-2-1. virt/libvirt/firewall.py.NWFilterFirewall -> setup_basic_filtering()
                                                  3-1-7-2-1-1. self._ensure_static_filters()
                                                  3-1-7-2-1-2. self._define_filter(self._filter_container())
                                  3-1-7-2-2. self.refresh_provider_fw_rules()
                                                  3-1-7-2-2-1. self._do_refresh_provider_fw_rules()
                                                                     3-1-7-2-2-1-1. self._purge_provider_fw_rules()
                                                                     3-1-7-2-2-1-2. self._build_provider_fw_rules()
                                                  3-1-7-2-2-2. self.iptables.apply()
                                                                     3-1-7-2-2-2-1. network/linux_net.py.IptablesManager
                                                                                                                                         -> apply()
                                                                                          3-1-7-2-2-2-1-1. self._modify_rules() 
                     3-1-7-3. virt/libvirt/firewall.py.IptablesFirewallDriver -> prepare_instance_filter()
                                  3-1-7-3-1. self.add_filters_for_instance()
                                                  3-1-7-3-1-1. network/linux_net.py.IpTablesTable -> add_chain()
                                                  3-1-7-3-1-2. self._filters_for_instance()
                                                  3-1-7-3-1-3. self._add_filters()
                                                  3-1-7-3-1-4. self.instance_rules()
                                                  3-1-7-3-1-3. self._add_filters()
                                  3-1-7-3-2. network/linux_net.py.IpTablesTable -> apply()
                                                  3-1-7-3-2-1. self._modify_rules()
                     3-1-7-4. self._create_image()
                                  .......
                     3-1-7-5. self._create_new_domain()
                                  .......
                     3-1-7-6. virt/libvirt/firewall.py.IptablesFirewallDriver -> apply_instance_filter()
                                  pass
                     3-1-7-7. utils.py.LoopingCall(_wait_for_boot)
                                  3-1-7-7-1. self.get_info()
                                                  - libvirt 로 부터 state를 주기적으로 받아와서 power_state.RUNNING 일 때
                                                     멈춤
                     3-1-7-8. utils.py.LoopingCall -> timer.start()
            3-1-8. self._get_power_state()
                     ........
           3-1-9. self._instance_update()
                     3-1-9-1. self.db.instance_update()
                                  - instances 테이블에 power_state, vm_state 와 task_state 를 libvirt를 조회하여
                                    compute/power_state.py.변수, ACTIVE, None 으로 변경
           3-1-10. utils.py -> usage_from_instance()
                      - instance 상태 변수를 넘겨서 usage_info dict 변수 값으로 변경하여 리턴
           3-1-11. notifier/api.py -> notify('compute.%s' % self.host,
                                                       'compute.instance.create',
                                                       notifier.INFO, usage_info)



반응형
Posted by seungkyua@gmail.com
,
반응형
sqlalchemy 를 사용하면서 sql 문을 log 로 남기는 방법

1. create_engine() 의 전달인자 중에서 echo 값을 True 로 설정 

2. nova/db/sqlalchemy/session.py 66 라인에 값을 변경

engine_args = {

    "pool_recycle": FLAGS.sql_idle_timeout,

    "echo": True,

}



3. nova/db/sqlalchemy/models.py 878 라인의 값을 변경

engine = create_engine(FLAGS.sql_connection, echo=True)



4. nova/db/sqlalchemy/api.py 의 43 라인 변경

LOG = logging.getLogger("sqlalchemy.engine")

LOG.setLevel(logging.INFO)




5. nova.conf 값에 추가하여 처리할 수도 있음

# /etc/nova/nova.conf
--sql_echo=True

# nova/db/sqlalchemy/session.py
flags.DEFINE_bool('sql_echo', False, 'show sql log output')

# nova/db/sqlalchemy/session.py
engine_args = {

    "pool_recycle": FLAGS.sql_idle_timeout,

    "echo": FLAGS.sql_echo,

}

# nova/db/sqlalchemy/models.py
engine = create_engine(FLAGS.sql_connection, echo= FLAGS.sql_echo) 




 
반응형
Posted by seungkyua@gmail.com
,
반응형
I. Import 하기

from carrot import connection as carrot_connection
from carrot import messaging

II. Connection 객체 생성

params = dict(hostname=FLAGS.rabbit_host,
                    port=FLAGS.rabbit_port,
                    ssl=FLAGS.rabbit_use_ssl,
                    userid=FLAGS.rabbit_userid,
                    password=FLAGS.rabbit_password,
                    virtual_host=FLAGS.rabbit_virtual_host)

connection = carrot_connection.BrokerConnection(params);

III. Consumer 생성

consumer = messaging.Consumer( connection=self,
                                                  topic=topic,
                                                  proxy=proxy)

IV. Sample (http://nathanborror.com/posts/2009/may/20/working-django-and-rabbitmq/)

########## Set global variables ###################

AMQP_SERVER = 'localhost'
AMQP_PORT = 5672
AMQP_USER = 'guest'
AMQP_PASSWORD = 'guest'
AMQP_VHOST = '/'

########## Create a consumer ###################

>>> from flopsy import Connection, Consumer
>>> consumer = Consumer(connection=Connection())
>>> consumer.declare(queue='books', exchange='readernaut', routing_key='importer', auto_delete=False)

>>> def message_callback(message):
...     print 'Recieved: ' + message.body
...     consumer.channel.basic_ack(message.delivery_tag)
>>>
>>> consumer.register(message_callback)
>>> consumer.wait()


########## Create a publisher ###################

>>> from flopsy import Connection, Publisher
>>> publisher = Publisher(connection=Connection(), exchange='readernaut', routing_key='importer')
>>> publisher.publish('Test message!')
>>> publisher.close()



[ Pool 사용 ]

1. Publisher 가 cast 로 호출할 때 pools.Pool을 사용 (Connection 을 Pool로 연결)

from eventlet import pools

class Pool(pools.Pool):
    def create(self):
        LOG.debug('Pool creating new connection')
        return Connection.instance(new=True)

ConnectionPool = Pool(
        max_size=FLAGS.rpc_conn_pool_size,
        order_as_stack=True)

with ConnectionPool.item() as conn:
        publisher = DirectPublisher(connection=conn, msg_id=msg_id)

2. Consumer 가 메세지를 받을 때 GreenPool을 사용 (메소드를 Pool로 실행)

from eventlet import greenpool

self.pool = greenpool.GreenPool(FLAGS.rpc_thread_pool_size)
self.pool.spawn_n(self._process_data, msg_id, ctxt, method, args)

def _process_data(self, msg_id, ctxt, method, args):
...
 
3. Consumer 를 Thread로 변경하여 실행을 분기시키고자 할 때 eventlet.spawn을 사용
    - 코드를 wait() block 없이 계속 실행
    - 해당 Thread 가 return 값으로 넘어옮

import eventlet

self._rpc_consumer_thread = eventlet.spawn(_consumer_thread)
 
4. Report 와 같이 내부 LoopingCall 을 분기시켜 실행하고자 할 때 eventlet.greenthread 를 사용

from eventlet import greenthread

def _inner():
    ...
    greenthread.sleep(interval)
    ...

greenthread.spawn(_inner)




[ 용어 정리 ]
- queue      : Queue 이름을 의미
- exchange : Queue 와 Bind 하기 위한 exchange 이름을 의미
- exchange_type :
    . direct  : routing_key 가 정확하게 매칭되어야 함
    . topic   : routing_key 를 패턴 매칭으로 사용 가능
    . fanout : routing_key 가 필요 없이 모두 통신
- routing_key : Key 이름에 해당하는 Queue 에만 메세지를 보낼 수 있음




반응형
Posted by seungkyua@gmail.com
,
반응형

I. import 모듈

import eventlet.patcher
eventlet.patcher.monkey_patch()

import eventlet.db_pool
import sqlalchemy.orm
import sqlalchemy.pool

try:
    import MySQLdb
except ImportError:
    MySQLdb = None

II. orm sessionmaker 함수를 통한 session 생성

session = sqlalchemy.orm.sessionmaker(bind=engine,
                                                          autocommit=autocommit,
                                                          expire_on_commit=expire_on_commit)

III. sessionmaker의 첫번째 인수, bind 를 하기 위한 engine 을 생성하는 방법

engine = sqlalchemy.create_engine(FLAGS.sql_connection, **engine_args)

IV. create_engine을 하기 위한 engine_args dict 변수를 만드는 방법

engine_args = {
    "pool_recycle": FLAGS.sql_idle_timeout,
    "echo": False,
}
engine_args["pool_size"] = FLAGS.sql_max_pool_size
engine_args["pool_timeout"] = FLAGS.sql_pool_timeout
engine_args["creator"] = creator.create

V. creator (Connection Pool) 를 구하는 방법

creator = eventlet.db_pool.ConnectionPool(MySQLdb, **pool_args)

VI. ConnectionPool을 구하기 위한 pool_args 변수를 만드는 방법

# sqlalchemy.engine.url.make_url 을 이용하면 url 을 가지고 dict 형태로 변환이 가능하다.
connection_dict = sqlalchemy.engine.url.make_url(FLAGS.sql_connection)

pool_args = {
        "db": connection_dict.database,
        "passwd": password,
        "host": connection_dict.host,
        "user": connection_dict.username,
        "min_size": FLAGS.sql_min_pool_size,
        "max_size": FLAGS.sql_max_pool_size,
        "max_idle": FLAGS.sql_idle_timeout,
}





















 

반응형
Posted by seungkyua@gmail.com
,
반응형
[ context ]
{'request_id': 'd3f06598-456a-41d4-8b64-0f363f1c881d',
  'user_id': 'test_user_id',
  'roles': [],
  'timestamp': '2011-10-21T09:21:40.225901',
  'is_admin': True,
  'auth_token': None,
  'project_id': 'test_project',
  'remote_address': '127.0.0.1',
  'read_deleted': False,
  'strategy': 'noauth'
}


[ body ]
{'server': {'name': 'ahn1',
                'imageRef': '3', 
                'key_name': None, 
                'flavorRef': '2', 
                'max_count': 1, 
                'min_count': 1
               }
}

* 'server' 에 더 추가될 수 있는 내용
'server': {'personality':
              'config_drive':
              'security_groups':
              'networks':
              'blob':
              'key_name':
              'user_data':
              'availability_zone':
              'reservation_id':
             }



[ image_meta ]
{'status': 'active',
 'properties': {'kernel_id': '2', 'ramdisk_id': '1'},
 'name': 'lucid_ami',
 'deleted': False,
 'container_format': 'ami',
 'created_at': '2011-10-17T23:30:45.570475',
 'disk_format': 'ami',
 'updated_at': '2011-10-17T23:30:50.942699',
 'id': 3,
 'min_disk': '0',
 'location': 'file:///var/lib/glance/images/3',
 'checksum': 'a36d714c27b2a0eabd2e32289ec70800',
 'owner': None,
 'is_public': True,
 'deleted_at': None,
 'min_ram': '0',
 'size': 524288000
}
 
반응형
Posted by seungkyua@gmail.com
,