Clojure - как подключиться к запущенному процессу REPL удаленно
Как я могу подключиться к сеансу REPL, запущенному на удаленном сервере, к которому я могу получить доступ, например, через SSH?
6 ответов
Это может быть очевидно для сетевых специалистов, но мне потребовалось некоторое время, чтобы выяснить это, документируя это здесь.
На удаленном сервере, при запуске вашего приложения REPL, а не просто lein repl
принудительная привязка к порту:
lein repl :start :port 40000
На вашей машине подключитесь к удаленному серверу обычным способом (например, через ssh). Затем подключитесь к вашему приложению следующим образом:
lein repl :connect localhost:40000
Это оно!
Я просто хочу суммировать два ответа выше. Это работает на моей машине:
На удаленной машине
lein repl :start :port 40000
На локальной машине
# SSH tunnel on one shell
ssh -NL 40000:localhost:40000 username@host
# Connect to the remote repl on another shell
lein repl :connect localhost:40000
Ну, это просто. Вкратце, необходимо сделать несколько шагов:
nrepl
пакет должен быть частью производственной сборки, а не просто зависимостью от разработчика;- Когда ваше приложение запускается, оно также порождает сеанс repl в отдельном потоке на определенном порту;
- ваш сервер либо предоставляет этот порт, либо вы туннелируете его через SSH.
Теперь подробности:
1) Добавьте эти deps в основной :dependencies
вектор:
:dependencies [[org.clojure/clojure "1.9.0"]
;; for remote debugging
[cider/cider-nrepl "0.17.0"]
[org.clojure/tools.nrepl "0.2.13"]
Тебе нужно cider-nrepl
если вы работаете с Emacs/Cider. В противном случае вы можете пропустить это.
2) Добавьте отдельное пространство имен для сервера nrepl
(ns project.nrepl
(:require [clojure.tools.nrepl.server
:refer (start-server stop-server)]))
(defn nrepl-handler []
(require 'cider.nrepl)
(ns-resolve 'cider.nrepl 'cider-nrepl-handler))
(defonce __server (atom nil))
(def set-server! (partial reset! __server))
(def port 7888)
(defn start
[]
(when-not @__server
(set-server!
(start-server :port port :handler (nrepl-handler)))))
(defn stop
[]
(when-let [server @__server]
(stop-server server)
(set-server! nil)))
(defn init
[]
(start))
В вашем основном модуле просто позвоните (project.nrepl/init)
, Теперь ваше приложение позволяет подключаться к нему через nrepl.
3) На удаленном сервере вы можете открыть порт TCP 7888 для внешнего мира, который небезопасен. По крайней мере, порт должен быть ограничен определенными IP-адресами, например, вашим офисом. Лучшим вариантом было бы переслать его через SSH следующим образом:
ssh -L 7888:<remote-host>:7888 <user>@<remote-host>
Теперь откройте Emacs, позвоните M-x cider-connect RET localhost 7888
и все готово: вы подключены к удаленному приложению.
Кстати, вы можете легко подключиться из одного приложения REPL/ Clojure к другому REPL (например, для сравнения результатов eval между dev и UAT), как это
=> (require '[clojure.tools.nrepl :as repl])
nil
=> (with-open [conn (repl/connect :port 59258)]
(-> (repl/client conn 1000) ; message receive timeout required
(repl/message {:op "eval" :code "(+ 2 3)"})
repl/response-values))
[5]
подробнее здесь https://nrepl.xyz/nrepl/usage/clients.html
Безопасный способ подключения к удаленному clojure repl
- запустить repl на локальном хосте на удаленной машине
$ clj "-J-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"
- создать туннель ssh на локальной машине
$ ssh -L :5555:localhost:5555 remoteuser@remotehost -p 22 -N -v
- запустите repl на локальной машине и подключитесь к удаленному repl через ssh:
$ clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}'
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.pom from clojars <br>
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.jar from clojars <br>Clojure 1.10.1 <br>
(require '[vlaaad.remote-repl :as rr])<br>
user=> (rr/repl :port 5555)
- или запустите реплику на локальной машине и сразу же зайдите на удаленную реплику
clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}' -m vlaaad.remote-repl :port 5555
Возможно ssh tunnel (если repl запущен на удаленном хосте как localhost:6666)
на локальной машине ssh -L:6666:localhost:6666 remoteuser@remotehost -N -v
затем просто подключитесь к localhost: 6666