Я работаю над решением для мониторинга сетевых устройств на работе. Прототип написан на Python с использованием PySNMP, который ужасно медленный и сильно нагружает процессор при небольшом количестве контролируемых устройств. Поэтому я подумал о создании небольшого высокопроизводительного сервера опросов SNMP, чтобы избавиться от PySnmp и разделить программу на две части (поставщик данных и анализатор данных / лицо, принимающее решения).
Net-SNMP не является хорошим выбором для SNMPv3 (не поточно-ориентированный, не полностью асинхронный из-за синхронного обнаружения engineID, который работает медленно, если устройство не отвечает), и мне не нравится SNMP ++, поэтому я решил попробовать написать этот сервер на других языках. Java не вариант (нет JVM), так что в конце концов это Erlang или Haskell (я не знаю их обоих ..). Erlang имеет встроенную поддержку SNMP, но мне не нужно распределение процессов / машин.
Поэтому не могли бы вы порекомендовать, какая реализация протокола (менеджера) lang и snmp лучше подходит для этой задачи?
Требования:
Поддержка Erlang для SNMP в распределении OTP как приложения snmp
. Это означает, что он стабилен, выдержан и испытан в бою в корпоративной среде. Это опоры:
Инструментарий разработки SNMP состоит из следующих частей:
- Расширяемый многоязычный агент SNMP, который понимает SNMPv1
(RFC1157), SNMPv2c (RFC1901, 1905, 1906 и 1907), SNMPv3 (RFC2271,
2272, 2273, 2274 и 2275) или любую комбинацию этих протоколов.- Многоязычный SNMP-менеджер.
- Компилятор MIB, который понимает SMIv1
(RFC1155, 1212 и 1215) и SMIv2 (RFC1902, 1903 и 1904).
С точки зрения языка Erlang является строгим, но динамически типизированным функциональным языком со строгой оценкой и встроенным параллелизмом (на основе акторов) и сильной поддержкой надежности. (Вы можете подумать, что это как DSL для написания надежных кластеризованных сервисов.) Erlang компилируется в байт-код или в нативный (но не такой эффективный, как Haskell) и запускается в собственной VM BEAM. Haskell — это строгий статический типизированный функционал с отложенной оценкой и без встроенной поддержки параллелизма и надежности, но в модулях есть решения. По моему личному мнению, эрлангский язык намного меньше, и его проще выучить для кого-то, кто говорит на императивном языке.
Erlang часто не признается за его скорость, но есть реальные приложения, где Erlang превосходит решения Java, C ++ или C #, особенно при одновременной нагрузке. Есть даже изучение сравнение реального приложения на C ++ с аналогом Erlang. Результат действительно удивителен.
Я лично выбрал бы Erlang ower Haskell. Есть один главный улов: для написания корпоративного решения OTP это необходимо. Где Erlang как язык маленький и простой, OTP намного сложнее, но параллелизм и надежность сами по себе сложны, а OTP делает это на самом деле проще.
Как последнее замечание, всегда есть возможность переписать критичные по времени части с Erlang на C или C ++ как встроенные функции (NIF), и я обнаружил, что это удивительно легко по сравнению с моим предыдущим опытом написания подобных функций для Perl или Python.
Как язык сценариев я бы ожидал, что Python будет довольно медленным.
C или C ++ должны быть настолько быстрыми, насколько это возможно. C # или Java, вероятно, не плохо. Эрланг должен быть разумным. GHC компилирует Haskell в машинный код, поэтому он должен быть достаточно быстрым. В конце концов, все зависит от того, какая библиотека вам нравится больше всего.
Я понятия не имею, что такое SNMP или что он делает. Но я нашел библиотека Haskell для SNMP. Согласно документации, простой клиент SNMP может выглядеть примерно так:
import Network.Protocol.Snmp
import Control.Applicative
import Network.Socket.ByteString (recv, sendAll)
import Network.Socket hiding (recv, sendAll)
-- create new empty packet
v2 :: Packet
v2 = initial Version2
community = Community "hello"
oi = Coupla [1,3,6,1,2,1,1,4,0] Zero
-- set community, oid
packet :: Community -> Coupla -> Packet
packet community oi =
setCommunityP community . setSuite (Suite [oi]) $ v2
-- here must be code for create udp socket
makeSocket :: Hostname -> Port -> IO Socket
makeSocket = undefined
main :: IO ()
main = do
socket <- makeSocket "localhost" "161"sendAll socket $ encode $ setRequest (GetRequest 1 0 0) packet
result <- decode <$> recv socket 1500 :: IO Packet
print $ getSuite result
Если это выглядит нормально, иди в себя …