質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.92%

AzureのQueue Storageをトリガーとして、Functionsを実行し、1つ1つ処理をしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,541

score 24

機能構成・概要

  • Functions①:httpトリガー。webページを表示した際に実行される。受け取ったメッセージをQueue Storageに格納する。
  • Queue Storage:Functions①からのメッセージを一時的に格納。
  • Functions②:Azure Queue Storageトリガー。Queueにメッセージが格納されたときに実行される。Queueから取り出したメッセージを加工し、Blob Storage内のファイルに追記する。
  • Blob Storage:ファイルの配置場所。ファイルは現状1つで、Functions②により追記される。

処理概要

  1. Webページ表示
  2. Functions①実行(Functions①のURL実行)
  3. メッセージをQueue Storageに格納
  4. 3をトリガーとして、Functions②を実行
  5. メッセージを加工して、Blob Storage内のファイルに追記

やりたいこと

  • ほぼ同時にQueue Storageに入ったデータを過不足なく、Blob Storage内のファイルに追記したい。
    (Functions②が実行中に別のFunctions②を実行しないか、
    Queue Storage内のメッセージをすべて、1つのFunctions②でBlob Storage内のファイルに格納するか。)

課題・問題点

  • 現状、Queue Storageに同時に10個メッセージが入った場合、Functions②が10個同時に実行され、処理がバッティングしてしまう。
  • したがって、Blob Storageのファイルには、10個分のメッセージは追記されず、1個分とか2個分のみ追記されてしまう。

エラー内容

The specified block list is invalid.

コード

/*Functions②*/
#r "Newtonsoft.Json"

using System;
using Newtonsoft.Json;
using System.Threading;

public static void Run(
    string queue01,
    string Blob01In,
    out string Blob01Out,
    ILogger log)
{
    //JSONデータからC#オブジェクト作成
    dynamic jsonData = JsonConvert.DeserializeObject(queue01);
    //C#オブジェクト⇒CSVデータ
    string csvData = jsonData.clm1 + "," + jsonData.clm2;

    //Blobの内容にQueueの内容を追記
    Blob01Out = Blob01In + csvData + System.Environment.NewLine;
    Thread.Sleep(5000);
    log.LogInformation("処理終了");
}


(Sleepは、処理がバッティングしていることをわかりやすくしているために使用しています。ログ出力も同様)

/*Function.json*/
{
  "bindings": [
    {
      "name": "queue01",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "queue01",
      "connection": "AzureWebJobsStorage"
    },
    {
      "type": "blob",
      "name": "Blob01Out",
      "path": "test01/test.csv",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    },
    {
      "type": "blob",
      "name": "Blob01In",
      "path": "test01/test.csv",
      "connection": "AzureWebJobsStorage",
      "direction": "in"
    }
  ]
}

Azure機能にあまり詳しくないため、不備等ございましたら、
補足致しますので、お力添えをお願いいたします。

補足(20181227)

それっぽい情報は見つかりましたが、記事通り、host.jsonに追記しても、何も変化はありません・・・
https://4423lab.wpblog.jp/archives/548

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • NakamuraYoichi

    2018/12/28 08:57

    すみません、念のために確認です。アトリビュートやhost.jsonを変更した後、変更を反映するためにFunction Appの「再開」はしていますでしょうか。

    キャンセル

  • HelloWorld2

    2019/01/10 18:08 編集

    レスポンスが大変遅くなり、申し訳ございません。
    「再開」はしてみましたが、状況は変わりませんでした。

    ■試したこと
    ①メソッドの1行上に[Singleton]を記載。
    ②同様に、[Singleton(Mode = SingletonMode.Listener)]を記載。
    ③host.jsonに、「 "queues": {"batchSize": 1,"newBatchThreshold": 0}」を記載。
    ④①と③の組み合わせ
    ⑤②と③の組み合わせ
    ※いずれも設定後「再開」をしています。

    host.jsonの設定は、「Function App の設定」からで合っていますでしょうか?(ストレージ内にもhost.jsonがありますが・・・)
    上記のhost.jsonには、{"version":"2.0"}の記述のみ存在していました。

    キャンセル

  • HelloWorld2

    2019/01/10 19:53 編集

    public static async Task Run()じゃなければならない、みたいな制約とかってないですか(サンプルがAsyncなため不安になりました)

    キャンセル

回答 3

check解決した方法

0

インスタンス自動増加のため

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Functions② の方に [Singleton] アトリビュートを付けるといけるような気がします。試していないので、ダメだったらごめんなさい...

Azure Functionsでのトリガーの流量制御

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/26 11:56

    ありがとうございます!試してみます。

    キャンセル

  • 2018/12/26 18:17

    [Singleton]を付けてみましたが、状況は変わらずでした・・・

    キャンセル

  • 2019/01/11 16:44

    私も試してみましたが、ダメでした。C# Script (.csx) で [Singleton] は効かないのでしょうか...

    キャンセル

0

C# なら Singleton が効きますが、微妙な挙動です。

Singleton を指定しても、メソッドの先頭で待機するようになるだけで、同時に呼ばれる点は変わらないようです。すると、呼ばれた時の Blob を元に処理を進めてしまうので、同時に開始された他のメソッドによる更新は反映されない。

Blob の内容を string で受け取るのではなく、一旦 ICloudBlob で受けておいて、メソッドの中で読み込む、という作戦を考えました。

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Blob;
using System.IO;
using System.Text;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1"), Singleton]
        public static void Run([QueueTrigger("queue01", Connection = "AzureWebJobsStorage")]string queue01,
            [Blob("test01/test.csv", Connection = "AzureWebJobsStorage")] ICloudBlob Blob01In,
            [Blob("test01/test.csv", Connection = "AzureWebJobsStorage")] out string Blob01Out,
            TraceWriter log)
        {
            log.Info($"C# Queue trigger function processed: {queue01}");

            var builder = new StringBuilder();
            using (var stream = Blob01In.OpenRead())
            {
                using (var reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        builder.AppendLine(reader.ReadLine());
                    }
                }
            }
            builder.AppendLine(queue01);
            Blob01Out = builder.ToString();

            System.Threading.Thread.Sleep(5_000);
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る