Rabbitmq 在docker容器中使用lisp向rabbit mq发送消息

Rabbitmq 在docker容器中使用lisp向rabbit mq发送消息,rabbitmq,common-lisp,amqp,sbcl,docker-compose,Rabbitmq,Common Lisp,Amqp,Sbcl,Docker Compose,我试图使用cl rabbit从Docker容器中运行的lisp进程与RabbitMQ代理通信。我的代码在docker容器外运行时可以工作,因此问题要么与操作系统有关,要么与docker有关。(它在容器外部的Mac OS X上运行,但在容器内部的Ubuntu 14.04上运行。) 当我用docker compose up运行系统时,我看到message broker已成功启动的输出。lisp客户端提供以下输出: sbcl-rabbit_1 | This is SBCL 1.2.15, an imp

我试图使用cl rabbit从Docker容器中运行的lisp进程与RabbitMQ代理通信。我的代码在docker容器外运行时可以工作,因此问题要么与操作系统有关,要么与docker有关。(它在容器外部的Mac OS X上运行,但在容器内部的Ubuntu 14.04上运行。)

当我用docker compose up运行系统时,我看到message broker已成功启动的输出。lisp客户端提供以下输出:

sbcl-rabbit_1 | This is SBCL 1.2.15, an implementation of ANSI Common Lisp.
sbcl-rabbit_1 | More information about SBCL is available at <http://www.sbcl.org/>.
sbcl-rabbit_1 |
sbcl-rabbit_1 | SBCL is free software, provided as is, with absolutely no warranty.
sbcl-rabbit_1 | It is mostly in the public domain; some portions are provided under
sbcl-rabbit_1 | BSD-style licenses.  See the CREDITS and COPYING files in the
sbcl-rabbit_1 | distribution for more information.
sbcl-rabbit_1 | Created connection #<CL-RABBIT::CONNECTION {10047054F3}>
sbcl-rabbit_1 | Created socket #.(SB-SYS:INT-SAP #X00651650)
sbcl-rabbit_1 | Opened socket #.(SB-SYS:INT-SAP #X00651650)
sbcl-rabbit_1 | CORRUPTION WARNING in SBCL pid 10(tid 140737354065728):
sbcl-rabbit_1 | Memory fault at 0x7ffff266ce10 (pc=0x7ffff2c957c2, sp=0x7ffff309f3d0)
sbcl-rabbit_1 | The integrity of this image is possibly compromised.
sbcl-rabbit_1 | Continuing with fingers crossed.
sbcl-rabbit_1 | Unhandled SB-SYS:MEMORY-FAULT-ERROR in thread #<SB-THREAD:THREAD
sbcl-rabbit_1 |                                                 "main thread" RUNNING
sbcl-rabbit_1 |                                                  {1003FAF093}>:
sbcl-rabbit_1 |   Unhandled memory fault at #x7FFFF266CE10.
sbcl-rabbit_1 |
sbcl-rabbit_1 | Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1003FAF093}>
sbcl-rabbit_1 | 0: ((LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX))
sbcl-rabbit_1 | 1: (SB-IMPL::CALL-WITH-SANE-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX) {10047B016B}>)
sbcl-rabbit_1 | 2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX) {10047B013B}>)
sbcl-rabbit_1 | 3: (PRINT-BACKTRACE :STREAM #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDERR* {1000164243}> :START 0 :FROM :INTERRUPTED-FRAME :COUNT NIL :PRINT-THREAD T :PRINT-FRAME-SOURCE NIL :METHOD-FRAME-STYLE NIL)
sbcl-rabbit_1 | 4: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SB-SYS:MEMORY-FAULT-ERROR {10047ACE93}> #<unavailable argument>)
sbcl-rabbit_1 | 5: (SB-DEBUG::RUN-HOOK *INVOKE-DEBUGGER-HOOK* #<SB-SYS:MEMORY-FAULT-ERROR {10047ACE93}>)
sbcl-rabbit_1 | 6: (INVOKE-DEBUGGER #<SB-SYS:MEMORY-FAULT-ERROR {10047ACE93}>)
sbcl-rabbit_1 | 7: (ERROR SB-SYS:MEMORY-FAULT-ERROR :ADDRESS 140737260211728)
sbcl-rabbit_1 | 8: (SB-SYS:MEMORY-FAULT-ERROR)
sbcl-rabbit_1 | 9: ("foreign function: call_into_lisp")
sbcl-rabbit_1 | 10: ("foreign function: post_signal_tramp")
sbcl-rabbit_1 | 11: (CFFI::PREPARE-FUNCTION "amqp_login_with_properties" (:STRUCT CL-RABBIT::AMQP-RPC-REPLY-T) (:POINTER :POINTER :INT :INT :INT :POINTER :INT :POINTER :POINTER) :DEFAULT-ABI)
sbcl-rabbit_1 | 12: (CL-RABBIT::AMQP-LOGIN-SASL-PLAIN-WITH-PROPERTIES #.(SB-SYS:INT-SAP #X00641500) "/" 0 131072 0 #.(SB-SYS:INT-SAP #X7FFFF329FFE8) 0 "guest" "guest")
sbcl-rabbit_1 | 13: ((LABELS #:FN274 :IN CL-RABBIT:LOGIN-SASL-PLAIN) (CL-RABBIT::NUM-ENTRIES 2 CL-RABBIT::ENTRIES #.(SB-SYS:INT-SAP #X00651840)))
sbcl-rabbit_1 | 14: (CL-RABBIT::CALL-WITH-AMQP-TABLE #<CLOSURE (LABELS #:FN274 :IN CL-RABBIT:LOGIN-SASL-PLAIN) {100470785B}> (("product" . "cl-rabbit") ("version" . "0.1")))
sbcl-rabbit_1 | 15: (CL-RABBIT.EXAMPLES::TROY-TEST)
sbcl-rabbit_1 | 16: (SB-INT:SIMPLE-EVAL-IN-LEXENV (CL-RABBIT.EXAMPLES::TROY-TEST) #<NULL-LEXENV>)
sbcl-rabbit_1 | 17: (EVAL (CL-RABBIT.EXAMPLES::TROY-TEST))
sbcl-rabbit_1 | 18: (SB-IMPL::PROCESS-EVAL/LOAD-OPTIONS ((:LOAD . "examples.lisp") (:EVAL . "(sleep 3)") (:EVAL . "(cl-rabbit.examples::troy-test)") (:QUIT)))
sbcl-rabbit_1 | 19: (SB-IMPL::TOPLEVEL-INIT)
sbcl-rabbit_1 | 20: ((FLET #:WITHOUT-INTERRUPTS-BODY-83 :IN SAVE-LISP-AND-DIE))
sbcl-rabbit_1 | 21: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))
sbcl-rabbit_1 |
sbcl-rabbit_1 | unhandled condition in --disable-debugger mode, quitting
这是使用
docker build-f Dockerfile sbcl-t sbcl
构建的。然后,我有第二个docker文件,用cl rabbit构建一个图像

# SBCL with cl-rabbit installed
FROM sbcl

RUN apt-get update -y && apt-get install -y librabbitmq-dev

ENV SBCL_CORE_DIR=/sbcl


RUN mkdir -p $SBCL_CORE_DIR
RUN sbcl --eval '(ql:quickload :cl-rabbit)' \
         --eval '(sb-ext:save-lisp-and-die "/'${SBCL_CORE_DIR}'/sbcl-rabbit.core")'

RUN echo Saved core in $SBCL_CORE_DIR
RUN ls -l $SBCL_CORE_DIR

CMD sbcl --core $SBCL_CORE_DIR/sbcl-rabbit.core \
    --non-interactive                           \
    --load examples.lisp                        \
    --eval '(sleep 3)'                          \
    --eval '(cl-rabbit.examples::troy-test)'

#CMD ls -l
# EOF
这是使用带有此docker-compose.yml的
docker compose build
构建的

sbcl-rabbit:
  build: .
  dockerfile: Dockerfile-sbcl-rabbitmq
  volumes:
   - ../../path/to/lisp://app
  links:
   - msgbroker


msgbroker:
  image: rabbitmq
  ports:
   - "5672:5672"
当我使用
docker compose up
运行此命令时,我得到了上面描述的输出

Examples.lisp如下所示:

(require 'cl-rabbit)
(in-package :cl-rabbit.examples)

(defvar msgbroker "msgbroker")
;;(setq msgbroker "localhost")

(defun troy-test ()
  (with-connection (conn)
    (format t "Created connection ~s~%" conn)
    (let ((socket (tcp-socket-new conn))
          (channel 1))
      (format t "Created socket ~s~%" socket)
      (socket-open socket msgbroker 5672)
      (format t "Opened socket ~s~%" socket)
      (login-sasl-plain conn "/" "guest" "guest")
      (format t "logged in ~s~%" conn)
      (channel-open conn channel)
      (format t "Openned channel ~s~%" conn)
      (queue-declare conn channel
                     :queue "lisp-queue"
                     :durable t)
      (exchange-declare conn channel "lisp-exchange" "direct"
                        :durable t)
      (queue-bind conn channel
                  :queue "lisp-queue"
                  :routing-key "lisp-queue"
                  :exchange "lisp-exchange")
      (print "Bound queue")
      (basic-publish conn channel
                     :exchange "lisp-exchange"
                     :routing-key "lisp-queue"
                     :body "Message from lisp")
      (print "Pubished");
      (basic-consume conn channel "lisp-queue")
      (print "Received")
      (let* ((result (consume-message conn))
             (message (envelope/message result))
             (formatted (format t "Got message: ~s~%content: ~s~%props: ~s"
                                result (babel:octets-to-string (message/body message) :encoding :utf-8)
                                (message/properties message))))
        (prin1 formatted)
        (pprint formatted)
        (cl-rabbit:basic-ack conn channel (envelope/delivery-tag result))))))
根据print语句,问题发生在
login sasl plain

我使用
docker run rabbit_sbcl-rabbit bash
启动带有交互式shell的docker容器,并使用
telnet msgbroker 5672
验证主机msgbroker上的端口5672是否连接到兔子MQ服务器。如果我在telnet会话中键入文本,我会看到来自服务器的消息,表明已建立AMQP连接

当lisp客户端尝试连接时,我没有看到类似的消息

使用类似的配置,我使用Java客户端发送和接收消息,发送方和接收方位于一个Docker容器中,RabbitMQ服务器位于另一个容器中,正如我在这里尝试的那样


你知道哪里出了问题,或者对如何诊断出问题有进一步的建议吗?

嘿,如果你仍然有问题,试着用静态链接的librabbitmq和libffi构建sbcl


此外,您可能会发现我的项目很有帮助-

也许值得在普通的ubuntu虚拟机上尝试一下?也许你能想出一个流浪汉的例子,在那里试一试?如果您得到相同的错误,这可能会使调试更容易一些。如果不是,那么。。。你已经排除了完全无法在linux上运行它的可能,也许你会得到一些其他有用的东西。。。希望如此。注意guest:guest用户只能连接到localhost
(require 'cl-rabbit)
(in-package :cl-rabbit.examples)

(defvar msgbroker "msgbroker")
;;(setq msgbroker "localhost")

(defun troy-test ()
  (with-connection (conn)
    (format t "Created connection ~s~%" conn)
    (let ((socket (tcp-socket-new conn))
          (channel 1))
      (format t "Created socket ~s~%" socket)
      (socket-open socket msgbroker 5672)
      (format t "Opened socket ~s~%" socket)
      (login-sasl-plain conn "/" "guest" "guest")
      (format t "logged in ~s~%" conn)
      (channel-open conn channel)
      (format t "Openned channel ~s~%" conn)
      (queue-declare conn channel
                     :queue "lisp-queue"
                     :durable t)
      (exchange-declare conn channel "lisp-exchange" "direct"
                        :durable t)
      (queue-bind conn channel
                  :queue "lisp-queue"
                  :routing-key "lisp-queue"
                  :exchange "lisp-exchange")
      (print "Bound queue")
      (basic-publish conn channel
                     :exchange "lisp-exchange"
                     :routing-key "lisp-queue"
                     :body "Message from lisp")
      (print "Pubished");
      (basic-consume conn channel "lisp-queue")
      (print "Received")
      (let* ((result (consume-message conn))
             (message (envelope/message result))
             (formatted (format t "Got message: ~s~%content: ~s~%props: ~s"
                                result (babel:octets-to-string (message/body message) :encoding :utf-8)
                                (message/properties message))))
        (prin1 formatted)
        (pprint formatted)
        (cl-rabbit:basic-ack conn channel (envelope/delivery-tag result))))))