1

この質問をご覧いただきありがとうございます....我慢して....

先日、Web サーバーの 1 つが Web ページの提供を停止しました。Web サーバーは、Windows Server 2003 R2 Standard Edition Service Pack 2 と IIS 6 を実行する物理サーバーです。ColdFusion 8.0.1 Standard と Java 1.6.0_24 を実行します。このサーバーには、実際にはあまり使用されていない 3 つの公開 Web サイトがあります。3 つの Web サイトすべてのページがタイムアウトするか、500 エラーを返しました。

サーバーにサインオンして問題を確認したところ、JRUN サービスが大量のメモリを使用していることが予想されました。メモリは問題ありませんでしたが、CPU が 100% またはほぼ 100% で実行されていることに気付きました。約 50% は JRUN によって使用され、残りの 50% はランナウェイ バックアップ プロセスによって使用されていました。しかしその後、JRUN はすぐに CPU を使い果たし、100% 近く使用していました。

ColdFusion のログを確認したところ、いくつかのJava ヒープ スペースエラーが発生していることに気付きました。

IIS のログを調べたところ、あるアプリに対して多数のリクエストがあり、顧客の 1 人が、uploadify を使用して自社製品の複数の画像ファイルをアップロードできるようになっていることに気付きました。このアプリは ColdFusion で作成されており、jQuery を使用して Web サービスを呼び出します。この Web サービスはアップロードを処理し、アップロードされた画像のサイズを を使用して変更します<CFIMAGE>

ログでこの情報を確認した後、このアプリの一部が原因であるに違いないと考えました。

Java ヒープ スペース エラーと CPU スパイクの正確な原因を特定できないようです。何かご意見は?

WebService CFC メソッド:

<cffunction
    name="uploadFile"
    access="remote"
    returntype="Struct"
    output="false"
    returnformat="JSON">
    <cfargument name="FileName" type="String" default="" />
    <cfargument name="FileData" type="String" default="" />

    <cfscript>
        var _response = NewAPIResponse();
        var _tempFilePath = APPLICATION.TempDir & "\" & ARGUMENTS.FileName;
        var _qItem = QueryNew("");
        var _product = CreateObject("component", "cfc.Product");
        var _result = {};
        var _sku = "";

        /*
            Each file must be named [Part Number].[file extension], so, \
            parse the file name to get everything before the file extension
        */
        _sku =
            Trim(
                REQUEST.UDFLib.File.getFileNameWithoutExtension(
                    ARGUMENTS.FileName
                    )
                );
    </cfscript>

    <cfif Len(_sku) GT 20>
        <cfthrow
            message="#ARGUMENTS.FileName#: File Name does not correspond to an existing Part Number." />
    </cfif>

    <cfset _qItem = _product.readSKU(_sku) />

    <cfif NOT _qItem.RECORDCOUNT>
        <cfthrow
            message="#ARGUMENTS.FileName#: File Name does not correspond to an existing Part Number." />
    </cfif>

    <cfscript>
        FileCopy(ARGUMENTS.FileData, _tempFilePath);

        _aMessages =
            _product.setId(
                _qItem.SKU
                ).updateThumbnailImages(uploadFilePath = _tempFilePath);
    </cfscript>

    <cfif ArrayLen(_aMessages)>
        <cfthrow
            message="#ARGUMENTS.FileName#: #_aMessages[1].getText()#" />
    </cfif>

    <cfscript>
        _result["SKU"] = _product.getSKU();
        _result["SMALLIMAGESRC"] = _product.getSmallImageSrc();
        _result["LARGEIMAGESRC"] = _product.getLargeImageSrc();

        ArrayAppend(_response.data, _result);
    </cfscript>

    <cfreturn _response />
</cffunction>

画像リサイズ機能:

<cffunction name="updateThumbnailImages" returntype="Array" output="false">
    <cfargument name="uploadFilePath" type="String" required="true" />

    <cfset var _image = {} />

    <cfif FileExists(ARGUMENTS.uploadFilePath)>
        <cfset _image =
            REQUEST.UDFLib.Image.scale(
                imagePath = ARGUMENTS.uploadFilePath,
                maxHeight = 500,
                maxWidth = 700
                ) />

        <cfimage
            action="write"
            source="#_image#"
            overwrite="true"
            destination="#getLargeImagePath()#" />

        <cfset _image =
            REQUEST.UDFLib.Image.scale(
                imagePath = ARGUMENTS.uploadFilePath,
                maxHeight = 300,
                maxWidth = 300
                ) />

        <cfimage
            action="write"
            source="#_image#"
            overwrite="true"
            destination="#getMediumImagePath()#" />

        <cfset _image =
            REQUEST.UDFLib.Image.scale(
                imagePath = ARGUMENTS.uploadFilePath,
                maxHeight = 50,
                maxWidth = 50
                ) />

        <cfimage
            action="write"
            source="#_image#"
            overwrite="true"
            destination="#getSmallImagePath()#" />
    </cfif>
</cffunction>

画像スケーリング UDF:

<cffunction name="getDimensionsToEnlarge" returntype="Struct" output="false">
    <cfargument name="imageWidth" type="Numeric" required="true" />
    <cfargument name="imageHeight" type="Numeric" required="true" />
    <cfargument name="minWidth" type="Numeric" required="true" />
    <cfargument name="minHeight" type="Numeric" required="true" />

    <cfscript>
        var dimensions = {
            width = -1,
            height = -1
            };

        if  (
                ARGUMENTS.minHeight > 0
            &&  ARGUMENTS.minWidth > 0
            &&  imageHeight < ARGUMENTS.minHeight
            &&  imageWidth < ARGUMENTS.minWidth
            ) {
            dimensions.width = ARGUMENTS.minWidth;
            dimensions.height = ARGUMENTS.minHeight;
        }

        return dimensions;
    </cfscript>
</cffunction>

<cffunction name="getDimensionsToShrink" returntype="Struct" output="false">
    <cfargument name="imageWidth" type="Numeric" required="true" />
    <cfargument name="imageHeight" type="Numeric" required="true" />
    <cfargument name="maxWidth" type="Numeric" required="true" />
    <cfargument name="maxHeight" type="Numeric" required="true" />

    <cfscript>
        var dimensions = {
            width = -1,
            height = -1
            };

        if  (
                ARGUMENTS.maxHeight > 0
            &&  ARGUMENTS.maxWidth > 0
            &&  (
                    imageHeight > ARGUMENTS.maxHeight
                ||  imageWidth > ARGUMENTS.maxWidth
                )
            ) {
            dimensions.width = ARGUMENTS.maxWidth;
            dimensions.height = ARGUMENTS.maxHeight;
        }

        return dimensions;
    </cfscript>
</cffunction>

<cffunction name="getDimensionsToFit" returntype="Struct" output="false">
    <cfargument name="imageWidth" type="Numeric" required="true" />
    <cfargument name="imageHeight" type="Numeric" required="true" />
    <cfargument name="minWidth" type="Numeric" required="true" />
    <cfargument name="minHeight" type="Numeric" required="true" />
    <cfargument name="maxWidth" type="Numeric" required="true" />
    <cfargument name="maxHeight" type="Numeric" required="true" />

    <cfscript>
        var dimensions = {
            width = -1,
            height = -1
            };

        dimensions =
            getDimensionsToEnlarge(
                imageHeight = ARGUMENTS.imageHeight,
                imageWidth = ARGUMENTS.imageWidth,
                minWidth = ARGUMENTS.minWidth,
                minHeight = ARGUMENTS.minHeight
                );

        if (dimensions.width < 0 && dimensions.height < 0)
            dimensions =
                getDimensionsToShrink(
                    imageHeight = ARGUMENTS.imageHeight,
                    imageWidth = ARGUMENTS.imageWidth,
                    maxWidth = ARGUMENTS.maxWidth,
                    maxHeight = ARGUMENTS.maxHeight
                    );

        return dimensions;
    </cfscript>
</cffunction>

<cffunction name="scale" returntype="Any" output="false">
    <cfargument name="imagePath" type="String" required="true" />
    <cfargument name="action" type="String" default="fit" hint="shrink, enlarge, or fit"/>
    <cfargument name="minWidth" type="Numeric" default="-1" />
    <cfargument name="minHeight" type="Numeric" default="-1" />
    <cfargument name="maxWidth" type="Numeric" default="-1" />
    <cfargument name="maxHeight" type="Numeric" default="-1" />

    <cfscript>
        var scaledDimensions = {
                width = -1,
                height = -1
            };
        var scaledImage = ImageNew();

        scaledImage = ImageNew(ARGUMENTS.imagePath);

        switch (ARGUMENTS.action) {
            case "shrink":
                scaledDimensions =
                    getDimensionsToShrink(
                        imageHeight = scaledImage.getHeight(),
                        imageWidth = scaledImage.getWidth(),
                        maxWidth = ARGUMENTS.maxWidth,
                        maxHeight = ARGUMENTS.maxHeight
                    );

                break;
            case "enlarge":
                scaledDimensions =
                    getDimensionsToEnlarge(
                        imageHeight = scaledImage.getHeight(),
                        imageWidth = scaledImage.getWidth(),
                        minWidth = ARGUMENTS.minWidth,
                        minHeight = ARGUMENTS.minHeight
                    );

                break;
            default:
                scaledDimensions =
                    getDimensionsToFit(
                        imageHeight = scaledImage.getHeight(),
                        imageWidth = scaledImage.getWidth(),
                        minWidth = ARGUMENTS.minWidth,
                        minHeight = ARGUMENTS.minHeight,
                        maxWidth = ARGUMENTS.maxWidth,
                        maxHeight = ARGUMENTS.maxHeight
                    );

                break;
        }

        if (scaledDimensions.width > 0 && scaledDimensions.height > 0) {
            // This helps the image quality
            ImageSetAntialiasing(scaledImage, "on");

            ImageScaleToFit(
                scaledImage,
                scaledDimensions.width,
                scaledDimensions.height
                );
        }

        return scaledImage;
    </cfscript>
</cffunction>
4

1 に答える 1