ZeroRPC — легкая, надежная библиотека для распределенной связи между серверами

от автора

Давече мне понадобилось реализовать некое подобие собственного statsd-like сервера сбора метрики, но с несколько узко-специфичными фичами, под которые без хорошего напильника не ложилось ни одно готовое или полуготовое решение. В связи в этим было решено реализовать простой клиент-сервер протокол на python с использованием tcp/udp soket’ов. Оговорюсь, что с сетевым программированием знаком я был, да и остаюсь, постольку-поскольку, хотя общее понимание tcp/ip стека имелись. Решение в лоб на синтетике показало себя замечательно, но стоило мне нагрузить его более-менее реальными данными (всего-то порядка 20к сообщений в секунду с нескольких потоков) и оно начало показывать свои подводные камушки. Наверное, я просто не смог правильно приготовить raw сокеты, но задачу нужно было решить быстро, времени на глубокое понимание и изучение сетевого программирования не было, поэтому я начал искать решения, где за меня уже хотя бы половину придумали бы. Поиск меня привел к библиотеке ZeroRPC, которая была не так давно, как я понял, выпущенна в мир из недр dotCloud.

Меня удивило, что я нашел всего одно упоменение про эту разработку на хабре да и то в скольз, поэтому решил написать эту заметку.

Как пишут на официальном сайте разработчики самой библиотеки, ZeroRPC – это легкая, надежная, языко-независимая библиотека для распределенной связи между серверами.
ZeroRPC построена на вершине стека ZeroMQ и MessagePack, о которых уже не раз говорилось на хабре. И из коробки поддерживает stream responses, heartbeat’ы, определение таймаутов и даже автоматическое переподключение после какого-нибудь фейла.

Звучало хорошо и я решил попробовать. По большому счету я еще не изучил все возможности библиотеки и расскажу только о том, как применил ее в своем случае. Но возможно уже это заинтересует Вас почитать и возможно попробовать ZeroMQ в своих проектах.

Установка проста и понятна, как и у большинства python библиотек:

pip install zerorpc

за собой она притянет еще парочку либ, среди которых:

  • gevent,
  • msgpack-python,
  • pyzmq

Ставится не за пару секунд, поэтому если установка вдруг остановилась на одном месте, не бейте панику – скоро все продолжится.

Сообственно согласно документации ей уже можно начать пользоваться без написания какого-либо кода.

zerorpc --server --bind tcp://*:1234 time

Охотно верю, но меня это не сильно интересовало. Более интересными выглядили примеры на главной странице сайта.

Сервер

import zerorpc  class HelloRPC(object):     def hello(self, name):         return "Hello, %s" % name  s = zerorpc.Server(HelloRPC()) s.bind("tcp://0.0.0.0:4242") s.run() 

Клиент

import zerorpc  c = zerorpc.Client() c.connect("tcp://127.0.0.1:4242") print c.hello("RPC") 

Копи-паста, запуск, работает.
Круто, но hello world’ы всегда работают, поэтому немного усложним первичные тесты

Сервер

import zerorpc, time  class StreamingRPC(object): 	count = 0      def commit(self, cid):     	self.count += 1     	print(str(self.count))     	     	return str(cid)+'_done'   s = zerorpc.Server(StreamingRPC()) s.bind("tcp://0.0.0.0:4242") s.run()  

Клиент

import zerorpc  c = zerorpc.Client() c.connect("tcp://127.0.0.1:4242") for i in range(0,290000): 	print c.commit(i) 

И запустим несколько клиентов дабы посмотреть, что будет с пакетами.
Меня больше всего волновал этот вопрос, ибо в моей реализации я уперся в то, что при большой нагрузке я терял больше 40% сообщений на udp сокетах, что собственно не очень-то удивительно…
Тест конечно показал, что все совсем не так быстро как было на сокетах, но зато не единой потери пакета. Чуть позже я провел еще парочку тестов с тредами и записью в базу данных и остался вполне доволен. Через несколько дней тестов, я переписал код сокет сервера и клиента для своей метрики и вот спустя две недели метрика собирает кучу данных и “ни единого разрыва”. Более того, повысив скорость сбора данных, просадки в производительности я не увидел. В данный момент метрика собирает в пике до 100к сообщений в секунду и замечательно себя чувствует.

Конечно в моем случае ZeroRPC скорее всего избыточна и я уверен, что будь на моем месте более сведующий программист, он бы смог победить потери пакетов, зависание сессий и обрывы коннектов сокетов и реализовал бы более производительное решение.
Но тогда я бы не познакомился с ZeroRPC и не рассказал бы о ней здесь.
И быть может другие возможности этой библиотеки очень могут пригодиться в рабочих буднях читающих эту заметку разработчиков.

Рекомендую посмотреть-почитать доклад Jérôme Petazzoni из dotCloud о том, зачем и для чего они ее сделали
pycon-2012-notes.readthedocs.org/en/latest/dotcloud_zerorpc.html
Сайт проекта — www.zerorpc.io
GitHub — github.com/etsy/statsd

ссылка на оригинал статьи http://habrahabr.ru/post/263673/