Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 20, 2015 21:06:34

alexte
Зарегистрирован: 2015-10-20
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

Возникла задача, в которой есть сотня-другая очень малонагруженных приложений-сервисов,
которые общаются друг с другом и с приложениями на других серверах посредством, например, ZeroMQ (непринципиально).
Запускать столько приложений отдельно одновременно, боюсь никакого ОЗУ не хватит.
Обязательно нужно иметь возможность любое приложение останавливать, модифицировать код и снова запускать.
Привожу рисунок для лучшего понимания задачи. Что посоветуете?

Отредактировано alexte (Окт. 20, 2015 21:09:19)

Прикреплённый файлы:
attachment Концепция.png (13,7 KБ)

Офлайн

#2 Окт. 20, 2015 21:37:05

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

alexte
ZeroMQ (непринципиально).
Например в ZMQ сообщения могут вставать в очередь на обработку, обработчики при этом не обязаны быть в оперативной памяти. Диспетчер обработчиков может их подгружать после посылки им сообщений.

А самое простое решение просто сделать swap побольше. Все что не активно будет вытеснено на диск. Так что делать ничего не надо.

Вообще в древности были такие штуки https://ru.wikipedia.org/wiki/Overlay_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5). Но те времена давно прошли. Запустите вашу сотню приложений и покажите что вам не хватает памяти или не будет хватать с развитием системы.

Если приложения это код на питоне то имеет смысл не городить огород с zeromq а сделать динамический импорт плагинов в одно приложение. Обмен - greenlet/asyncio.



Отредактировано doza_and (Окт. 20, 2015 21:53:58)

Офлайн

#3 Окт. 25, 2015 00:40:45

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Фреймворк для большого количества отдельных приложений

Если приложение жрёт 100мб, например. И их сотня-другя. То это 10-20гб. В чём проблема?

Офлайн

#4 Окт. 26, 2015 08:56:15

alexte
Зарегистрирован: 2015-10-20
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

Проблема в том, что ОЗУ ограничено и сильно. Это миникомпьютеры на ARM всего с 1ГБ.
В принципе задача почти решена при помощи asyncio task. Разбираюсь с возможностью перезагрузки модулей “на лету”…

Офлайн

#5 Окт. 26, 2015 10:57:27

alexte
Зарегистрирован: 2015-10-20
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

Решил. Что-то нарыл в инете, что-то дописал.

Вот основной модуль

import time
import asyncio
import functools
from threading import Thread, current_thread, Event
from concurrent.futures import Future
import importlib
import sys
class Apps(Thread):
    def __init__(self, start_event):
        Thread.__init__(self)
        self.loop = None
        self.tid = None
        self.event = start_event
    def run(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.tid = current_thread()
        self.loop.call_soon(self.event.set)
        self.loop.run_forever()
    def stop(self):
        self.loop.call_soon_threadsafe(self.loop.stop)
    def add_task(self, coro):
        """this method should return a task object, that I
          can cancel, not a handle"""
        def _async_add(func, fut):
            try:
                ret = func()
                fut.set_result(ret)
            except Exception as e:
                fut.set_exception(e)
        f = functools.partial(asyncio.async, coro, loop=self.loop)
        if current_thread() == self.tid:
            return f() # We can call directly if we're not going between threads.
        else:
            # We're in a non-event loop thread so we use a Future
            # to get the task from the event loop thread once
            # it's ready.
            fut = Future()
            self.loop.call_soon_threadsafe(_async_add, f, fut)
            return fut.result()
    def cancel_task(self, task):
        self.loop.call_soon_threadsafe(task.cancel)
class Tasks:
    def __init__(self, module):
        self.module = module
        importlib.import_module(self.module)
        self.t = appl.add_task(sys.modules[self.module].tst1())
    def reload(self):
        appl.cancel_task(self.t)
        importlib.reload(sys.modules[self.module])
        self.t = appl.add_task(sys.modules[self.module].tst1())
    def cancel(self):
        appl.cancel_task(self.t)
event = Event()
appl = Apps(event)
appl.start()
event.wait()  # Let the loop's thread signal us, rather than sleeping
t1 = Tasks('appl1')
t2 = Tasks('appl2')
t3 = Tasks('appl3')
time.sleep(5)
t1.reload()
t2.reload()
time.sleep(5)
t1.cancel()
t2.cancel()
t3.cancel()
time.sleep(1)
appl.stop()

запускает подгружаемые модули appl1…3
import asyncio
@asyncio.coroutine
def tst1():
    i = 0
    while True:
        print('appl1... {0}'.format(i))
        i += 1
        yield from asyncio.sleep(1)

Отредактировано alexte (Окт. 26, 2015 10:58:50)

Офлайн

#6 Окт. 26, 2015 20:34:35

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

alexte
Возникла задача, в которой есть сотня-другая очень малонагруженных приложений-сервисов,которые общаются друг с другом и с приложениями на других серверах посредством, например, ZeroMQ
Может тупо по типу CGI: одно приложение, которое слушает очередь, запускает другие, передавая им параметры из очереди и собирая их выхлоп?



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#7 Окт. 27, 2015 04:38:28

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

alexte
расскажите что за конкретно микропк, название/модель ?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#8 Окт. 27, 2015 07:00:29

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

t1 = Tasks('appl1')
t2 = Tasks('appl2')
t3 = Tasks('appl3')
time.sleep(5)
t1.reload()
t2.reload()
time.sleep(5)
t1.cancel()
t2.cancel()
t3.cancel()
time.sleep(1)
appl.stop()
Это некрасиво. Обычно сканируют папку с плагинами и все их пихают в приложение.
yield from asyncio.sleep(1)
Тут я просто не понял. Зачем time.sleep(5), sleep(1) Наверное нужно sleep(0). Если хотите запускать задачи по расписанию то на это есть https://docs.python.org/2/library/sched.html или его аналоги. А использовать sleep для ожидания завершения операций очень плохая практика. Неожиданно перестанет работать в тот момент когда вы уже забудете для чего все эти sleep



Офлайн

#9 Окт. 27, 2015 08:24:44

alexte
Зарегистрирован: 2015-10-20
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

Код, приведенный ниже классов, - это просто маленький тест на создание приложений их перезагрузку и остановку. Если запустите, то увидите зачем там паузы.

JOHN_16
расскажите что за конкретно микропк, название/модель ?

Orange pi pc, с 1ГБ памяти и ценой 18 USD…

Офлайн

#10 Ноя. 5, 2015 17:59:16

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Фреймворк для большого количества отдельных приложений

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version