Everything posted by IThub
- IMG_3974.jpeg
-
У нас появилась группа IThub в телеграмме
Рады сообщить ,что мы сделали группу в Телеграмм, с топиками ботами и прочими приколюхами))) Заходи и подписывайся в ТГ
-
Systemd: The Complete Guide from Zero to Hero — Architecture, Units, cgroups, Logging, and Real-World Examples
Introduction: Why SysVinit Died and What Systemd FixedImagine a chef cooking dinner for 10 guests but making each dish completely from scratch, one at a time — starting the salad only after the soup is fully served. That's essentially how SysVinit worked: it started services one by one, in a fixed order, regardless of whether they were actually dependent on each other. As Linux systems grew more complex, this became a serious bottleneck: Slow boot times. Service A waits for Service B to finish, even if there's zero dependency between them. No process tracking. Init launched a script and moved on. A child process crashed? SysVinit had no idea. Log chaos. Every service wrote logs wherever it wanted — /var/log/nginx/, syslog, /tmp/ — no unified interface. Brittle shell scripts. The /etc/init.d/ scripts were fragile, hard to maintain, and inconsistent across distros. In 2010, Lennart Poettering introduced systemd to solve all of these problems simultaneously: parallel startup, dependency graphs, control groups, and centralized logging. The community response was controversial (to put it mildly), but today systemd is the de-facto standard on Fedora, Debian, Ubuntu, Arch, RHEL, and most other major distributions. Let's break it down piece by piece. Part 1. Systemd Architecture — What's Under the Hood1.1 PID 1 — The Ruler of All ProcessesWhen the Linux kernel boots, it launches the very first user-space process with PID 1. On systemd systems, that process IS the systemd daemon. It's the direct parent of everything else in the system. This matters for two reasons: If PID 1 crashes, the system panics. Hence systemd is written to be extremely robust. All orphaned processes (whose parent died) are automatically reparented to PID 1. Linux Kernel └── systemd (PID 1) ├── journald (logging) ├── udevd (device management) ├── networkd (networking) ├── nginx.service (your web server) ├── postgresql.service (database) └── ... all other services1.2 Key Componentssystemd (PID 1) The conductor of the whole orchestra. It reads unit files, builds a dependency graph, launches processes in the right order, and tracks them via cgroups. systemctl Your control panel. When you type systemctl start nginx, this tool does NOT start nginx directly. It sends a D-Bus message to the systemd daemon, which does the actual work. This is a fundamental difference from running a script. journald Centralized logging daemon. It captures stdout and stderr from all services, enriches each entry with structured metadata (PID, UID, unit name, hostname), and stores everything in a binary format that supports complex queries — think SQL for logs. udevd Device manager. When you plug in a USB drive, udevd creates /dev/sdb, loads the appropriate kernel modules, and can trigger specific services. networkd, timedated, logind Specialized daemons for network management, system time, and user sessions. They all communicate with PID 1 via D-Bus. 1.3 D-Bus — The Communication BackboneD-Bus is an inter-process communication (IPC) system bus — think of it as an internal messaging platform between processes. Instead of processes calling each other's functions directly (which is unsafe), they send structured messages through the bus. Example flow for systemctl start nginx: systemctl forms a D-Bus message: "Call the StartUnit method with argument nginx.service" The message goes onto the system bus The systemd daemon receives and processes it Returns the result through the same bus This provides security (permissions checked at the D-Bus level), flexibility (any program can manage services), and extensibility. Part 2. Units — The Building Blocks of SystemdA unit is a description of any system resource as a declarative configuration file. Think of it as the "passport" for a service, socket, timer, or mount point. 2.1 Where Units LivePath Purpose Priority /usr/lib/systemd/system/ Units installed by package manager Lowest /etc/systemd/system/ Your custom units and overrides High /run/systemd/system/ Temporary units (gone after reboot) Highest 2.2 Unit Types.service — Service Units (Most Common)Describes a daemon or process. This is what you'll use in 90% of cases. ini # /etc/systemd/system/myapp.service [Unit] Description=My Awesome Application After=network.target postgresql.service Requires=postgresql.service [Service] Type=simple ExecStart=/usr/bin/myapp --config /etc/myapp/config.yml ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5s User=myapp Group=myapp [Install] WantedBy=multi-user.targetThe Type= parameter — get this right: Type Behavior When to Use simple Service is considered started immediately after ExecStart launches Most modern applications forking Program calls fork() and the parent exits. Systemd waits for this. Classic Unix daemons (nginx, apache) notify Program signals systemd via sd_notify() when ready Programs with native systemd API support oneshot Program runs and exits. Systemd waits for completion. Scripts, one-off tasks dbus Service is considered started when it claims a D-Bus name Daemons using D-Bus idle Start delayed until all other jobs complete Low-priority background tasks Restart policy: ini [Service] # Restart= options: # no — never restart # on-success — only on exit code 0 # on-failure — on non-zero exit, signal, or timeout (most common choice) # on-abnormal — on signal or timeout (not normal exit) # always — always restart (even after systemctl stop!) Restart=on-failure RestartSec=5s # Limit restart attempts: # Max 5 attempts within 30 seconds, then give up StartLimitIntervalSec=30s StartLimitBurst=5.socket — Socket-Based Activation (Lazy Launch)This is one of the most powerful and underappreciated features of systemd. The idea: why keep 20 services running when most of them get called once an hour? Socket-based activation works like this: systemd opens and listens on a socket (port, Unix socket, or FIFO) The actual service is not running The first connection arrives systemd launches the service and passes the established connection to it The client never notices — the connection isn't lost! ini # /etc/systemd/system/echo.socket [Unit] Description=Echo Server Socket [Socket] ListenStream=12345 Accept=no [Install] WantedBy=sockets.targetini # /etc/systemd/system/echo.service [Unit] Description=Echo Server [Service] Type=simple ExecStart=/usr/local/bin/echo-server # Service receives the socket via file descriptor 3 StandardInput=socketEnable: sudo systemctl enable --now echo.socket — and the service starts on the first connection. .timer — Cron Replacement with SuperpowersSystemd timers beat cron on several fronts: Support dependencies (run only if some service is running) Logged in journald like any other unit Can "catch up" on missed runs after reboot (Persistent=true) Support random delays to spread load across the hour ini # /etc/systemd/system/backup.timer [Unit] Description=Daily Backup Timer [Timer] # Run every day at 02:30 OnCalendar=*-*-* 02:30:00 # Random delay up to 10 minutes (don't hammer the server at exactly 02:30!) RandomizedDelaySec=10m # Run the task if it was missed (e.g. system was off) Persistent=true [Install] WantedBy=timers.targetini # /etc/systemd/system/backup.service [Unit] Description=Daily Backup Job [Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh User=backupEnable: sudo systemctl enable --now backup.timer Check all active timers: systemctl list-timers --all OnCalendar syntax cheatsheet: Expression Meaning daily Every day at 00:00 weekly Every Monday at 00:00 monthly 1st of every month *-*-* 09:00:00 Every day at 09:00 Mon-Fri *-*-* 08:30:00 Weekdays at 08:30 *-*-1,15 00:00:00 1st and 15th of every month Validate an expression: systemd-analyze calendar "Mon-Fri *-*-* 08:30:00" .target — Unit Groups (Replacing Runlevels)A target is not a service — it's a synchronization point. Think of it as a "system state" to be reached. Target SysV Runlevel Meaning poweroff.target 0 Shutdown rescue.target 1 Single-user mode multi-user.target 3 Multi-user, no GUI graphical.target 5 With graphical interface reboot.target 6 Reboot bash # Check current default target (like current runlevel) systemctl get-default # Switch target (like init 3) sudo systemctl isolate multi-user.target # Set default target sudo systemctl set-default multi-user.target2.3 Unit Dependencies — A Graph, Not a QueueThis is one of the key differentiators from SysVinit. Instead of a fixed sequence, systemd builds a directed dependency graph. Dependency directives: Directive Type Behavior Requires= Hard If the dependency fails to start, this unit also fails and stops with it Wants= Soft Tries to start the dependency, but won't stop if it fails BindsTo= Very hard Like Requires, but this unit stops whenever the dependency stops PartOf= One-way Stops/restarts together with the dependency, but doesn't start with it Conflicts= Conflict Cannot run simultaneously with the specified unit Ordering directives: Directive Behavior After= This unit starts AFTER the specified one Before= This unit starts BEFORE the specified one Part 3. cgroups — Why Systemd Always Knows Your Processes3.1 The Problem cgroups SolveConsider: nginx is running. It forks 4 workers. One worker forks a CGI process. That forks something else. Now there are 10 processes, all "belonging" to nginx, but in SysVinit there was no way to track this. Control Groups (cgroups) are a Linux kernel mechanism that lets you group processes hierarchically and manage them collectively. Systemd automatically creates a cgroup for every service. All child processes live inside that group. Always. /sys/fs/cgroup/ ├── system.slice/ │ ├── nginx.service/ ← all nginx processes here │ │ ├── pid: 1234 (master) │ │ ├── pid: 1235 (worker 1) │ │ ├── pid: 1236 (worker 2) │ │ └── pid: 1237 (cache loader) │ ├── postgresql.service/ │ └── redis.service/ └── user.slice/ └── user-1000.slice/ ← user processes3.2 What cgroups Give You in PracticeClean process termination — no zombie processes: When you run systemctl stop nginx, systemd sends the signal to the entire cgroup — all 10 processes die, including ones you didn't know existed. No more phantom workers. Monitoring: bash # Show process tree for a service's cgroup systemd-cgls /system.slice/nginx.service # Real-time resource monitoring (like top, but for cgroups) systemd-cgtop3.3 Resource Limits via Unit FilesInstead of manually configuring cgroups, just add lines to your [Service] section: ini [Service] # === MEMORY === # Soft limit: systemd will aggressively reclaim memory MemoryHigh=400M # Hard limit: OOM Killer will kill the process if exceeded MemoryMax=512M # Guaranteed memory (won't be given to others) MemoryMin=100M # === CPU === # 50% of a single core CPUQuota=50% # Or: CPU weight (1-10000, default=100) CPUWeight=200 # === DISK I/O === IOReadBandwidthMax=/dev/sda 50M IOWriteBandwidthMax=/dev/sda 20M # === NETWORK === IPAccounting=yes IPAddressAllow=192.168.0.0/24 IPAddressDeny=anyVerify current limits: bash # Check cgroup filesystem directly cat /sys/fs/cgroup/system.slice/nginx.service/memory.max # 536870912 (512 MB in bytes) # Or via systemctl systemctl show nginx.service | grep -E 'Memory|CPU|IO'Part 4. journald — Logs as a Database4.1 Why journald Beats Plain Text LogsA plain syslog is a text file. Want to find all nginx errors from the last hour? You write grep "error" /var/log/nginx/error.log | grep "$(date +%b\ %d)" and hope for the best. journald is a structured store with indexes. Every entry is not a text string but an object with fields: _SYSTEMD_UNIT=nginx.service ← which service _PID=1234 ← which process _UID=www-data ← which user _HOSTNAME=web-01 ← which host PRIORITY=3 ← severity level (err) MESSAGE=connection refused... ← the message itself _SOURCE_REALTIME_TIMESTAMP=... ← precise timestamp4.2 Complete journalctl Referencebash # === BASIC QUERIES === # All logs for a service sudo journalctl -u nginx.service # Last 50 lines sudo journalctl -u nginx.service -n 50 # Follow in real time (like tail -f) sudo journalctl -u nginx.service -f # From a specific time sudo journalctl -u nginx.service --since "2024-01-15 10:00:00" sudo journalctl -u nginx.service --since "1 hour ago" sudo journalctl -u nginx.service --since today sudo journalctl -u nginx.service --since yesterday --until "2024-01-14 23:59:59" # === FILTERING BY SEVERITY === # 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug sudo journalctl -p err # only errors sudo journalctl -p err..warning # err through warning sudo journalctl -u nginx -p warning # nginx warnings only # === FILTERING BY BOOT === sudo journalctl -b # current boot sudo journalctl -b -1 # previous boot sudo journalctl -b -2 # two boots ago sudo journalctl --list-boots # list all boots # === OUTPUT FORMATS === sudo journalctl -u nginx -o json # JSON (for parsing) sudo journalctl -u nginx -o json-pretty # Formatted JSON sudo journalctl -u nginx -o verbose # All metadata fields sudo journalctl -u nginx -o cat # Message text only # === ADVANCED QUERIES === # Logs for a specific process sudo journalctl _PID=1234 # Logs from a specific user sudo journalctl _UID=1000 # Combine conditions (OR) sudo journalctl _SYSTEMD_UNIT=nginx.service + _SYSTEMD_UNIT=php-fpm.service # Export to file sudo journalctl -u nginx --since today -o json > nginx-today.json # === JOURNAL MANAGEMENT === # Disk usage of the journal sudo journalctl --disk-usage # Clean up logs older than 2 weeks sudo journalctl --vacuum-time=2weeks # Clean up to a specific size sudo journalctl --vacuum-size=500MPart 5. Real-World Scenarios5.1 Creating a Production-Ready Service from Scratchini # /etc/systemd/system/api-server.service [Unit] Description=API Server Documentation=https://github.com/company/api-server After=network-online.target Wants=network-online.target Requires=postgresql.service After=postgresql.service [Service] Type=notify ExecStart=/usr/local/bin/api-server EnvironmentFile=/etc/api-server/env Environment="PORT=8080" Environment="LOG_LEVEL=info" Restart=on-failure RestartSec=5s StartLimitIntervalSec=60s StartLimitBurst=3 User=api Group=api WorkingDirectory=/opt/api-server # === SECURITY HARDENING === NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes SystemCallFilter=@system-service ReadWritePaths=/var/lib/api-server /var/log/api-server # === RESOURCE LIMITS === MemoryMax=512M CPUQuota=200% LimitNOFILE=65536 [Install] WantedBy=multi-user.target5.2 Drop-in Files — Override Without Touching Originalsbash # systemctl edit creates the override file automatically sudo systemctl edit nginx.service # Creates: /etc/systemd/system/nginx.service.d/override.confini [Service] MemoryMax=256M Restart=always Environment="NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx"bash sudo systemctl daemon-reload sudo systemctl restart nginx.service # View the full effective config (original + drop-ins) sudo systemctl cat nginx.service5.3 Boot Time Analysis and Optimizationbash # Total boot time systemd-analyze # Startup finished in 2.134s (kernel) + 8.643s (userspace) = 10.777s # Top boot-time offenders systemd-analyze blame # Critical path to a specific target systemd-analyze critical-chain graphical.target # Generate visual timeline (open in browser!) systemd-analyze plot > boot-plot.svg # Validate a unit file for errors systemd-analyze verify /etc/systemd/system/myapp.service5.4 Diagnosing a Failing Service — Step by Stepbash # Step 1: Service status sudo systemctl status myapp.service # Step 2: Recent logs with full detail sudo journalctl -u myapp.service -n 100 --no-pager # Step 3: Logs since last boot (for startup issues) sudo journalctl -u myapp.service -b # Step 4: All errors in the system at the time of failure sudo journalctl -p err --since "10 min ago" --no-pager # Step 5: Check dependencies systemctl list-dependencies myapp.service # Step 6: Run manually as the service user (to reproduce) sudo -u myapp /usr/local/bin/myapp --config /etc/myapp/config.yml # Step 7: Check environment variables sudo systemctl show myapp.service -p Environment # Step 8: Check file permissions sudo systemctl cat myapp.service | grep -E 'ExecStart|WorkingDirectory|User' sudo ls -la /usr/local/bin/myappQuick Reference CheatsheetService ControlTask Command Start sudo systemctl start <name> Stop sudo systemctl stop <name> Restart sudo systemctl restart <name> Reload config (no stop) sudo systemctl reload <name> Status systemctl status <name> Enable autostart sudo systemctl enable <name> Disable autostart sudo systemctl disable <name> Enable AND start sudo systemctl enable --now <name> Block permanently sudo systemctl mask <name> Viewing StateTask Command All running services systemctl list-units --type=service --state=running All failed systemctl --failed Check autostart systemctl is-enabled <name> Check active systemctl is-active <name> Dependency tree systemctl list-dependencies <name> Who depends on this systemctl list-dependencies --reverse <name> All timers systemctl list-timers Logs (journalctl)Task Command Service logs sudo journalctl -u <name> Last N lines sudo journalctl -u <name> -n 50 Real-time sudo journalctl -u <name> -f Current boot sudo journalctl -u <name> -b Errors only sudo journalctl -u <name> -p err Since time sudo journalctl -u <name> --since "1h ago" Journal size sudo journalctl --disk-usage Cleanup sudo journalctl --vacuum-time=2weeks Performance DiagnosticsTask Command Boot time systemd-analyze Boot bottlenecks systemd-analyze blame Critical chain systemd-analyze critical-chain <target> Visual timeline systemd-analyze plot > boot.svg Validate unit file systemd-analyze verify /path/to/unit cgroup tree systemd-cgls cgroup resource usage systemd-cgtop ConclusionSystemd is not a monster to be feared — it's a powerful tool that makes you dramatically more effective as a sysadmin or developer. Key takeaways from this guide: Units are declarative resource descriptions. Write them properly and use available security directives. cgroups mean systemd always knows where your processes are. Use this for monitoring and resource constraints. journald is a database, not a text file. Learn to query it properly. Drop-in files — never edit original package-installed unit files. systemd-analyze — your first tool when diagnosing boot problems.
-
Systemd: Полное руководство от новичка до эксперта — Архитектура, Юниты, cgroups, Логирование и Реальные Примеры
Введение: Почему SysVinit умер, и при чём тут SystemdПредставьте себе повара, который готовит ужин на 10 человек, но строго по одному блюду за раз — сначала суп, потом только начинает нарезать салат. Именно так работала старая система инициализации SysVinit: запускала службы строго по одной, в заранее заданном порядке. Независимо от того, зависят ли они друг от друга. С усложнением Linux-систем это стало болью: Медленная загрузка. Служба A ждёт завершения службы B, даже если между ними нет никакой реальной зависимости. Нет контроля за процессами. Запустил — и забыл. Упал дочерний процесс? SysVinit об этом не знает. Хаос в логах. Каждый сервис пишет куда хочет: один в /var/log/nginx/, другой в syslog, третий в /tmp/. Никакой единой точки входа. Хрупкие скрипты. Shell-скрипты в /etc/init.d/ — это огромное поле для ошибок и несовместимостей между дистрибутивами. В 2010 году Леннарт Поттеринг (Lennart Poettering) представил systemd — систему, которая решала все эти проблемы разом. Параллельный запуск, граф зависимостей, контрольные группы, централизованные логи. Сообщество поначалу встретило его в штыки (споры были жаркими), но сегодня systemd — стандарт де-факто в Fedora, Debian, Ubuntu, Arch, RHEL, CentOS и большинстве других дистрибутивов. Давайте разберём его по косточкам. Часть 1. Архитектура systemd — что происходит под капотом1.1 PID 1 — главный процесс системыКогда ядро Linux загружается, оно запускает самый первый пользовательский процесс с PID 1. В системах с systemd это и есть демон systemd. Он — прямой родитель всех остальных процессов в системе. Это важно по двум причинам: Если PID 1 упадёт — система паникует. Поэтому systemd написан максимально надёжно. Все процессы, которые становятся «сиротами» (их родитель умер), автоматически переходят под крыло PID 1. Ядро Linux └── systemd (PID 1) ├── journald (логирование) ├── udevd (устройства) ├── networkd (сеть) ├── nginx.service (ваш веб-сервер) ├── postgresql.service (БД) └── ... все остальные сервисы1.2 Ключевые компоненты системыsystemd (PID 1) Главный дирижёр. Читает юнит-файлы, строит граф зависимостей, запускает процессы в нужном порядке, следит за их состоянием через cgroups. systemctl Ваш пульт управления. Когда вы пишете systemctl start nginx, эта утилита НЕ запускает nginx напрямую. Она отправляет сообщение по D-Bus демону systemd, который и выполняет работу. Это ключевое отличие от простого вызова скрипта. journald Централизованная система логирования. Перехватывает stdout и stderr всех сервисов, обогащает каждую запись метаданными (PID, UID, имя юнита, хостнейм) и сохраняет в структурированном бинарном формате. Это позволяет делать сложные запросы к логам — как SQL к базе данных. udevd Менеджер устройств. Когда вы подключаете USB-флешку, именно udevd создаёт /dev/sdb, загружает нужные модули ядра и может запустить определённый сервис. networkd, timedated, logind Специализированные демоны для управления сетью, системным временем и пользовательскими сессиями. Они общаются с PID 1 через D-Bus. 1.3 D-Bus — как компоненты разговаривают друг с другомD-Bus — это системная шина сообщений, аналог внутренней корпоративной почты между процессами. Вместо того чтобы процессы вызывали функции друг друга напрямую (что небезопасно), они отправляют структурированные сообщения через шину. Практический пример: systemctl start nginx systemctl формирует D-Bus-сообщение: «Вызови метод StartUnit с аргументом nginx.service» Сообщение уходит в системную шину Демон systemd получает его и выполняет Возвращает ответ через ту же шину Это даёт безопасность (права проверяются на уровне D-Bus), гибкость (любая программа может управлять сервисами) и расширяемость. Часть 2. Юниты — строительные блоки systemdЮнит (unit) — это описание любого системного ресурса в виде декларативного конфигурационного файла. Думайте о нём как о «паспорте» для сервиса, сокета, таймера или точки монтирования. 2.1 Где хранятся юнитыПуть Назначение Приоритет /usr/lib/systemd/system/ Юниты, установленные пакетным менеджером Низкий /etc/systemd/system/ Ваши кастомные юниты и переопределения Высокий /run/systemd/system/ Временные юниты (исчезают после перезагрузки) Высший 2.2 Типы юнитов.service — сервисы (самый частый тип)Описывает демон или процесс. Именно с ним вы работаете в 90% случаев. ini # /etc/systemd/system/myapp.service [Unit] Description=My Awesome Application After=network.target postgresql.service Requires=postgresql.service [Service] Type=simple ExecStart=/usr/bin/myapp --config /etc/myapp/config.yml ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5s User=myapp Group=myapp [Install] WantedBy=multi-user.targetПараметр Type= — это важно понимать правильно: Тип Поведение Когда использовать simple systemd считает сервис запущенным сразу после старта ExecStart Большинство современных программ forking Программа делает fork() и завершает родительский процесс. systemd ждёт этого. Старые Unix-демоны (nginx, apache) notify Программа сама сигнализирует systemd через sd_notify(), что готова Программы с поддержкой systemd API oneshot Программа выполняется и завершается. systemd ждёт завершения. Скрипты, одноразовые задачи dbus Сервис считается запущенным, когда занял имя на D-Bus Демоны, использующие D-Bus idle Запуск откладывается до завершения всех остальных задач Фоновые задачи с низким приоритетом Жизненный цикл и перезапуск: ini [Service] # Варианты для Restart=: # no — не перезапускать никогда # on-success — только при коде выхода 0 # on-failure — при любом ненулевом коде, сигнале или таймауте (самый частый выбор) # on-abnormal — при сигнале или таймауте (не при коде выхода) # always — перезапускать всегда (даже при systemctl stop!) Restart=on-failure RestartSec=5s # Ограничение на количество перезапусков: # Максимум 5 попыток за 30 секунд, потом сдаться StartLimitIntervalSec=30s StartLimitBurst=5.socket — socket-based activation (ленивый запуск)Это одна из самых мощных и недооценённых фич systemd. Идея простая: зачем держать 20 сервисов запущенными, если большинство из них обращаются раз в час? Socket-based activation работает так: systemd открывает и слушает сокет (порт, Unix socket, FIFO) Сам сервис не запущен Приходит первое подключение systemd запускает сервис и передаёт ему уже установленное соединение Клиент не замечает разницы — соединение не потеряно! ini # /etc/systemd/system/echo.socket [Unit] Description=Echo Server Socket [Socket] ListenStream=12345 Accept=no [Install] WantedBy=sockets.targetini # /etc/systemd/system/echo.service [Unit] Description=Echo Server Service [Service] Type=simple ExecStart=/usr/local/bin/echo-server # Сервис получит сокет через файловый дескриптор 3 StandardInput=socketАктивация: sudo systemctl enable --now echo.socket — и сервис будет запускаться автоматически при первом подключении. .timer — замена cron с суперспособностямиТаймеры systemd мощнее cron по нескольким причинам: Поддерживают зависимости (запустить только если работает такой-то сервис) Логируются в journald как обычные юниты Могут «догнать» пропущенные запуски после перезагрузки (Persistent=true) Точность до секунды и поддержка случайных задержек для распределения нагрузки ini # /etc/systemd/system/backup.timer [Unit] Description=Daily Backup Timer [Timer] # Запускать каждый день в 02:30 OnCalendar=*-*-* 02:30:00 # Случайная задержка до 10 минут (не всё одновременно в 02:30!) RandomizedDelaySec=10m # Запустить задачу, если она была пропущена (например, система была выключена) Persistent=true [Install] WantedBy=timers.targetini # /etc/systemd/system/backup.service [Unit] Description=Daily Backup Job [Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh User=backupАктивация: sudo systemctl enable --now backup.timer Проверить все активные таймеры: systemctl list-timers --all Синтаксис OnCalendar: Выражение Значение daily Каждый день в 00:00 weekly Каждый понедельник в 00:00 monthly 1-го числа каждого месяца *-*-* 09:00:00 Каждый день в 09:00 Mon-Fri *-*-* 08:30:00 По будням в 08:30 *-*-1,15 00:00:00 1-го и 15-го каждого месяца Проверить выражение: systemd-analyze calendar "Mon-Fri *-*-* 08:30:00" .target — группы юнитов (замена runlevel)Target — это не сервис, а точка синхронизации. Думайте об этом как о «состоянии системы», которого нужно достичь. Target Аналог runlevel Значение poweroff.target 0 Выключение rescue.target 1 Однопользовательский режим multi-user.target 3 Многопользовательский без GUI graphical.target 5 С графическим интерфейсом reboot.target 6 Перезагрузка bash # Узнать текущий target (аналог текущего runlevel) systemctl get-default # Сменить target (аналог init 3) sudo systemctl isolate multi-user.target # Установить target по умолчанию sudo systemctl set-default multi-user.target.path — реакция на события файловой системыАналог incron. Запускает сервис при изменениях в файловой системе. ini # /etc/systemd/system/watch-uploads.path [Unit] Description=Watch for new uploads [Path] # Запустить связанный .service когда появится этот файл PathExists=/var/spool/uploads/trigger.flag # Или мониторить директорию на изменения DirectoryNotEmpty=/var/spool/uploads/ [Install] WantedBy=multi-user.target2.3 Зависимости между юнитами — граф, а не очередьЭто одно из ключевых отличий systemd от SysVinit. Вместо фиксированного порядка — направленный граф зависимостей. Директивы зависимостей: Директива Тип Поведение Requires= Жёсткая Если зависимость не запустилась — этот юнит тоже не стартует и останавливается вместе с ней Wants= Мягкая Пробует запустить зависимость, но если та упадёт — не останавливается BindsTo= Очень жёсткая Как Requires, но юнит останавливается если зависимость остановится в любой момент PartOf= Односторонняя Останавливается/перезапускается вместе с зависимостью, но не запускается вместе с ней Conflicts= Конфликт Не может работать одновременно с указанным юнитом Директивы порядка: Директива Поведение After= Этот юнит запускается ПОСЛЕ указанного Before= Этот юнит запускается ДО указанного ini [Unit] # Правильная комбинация: сначала БД, потом мы, и мы не работаем без БД After=postgresql.service Requires=postgresql.serviceЧасть 3. cgroups — почему systemd знает всё о ваших процессах3.1 Проблема, которую решают cgroupsПредставьте: nginx запущен. Он форкает 4 воркера. Один воркер форкает ещё процесс для CGI. Тот форкает что-то ещё. Итого 10 процессов, и все они «принадлежат» nginx, но в SysVinit это было невозможно отследить. Control Groups (cgroups) — механизм ядра Linux, который позволяет объединять процессы в иерархические группы и управлять ими совместно. Systemd автоматически создаёт cgroup для каждого сервиса. Все дочерние процессы — внутри этой группы. Всегда. /sys/fs/cgroup/ ├── system.slice/ │ ├── nginx.service/ ← все процессы nginx здесь │ │ ├── pid: 1234 (master) │ │ ├── pid: 1235 (worker 1) │ │ ├── pid: 1236 (worker 2) │ │ └── pid: 1237 (cache loader) │ ├── postgresql.service/ ← и postgres здесь │ └── redis.service/ └── user.slice/ └── user-1000.slice/ ← процессы пользователя3.2 Что даёт cgroup на практикеТочный kill без зомби-процессов: При systemctl stop nginx systemd отправляет сигнал всей cgroup — умирают все 10 процессов, включая те, о которых вы не знали. Больше никаких «phantom workers». Мониторинг: bash # Показать дерево процессов cgroup сервиса systemd-cgls /system.slice/nginx.service # Вывод: # /system.slice/nginx.service # └─ 1234 /usr/sbin/nginx -g daemon off; # ├─ 1235 nginx: worker process # ├─ 1236 nginx: worker process # └─ 1237 nginx: cache loader process # Мониторинг ресурсов в реальном времени (как top, но для cgroups) systemd-cgtop3.3 Ограничение ресурсов через юнит-файлыЭто магия. Вместо сложных настроек cgroups вручную — просто добавляете строки в секцию [Service]: ini [Service] # === ПАМЯТЬ === # Мягкий лимит: systemd начнёт агрессивно освобождать память MemoryHigh=400M # Жёсткий лимит: OOM Killer убьёт процесс если превысит MemoryMax=512M # Гарантированная память (не будет отдана другим) MemoryMin=100M # === CPU === # 50% от одного ядра CPUQuota=50% # Или: вес CPU (1-10000, default=100) CPUWeight=200 # === ДИСК (I/O) === # Ограничение чтения/записи для конкретного устройства IOReadBandwidthMax=/dev/sda 50M IOWriteBandwidthMax=/dev/sda 20M # === СЕТЬ (через IP accounting) === IPAccounting=yes IPAddressAllow=192.168.0.0/24 IPAddressDeny=anyПроверка текущих лимитов: bash # Посмотреть параметры cgroup напрямую в файловой системе cat /sys/fs/cgroup/system.slice/nginx.service/memory.max # 536870912 (512 МБ в байтах) # Или через systemctl systemctl show nginx.service | grep -E 'Memory|CPU|IO'Часть 4. journald — логи как база данных4.1 Почему journald лучше текстовых логовОбычный syslog — это текстовый файл. Хочешь найти все ошибки nginx за последний час? Пишешь grep "error" /var/log/nginx/error.log | grep "$(date +%b\ %d)" и молишься. journald — структурированное хранилище с индексами. Каждая запись — не строчка текста, а объект с полями: _SYSTEMD_UNIT=nginx.service ← какой сервис _PID=1234 ← какой процесс _UID=www-data ← от какого пользователя _HOSTNAME=web-01 ← на каком хосте PRIORITY=3 ← уровень важности (err) MESSAGE=connection refused... ← само сообщение _SOURCE_REALTIME_TIMESTAMP=... ← точное время4.2 Полное руководство по journalctlbash # === БАЗОВЫЕ ЗАПРОСЫ === # Все логи конкретного сервиса sudo journalctl -u nginx.service # Последние 50 строк sudo journalctl -u nginx.service -n 50 # Следить в реальном времени (как tail -f) sudo journalctl -u nginx.service -f # С определённого момента sudo journalctl -u nginx.service --since "2024-01-15 10:00:00" sudo journalctl -u nginx.service --since "1 hour ago" sudo journalctl -u nginx.service --since today sudo journalctl -u nginx.service --since yesterday --until "2024-01-14 23:59:59" # === ФИЛЬТРАЦИЯ ПО УРОВНЮ ВАЖНОСТИ === # 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug sudo journalctl -p err # только err sudo journalctl -p err..warning # от err до warning sudo journalctl -u nginx -p warning # предупреждения nginx # === ФИЛЬТРАЦИЯ ПО ЗАГРУЗКЕ === sudo journalctl -b # текущая загрузка sudo journalctl -b -1 # предыдущая загрузка sudo journalctl -b -2 # позапрошлая загрузка sudo journalctl --list-boots # список всех загрузок # === ФОРМАТЫ ВЫВОДА === sudo journalctl -u nginx -o json # JSON (для парсинга) sudo journalctl -u nginx -o json-pretty # JSON с форматированием sudo journalctl -u nginx -o verbose # Все поля записи sudo journalctl -u nginx -o cat # Только текст сообщений # === ПРОДВИНУТЫЕ ЗАПРОСЫ === # Логи конкретного процесса sudo journalctl _PID=1234 # Логи от конкретного пользователя sudo journalctl _UID=1000 # Комбинирование условий (OR) sudo journalctl _SYSTEMD_UNIT=nginx.service + _SYSTEMD_UNIT=php-fpm.service # Экспорт в файл sudo journalctl -u nginx --since today -o json > nginx-today.json # === УПРАВЛЕНИЕ ЖУРНАЛОМ === # Размер журнала на диске sudo journalctl --disk-usage # Очистка старых логов (оставить только за последние 2 недели) sudo journalctl --vacuum-time=2weeks # Очистка до определённого размера sudo journalctl --vacuum-size=500M4.3 Настройка journaldini # /etc/systemd/journald.conf [Journal] # Максимальный размер журнала на диске SystemMaxUse=1G # Максимальный размер одного файла журнала SystemMaxFileSize=100M # Хранить журналы не дольше MaxRetentionSec=1month # Сжатие (по умолчанию включено) Compress=yes # Перенаправить в syslog (для совместимости) ForwardToSyslog=no # Уровень логирования по умолчанию MaxLevelStore=debug MaxLevelSyslog=warningПосле изменения: sudo systemctl restart systemd-journald Часть 5. Практика — реальные сценарии5.1 Создание production-ready сервиса с нуляЗадача: создать сервис для Go-приложения с полной изоляцией и автоматическим перезапуском. ini # /etc/systemd/system/api-server.service [Unit] Description=API Server Documentation=https://github.com/company/api-server After=network.target Wants=network-online.target After=network-online.target # Если зависит от БД: Requires=postgresql.service After=postgresql.service [Service] Type=notify # Путь к бинарнику ExecStart=/usr/local/bin/api-server # Путь к конфигу через переменную окружения EnvironmentFile=/etc/api-server/env # Или напрямую: Environment="PORT=8080" Environment="LOG_LEVEL=info" # Перезапуск Restart=on-failure RestartSec=5s StartLimitIntervalSec=60s StartLimitBurst=3 # Пользователь и группа User=api Group=api # Рабочая директория WorkingDirectory=/opt/api-server # === БЕЗОПАСНОСТЬ === # Запрет повышения привилегий NoNewPrivileges=yes # Изолированный /tmp PrivateTmp=yes # Только чтение для /usr, /boot, /etc ProtectSystem=strict # Запрет доступа к домашним директориям ProtectHome=yes # Изолированная сеть для системных вызовов ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes # Список разрешённых системных вызовов SystemCallFilter=@system-service # Разрешить запись только в эти директории ReadWritePaths=/var/lib/api-server /var/log/api-server # === РЕСУРСЫ === MemoryMax=512M CPUQuota=200% # Ограничение открытых файлов LimitNOFILE=65536 [Install] WantedBy=multi-user.targetПрименение: bash sudo systemctl daemon-reload sudo systemctl enable --now api-server.service sudo systemctl status api-server.service5.2 Drop-in файлы — переопределение без изменения оригиналаЗолотое правило: никогда не редактируйте файлы в /usr/lib/systemd/system/. Используйте drop-in файлы. bash # Удобный способ — systemctl edit сам создаст файл sudo systemctl edit nginx.serviceСоздастся файл /etc/systemd/system/nginx.service.d/override.conf: ini [Service] # Добавим лимит памяти к стандартному nginx MemoryMax=256M # Переопределим тип перезапуска Restart=always # Добавим переменную окружения Environment="NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx"bash # После сохранения: sudo systemctl daemon-reload sudo systemctl restart nginx.service # Посмотреть итоговую конфигурацию (оригинал + drop-ins) sudo systemctl cat nginx.service5.3 Анализ и оптимизация времени загрузкиbash # Общее время загрузки systemd-analyze # Startup finished in 2.134s (kernel) + 8.643s (userspace) = 10.777s # Топ «тормозов» при загрузке systemd-analyze blame # 4.123s NetworkManager-wait-online.service # 2.456s plymouth-quit-wait.service # 1.234s dev-sda1.device # 0.987s apparmor.service # Критический путь загрузки — что тормозит конкретный target systemd-analyze critical-chain graphical.target # Визуальная диаграмма в SVG (откройте в браузере!) systemd-analyze plot > boot-plot.svg # Проверить юнит-файл на ошибки systemd-analyze verify /etc/systemd/system/myapp.serviceЧастые причины медленной загрузки и как их лечить: Проблема Симптом Решение NetworkManager-wait-online.service 20-30 секунд ожидания сети sudo systemctl disable NetworkManager-wait-online.service (если сеть не нужна при загрузке) Сервис висит на старте Долгий timeout Проверить TimeoutStartSec= и зависимости Много последовательных зависимостей Длинный critical chain Заменить Requires= на Wants= где возможно 5.4 Диагностика падающего сервиса — пошаговый алгоритмbash # Шаг 1: Статус сервиса sudo systemctl status myapp.service # Ищем: статус (failed/active), последние строки лога, код выхода # Шаг 2: Последние логи с подробными метаданными sudo journalctl -u myapp.service -n 100 --no-pager # Шаг 3: Логи с момента последней загрузки (для проблем при старте) sudo journalctl -u myapp.service -b # Шаг 4: Все ошибки в системе в момент падения sudo journalctl -p err --since "10 min ago" --no-pager # Шаг 5: Проверить зависимости systemctl list-dependencies myapp.service # Все зависимости должны быть зелёными # Шаг 6: Запустить вручную под тем же пользователем (для воспроизведения) sudo -u myapp /usr/local/bin/myapp --config /etc/myapp/config.yml # Шаг 7: Посмотреть все переменные окружения сервиса sudo systemctl show myapp.service -p Environment # Шаг 8: Проверить права доступа к файлам sudo systemctl cat myapp.service | grep -E 'ExecStart|WorkingDirectory|User' sudo ls -la /usr/local/bin/myappЧасть 6. Продвинутые техники6.1 Шаблонные юниты — один файл для многих экземпляровЕсли нужно запустить один и тот же сервис с разными параметрами (например, несколько воркеров), используйте шаблоны. ini # /etc/systemd/system/worker@.service # Обратите внимание на @ в имени файла! [Unit] Description=Worker Instance %i After=network.target [Service] Type=simple ExecStart=/usr/local/bin/worker --id=%i --config=/etc/worker/config.yml User=worker Restart=on-failure [Install] WantedBy=multi-user.targetЗапуск нескольких экземпляров: bash # %i заменится на значение после @ sudo systemctl start worker@1.service sudo systemctl start worker@2.service sudo systemctl start worker@3.service # Или всех сразу: sudo systemctl enable worker@{1..5}.service sudo systemctl start worker@{1..5}.service # Посмотреть все запущенные экземпляры systemctl list-units 'worker@*'6.2 Временные сервисы через systemd-runbash # Запустить команду как временный сервис (исчезнет после завершения) sudo systemd-run --unit=my-task /usr/bin/python3 /opt/scripts/heavy_task.py # С ограничением ресурсов sudo systemd-run --unit=cpu-heavy --property=CPUQuota=50% --property=MemoryMax=256M \ /usr/bin/python3 /opt/scripts/heavy_task.py # Следить за прогрессом journalctl -u my-task -f6.3 Полезные команды, о которых мало кто знаетbash # Проверить юнит-файл на синтаксические ошибки ДО применения systemd-analyze verify /etc/systemd/system/myapp.service # Показать все переопределения (drop-in файлы) для сервиса systemctl cat nginx.service # Показать все свойства юнита systemctl show nginx.service # Показать конкретное свойство systemctl show nginx.service -p MainPID systemctl show nginx.service -p MemoryCurrent # Перезагрузить конфиги без daemon-reload (для drop-in файлов) sudo systemctl daemon-reload # Перечитать конфиги всех сервисов (более мягкий вариант) sudo systemctl reload-or-restart nginx.service # Узнать, какой пакет установил юнит systemctl cat nginx.service | head -1 # # /lib/systemd/system/nginx.service dpkg -S /lib/systemd/system/nginx.service # Debian/Ubuntu rpm -qf /lib/systemd/system/nginx.service # RHEL/Fedora # Блокировка: сервис не запустится даже вручную sudo systemctl mask dangerous-service.service # Разблокировка sudo systemctl unmask dangerous-service.serviceШпаргалка — все команды в одном местеУправление сервисамиЗадача Команда Запустить sudo systemctl start <name> Остановить sudo systemctl stop <name> Перезапустить sudo systemctl restart <name> Перечитать конфиг (без остановки) sudo systemctl reload <name> Reload или restart sudo systemctl reload-or-restart <name> Статус systemctl status <name> Включить автозапуск sudo systemctl enable <name> Выключить автозапуск sudo systemctl disable <name> Включить И запустить sudo systemctl enable --now <name> Заблокировать навсегда sudo systemctl mask <name> Просмотр состоянияЗадача Команда Все запущенные сервисы systemctl list-units --type=service --state=running Все упавшие systemctl --failed Проверить автозапуск systemctl is-enabled <name> Проверить активность systemctl is-active <name> Дерево зависимостей systemctl list-dependencies <name> Кто зависит от этого systemctl list-dependencies --reverse <name> Все таймеры systemctl list-timers Логи (journalctl)Задача Команда Логи сервиса sudo journalctl -u <name> Последние N строк sudo journalctl -u <name> -n 50 В реальном времени sudo journalctl -u <name> -f За текущую загрузку sudo journalctl -u <name> -b Только ошибки sudo journalctl -u <name> -p err С определённого времени sudo journalctl -u <name> --since "1h ago" Размер журнала sudo journalctl --disk-usage Очистить старые sudo journalctl --vacuum-time=2weeks Диагностика производительностиЗадача Команда Время загрузки systemd-analyze Что грузилось дольше всех systemd-analyze blame Критический путь systemd-analyze critical-chain <target> Визуальная диаграмма systemd-analyze plot > boot.svg Проверить юнит-файл systemd-analyze verify /path/to/unit Дерево cgroups systemd-cgls Ресурсы cgroups в реальном времени systemd-cgtop ЗаключениеSystemd — это не монстр, которого стоит бояться. Это мощный инструмент, понимание которого делает вас значительно эффективнее как системного администратора или разработчика. Несколько ключевых идей, которые стоит унести из этой статьи: Юниты — декларативные описания ресурсов. Пишите их правильно, используя все доступные настройки безопасности. cgroups — системd всегда знает, где ваши процессы. Используйте это для мониторинга и ограничения ресурсов. journald — это база данных, а не текстовый файл. Учитесь делать правильные запросы. Drop-in файлы — никогда не редактируйте оригинальные юнит-файлы из пакетов. systemd-analyze — ваш первый инструмент при проблемах с загрузкой.
-
Скачать HPE 3PAR Management Console и TOOLS — полный набор ISO (SSMC, Excel Client, 3PAR MC 4.7.3) для администрирования StoreServ
Собран полный набор установочных ISO-образов для администрирования систем хранения HPE 3PAR StoreServ. В архиве представлены оригинальные дистрибутивы консолей управления, вспомогательных инструментов и клиентов для работы с массивами 3PAR. Доступны следующие образы: • 3PAR_Management_Console_4.7.3_QR482-11188.iso • 3PAR_Management_Console_4.7_QR482-10116.iso • 3PAR_SSMC_Excel_client_installer_SW_QR482-10120.iso • 3PAR_StoreServ_Management_Console_2.2_QR482-10119.iso • TOOLS_3.1.3.202_GA_Z7550-10556.iso Эти пакеты включают: 3PAR Management Console (MC) — классическую Java-консоль для управления массивами HPE 3PAR. StoreServ Management Console (SSMC) — современный веб-интерфейс администрирования. SSMC Excel Client — плагин для управления и мониторинга массивов через Microsoft Excel. 3PAR Tools — набор служебных утилит и вспомогательных компонентов для обслуживания системы. Подходит для администрирования и обслуживания различных моделей HPE 3PAR StoreServ, включая среды виртуализации, SAN-инфраструктуру и корпоративные системы хранения. Скачать образы можно по ссылке: Вот ссылка (Тык тут) Материалы будут полезны администраторам систем хранения, инженерам по инфраструктуре и специалистам по поддержке SAN, которым требуется доступ к классическим версиям консолей управления HPE 3PAR.
-
EMC VNX5300 не загружается после дегауcса системных дисков — где найти образы FLARE и можно ли восстановить ОС?
Коллеги, всем доброго времени суток! Столкнулся с проблемой при восстановлении EMC VNX5300 (дисковая полка на 25 дисков 2.5"). Информация по устройству: PROD ID / SN: CKM0013120101506 P/N: 900-567-002 Ситуация следующая: первые 4 системных диска, на которых находилась ОС массива, были уничтожены дегауссом. После этого были куплены 4 новых диска, но, разумеется, без системного образа. Что уже сделал: подключился к контроллеру через COM-порт (есть консольный кабель); при загрузке система пишет, что необходимо обратиться в поддержку; пробовал использовать команду recover. После ввода recover появляется ошибка: Data directory boot service Not Loaded Error! после чего происходит перезагрузка контроллера. Фактически массив сейчас не может загрузиться, так как системные диски пустые. В поддержку Dell обратиться не получается — профиль помечен жёлтой галкой, и дальнейшие действия непонятны (нет доступа к загрузкам). Собственно вопросы: Есть ли вообще возможность восстановить ОС на EMC VNX5300, если системные диски были полностью уничтожены? Можно ли самостоятельно развернуть системный образ на новые диски? Где можно найти образы для установки на системные диски? Насколько удалось выяснить, нужен образ примерно такого вида: FLARE-05.33.009.5.186.mif или что-то из этой же ветки FLARE OS для VNX5300. Диски, если что, имеются разные (совместимые), с этим проблем нет. Буду очень благодарен, если кто-то подскажет: возможную процедуру восстановления, либо поделится образами FLARE / recovery для VNX5300. Перепробовал уже, кажется, всё, что можно — но пока безрезультатно.
-
iLo advanced futures activation code/ код активации - ключи дополнительных функций iLo 2 iLo 4
Коллеги, всем привет! iLO 2 Activation Key: 372CG-JCDSP-ZXKL9-WVBZ9-SJHHM iLo2/iLO4 Advanced License Keys: 35DPH-SVSXJ-HGBJN-C7N5R-2SS4W 35SCR-RYLML-CBK7N-TD3B9-GGBW2Делюсь ключиками для iLo, чтоб вам былы доступны все функции вашего сервера HP
-
В очередной раз искал Service Pack for ProLiant (SPP) Gen 9.1 и FIX Gen 9.4 для обновления серверов HPE bl460c Gen9
В общем в очередной раз лазил в сети в поисках образа для обновления платформы HP Gen9 и нашел таки! Вот список, чего там есть: P52574_001_spp-Gen9.1-Gen9SPPGen91.2022_0822.4.iso - сам основной образ для пакетного обновления платформы P69223_001_Gen9.4HotfixBundle-Gen9PPHotFixBundleGen9.4.2.7z - самый свежий на сегодня фикс Ну и по мелочи, прошивки... Делюсь ссылкой на все файлы с вами ССЫлка на скачивание
-
Windows.exe перестал отвечать: сборник - Север не найден и другие истории
Поймал программист золотую рыбку: — Загадывай желание! — Хочу, чтобы Python никогда не падал в продакшне! — Слушай, лучше мир во всём мире — оно реальнее. Построили полностью роботизированный завод. Экскурсия по цехам: — Здесь роботы на Unix. Работают как часы уже 15 лет. — Здесь на MS-DOS. Немного устарело, но стабильно. — А вот здесь — на Windows 98. Прошу всех надеть скафандры и не делать резких движений. Новый карманный компас на Windows CE. На экране: «Север не найден. Повторить поиск? Да / Позже» Звонок на радио: — Поставьте, пожалуйста, ту песню Пугачёвой — про зависший Windows! — Хм... не припомню такой. Можете напеть? — Ну там припев: «Кликну — а в ответ тишина, снова я осталась одна. Сильная женщина плачет у Окна» Пресс-конференция NASA по поводу сбоя компьютера на МКС: — Скажите, МКС работает под Windows? — А вы вообще видели, чтобы под Windows хоть что-то летало? Умер Билл Гейтс. Архангел Пётр: — Что скажешь в своё оправдание? — Я осчастливил всё человечество! — Это каким же образом? — Ну... умер же. Установка Windows. Приветственный экран: «Добро пожаловать. Откиньтесь в кресле, расслабьтесь, закройте глаза — и молитесь»
-
UDP/TCP Сетевой юмор без фрагментации: 54 протокола, один broadcast и ноль гарантий что оно дойдет...
У меня есть примерно 450 000 шуток про BGP 📡 Шутки про RAID почти всегда избыточны 💾 Шутку про 127.0.0.1 каждый может пошутить себе сам 🖥️ Я знаю отличную шутку про UDP, но не факт, что она до вас дойдёт 📦 Жаль, что шутка про Fault Tolerance не может состоять больше чем из одного слова ⚙️ Шутки про IPv6 плохи тем, что их мало кому можно рассказать 🌍 А вы слышали шутку про ICMP? 📢 Самое клёвое в шутках про rsync — её рассказывают только если вы не слышали её до этого 🔁 Шутки про RFC 1918 можно рассказывать только своим 🏠 Я бы рассказал отличную шутку про Token Ring, но сейчас не моя очередь 🎟️ Про DWDM шутят сразу несколькими голосами 🎙️ DHCP шутки смешны, только если их рассказывает один человек 🧾 Подождите все, я расскажу шутку о сети типа «шина» 🚌 Шутки про SSH-1 и SSH-2 несовместимы между собой 🔐 Из-за одного, кто зевнул, придётся заново рассказывать шутку про frame relay в топологии point-to-multipoint 🔄 Я знаю отличную шутку про TCP, но если она не дойдёт — повторю 📬 IGMP шутка; пожалуйста, передай дальше 📡 Шутки про IPv4 уже закончились? 🤔 Шутки про MAC-адрес могут не дойти до тёзок 🏷️ Я сейчас расскажу отличную шутку про VPN, но её поймёт только один 🔒 PPP шутки всегда рассказываются только между двумя людьми 🤝 Про Schema Master шутит только один в этом лесу 🌲 Лучшее в шутках про проприетарные протоколы — это УДАЛЕНО 🚫 Фрагментированные шутки… ✂️ …всегда рассказываются… 📦 …по кусочкам. 🧩 У кого есть кабель? Есть смешная шутка про RS-232 и полусмешная про RS-485 🔌 DNS-сервер не понял шутку про DDoS и ему её стали пересказывать сто тысяч раз в секунду 🌪️ Я подожду Антона и расскажу классную шутку про QoS ⏳ Самое лучшее в шутках про BitTorrent — они могут идти в любом порядке 🧲 К шутке про SCTP вначале должны все подготовиться 📋 Я бы рассказал шутку про CSRF, если бы ты САМ только что этого не сделал 🕵️ Нет ничего забавного в шутках про определение MTU… 📏 Шутки про 10/100/1000BASE-T вряд ли услышат с расстояния больше 100 📶 Жаль, никто не помнит шутки про IPX 🗂️ А кто знает отличную шутку про ARP? 🧠 Шутки про HDLC обычно не понимают те, кто знает другие шутки про HDLC 🔄 Только что специально для сообщества пришла шутка про мультикаст 📣 И ГОСТ, и ISO согласны, что есть 7 уровней рассказывания шуток 📚 Министерство обороны США понимает только четыре уровня шуток 🪖 Вы уже слышали шутку про Jumbo фреймы? Она о-о-очень длинная 📏 Шутки про MitM любят все. Ну кроме Алисы и Боба 😏 А шутки про STP вам кто-нибудь рассказывал? 🌳 Я сейчас всем расскажу шутку про бродкаст 📢 Настало время рассказать шутку про NTP ⏰ Помню времена, когда шутка про модем пшшшшшш… 📞 Про MTU тоже есть классная 📐 <шутка><смешная/><про>XML</про></шутка> 🧾 Шутки про шутки про шутки часто звучат в туннелях 🚇 У кого есть пароли — приходите за шутками про RADIUS 🔑 Шутки про IPSec надо говорить, кому их рассказываешь 🛡️ Шутка про Е3 — это 30 одинаковых шуток про Е1 и ещё две для тех, кто в теме 📊 Шутки про FSMO роли могут шутить не более пяти человек 👑 Единственная проблема в шутках про Token Ring — если кто-то начнёт говорить одновременно с вами, обе шутки обрываются 🎙️
-
PSRAM в ESP32: архитектура, ограничения и практическое использование в ESP-IDF
1. Зачем нужна PSRAM в ESP32Микроконтроллеры семейства ESP32 имеют сотни килобайт встроенной SRAM, размещённой на том же кристалле, что и CPU, периферия и контроллеры. Для задач вроде: обработки графики (LVGL, дисплеи), буферизации аудио, работы с большими JSON, сетевых стеков, ML-моделей, этого объёма часто недостаточно. Поэтому архитектура предусматривает подключение внешней PSRAM (Pseudo-Static RAM) — псевдо-статической оперативной памяти, которая расширяет доступный heap. 2. Что такое PSRAM2.1 ТерминологияВ документации Espressif используются как взаимозаменяемые: PSRAM SPI RAM SPIRAM Во всех случаях речь идёт об одном типе внешней памяти. 2.2 Почему «Pseudo-Static»PSRAM сочетает в себе: Внутренняя структура: DRAMЯчейки динамические (как в DRAM) Требуется refresh Внешний интерфейс: как у SRAMВстроенная логика регенерации CPU работает с ней как с обычной RAM Внешний контроллер refresh не нужен Именно поэтому — Pseudo-Static. 3. Аппаратная архитектура доступа к PSRAM3.1 ПодключениеPSRAM подключается: через SPI / QSPI / OPI по той же шине, что и Flash с отдельной линией Chip Select В модулях типа WROVER чип PSRAM обычно установлен внутри металлического экрана. В новых сериях возможна: in-package PSRAM (в одном корпусе с SoC) но архитектурно она остаётся «внешней» 3.2 Как CPU обращается к PSRAMДоступ НЕ прямой. Схема: CPU → Cache → MMU → SPI → PSRAM Алгоритм:CPU обращается к виртуальному адресу. MMU отображает его в физический адрес PSRAM. Cache: cache hit → мгновенно cache miss → чтение через SPI В новых сериях используется write-back cache. 3.3 Главное ограничениеPSRAM всегда медленнее внутренней SRAM, потому что: последовательная шина работа через кэш латентность SPI Следствие: стек задач и DMA-буферы по умолчанию остаются во внутренней памяти. 4. Важные аппаратные ограничения4.1 НапряжениеPSRAM бывает: 1.8 В 3.3 В Оно должно совпадать с Flash. Выбор задаётся: strapping pins eFuse Ошибка может: отключить память повредить чип 4.2 DMAНа старых ESP32: DMA напрямую с PSRAM невозможен На новых сериях: возможен но требует контроля когерентности кэша 4.3 Стек FreeRTOSПо умолчанию: стек задач → внутренняя RAM Технически можно разместить в PSRAM (через xTaskCreateStatic), но это не рекомендуется. 5. Особенности разных серий ESP325.1 Классический ESP32QSPI (4 линии) максимум 4 МБ отображаемого окна кэш 32 КБ на ядро при 8 МБ требуется Himem API (bank switching) Поддерживаются режимы MMU: Normal Low-High Even-Odd DMA напрямую не работает. 5.2 ESP32-S2независимые ICache и DCache до 10.5 МБ виртуального адресного пространства возможно выполнение кода из PSRAM настраиваемый размер кэша 5.3 ESP32-S3Quad / Octal SPI поддержка XTS-AES до 32 МБ отображаемого пространства общий кэш для двух ядер Octal PSRAM заметно быстрее Quad. 5.4 ESP32-C5 и ESP32-C61поддержка PSRAM есть до 32 МБ отображения доступ через кэш и GDMA Ранние C-серии (C2, C3, C6) PSRAM не поддерживают. 5.5 ESP32-P4Наиболее производительная архитектура: до 64 МБ PSRAM интерфейсы OPI и HPI двухуровневый кэш (L1 + L2) частоты до 200 МГц аппаратное шифрование 6. Использование PSRAM в ESP-IDFОсновной компонент: esp_psram В новых версиях ESP-IDF его нужно явно добавить в зависимости: idf_component_register( SRCS "main.c" INCLUDE_DIRS "." REQUIRES esp_psram )После этого появляется меню: Component config → ESP PSRAM7. Ключевые параметры menuconfig7.1 CONFIG_SPIRAM_BOOT_INITАвтоматическая инициализация при старте. Рекомендуется включать. 7.2 CONFIG_SPIRAM_IGNORE_NOTFOUNDПозволяет загружаться без PSRAM. Полезно для универсальных прошивок. 7.3 CONFIG_SPIRAM_MEMTESTТест памяти при старте. ≈ 1 секунда на 4 МБ. 7.4 CONFIG_SPIRAM_USEОпределяет стратегию интеграции: 1) MEMMAPПросто отображение в адресное пространство. Вы сами управляете памятью. 2) CAPS_ALLOCИспользование через: heap_caps_malloc(size, MALLOC_CAP_SPIRAM);Наиболее управляемый способ. 3) MALLOC (по умолчанию)PSRAM объединяется с общей кучей. malloc() автоматически выбирает регион. 7.5 CONFIG_SPIRAM_MALLOC_ALWAYSINTERNALПорог (по умолчанию 16 КБ): меньше → внутренняя RAM больше → PSRAM 7.6 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNALРезервирует внутреннюю память под: DMA стеки задач критические участки Очень важная опция для стабильности. 7.7 Перенос кода и данныхCONFIG_SPIRAM_FETCH_INSTRUCTIONS CONFIG_SPIRAM_RODATA CONFIG_SPIRAM_XIP_FROM_PSRAM Позволяют: выполнять код из PSRAM разгрузить Flash ускорить систему (в Octal-режиме) 8. API esp_psramФункции: esp_psram_init(); esp_psram_is_initialized(); esp_psram_get_size();Практически используется только: esp_psram_get_size();9. Выделение памяти9.1 Автоматический режимvoid *ptr = malloc(size);Работает при CONFIG_SPIRAM_USE_MALLOC. 9.2 Явное выделение в PSRAMvoid *ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);Освобождение — обычный free(). 9.3 Когда использовать PSRAMПодходит для: больших JSON framebuffer аудиобуферов кешей временных массивов Не подходит для: DMA ISR стека задач структур с высокой частотой доступа 10. Практическая стратегияОптимальный подход для production: CONFIG_SPIRAM_USE_CAPS_ALLOC CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL WiFi/LWIP → в PSRAM Стек, DMA → внутренняя RAM Это даёт предсказуемую производительность. 11. ИтогPSRAM — это: дешёвый способ расширить RAM возможность работать с графикой и ML разгрузка внутренней памяти Но: – всегда медленнее внутренней SRAM – требует грамотной конфигурации – может вызывать проблемы когерентности Для серьёзных проектов рекомендуется: ESP-IDF ручное управление аллокацией контроль DMA-буферов резерв внутренней памяти
-
Принцип работы LiDAR (лидара)
LiDAR (Light Detection and Ranging) — это технология измерения расстояния с помощью лазерного излучения. Метод основан на регистрации времени пролёта лазерного импульса (TOF, Time of Flight) от источника до объекта и обратно к приёмнику. По сути, лидар — это высокоточный лазерный дальномер, формирующий трёхмерную модель окружающего пространства в виде облака точек. История технологииКонцепция лидара была предложена в 1930 году британским физиком Edward Hutchinson Synge, который рассматривал возможность исследования атмосферы с помощью мощных световых источников. Сегодня LiDAR широко применяется в: метеорологии, геодезии, автономном транспорте, сельском хозяйстве, робототехнике, космических исследованиях. Как работает LiDARПринцип работы включает несколько этапов: Генерация импульса Лазерный излучатель (часто 905 нм или 1550 нм) формирует короткий импульс света. Отражение от объекта Луч достигает поверхности (здание, автомобиль, дерево, человек) и отражается. Регистрация сигнала Отражённый свет фиксируется фотоприёмником. Расчёт расстояния Система измеряет время пролёта импульса и вычисляет расстояние по формуле: D=c⋅t2D = \frac{c \cdot t}{2}D=2c⋅t где: D — расстояние, c — скорость света, t — время между отправкой и приёмом импульса. Формирование облака точек Миллионы измерений объединяются в трёхмерную карту сцены. Основные компоненты лидараТиповая система LiDAR включает: лазерный модуль (часто VCSEL); оптическую систему (линзы, фильтры); фотоприёмник (SiPM или лавинный фотодиод); АЦП (аналогово-цифровой преобразователь); вычислительный модуль (FPGA, AI-процессор); систему сканирования. Типы лидаров1. Механические лидары (360°)Имеют вращающуюся платформу с излучателем и приёмником. Особенности: горизонтальный обзор 360° высокая точность сложная механика более высокая стоимость Применяются в автономных автомобилях и картографировании. 2. Твердотельные лидарыНе содержат вращающихся элементов. Сканирование выполняется с помощью MEMS-зеркал или фазированных решёток. Преимущества: компактность устойчивость к вибрациям меньшая стоимость высокая надёжность Широко применяются в ADAS, дронах и робототехнике. Методы измерения скоростиLiDAR может измерять скорость объектов: Доплеровский метод — по изменению частоты отражённого сигнала. Последовательные измерения — по изменению расстояния во времени. Используется для определения скорости: ветра, транспортных средств, движущихся объектов. Области применения LiDAR1. Автономный транспорт и ADASLiDAR — ключевой сенсор в системах автопилотирования. Пример промышленного внедрения — разработки компании Waymo и беспилотные проекты Яндекс. Функции: обнаружение препятствий распознавание пешеходов адаптивный круиз-контроль экстренное торможение удержание полосы 2. Геодезия и картографияАэро-лидары устанавливаются на самолёты и БПЛА. Используются совместно с: GPS инерциальными системами (IMU) Результат — цифровая модель рельефа (ЦМР). 3. Метеорология и атмосферные исследованияПозволяют измерять: аэрозольную нагрузку концентрацию метана параметры облаков скорость ветра интенсивность осадков 4. Сельское хозяйствоПрименение: построение топографии полей анализ зон урожайности обнаружение сорняков (с применением ML) навигация сельхозтехники без GPS мониторинг виноградников и садов 5. АрхеологияLiDAR позволяет выявлять объекты под густым лесным покровом. Пример — обнаружение древних сооружений в регионе Ла-Москития (Гондурас) и исследование древнего города Махендрапарвата. 6. КосмосЛазерная альтиметрия применяется для картографирования планет. Пример — марсианский альтиметр MOLA на орбитальном аппарате NASA. Также лидар используется при сближении космических аппаратов и посадке на поверхность. Российский рынок лидаровПроизводствоВ 2025 году компания Радар ММС запустила производство модулей воздушно-лазерного сканирования для автомобилей и дронов. ИсследованияВ 2022 году МТУСИ совместно с ИОФ РАН протестировали мобильный лидар в рамках научной установки беспроводной подводной лазерной связи. Мировой рынок LiDARАвтомобильный сегментПо данным Fortune Business Insights: 2024 год — $3,72 млрд 2026 год — $4,16 млрд прогноз к 2032 году — $9,54 млрд CAGR — 12,6% Крупные игроки: Luminar Technologies Valeo S.A. Innoviz Technologies Continental Aeva Technologies Ouster Hesai Technology RoboSense Рынок лидаров для смартфонов2023 год — $2,03 млрд 2024 год — $2,42 млрд прогноз к 2032 году — $10 млрд CAGR — 19,38% Рост обеспечен развитием AR/VR и мобильной съёмки. Преимущества и ограничения технологииПреимуществавысокая точность (до сантиметров) независимость от освещённости формирование 3D-моделей в реальном времени высокая дальность (до 300+ м) Ограничениячувствительность к погодным условиям высокая стоимость (для высокодальних систем) необходимость обработки больших массивов данных Перспективы развитияТренды отрасли: переход от механических к твердотельным решениям интеграция с AI снижение стоимости модулей рост применения в умных городах развитие FMCW-лидаров интеграция в потребительскую электронику
-
Конденсаторы: виды, неисправности и проверка мультиметром
Конденсаторы — обязательные компоненты большинства электронных устройств: от бытовой техники до промышленной автоматики. Они выполняют функции накопления и отдачи энергии, фильтрации помех, формирования частоты и сглаживания пульсаций напряжения. Во многих случаях отказ оборудования связан именно с неисправностью конденсатора. Поэтому важно понимать, как корректно проверить его работоспособность с помощью мультиметра и какие дефекты встречаются чаще всего. Что такое конденсатор и как он работаетКонденсатор — это пассивный электронный компонент, состоящий из двух проводящих обкладок, разделённых диэлектриком. Его ключевые параметры: Ёмкость (Ф, мкФ, нФ, пФ) — способность накапливать заряд Рабочее напряжение (В) — максимально допустимое напряжение Тип диэлектрика — влияет на стабильность и область применения Полярность — у некоторых типов строго соблюдается Основные виды конденсаторов1. По назначениюВысоковольтныеИспользуются в силовой электронике и высоковольтном оборудовании. Бывают керамические, масляные, вакуумные. Доступ к ним часто ограничен требованиями безопасности. ПусковыеПрименяются в электродвигателях для увеличения пускового момента. Подстроечные (переменные)Позволяют изменять ёмкость регулировкой положения подвижной пластины. ИмпульсныеФормируют короткие пики напряжения для передачи сигналов. Помехоподавляющие (X и Y-класса)Стабилизируют работу чувствительных устройств, подавляя электромагнитные помехи. 2. По типу диэлектрикаБумажные Плёночные Керамические Слюдяные Электролитические (алюминиевые, танталовые) Стеклокерамические Оксидно-полупроводниковые 3. По полярностиПолярныеЭлектролитические Танталовые Имеют маркировку минусового вывода. Нарушение полярности приводит к выходу из строя. НеполярныеКерамические Плёночные Слюдяные Не требуют соблюдения полярности при подключении. Типичные неисправности конденсаторов1. Короткое замыкание (КЗ)Причины: пробой изоляции превышение рабочего напряжения перегрев механические повреждения Симптом: сопротивление близко к нулю. 2. ОбрывПотеря электрического контакта с обкладкой. Ёмкость становится равной нулю. Часто встречается: в электролитических в помехоподавляющих Y-конденсаторах (конструктивно защищены от КЗ) 3. Потеря ёмкостиОсобенно характерна для электролитических конденсаторов из-за высыхания электролита. 4. Повышенная утечкаЭлемент не удерживает заряд. Часто наблюдается у: электролитических танталовых Подготовка к проверке мультиметромПеред измерениями необходимо: Отключить устройство от сети Разрядить конденсатор Замкнуть выводы металлическим предметом (для мощных — через резистор) Осмотреть корпус вздутие потёки трещины обугливание Определить полярность Выпаять элемент Проверка на плате часто даёт некорректные результаты из-за влияния других компонентов. Как проверить полярный (электролитический) конденсаторПроверка на КЗ или обрывРазрядить элемент Установить мультиметр в режим: «прозвонка» «сопротивление» Подключить: «+» к плюсу «−» к минусу Интерпретация результатов:Показание Диагноз 0 Ом Короткое замыкание 1 без изменений Обрыв Сопротивление растёт Исправен Рост сопротивления означает заряд конденсатора от батареи мультиметра. Как проверить неполярный конденсаторУстановить режим измерения сопротивления (МОм) Подключить щупы без соблюдения полярности Результат:Более 2 МОм → исправен Менее 2 МОм → вероятна неисправность Проверка на короткое замыканиеВ режиме прозвонкиЕсли мультиметр постоянно издаёт звуковой сигнал — присутствует КЗ. В режиме сопротивленияСопротивление близкое к 0 Ом — короткое замыкание. Проверка на обрывМетод 1 — прозвонкаКратковременный щелчок → исправен Отсутствие реакции → возможен обрыв Метод 2 — измерение сопротивленияНа максимальном диапазоне сопротивление должно плавно увеличиваться. Проверка остаточного напряженияСамый чувствительный способ: В режиме сопротивления зарядить конденсатор 2–3 секунды Переключить мультиметр на измерение постоянного напряжения Подключить снова Если прибор показывает остаточное напряжение — элемент исправен. Подходит для большинства типов, кроме сверхмалых ёмкостей (<470 пФ). Как измерить ёмкость мультиметромЕсли прибор имеет функцию измерения ёмкости: Выбрать режим Cx Установить диапазон Подключить выводы Сравнить значение с номиналом Допустимое отклонение обычно: ±5–20% для большинства типов ±10% для электролитических Проверка пускового конденсатораОбесточить оборудование Выпаять и разрядить элемент Измерить ёмкость Сравнить с номиналом Если расхождение превышает допустимое — требуется замена. Проверка керамического конденсатораКерамические — неполярные. Режим измерения сопротивления Предел — МОм Показание >2 МОм → исправен Для точной оценки ёмкости нужен специализированный прибор. Можно ли проверять без выпаивания?В большинстве случаев — нет. Причины: параллельные цепи искажают показания диоды и транзисторы могут симулировать КЗ измеряется суммарная ёмкость Допустимо проверять: электролитические >1 мкФ только на КЗ или обрыв Для точной диагностики рекомендуется выпаивание. Когда лучше заменить, чем проверять?Если наблюдаются: вздутие утечка электролита сильный перегрев значительное отклонение ёмкости В таких случаях замена быстрее и надёжнее ремонта. ВыводПроверка конденсатора мультиметром — эффективный способ диагностики короткого замыкания, обрыва и грубых отклонений ёмкости. Для точных измерений малых ёмкостей и оценки ESR требуется специализированное оборудование.
-
Интернет вещей (IoT) и промышленный интернет вещей (IIoT): технологии, архитектура и практическое применение
Интернет вещей (IoT, Internet of Things) в промышленной среде получил отдельное направление — промышленный интернет вещей (IIoT, Industrial Internet of Things). Это комплекс аппаратных и программных решений, который объединяет датчики, оборудование, контроллеры и ИТ-системы в единую цифровую среду с возможностью обмена данными в режиме, близком к реальному времени. Внедрение IIoT позволяет: осуществлять непрерывный мониторинг оборудования; переходить от планового к прогнозирующему обслуживанию (Predictive Maintenance); снижать внеплановые простои; оптимизировать энергопотребление; повышать прозрачность производственных процессов; интегрировать производство с ERP- и MES-системами. Что такое IIoT и какие задачи он решаетПромышленный интернет вещей (IIoT) — это совокупность технологий, обеспечивающих подключение оборудования и датчиков к сети для сбора, передачи, обработки и анализа данных. Ключевая задача IIoT — переход от реактивной модели эксплуатации оборудования («сломалось — ремонтируем») к проактивной модели управления активами. Проблема традиционного подходаНа предприятии с большим количеством сложных машин: оборудование обслуживается по регламенту, а не по фактическому состоянию; поломки часто возникают внезапно; возникают внеплановые простои; требуется держать избыточный склад запчастей; увеличиваются эксплуатационные расходы (OPEX). Как IIoT меняет модель управленияКаждая единица оборудования оснащается датчиками, которые фиксируют: температуру, вибрацию, давление, ток и напряжение, скорость вращения, другие технологические параметры. Данные передаются на локальные серверы или в облачную инфраструктуру, где автоматически анализируются. При отклонении параметров от нормативных значений система: уведомляет оператора; формирует заявку на обслуживание; может инициировать автоматическое регулирование. Это позволяет: предотвратить аварии, сократить downtime, снизить стоимость владения оборудованием (TCO). Прогнозирующее обслуживание: практический примерОдин из наиболее показательных кейсов — авиационная промышленность. Производители двигателей устанавливают независимые каналы связи, предназначенные исключительно для передачи телеметрии наземным службам. На основе массивов данных строятся аналитические модели, которые прогнозируют: остаточный ресурс узлов; вероятность отказа; оптимальное время замены деталей. В промышленности аналогичный подход применяет, например, Siemens. На производственных площадках компания внедряет системы датчиков, которые контролируют: механические параметры станков, энергопотребление, режимы загрузки линий. Если линия простаивает, система автоматически снижает энергопотребление, что напрямую сокращает операционные затраты. История развития IoT и становление IIoTКонцептуальные предпосылки IoT появились еще в 1980-х годах с развитием сетевых технологий. Термин «Internet of Things» в 1999 году предложил Kevin Ashton. Он рассматривал применение RFID-меток для отслеживания товаров в цепочках поставок. Активная фаза развития IoT началась в 2010-х годах благодаря: удешевлению сенсоров; распространению беспроводной связи; развитию облачных платформ; росту вычислительных мощностей. В промышленности это привело к формированию концепции IIoT и «умных фабрик» (Smart Factory) в рамках парадигмы Industry 4.0. Архитектура IIoT: уровни и требованияТиповая архитектура IIoT представляет собой многоуровневую систему. 1. Уровень сенсоров и устройств (Device Layer)Физический уровень включает: датчики, исполнительные механизмы, контроллеры, производственное оборудование. Критические требования: устойчивость к температуре, пыли, влажности; виброустойчивость; низкое энергопотребление; промышленная степень защиты (IP, EMI/EMC). 2. Сеть передачи данных (Communication Layer)Обеспечивает передачу информации между устройствами, edge-узлами и центрами обработки. Используются: Ethernet; Wi-Fi; 4G/5G; LPWAN; промышленные протоколы. Требования: высокая пропускная способность; минимальная задержка; отказоустойчивость; защищенность передачи данных. Оборудование промышленного уровня поставляют такие компании, как: Schneider Electric Allied Telesis Moxa Hirschmann Automation and Control B&R Выбор оборудования должен учитывать реальные условия эксплуатации — перепады температур, влажность, вибрации и электромагнитные помехи. 3. Граничные устройства (Edge Layer)Edge-устройства обрабатывают данные непосредственно на объекте. Их задачи: локальная фильтрация и агрегация данных; анализ в реальном времени; снижение нагрузки на облако; обеспечение автономной работы при потере связи. Обычно поддерживаются протоколы MQTT, OPC UA и другие индустриальные стандарты. Важно разграничивать: Edge — анализ и предварительная обработка данных; PLC/контроллеры — управление оборудованием. 4. Уровень управления (Control Layer)Включает: PLC; SCADA-системы; MES; интеграцию с ERP. Системы класса SCADA обеспечивают диспетчеризацию и визуализацию процессов, а MES — управление производственными операциями. 5. Обработка данных и аналитика (Data & Analytics Layer)На этом уровне используются: Big Data; машинное обучение; предиктивная аналитика; цифровые двойники (Digital Twin). Цель — выявление закономерностей, оптимизация процессов и стратегическое управление активами. Применение IIoT в различных отрасляхПромышленность и машиностроениемониторинг станков; оптимизация производственных линий; снижение брака; предиктивное обслуживание. Особое значение имеют edge-вычисления и отказоустойчивые сети. Логистика и транспортотслеживание транспорта в реальном времени; контроль состояния грузов; автоматическое пополнение запасов. Ключевую роль играют мобильные сети и устойчивость связи при перемещении между зонами покрытия. Энергетикамониторинг генерации и распределения; контроль подстанций; управление распределенными энергоресурсами; интеграция ВИЭ. Системы должны быть масштабируемыми и устойчивыми к тяжелым условиям эксплуатации. Сельское хозяйствомониторинг влажности почвы; контроль микроклимата; управление сельхозтехникой; автоматизация полива. Основной акцент — энергоэффективные беспроводные технологии и автономность. Преимущества внедрения IIoTВнедрение промышленного интернета вещей позволяет: снизить внеплановые простои; сократить издержки на обслуживание; уменьшить энергопотребление; повысить прозрачность процессов; улучшить управляемость цепочек поставок; повысить общую операционную эффективность предприятия. IIoT становится фундаментом цифровой трансформации промышленности и ключевым элементом конкурентоспособности в условиях Industry 4.0.
-
Что такое ИК-приемник: устройство, принцип работы и области применения
Сегодня сложно представить электронику без инфракрасных (ИК) технологий: пульты дистанционного управления, системы безопасности, промышленная автоматизация, медицинские приборы и робототехника — во всех этих решениях применяются ИК-приемники. Разберем подробно, что такое инфракрасный приемник, как он устроен, по какому принципу работает и как диагностировать его неисправности. Что такое ИК-приемникИК-приемник (инфракрасный приемник) — это электронное устройство, предназначенное для приема и декодирования сигналов, передаваемых в виде инфракрасного излучения от источника (обычно ИК-светодиода). Классический пример — пульт дистанционного управления телевизором или кондиционером. Передатчик формирует последовательность модулированных ИК-импульсов, а приемник: Улавливает инфракрасное излучение. Преобразует его в электрический сигнал. Демодулирует и передает данные в управляющую схему устройства. Где применяются инфракрасные приемники1. Бытовая электроникаПульты ДУ (телевизоры, аудиосистемы, кондиционеры). Медиаплееры и приставки. Ранее — передача данных в мобильных телефонах и ПК (до распространения Bluetooth и Wi-Fi, скорость достигала ~4 Мбит/с). 2. Освещение и автоматизация зданийДатчики движения в подъездах, коридорах, санузлах. Автоматическое включение/выключение освещения. Энергосберегающие системы «умного дома». 3. Системы безопасностиОхранные датчики движения. Инфракрасные барьеры периметра. Контроль несанкционированного доступа. 4. Бесконтактные устройстваДиспенсеры мыла и воды. Сенсорные смесители. Бесконтактные мусорные контейнеры. 5. Медицинская техника и носимая электроникаБесконтактные термометры. Пульсометры и фитнес-трекеры (анализ кровотока по отраженному ИК-сигналу). Применение ИК-приемников в промышленностиПростота, надежность и низкая стоимость делают ИК-датчики востребованными в промышленной среде. Конвейерные линииДетекция присутствия объекта. Контроль положения детали. Синхронизация этапов сборки и упаковки. Системы безопасностиИнфракрасные барьеры. Контроль складов и производственных зон. Защита оборудования. Контроль качестваИнфракрасная спектроскопия для анализа состава материалов. Выявление дефектов. Контроль смесей в химическом и пищевом производстве. Энергетика и металлургияПирометры и тепловизоры. Контроль температуры печей, трубопроводов, реакторов. Предотвращение перегрева и аварий. ЛогистикаСистемы учета и сортировки. Взаимодействие со сканерами штрихкодов и RFID. Машиностроение и робототехникаОбнаружение препятствий. Навигация автономных систем. Системы точного позиционирования. Принцип работы инфракрасного приемникаИК-приемники работают в диапазоне длин волн 700 нм – 1 мм, однако в бытовых и промышленных системах чаще используется диапазон 850–950 нм. Основные этапы работы:Прием излучения Чувствительный элемент (фотодиод или фототранзистор) реагирует на ИК-свет. Преобразование в электрический сигнал При попадании излучения генерируется ток. Фильтрация Оптический фильтр подавляет помехи (солнечный свет, лампы). Модуляция и демодуляция Сигнал передается импульсами (обычно 36–38 кГц). Приемник выделяет именно эту частоту, игнорируя фон. Передача в контроллер Демодулированный сигнал поступает в микроконтроллер. Устройство ИК-приемникаТиповой ИК-модуль включает: фотодиод; усилитель; полосовой фильтр; демодулятор; формирователь цифрового сигнала. Основные характеристикиПараметр Описание Длина волны 850–950 нм (типично) Частота модуляции 36–38 кГц (иногда 56 кГц) Чувствительность Минимальная мощность сигнала (мкВт) Угол обзора 30–90° Дальность Зависит от мощности передатчика Время отклика От миллисекунд Тип выхода Аналоговый или цифровой Пример: Vishay TSOP4456Рассмотрим популярный модуль — TSOP4456 компании Vishay Intertechnology. Основные параметры:Питание: 2,5–5,5 В Частота модуляции: 56 кГц Потребляемый ток: ~0,4 мА Угол обзора: ~45° Дальность приема: до 45 м Температура: –25…+85 °C Выход: цифровой (активный низкий уровень) Модуль применяется в системах дистанционного управления, совместим с протоколами RCA и другими распространенными стандартами. Факторы, влияющие на работу ИК-приемникаВ промышленной эксплуатации необходимо учитывать: запыленность; задымленность; влажность; вибрации; температурные перепады; электромагнитные помехи. В сложных условиях применяются модули в герметичных корпусах с промышленным исполнением. Устранение неисправностей ИК-приемникаДиагностика проводится поэтапно. 1. Проверка передатчикаНавести пульт на камеру смартфона и нажать кнопку — мигающий свет указывает на исправность ИК-диода. 2. Осмотр приемникаПроверить загрязнение линзы. Осмотреть корпус на механические повреждения. 3. Проверка питанияИзмерить напряжение мультиметром. Проверить цепь питания и предохранители. 4. Проверка пайкиОсмотреть контакты. При необходимости перепаять соединения. 5. Проверка сигналаИспользовать осциллограф. Убедиться в наличии корректных импульсов. 6. Диагностика контроллераЕсли приемник исправен, проблема может быть в микроконтроллере или основной плате. Преимущества ИК-приемниковНизкая стоимость Простота интеграции Энергоэффективность Высокая помехоустойчивость (при модуляции) Надежность Широкий диапазон рабочих температур Несмотря на развитие Bluetooth, Wi-Fi и других беспроводных технологий, ИК-приемники остаются экономически и технически оправданным решением во множестве задач.
-
Нелинейная фильтрация временной структуры сложных сигналов для выявления аномалий в протяжённых средах
1. ВведениеАнализ сигналов, распространяющихся в протяжённых средах (например, атмосфере или океане), осложняется наличием: фоновых шумов; квазирегулярных структурных неоднородностей; случайных флуктуаций; локальных аномалий, нарушающих равновесное состояние среды. Классические методы линейной фильтрации ориентированы на подавление шума за счёт сглаживания сигнала. Однако при этом часто теряется информация о локальных скачках — именно тех особенностях, которые соответствуют аномальным неоднородностям. Предлагаемый подход основан на нелинейной обработке дискретизированного сигнала, при которой: периодические и квазирегулярные структуры сглаживаются; локальные разовые перепады усиливаются; обеспечивается высокая чувствительность к границам аномалий. Метод устраняет противоречие между необходимостью подавления фона и сохранением (или усилением) диагностически значимых перепадов сигнала. 2. Цель работыПредставить результаты численного моделирования оригинального метода нелинейной фильтрации временной структуры сложных негармонических сигналов, предназначенного для выявления аномалий в протяжённых средах. 3. Научная новизнаПредложен алгоритм нелинейной фильтрации, позволяющий: выявлять аномальные неоднородности в частично организованной структуре сигнала; определять положение границ таких неоднородностей; обеспечивать устойчивость к шумам и псевдорегулярным структурам. Метод сочетает свойства медианных, рекурсивных, итеративных и робастных фильтров, однако обладает рядом принципиальных отличий. 4. Методология4.1. Общая идея алгоритмаПусть задан дискретный сигнал S={s1,s2,...,sN}S = \{s_1, s_2, ..., s_N\}S={s1,s2,...,sN} Алгоритм включает последовательность операций накопления, сравнения и логарифмического преобразования интегральных характеристик сигнала. Основной принцип — сравнение поведения сигнала на симметричных участках трассы с использованием скользящих накопленных сумм. 4.2. Базовый алгоритм фильтрацииЭтап 1. Деление текущего интервалаТекущий временной интервал регистрации сигнала делится пополам с шагом, равным шагу дискретизации. Этап 2. Логарифм отношенияДля нарастающих интервалов вычисляется: ln(S1S2)\ln \left( \frac{S_1}{S_2} \right)ln(S2S1) где S1S_1S1 и S2S_2S2 — интегральные значения сигнала на соответствующих полуинтервалах. Шаг приращения равен удвоенному шагу дискретизации. Этап 3. НормировкаПолученный ряд умножается на отношение: Nn\frac{N}{n}nN где NNN — общее число отсчётов, nnn — число отсчётов в текущем интервале. Этап 4. Выделение аномалииАномалия определяется как: выраженный провал во временном ходе отфильтрованного сигнала; чем уже и глубже провал — тем контрастнее неоднородность. 5. Формирование модельной структуры неоднородностиДля точного определения положения границ используется более детальная процедура. 5.1. Формирование двух накопительных последовательностейИз исходных отсчётов формируются: Последовательность типа A — накопление от начала к концу. Последовательность типа B — накопление от конца к началу. Шаг приращения соответствует требуемому разрешению. 5.2. Формирование дополнительных отсчётовДля каждой накопительной величины: для типа A формируется AD — сумма последующих отсчётов; для типа B формируется BD — сумма предшествующих отсчётов. 5.3. Нормированное логарифмическое преобразованиеВычисляется: ln(min(AD,A)max(AD,A))\ln \left( \frac{\min(AD, A)}{\max(AD, A)} \right)ln(max(AD,A)min(AD,A)) Аналогично для пары B и BD. Результат нормируется на число исходных отсчётов, формируя последовательности: IAn,IBnIA_n, \quad IB_nIAn,IBn Эти величины пропорциональны средним коэффициентам ослабления среды на соответствующих участках. 5.4. Поиск общей части ΔРассматриваются отношения: IA1IBn,IA2IBn−1,…,IAnIB1\frac{IA_1}{IB_n}, \frac{IA_2}{IB_{n-1}}, \dots, \frac{IA_n}{IB_1}IBnIA1,IBn−1IA2,…,IB1IAn при условии, что соответствующие участки имеют общую часть: Δ=12 шага дискретизации\Delta = \frac{1}{2} \text{ шага дискретизации}Δ=21 шага дискретизации Находится глобальный минимум: IAk/IBn−k+1IA_k / IB_{n-k+1}IAk/IBn−k+1 5.5. Формирование основной цифровой последовательностиОсновная последовательность строится: из IAnIA_nIAn при n>kn > kn>k; из IBnIB_nIBn при n≤kn \le kn≤k. 5.6. Определение границ аномалииМаксимальный перепад основной последовательности → ближняя граница. Вторичный перепад → дальняя граница. 6. Численное моделированиеПроведено сравнение предложенной фильтрации с: линейной фильтрацией (LINF), медианной фильтрацией (MEDF). Моделирование выполнялось для экспоненциально спадающего сигнала длиной 50 отсчётов с перепадом в центре выборки. Использовались три отношения сигнал : перепад : шум: SIG1 — 10:1:1 SIG2 — 10:1:5 SIG3 — 10:1:10 7. Критерий эффективностиИспользовалось отношение дисперсий: σфильтр2σисходный2\frac{\sigma^2_{\text{фильтр}}}{\sigma^2_{\text{исходный}}}σисходный2σфильтр2 Отдельно анализировались участки до и после перепада. Для предложенной фильтрации (GRAN): значения DISP1 и DISP2 существенно превышают 1; это указывает на нелинейное усиление локального перепада; чувствительность возрастает при увеличении шумовой компоненты. Линейная и медианная фильтрации не обеспечивают сопоставимого выделения перепада при высоком уровне шума. 8. Сопоставление с известными методамиПредлагаемая фильтрация имеет общие черты со следующими методами: 8.1. Медианная фильтрацияподавление повторяющихся выбросов; сохранение одиночных перепадов. 8.2. Рекурсивная фильтрацияпрогнозирование гладкости; зависимость от порядка фильтра. 8.3. Итеративная обработкапоследовательное изменение порога дискриминации. 8.4. Робастные методыслабая чувствительность к малым возмущениям входных данных. 9. Преимущества предложенного методаИсключается усиление случайных мелких перепадов. Порядок фильтрации автоматически возрастает с длиной интервала. Используется адаптивный порог выявления перепадов. Отсутствуют отрицательные значения сигнала. Не требуется частотное подавление шумов. Робастность возрастает от центра выборки к её краям. Слабо зависит от длины выборки. Прост в аппаратурной реализации. Обеспечивает высокое быстродействие. 10. ВыводыЧисленное моделирование показало, что предложенный метод нелинейной фильтрации: эффективно выделяет локальные перепады сигнала; устойчив к шуму; подавляет псевдорегулярную структуру; превосходит линейные и медианные фильтры в условиях высокого уровня шума. Метод особенно перспективен для анализа сигналов обратного рассеяния в протяжённых средах, включая атмосферные приложения. 11. ЛитератураПолканов Ю.А. Способ определения положения оптической неоднородности атмосферы. Авт. свид-во СССР №1448907, кл. G01W1/00, 1988. Полканов Ю.А. Выявление аномальной неоднородности на фоне псевдорегулярной структуры сложного спадающего сигнала. Вестник БГУ, Серия 1, 1991. Полканов Ю.А. Об одной возможности выделения аномальной неоднородности атмосферы (Метод нелинейной фильтрации). Оптика атмосферы и океана, 1992.
-
Корректный запуск процессов в Docker-контейнере: ENTRYPOINT, CMD, PID 1, exec и tini
ВведениеКорректный запуск процессов внутри контейнера — одна из ключевых тем при разработке Docker-образов. Формально всё описано в документации Docker, однако на практике регулярно возникают неоднозначные ситуации: контейнер не останавливается корректно; сигналы не доходят до приложения; появляются zombie-процессы; PID 1 ведёт себя неожиданно. В этой статье разберём: Разницу между ENTRYPOINT и CMD. Отличие exec и shell форм. Почему критически важно, какой процесс имеет PID 1. Как правильно писать docker-entrypoint.sh. Когда и зачем использовать tini. Материал ориентирован на практическое применение и реальные сценарии. 1. ENTRYPOINT и CMD: фундаментальная разницаВ Dockerfile существуют две директивы для запуска процессов: ENTRYPOINT CMD Обе участвуют в формировании итоговой команды запуска контейнера, но выполняют разные роли. Логическая модельМожно представить их так: ENTRYPOINT + CMD = финальная команда контейнераРекомендуемая практикаENTRYPOINT — фиксированная команда (исполняемый файл или скрипт). CMD — аргументы по умолчанию, которые можно переопределить. Exec-форма и Shell-формаDocker поддерживает два синтаксиса. 1️⃣ Exec-форма (рекомендуется)ENTRYPOINT ["/bin/ping"] CMD ["it-lux.ru"]Особенности: Не используется shell. Нет подстановки переменных. Процесс запускается напрямую. Корректная обработка сигналов. После сборки: docker run pingВнутри контейнера выполнится: /bin/ping it-lux.ruПереопределение аргументов: docker run ping google.comТеперь выполнится: /bin/ping google.comЭто правильная архитектура: один образ — разные параметры запуска. 2️⃣ Shell-форма (менее предпочтительна)ENTRYPOINT ping it-lux.ruФактически Docker запустит: /bin/sh -c "ping it-lux.ru"Минусы: Появляется промежуточный shell. Сигналы могут не дойти до целевого процесса. PID 1 становится shell. Shell-форма допустима, но требует понимания последствий. 2. Проблема PID 1В Linux процесс с PID 1 — особый. Особенности: Он не имеет обработчиков сигналов по умолчанию. Он ответственен за "усыновление" осиротевших процессов. Он должен корректно обрабатывать SIGTERM. Docker при остановке контейнера выполняет: docker stop → отправляет SIGTERM → PID 1Если PID 1: не обрабатывает сигнал, не передаёт его дочерним процессам, то контейнер завершится некорректно (force kill через SIGKILL спустя timeout). 3. Ошибка с docker-entrypoint.shТипичный пример: FROM centos:7 COPY docker-entrypoint.sh /usr/bin ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]Содержимое: #!/bin/bash ping ya.ruЧто происходит? PID 1 — это: /bin/bash /usr/bin/docker-entrypoint.shА ping — дочерний процесс. При docker stop: SIGTERM получает bash bash может не передать сигнал дальше ping зависает появляются zombie-процессы Это некорректная архитектура контейнера. 4. Правильное решение — execВ bash существует встроенная команда exec. Она: заменяет текущий процесс передаёт ему PID не создаёт дополнительный уровень Правильный вариант: #!/bin/bash exec ping ya.ruТеперь: PID 1 → pingКонтейнер завершится корректно. 5. Использование CMD внутри entrypointБолее гибкий вариант: ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] CMD ["ya.ru"]Скрипт: #!/bin/bash # подготовительные действия set -- ping "$@" exec "$@"Разбор: $@ — все аргументы контейнера. set -- — формирует новую команду. exec "$@" — запускает её как PID 1. Запуск: docker run ping google.comРезультат: PID 1 → ping google.comЭто production-подход. 6. Когда одного exec недостаточноТеперь усложним сценарий. Допустим, запускается: Jenkins Apache Zabbix server Такие системы активно создают дочерние процессы. Примеры: Jenkins Zabbix Apache HTTP Server Если дочерние процессы: завершаются некорректно, остаются "осиротевшими", то PID 1 должен их "подчищать". Но большинство приложений: не реализуют init-поведение, не умеют корректно reaping zombie-процессов. 7. Решение — tiniЗдесь используется tini. Минималистичный init для контейнеров. Корректно проксирует сигналы. Убирает zombie-процессы. Работает как PID 1. Название — это "init" наоборот. Как подключить tiniПример Dockerfile: FROM debian:stable RUN apt-get update && apt-get install -y tini ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["your-app"]Теперь: PID 1 → tini PID 7 → your-appЧто делает tini: Получает SIGTERM. Передаёт сигнал дочернему процессу. Reap'ит zombie-процессы. Корректно завершает контейнер. Это production best practice. 8. Почему bash ≠ tiniBash как PID 1 tini как PID 1 Не проксирует сигналы корректно Проксирует Не предназначен как init Предназначен Может терять SIGTERM Корректно передаёт Не чистит zombie Чистит Это принципиально разные роли. 9. Итоговые рекомендации (Best Practices)Используйте exec-форму всегда, когда возможно. В docker-entrypoint.sh обязательно применяйте exec. Разделяйте: ENTRYPOINT — исполняемый файл CMD — аргументы по умолчанию Если приложение создаёт дочерние процессы — используйте tini. Проверяйте, кто имеет PID 1: docker exec -it container ps auxЗаключениеНа простых примерах всё работает и без этих нюансов. Однако при усложнении логики контейнера: появляются проблемы с остановкой, теряются сигналы, возникают zombie-процессы, контейнер завершает работу некорректно. Docker упрощает деплой, но не отменяет фундаментальные принципы работы процессов в Linux. Понимание: роли PID 1, различий exec и shell, корректного построения entrypoint, необходимости tini позволяет создавать production-ready Docker-образы, которые ведут себя предсказуемо и корректно в любой среде.
-
Набор почти всех прошивок HPE_3PAR_INFORM_OS_3 и утилит Service Processor 4, 5 для СХД HPE 3par 7000, 7400, 8000, 8400
Всем привет! Дорогие друзья кто мучается с прошивкой и софтом для полок СХД HPE 3par 7000, 7400, 8000, 8400 может и к другим подходиит, хз.. Если у вас есть вопросы по данным СХД или вы хотите обсудить проблемы HPE 3par заходите в наш телеграмм канал В общем нашел я оромный сборник с прошивками и софтом, ниже список сделаю, он не полный. HPE 3PAR INFORM OS 3 HPE Service Processor 4, 5 образы ISO HPE_3PAR_INFORM_OS 3.2.1 HPE_3PAR_INFORM_OS 3.2.2 MU4 HPE_3PAR_INFORM_OS 3.2.2 MU6 HPE_3PAR_INFORM_OS 3.3.1 MU1 HPE_3PAR_INFORM_OS 3.3.1 MU2 HPE_3PAR_INFORM_OS 3.3.1 MU3 HPE_3PAR_INFORM_OS 3.3.1 MU5 HPE_3PAR_INFORM_OS 3.3.2 MU1 Firmware Proliant SP 4 SP 5 SSMC Witness 3PAR_Management_Console_4.7.3_QR482-11188.iso 3PAR_StoreServ_NODE_Maintenance.pptx.pptx 3PAR_SW_Upgrade_Tool_U019_QR482-11400.iso HPE_3PAR_StoreServe_Management_Console_3.5_QR482-11398.iso HPE_3PAR_SW_Upgrade_Tool_024_QR482-11470.iso HPE_3PAR_SW_Upgrade_Tool_025_QR482-11477.iso HPE_3PAR_SW_Upgrade_Tool_026_QR482-11489.iso HPE_3PAR_SW_Upgrade_Tool_029_QR482-11507.iso HPE_3PAR_SW_Upgrade_Tool_030_QR482-11517.iso HPE_3PAR_SW_Upgrade_Tool_031_QR482-11520.iso ВОТ ЭТА ССЫЛКА
-
Батя всех метрик - Что такое Load Average (LA) в Linux: как считается и что на самом деле показывает
Во время технического собеседования в крупную компанию мне задали простой вопрос: что такое Load Average? Формально ответить несложно — это «средняя загрузка системы за 1, 5 и 15 минут». Но если копнуть глубже, возникает ряд неудобных вопросов: Что именно усредняется? С какой частотой происходит измерение? Какие процессы считаются «ожидающими ресурсы»? Почему при кратковременных пиках мы не видим резких скачков? Почему Load Average = 1 соответствует 100% загрузке одноядерной системы? Если вас интересует не бытовое, а точное техническое понимание, разберёмся детально — с опорой на исходный код ядра Linux. Что такое Load Average (LA)В системах Linux и UNIX Load Average — это показатель среднего количества процессов: находящихся в состоянии RUNNING (исполняются или готовы к выполнению), находящихся в состоянии UNINTERRUPTIBLE (обычно ожидание I/O). Три значения, которые показывает команда uptime, соответствуют окнам: 1 минута 5 минут 15 минут Важно: Load Average — это не процент загрузки CPU. Это среднее количество активных (или ожидающих) задач. Для одноядерной системы: LA = 1 → процессор полностью занят LA < 1 → процессор простаивает часть времени LA > 1 → есть очередь процессов Где «подвох» в стандартном объяснении1. Это не арифметическое среднееЕсли бы LA считался как обычное среднее арифметическое, возникал бы вопрос о частоте дискретизации: считаем каждую секунду? каждые 10 мс? раз в минуту? Чем выше частота измерения — тем меньше получилось бы среднее значение. Но в Linux используется экспоненциальное сглаживание, а не классическое среднее. 2. Кто такие «ожидающие ресурсы»?Согласно исходному коду ядра Linux, учитываются процессы в состояниях: TASK_RUNNING TASK_UNINTERRUPTIBLEТо есть: задачи, выполняющиеся на CPU; задачи, ожидающие завершения операций ввода-вывода (например, медленный диск или NFS). Именно поэтому высокий Load Average может быть при низкой загрузке CPU — если система «застряла» на I/O. Как именно считается Load Average в LinuxРеализация находится в ядре Linux (например, в версии 2.4 — timer.c и sched.h). Ключевые факты:Измерение происходит каждые 5 секунд Используется фиксированная точка (fixed-point arithmetic) Применяется формула экспоненциального затухания Константы: #define LOAD_FREQ (5*HZ) /* интервал 5 секунд */ #define EXP_1 1884 /* коэффициент для 1 минуты */ #define EXP_5 2014 #define EXP_15 2037Формула расчётаВ упрощённом виде: Lnew=Lold⋅e−Δt/T+n⋅(1−e−Δt/T)L_{new} = L_{old} \cdot e^{-Δt/T} + n \cdot (1 - e^{-Δt/T})Lnew=Lold⋅e−Δt/T+n⋅(1−e−Δt/T) где: LLL — текущее значение Load Average nnn — число активных задач TTT — окно усреднения (1, 5, 15 минут) Δt=5Δt = 5Δt=5 секунд Это дискретная форма экспоненциального сглаживания. Почему используется экспонентаФормула основана на законе экспоненциального распада: dLdt=−1T(L−n)\frac{dL}{dt} = -\frac{1}{T}(L - n)dtdL=−T1(L−n) Смысл: если процессов больше текущего LA → показатель растёт если меньше → показатель экспоненциально уменьшается чем больше окно (15 минут), тем медленнее реакция Это обеспечивает: сглаживание кратковременных пиков устойчивость к «шуму» предсказуемую динамику Почему не видно резких скачков?Представим, что вы запустили 100 коротких процессов. Логично ожидать, что LA резко взлетит. Но этого не происходит, потому что: измерение идёт раз в 5 секунд используется экспоненциальное сглаживание старые значения затухают постепенно Экспонента выполняет роль фильтра низких частот. Почему LA = 1 означает 100% загрузку одноядерной системыПри постоянном числе процессов nnn: если n>Ln > Ln>L → LA растёт к n если n<Ln < Ln<L → LA уменьшается к n Если на одноядерной системе: в каждый момент времени активен ровно 1 процесс, очереди нет, то система полностью загружена — и LA стабилизируется на 1. Если LA > 1 — появляется очередь. Важные нюансы1. Load Average учитывает I/OЕсли процессы ждут диск или NFS, LA растёт, даже если CPU простаивает. 2. На многоядерных системахЕсли у вас 8 ядер: LA = 8 → система полностью загружена LA > 8 → есть очередь 3. Это не мгновенная метрикаLA показывает тренд, а не текущую загрузку. Ограничения моделиЭкспоненциальная модель предполагает: плавное изменение нагрузки отсутствие «жёстких» ограничений пропускной способности В реальности же: CPU имеет конечную пропускную способность I/O может быть узким местом высокие значения LA не всегда означают CPU-bound систему Поэтому интерпретировать Load Average нужно вместе с: top htop iostat vmstat ВыводыLoad Average — это экспоненциально сглаженное среднее количества активных процессов. Измерение происходит каждые 5 секунд. Учитываются процессы в состояниях RUNNING и UNINTERRUPTIBLE. Это не процент загрузки CPU. Значение > числа ядер означает наличие очереди. Главное: Load Average — это математическая модель сглаживания нагрузки, а не прямой счётчик занятости процессора.
-
Упс... Один git push --force, и полгода работы команды испарились за секунду
Есть команды, которые надо вводить с холодной головой и полным осознанием последствий. rm -rf / — очевидный пример. Но среди разработчиков и DevOps есть своя версия этой русской рулетки — git push --force. Я работал тогда в продуктовой компании — делали SaaS-платформу для управления проектами. Небольшая команда, человек двенадцать, хороший продукт, живые клиенты, нормальный процесс разработки. Мы использовали GitHub, feature-ветки, pull requests, code review — всё как у взрослых. Репозиторий был защищён: ветка main заблокирована от прямых пушей, обязательный PR с одобрением от двух ревьюеров. Всё серьёзно. Но была одна маленькая деталь, которую мы упустили: ветка develop — наша основная рабочая ветка, куда мерджились все фичи перед выходом в main — была защищена только от обычного push. Не от push --force. Это упущение жило полтора года. До того утра. Антон — старший разработчик, умный, опытный, пять лет в команде — в среду утром пришёл на работу в слегка раздражённом состоянии. Накануне вечером работал из дома, что-то переделывал в своей feature-ветке, несколько раз rebase'ил на свежий develop, история коммитов запуталась. Он хотел сделать красиво — squash коммиты, причесать историю, залить обратно. Он сделал git rebase -i HEAD~15. Причесал. Сделал git push origin feature/my-branch. Получил ошибку — ветка расходилась с remote из-за rebase. Это нормально. Написал git push --force origin feature/my-branch. И тут автодополнение в его терминале сыграло злую шутку. Он не заметил. Нажал Enter. Терминал отработал молниеносно. git push --force origin develop Ветка develop теперь содержала только его пятнадцать причёсанных коммитов. Полгода работы двенадцати разработчиков — восемьсот с лишним коммитов, десятки смёрджённых feature-веток — перестали существовать в remote. Первым заметил Кирилл — он в это время делал git pull origin develop и увидел странное сообщение о том, что его локальная ветка «впереди» remote на 847 коммитов. Написал в слак: «ребят, что-то странное с develop». Я в это время пил кофе. Зашёл в GitHub. Посмотрел на историю develop. Увидел пятнадцать коммитов за подписью Антона. Поставил кружку. Написал в общий чат: «стоп, никто не делайте git pull и не трогайте develop». Антон в этот момент только что дошёл до своего рабочего места — потому что через тридцать секунд в чате появилось его сообщение: «ребята, кажется, я что-то сломал». Восстановление заняло примерно двадцать минут и было почти триумфальным. Git — распределённая система. Это означает, что у каждого разработчика в локальном репозитории была актуальная копия develop на момент последнего git fetch. У Кирилла — который как раз делал git pull в момент инцидента — локальная ветка содержала все 847 коммитов. # На машине Кирилла: git log origin/develop..develop --oneline | wc -l # 847 # Пришлось временно снять все защиты с ветки в GitHub # и залить обратно правильную историю git push --force origin develop Через двадцать минут develop снова содержал все 847 коммитов. Все локальные репозитории сделали git fetch. Ничего не потерялось. Антон написал мне в личку: «Максим, я понимаю что случилось. Хочу объяснить». Мы созвонились. Он рассказал про автодополнение, про то, как перепутал ветки. Голос у него был как у человека, который ещё не понял, уволен он или нет. Я сказал ему три вещи. Первое: никто ничего не потерял, всё восстановлено, все живы. Второе: это системная ошибка, не личная — защита ветки была настроена неправильно, и это моя ответственность как DevOps. Третье: мы немедленно это исправим. В тот же день мы включили защиту от force push на develop. Добавили в onboarding раздел «Никогда не используй git push --force без явного указания feature-ветки». Везде заменили --force на --force-with-lease — он проверяет что remote не изменился с момента вашего последнего fetch, и отказывает если кто-то уже запушил. Антон остался в команде. Ещё через полгода стал тимлидом. Самый важный вывод из этой истории не технический. Технический прост: защищайте все ветки от force push, используйте --force-with-lease, настройте алиасы. Важный вывод другой: реакция команды на инцидент определяет культуру команды. Можно было устроить показательную порку. Вместо этого мы исправили систему — и получили разработчика, который с тех пор параноидально аккуратен с git и научил этому ещё троих новых. Ошибки надо исправлять в системе. Не в людях. А git push --force без явного указания ветки — это как ходить с заряженным пистолетом без предохранителя. Рано или поздно что-то нажмётся не то.
-
Rate limiting заблокировал наш нагрузочный тест, приняв его за DDoS-атаку
Эта история не о катастрофе — она о тех моментах, когда система работает именно так, как ты настроил, но совсем не так, как ты хотел. Мы запускали новый высоконагруженный сервис — рекомендательный движок. Перед запуском нужно было провести нагрузочный тест: убедиться что сервис держит планируемые 500 rps. Я накануне настроил nginx с rate limiting: 100 rps с одного IP, burst 200. Это защита от DDoS. Всё правильно, всё продуманно. На следующий день Вася из QA запустил нагрузочный тест с помощью k6 с офисного сервера. Офисный сервер имеет один внешний IP-адрес. Тест начался. Вася смотрел на метрики k6 — ошибки сыпались сразу: 503 Service Unavailable. Он написал мне: «Максим, сервис не выдерживает нагрузку, уже при 150 rps всё падает». Я зашёл в логи nginx. Увидел километры строк: [error] limiting requests, excess: 102.840 by zone "api_limit" Наш офисный сервер, с которого шёл тест, получил rate limit — и все 500 запросов в секунду, начиная со 101-го получали 503. Сервис при этом работал абсолютно нормально — его никто по-настоящему не нагружал. Я минуту просто смотрел в экран. Потом засмеялся — впервые за долгое время по-настоящему засмеялся в рабочее время. Мы добавили IP офисного нагрузочного сервера в whitelist. Провели нормальный тест. Сервис держал 800 rps без проблем. Все были довольны. Но главный урок этой истории не технический. Главный урок — это то, что перед тем как диагностировать проблему, надо убедиться что смотришь в нужное место. Вася видел ошибки и думал что сервис не справляется. Я видел ошибки и знал что это rate limit. Разница — в том, что смотрели на разные части системы. Коммуникация между QA и DevOps о том, с каких IP будет идти нагрузочный тест — теперь обязательный пункт в чеклисте перед любым нагрузочным тестированием. На ithub.uno есть хорошая статья про то, как правильно организовать этот процесс — рекомендую.
-
Дев написал «TODO: убрать перед прод-деплоем» — и это пролежало в проде два года
Есть комментарии в коде, которые являются либо руководством к действию, либо тихим криком о помощи. Комментарии с «TODO» — это обещания, которые редко выполняются. Денис, бэкенд-разработчик с которым я пересекался на одном проекте, рассказал мне эту историю как предупреждение. История произошла на его предыдущем месте работы. Был endpoint /api/debug/users — он возвращал список всех пользователей с email, именами и датами регистрации. Без всякой авторизации. Создан во время разработки, чтобы фронтенд-разработчик мог быстро проверять данные. В коде стоял комментарий: # TODO: УБРАТЬ ПЕРЕД ДЕПЛОЕМ В ПРОД!!! # Только для разработки, не для продакшна @app.route('/api/debug/users') def debug_users(): users = User.query.all() return jsonify([u.to_dict() for u in users]) Три восклицательных знака. Заглавные буквы. Всё честно. Разработчик сделал деплой. TODO не убрал — дедлайн, «потом». Потом не наступило. Endpoint жил в проде тихо и незаметно два года. Через два года при проведении security audit penetration tester обнаружил его за тридцать секунд работы с Burp Suite. База данных на тот момент содержала информацию о 340,000 пользователей. Всё это время данные были доступны любому, кто знал URL. Конца истории Денис не знает — его к тому времени уже не было в той компании. Знает только что был большой скандал и несколько уволенных. В нашей команде после этой истории появился CI-шаг: grep по всему коду на паттерны TODO.*прод, TODO.*prod, REMOVE BEFORE, DEBUG ONLY. Если находит — пайплайн падает с ошибкой. Работает без единого ложного срабатывания уже полтора года.
-
Скрипт бэкапа работал идеально. Кроме одной детали: он ничего не бэкапил
Самый коварный вид отказа систем — когда всё выглядит как работает, но не работает. Бэкап-система в этом смысле особенно опасна: вы никогда не проверяете её по-настоящему, пока не нужно восстановиться. Мой коллега Паша — педантичный и аккуратный инженер — настраивал резервное копирование для CRM-системы. Написал скрипт на bash: каждую ночь mysqldump, gzip, upload на S3. Всё логируется. При успехе в Slack приходит уведомление «Backup completed: 2.3GB». Скрипт работал восемь месяцев. Каждую ночь в Slack приходило: «Backup completed: 2.3GB». Красиво. Надёжно. Профессионально. Потом упал продакшн-сервер. Физически — сгорел диск. Паша пошёл восстанавливаться из бэкапа. Достал последний архив с S3. Распаковал. Открыл. Внутри был SQL-дамп базы данных information_schema. Не crm_production. А information_schema — системная база MySQL с метаданными: список таблиц, колонок, индексов. Никаких реальных данных. Паша открыл скрипт. Нашёл строку: mysqldump -u backup -p$PASS $DATABASE | gzip > backup.sql.gz Переменная $DATABASE. Посмотрел где она определяется: DATABASE=${DB_NAME:-information_schema} Переменная DB_NAME должна была передаваться через environment. Но при настройке cron-job он забыл добавить эту переменную. Cron запускал скрипт без переменной — скрипт использовал дефолтное значение information_schema — дамп создавался, весил 2.3GB (много метаданных за восемь месяцев), улетал на S3. Полное видимое благополучие. Восемь месяцев данных CRM были потеряны безвозвратно. После этого у нас появилось правило: бэкап-скрипт обязан проверять содержимое архива после создания. Не просто «файл существует» — а «внутри есть CREATE TABLE для нужных таблиц, INSERT строк больше нуля». И раз в месяц — тестовое восстановление в отдельную базу с проверкой количества записей. Если вы сейчас читаете это и у вас есть бэкап-система, которую вы ни разу не проверяли восстановлением — сделайте это сегодня. Не завтра. Сегодня.
-
Я удалил продакшн-неймспейс в Kubernetes, нажав не ту кнопку. Даунтайм — 7 минут 20 секунд
Это история о том, почему production дашборды должны быть красного цвета, а staging — зелёного. И почему вкладки браузера надо называть. Пятница. Последний рабочий день перед длинными майскими. Я чистил старый staging кластер Kubernetes — там скопился мусор за несколько месяцев. Namespace за namespace, удаляю deployment'ы, PVC, сервисы. Всё идёт хорошо. В соседней вкладке открыт продакшн дашборд — краем глаза поглядываю на метрики. Не помню точно как это случилось — кажется, я переключился между вкладками не обратив внимания. Увидел список namespace в дашборде. Увидел namespace с именем legacy-services — его я и собирался удалить в staging. Нажал Delete. Подтвердил (да, там был confirm dialog — и я его подтвердил, потому что только что двадцать раз делал то же самое). Через тридцать секунд в слаке началось: #alerts: CRITICAL: payment-service down #alerts: CRITICAL: auth-service down #alerts: CRITICAL: user-service down Я перевёл взгляд на адресную строку. Там был URL продакшн кластера. legacy-services в продакшне — это было название, которое выбрал кто-то три года назад. В нём жило восемь критических сервисов. Дальше начался самый быстрый деплой в моей карьере. ArgoCD хранил все манифесты, кластер был жив — я удалил только namespace с содержимым, но не сам кластер. Запустил sync для всех приложений через ArgoCD. Kubernetes начал поднимать поды. Stateless сервисы встали за две-три минуты. Payment-service — за пять, потому что у него была initContainer-миграция. Auth-service — за четыре. Общее время даунтайма: семь минут двадцать секунд. Что изменилось: все дашборды теперь имеют цветовую маркировку — продакшн красным, staging жёлтым, dev зелёным. Это реализовано через плагин kubie — при переключении в prod-контекст терминал меняет цвет prompt на красный. И главное — удаление namespace теперь требует ввода имени namespace вручную. Никаких кнопок «Delete» без явного подтверждения текстом.
-
Три дня я искал баг в коде — оказалось, сервер жил в другом часовом поясе
Есть баги, которые тихо портят данные и обнаруживаются через месяцы. А есть такие, которые существуют годами, всех раздражают, но никто не может их воспроизвести — потому что они зависят от часового пояса. Та система занималась планированием задач. Пользователь создаёт задачу на «завтра в 10:00» — система её выполняет в нужное время. Казалось бы, простейшая логика. Жалобы начались в марте. Клиенты из Екатеринбурга писали: «задачи выполняются не вовремя, иногда с опозданием на два часа». Я смотрел на логи — по нашим данным задачи выполнялись точно в срок. Поддержка закрывала тикеты: «не воспроизводится». Клиенты злились. Я взялся за это в начале апреля. Провёл два дня, читая код планировщика. Нашёл несколько мест где работа с временем выглядела подозрительно, отрефакторил — баг остался. Третий день — ревью всех datetime операций в системе. Ничего. На четвёртый день Игорь из поддержки сказал фразу, которая сразу всё объяснила: — Слушай, я заметил, что жалуются только пользователи из Екатеринбурга, Омска и вот этих городов... Он показал список. Я посмотрел на карту. Это были города в часовых поясах UTC+5 и восточнее. Зашёл на продакшн-сервер. Ввёл date. Увидел: Thu Apr 4 14:23:11 UTC 2024. Сервер работал в UTC. Это нормально. Проблема была в другом: когда пользователь из Екатеринбурга (UTC+5) создавал задачу на «завтра 10:00» через браузер, фронтенд отправлял строку 2024-04-05 10:00:00 — без timezone offset. Backend принимал её как UTC и сохранял в базу. Потом выполнял задачу в 10:00 UTC — что для пользователя в UTC+5 было 15:00 по местному времени. Пять часов разницы. Это проявилось только когда начали приходить пользователи из регионов — потому что первые клиенты и команда разработки были из Москвы (UTC+3), и у них разница была три часа, а не пять. Фикс: фронтенд теперь всегда отправляет datetime с timezone offset. Backend парсит только aware datetime объекты. На Хабре есть статья «Никогда не используйте naive datetime» — я её знал. Просто не я писал тот фрагмент. Теперь у нас есть линтер-правило, которое не даёт мержить код с naive datetime объектами.