0

jQuery Dropzone プラグインと paperclip gem を使用してビデオをアップロードできる Rails 4 アプリケーションがあります。アップロードされた各動画は複数の形式にエンコードされ、delayed_pa​​perclip、av-transcoder、sidekiq gem を使用してバックグラウンドで Amazon S3 にアップロードされます。

すべてがほとんどのビデオで正常に動作しますが、アップロードがドロップゾーン プラグインのプログレス バーの終わりのように見える値に達した後、1.1GB のようなより大きなサイズでは、Nginx 504 ゲートウェイ タイムアウトが返されます。

サーバーに関する限り、Rails アプリは、ロード バランサーの背後にある 2 台のサーバー上の Nginx + Passenger で実行されます (ここでも Nginx が使用されます)。ロード バランサーのアップストリーム セクションにタイムアウトを設定していません。client_max_body_size(ロード バランサーとサーバーの両方で) 2000M に設定されていますpassenger_pool_idle_time。大きな値 (600) に設定しようとしましたが、役に立ちませんでした。設定(600秒)も試しましたがsend_timeout、何も違いはありませんでした。

注: これらの変更を行うときは、両方のサーバーとロード バランサーのホスト ファイルで変更を行い、その後常に nginx を再起動しました。

this onethis oneのような同様の問題に関するいくつかの回答も読みましたが、まだこれを理解できません。Googleもそれほど役に立ちませんでした。

paperclip/delayed_pa​​perclip プロセス全体に不慣れな人向けの追加の注意事項。ファイルがサーバーにアップロードされ、ユーザーに関する限り、操作はバックグラウンドでビデオの後処理 (エンコード/S3 へのアップロード) で行われます。 ) はジョブとして Redis にプッシュされ、Sidekiq は時間/リソースがあるときはいつでもそれを処理します。

この問題の原因は何ですか? これをデバッグして解決するにはどうすればよいですか?

アップデート

Sergey's answer のおかげで、問題を解決できました。私は Paperclip の特定のバージョンに制限されていたため、修正された最新バージョンに更新できませんでした。

アップロードを処理するために使用するエンジンでは、engine_name.rbファイルに次のコードを追加して、修正が必要な Paperclip のメソッドをオーバーライドしました。

  Paperclip::AbstractAdapter.class_eval do
    def copy_to_tempfile(src)
      link_or_copy_file(src.path, destination.path)
      destination
    end

    def link_or_copy_file(src, dest)
      Paperclip.log("Trying to link #{src} to #{dest}")
      FileUtils.ln(src, dest, force: true) # overwrite existing
      @destination.close
      @destination.open.binmode
    rescue Errno::EXDEV, Errno::EPERM, Errno::ENOENT => e
      Paperclip.log("Link failed with #{e.message}; copying link #{src} to #{dest}")
      FileUtils.cp(src, dest)
    end
  end

  Paperclip::AttachmentAdapter.class_eval do
    def copy_to_tempfile(source)
      if source.staged?
        link_or_copy_file(source.staged_path(@style), destination.path)
      else
        source.copy_to_local_file(@style, destination.path)
      end
      destination
    end
  end

  Paperclip::Storage::Filesystem.class_eval do
    def flush_writes #:nodoc:
      @queued_for_write.each do |style_name, file|
        FileUtils.mkdir_p(File.dirname(path(style_name)))
        begin
          move_file(file.path, path(style_name))
        rescue SystemCallError
          File.open(path(style_name), "wb") do |new_file|
            while chunk = file.read(16 * 1024)
              new_file.write(chunk)
            end
          end
        end
        unless @options[:override_file_permissions] == false
          resolved_chmod = (@options[:override_file_permissions] &~ 0111) || (0666 &~ File.umask)
          FileUtils.chmod( resolved_chmod, path(style_name) )
        end
        file.rewind
      end

      after_flush_writes # allows attachment to clean up temp files

      @queued_for_write = {}
    end

    private

    def move_file(src, dest)
      # Support hardlinked files
      if File.identical?(src, dest)
        File.unlink(src)
      else
        FileUtils.mv(src, dest)
      end
    end

  end
4

1 に答える 1