ImageMagick Go API HTTP挂起在ReadImageBlob

时间:2016-09-22 16:24:18

标签: go docker imagemagick hang beego

我编写了一个Beego HTTP服务器,当用户点击端点时:

  • 服务器从另一台服务器请求图像(例如imgur)
  • 它读取图像的字节并将它们传递给gographics/imagick
  • 这个(应该)调整图像大小并返回结果的字节数组

实际发生的事情是我的HTTP服务器完全挂起,我甚至没有进行错误处理,而且我在服务器的所有端点上都有一个502坏网关。

我的代码如下所示:

func processContactImage(idx int, image []byte) ([]byte, error) {
    imagick.Initialize()
    defer imagick.Terminate()
    log.Println("idx: ", idx)
    mw := imagick.NewMagickWand()

    log.Println("reading image blob: ", image)
    err := mw.ReadImageBlob(image)
    if err != nil {
        log.Println("reading blob failed: ", err)
        return []byte{}, err
    }
//...
}

我可以在终端中看到日志消息“读取图像blob:[bytes,bytes bytes]”并且我已经将打印的字节复制到另一个小程序来测试字节确实持有图像,他们这样做。 它完全挂在err := mw.ReadImageBlob(image)上,我认为它甚至不会进入if err != nil,因为我从未看到该日志消息。

我应该如何调试这个提示。我已经编写了一个小程序来测试图像magick funtions在独立环境中对字节数组的工作,一切正常。

我的想法:

  • 我不完全理解Go如何处理堆栈/堆,我认为如果有必要,它可以将内容移动到堆中,我不需要管理它。但是我将图像存储在内存中,我想也许seg fault但我不确定为什么它不会崩溃而是挂起......
  • ReadImageBlob期待一种图像数据,而它没有得到它,虽然我当时认为它有错误

修改

好的感谢您的评论,经过更多研究后,似乎与我在Docker中运行此事实有关,但是并没有发现这可能是一个问题:

  1. 我已将imagemagick的初始化移至main,但错误仍然存​​在
  2. 当我运行没有docker的应用程序时,我将一个字节数组传递给处理程序,imagemagick代码运行正常。
  3. 当我附加到docker容器时,添加一个小的测试程序,使用imagemagick(但不是Web服务,只是一个二进制文件)为图像添加一个圆圈,它可以工作,虽然很慢
  4. 我的dockerfile如下所示:

    FROM golang:1.7-alpine
    
    RUN apk update && apk add git && apk add g++ && apk add bzr && \
        rm -rf /var/cache/apk/*
    
    # ENV GOPATH /go
    
    # Install beego & bee
    RUN go get github.com/astaxie/beego
    RUN go get github.com/beego/bee
    RUN go get github.com/tools/godep
    
    RUN apk add --update alpine-sdk
    RUN apk add imagemagick-dev
    RUN go get gopkg.in/gographics/imagick.v2/imagick
    

    我想知道我是否错过了一个图书馆或其他东西,它挂在C api和Go等待回应。有什么办法可以调试吗?

    好的......事实证明这个问题是另一回事......也许是一次又多次请求......我不确定,但我创建了这个gist使用imagemagick进行演示, Go,在一个处理程序中,它在我的docker容器中本地工作没问题。神秘感继续......

2 个答案:

答案 0 :(得分:2)

不要在你的处理程序中执行此操作:

<?php

$sql="SELECT e.es_id, e.es_sex, e.service_type, 
             e.working_name,  t.es_tou_id, t.es_id, 
             t.es_touring_city, t.es_touring_start_date, 
             t.es_touring_end_date, i.image
      FROM escorts AS e 
      INNER JOIN escorts_touring AS t ON e.es_id = t.es_id
      INNER JOIN (SELECT es_id, MAX(image) AS image
                  FROM escorts_image
                  GROUP BY es_id) AS i ON e.id = i.es_id
      ORDER BY e.es_id";
$result = mysql_query($sql);
$last_esid = null;
$counter = 0;

$dest = "uploads";

while ($row = mysql_fetch_assoc($result)) {
    $es_id=$row['es_id'];
    if ($counter++ == 4 || $es_id != $last_esid) {
        if ($last_esid) {
            echo "</div>";
        }
        echo "<div class='row'></div>";
        $last_esid = $es_id;
        $counter = 0;
    }

    $es_sex  =$row['es_sex'];
    $service_type=$row['service_type'];
    $working_name=$row['working_name'];
    $es_tou_id = $row['es_tou_id'];
    $es_touring_city = $row['es_touring_city'];
    $es_touring_start_date = $row['es_touring_start_date'];
    $es_touring_end_date =$row['es_touring_end_date'];
    $image = $row['image'];

    $newstartDate = date("dS F, Y", strtotime($es_touring_start_date));
    $newendDate = date("dS F, Y", strtotime($es_touring_end_date));

    // print the row
}

这应该只在你的imagick.Initialize() defer imagick.Terminate()

中完成一次

每次请求完成时,通过拆除整个ImageMagick,您很可能会遇到不同请求的冲突。

答案 1 :(得分:0)

好的@jdi与阿尔卑斯山有关...

下面是我的两个docker文件,第一个,Alpine @ 612MB不起作用,它在imagemagick尝试读取blob时挂起。第二个与golang:最新和931MB的作品。我不确定原因,但确实解决了我的问题。

谢谢,我希望这有助于其他人!

FROM golang:1.7-alpine

RUN apk update && apk add git && apk add g++ && apk add bzr && \
    rm -rf /var/cache/apk/*

RUN go get github.com/astaxie/beego
RUN go get github.com/beego/bee
RUN go get github.com/tools/godep

RUN apk add --update alpine-sdk
RUN apk add imagemagick-dev
RUN go get gopkg.in/gographics/imagick.v2/imagick

和第二个:

FROM golang:latest

RUN apt-get update && \
    apt-get install -qy \
        pkg-config \
        libmagickcore-dev \
        libmagickwand-dev \
        imagemagick \
        git \
        g++ \
        bzr \

    #clear up
    && apt-get autoremove && \
    apt-get autoclean && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

RUN go get gopkg.in/gographics/imagick.v2/imagick
RUN go get github.com/astaxie/beego
RUN go get github.com/beego/bee
RUN go get github.com/tools/godep