2

ユーザーが Amazon S3 に画像をアップロードするためにトリガーできる自動ルーチンがあります。通常、ユーザーは 500 を超えるアイテムをアップロードするので、プロセスがタイムアウトしないようにする方法を見つけるのに苦労しています。

今、私はこれをやっています:

<form action="hs_import.cfm?ansicht=Bilder&RequestTimeout=5000" method="post" name="uploader">
...
    <input type="button" OnClick="bilder_upload()" value="#tx_gen_run#">
    <input type="hidden" name="artikel_uploaden" value="ja">
    <input type="hidden" name="ansicht" value="imageloader">
</form>

私のアップロードをトリガーするjavascript関数をトリガーします(詳細はありません):

<cfif isdefined("artikel_uploaden")>
<cfscript>
        S3 variables
</cfscript>

    <!--- get img paths to upload --->
    <cfquery datasource="db" name="img_paths">
    SELECT DISTINCT imgpath
</cfquery>

    <cfif img_paths.recordcount GT 0>
        <cfloop query="img_paths">
            <cfif img_paths.typ NEQ "img">
                <cfset variables.testFilePath = img_paths.bildpfad & img_paths.bilddateiname>
                <cfset variables.fileExt = ListLast(variables.testFilePath, ".")>


                <!--- get image --->
                <cfhttp timeout="45" 
                    throwonerror="no" 
                    url="#variables.testFilePath#" 
                    method="get" 
                    useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12" 
                    getasbinary="yes" 
                    result="variables.objGet">

                <!--- validate --->
                <!--- upload 4 sizes (s,m,l,xl) to S3 --->          
                <cftry>
                    <cfset objImage = ImageNew(variables.objGet.FileContent )>
                    <cfimage source="#objImage#" action="write" quality=".99" destination="#variables.tempDirectory#_base_#img_paths.bilddateiname#" overwrite="yes">
                    <cfset variables.basePath = variables.tempDirectory & "_base_" & img_paths.bilddateiname>
                    <cfimage action="read" source="#variables.basePath#" name="base">
                    <cfset variables.imageSrc = variables.tempDirectory>
                    <cfscript>
                        if ( ImageGetWidth( base ) LT ImageGetHeight( base ) ) {
                        // portrait                                     
                        } else {
                        // landscape/square

                        }
                        // cleanup
                    </cfscript>

                    <!--- create IMG entry in media table  --->
                    <cfquery datasource="db"></cfquery>
                </cfif>
            <cfcatch>
                <cfset variables.errorCount = variables.errorCount+1>
                <cfset variables.failedLoads = variables.failedLoads & img_paths.bilddateiname & "  (" & tx_pop_error & ":" & tx_errors_import_ext & "), ">
            </cfcatch>
        </cftry>
    </cfif>
  </cfloop>
  <!--- alert on success and errors --->
</cfif>

これは問題なく機能しますが、画像の数が多すぎるとブラウザがハングアップ/タイムアウトするため、通常、ロード画面が終了せず、成功/エラーを警告しません。

質問:
このような大きなファイルのアップロードを処理するより良い代替手段は何ですか? cfscheduleたとえば、バックグラウンドで実行できるように、これを に入れる必要がありますか?

ヒントをありがとう!

4

3 に答える 3

2

1 回のリクエストで非常に多くのことを実行しようとしています。1 つまたは 5 つの画像ではタイムアウトが発生しない可能性がありますが、数百のメッセージでは確実にタイムアウトが発生します。上記で提供したコードから、単一のリクエストで次のことを行っています。

  1. [n]枚の画像をアップロード
  2. 各画像を取得するための http リクエストを作成します
  3. 各画像のサイズを変更します (おそらく 4 つの異なるサイズに、サンプルから完全には明らかではありません)
  4. 各画像の各操作バージョンを S3 にアップロードする

特に、cfhttp と、より具体的には cfimage の両方がこの言語で最速のタグではないことを考えると、これは大変な作業です。cfimage による画像操作は非常に遅くなる可能性があります。

あなたが提案したことを行う方がおそらくはるかに良いでしょう: 元の顧客の要求を待つ必要がないように、これらのタスクを分割し、バックエンドでできるだけ多くの処理を行う. 最初の画像のアップロードを行ってから、顧客のリクエストを終了し、すべての画像が処理されるまでに数分かかる場合があることを通知します。

次に、スケジュールされたタスクまたはタスク キュー (つまり、Rabbit MQ) を使用して、画像処理と S3 へのアップロードを行うオプションがあります。スケジュールされたタスクを処理する別のインスタンスを用意して、顧客が Web アプリと直接対話しているインスタンスでこの処理作業が行われないようにすることもお勧めします。画像操作と S3 アップロードを別のタスクに分割すると、S3 アップロード プロセスを中断することなく、画像操作の問題 (つまり、不適切なファイル形式) を捕捉するエラー処理ができるようになります。これには、バックエンドでもう少し追跡作業が必要です (つまり、どの画像をまだ処理する必要があるか、どの画像をまだ S3 にアップロードする必要があるか)、これを実装するのは難しくなく、全体的により堅牢なワークフロー設定を提供します.

于 2012-11-06T14:24:12.020 に答える
0

cfqueryをループしていますが、これは非常に悪いことであり、大幅な速度低下を引き起こす可能性があります。これを回避する1つの方法は、100個のクエリを変数に格納してから、一度に複数のクエリを実行することです(接続の開閉には時間がかかる場合があります)。このスタイルを一括更新に使用した場合、次のようになります。 90%高速のパフォーマンスの向上。

これは、プロセスを機能させるのに十分な場合があります。もちろん、非常に大きな画像がたくさんある場合は、それについて行うことはあまりありません(画像サイズの制限を除く)

于 2012-11-06T14:21:10.933 に答える
0

ユーザーにリクエストをトリガーさせたい場合は、応答を待たずに AJAX 呼び出しで実行できます。リクエストがバックグラウンドで実行されていることをユーザーに伝えるだけです。また、ページ スレッドを完了して「処理中のリクエスト」ページを表示している間に、cfthread を使用して大きなリクエストを開始することもできます。

ベンに聞く: ColdFusion で CFThread を使用してファイルを処理する

于 2012-11-06T17:53:52.897 に答える