Мне нужно запустить сценарий по HTTP-запросу на получение с внешней машины, и я использую для этого Node.js. Я хочу, чтобы сервер запустился вместе с системой. Все работает, за исключением того, что кажется, что сервер запускается слишком рано в процессе загрузки:
-- Logs begin at Mon 2017-01-23 09:55:21 UTC, end at Mon 2017-01-23 10:36:20 UTC. --
Jan 23 09:55:24 powercontrol systemd[1]: Starting Energenie Listener...
Jan 23 09:55:24 powercontrol systemd[1]: Started Energenie Listener.
Jan 23 09:55:28 powercontrol node[474]: events.js:160
Jan 23 09:55:28 powercontrol node[474]: throw er; // Unhandled 'error' event
Jan 23 09:55:28 powercontrol node[474]: ^
Jan 23 09:55:28 powercontrol node[474]: Error: listen EADDRNOTAVAIL 192.168.40.62:8001
Jan 23 09:55:28 powercontrol node[474]: at Object.exports._errnoException (util.js:1022:11)
Jan 23 09:55:28 powercontrol node[474]: at exports._exceptionWithHostPort (util.js:1045:20)
Jan 23 09:55:28 powercontrol node[474]: at Server._listen2 (net.js:1249:19)
Jan 23 09:55:28 powercontrol node[474]: at listen (net.js:1298:10)
Jan 23 09:55:28 powercontrol node[474]: at doListening (net.js:1397:7)
Jan 23 09:55:28 powercontrol node[474]: at _combinedTickCallback (internal/process/next_tick.js:77:11)
Jan 23 09:55:28 powercontrol node[474]: at process._tickCallback (internal/process/next_tick.js:98:9)
Jan 23 09:55:28 powercontrol node[474]: at Module.runMain (module.js:607:11)
Jan 23 09:55:28 powercontrol node[474]: at run (bootstrap_node.js:420:7)
Jan 23 09:55:28 powercontrol node[474]: at startup (bootstrap_node.js:139:9)
Jan 23 09:55:28 powercontrol systemd[1]: energenie_listener.service: main process exited, code=exited, s
Jan 23 09:55:28 powercontrol systemd[1]: Unit energenie_listener.service entered failed state.
Jan 23 09:55:30 powercontrol systemd[1]: energenie_listener.service holdoff time over, scheduling restar
Jan 23 09:55:30 powercontrol systemd[1]: Stopping Energenie Listener...
Jan 23 09:55:30 powercontrol systemd[1]: Starting Energenie Listener...
Jan 23 09:55:30 powercontrol systemd[1]: Started Energenie Listener.
Jan 23 09:55:31 powercontrol node[565]: events.js:160
Jan 23 09:55:31 powercontrol node[565]: throw er; // Unhandled 'error' event
Jan 23 09:55:31 powercontrol node[565]: ^
Jan 23 09:55:31 powercontrol node[565]: Error: listen EADDRNOTAVAIL 192.168.40.62:8001
Jan 23 09:55:31 powercontrol node[565]: at Object.exports._errnoException (util.js:1022:11)
Jan 23 09:55:31 powercontrol node[565]: at exports._exceptionWithHostPort (util.js:1045:20)
Jan 23 09:55:31 powercontrol node[565]: at Server._listen2 (net.js:1249:19)
Jan 23 09:55:31 powercontrol node[565]: at listen (net.js:1298:10)
Jan 23 09:55:31 powercontrol node[565]: at doListening (net.js:1397:7)
Jan 23 09:55:31 powercontrol node[565]: at _combinedTickCallback (internal/process/next_tick.js:77:11)
Jan 23 09:55:31 powercontrol node[565]: at process._tickCallback (internal/process/next_tick.js:98:9)
Jan 23 09:55:31 powercontrol node[565]: at Module.runMain (module.js:607:11)
Jan 23 09:55:31 powercontrol node[565]: at run (bootstrap_node.js:420:7)
Jan 23 09:55:31 powercontrol node[565]: at startup (bootstrap_node.js:139:9)
Jan 23 09:55:31 powercontrol systemd[1]: energenie_listener.service: main process exited, code=exited, s
Jan 23 09:55:31 powercontrol systemd[1]: Unit energenie_listener.service entered failed state.
Jan 23 09:55:33 powercontrol systemd[1]: energenie_listener.service holdoff time over, scheduling restar
Jan 23 09:55:33 powercontrol systemd[1]: Stopping Energenie Listener...
Jan 23 09:55:33 powercontrol systemd[1]: Starting Energenie Listener...
Jan 23 09:55:33 powercontrol systemd[1]: Started Energenie Listener.
Jan 23 09:55:34 powercontrol node[572]: Server running at http://192.168.40.62:8001/
Как вы можете видеть, после пары сбоев сервер в конечном итоге запускается, и после этого он работает нормально. Файл .service
выглядит следующим образом:
[Unit]
Description=Energenie Listener
After=network.target systemd-journald.service
[Service]
ExecStart=/usr/bin/node /var/opt/energenie/energenie_listener.js
Restart=always
RestartSec=2
User=root
Group=root
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/opt/energenie
[Install]
WantedBy=multi-user.target
Помимо After = network.target ...
, я попробовал network-online.target
, но это не имеет значения.
Стоит ли мне ждать другой услуги? Какой?
У меня есть одна мысль: у этой машины статический IP-адрес, но он назначается через DHCP. Если проблема в том, что network.target
(и network-online.target
) работает, но IP I ' m, пытающийся заявить в сценарии узла, еще не назначен, по-видимому, мне нужна служба для ожидания, которая гарантирует, что IP-адрес полностью настроен. Может ли это быть проблемой, и если да, то есть ли подходящая служба, на которую можно положиться?
Я изменил IP-адрес, который сервер прослушивал, с определенного в журналах вопросов на подстановочный знак 0.0.0.0
. Похоже, это решило проблему (что наводит на мысль, что мои подозрения относительно того, что адрес DHCP не был назначен, возможно, были правильными).
Это не идеальное решение (потому что я все еще не знаю, как ждать DHCP -заданный адрес должен быть доступен), но поскольку это не имеет практического значения для данного конкретного случая, это решает непосредственную проблему регистрируемых ошибок.
Бул сокетке негизделген иш-аракеттер үчүн кызыктуу пайдалануу болушу мүмкүн. Кызматыңызды жүктөө убагында баштоонун ордуна, аны иштетүү үчүн тармактык суроо-талап биринчи жолу келгенде башталат. DHCP тармагынын дайындалышы аягына чейин бүтүшү керек!
Сиздин кызмат бирдигиңиздин файлында STDIN кайдан чыккандыгын жарыялоо үчүн [Service]
бөлүмүнө жазууну кошуп жатасыз:
StandardInput=socket
Андан кийин .socket
файлы менен бирдей аталыштагы файл .service
окшош көрүнөт:
[Unit]
Description=Energenie Listener Socket
[Socket]
# Depending your app, you might also use ListenStream=
# or ListenSequentialPacket= See man systemd.socket for details
ListenDatagram=192.168.40.62:8001
# Allow binding to addresses that may not be configured yet.
FreeBind=true
[Install]
WantedBy=sockets.target
Кайра жүктөөдөн мурун розеткада systemd enable
иштетилгениңизди текшериңиз.
Көбүрөөк контекст үчүн man systemd.socket
караңыз же [systemd розетканы активациялоо] жөнүндө билдирүүлөрдү издеңиз.