Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Azure函数的实例是否共享变量?_Java_Azure Functions_Azure Blob Trigger - Fatal编程技术网

Java Azure函数的实例是否共享变量?

Java Azure函数的实例是否共享变量?,java,azure-functions,azure-blob-trigger,Java,Azure Functions,Azure Blob Trigger,不确定这个问题是否有意义,但这是我观察到的。My Azure函数使用BlobTrigger处理上载到Blob存储的PDF文件。一切正常,直到我一次上传几个blob,在这种情况下,使用下面的代码我观察到以下情况: 第一个context.getLogger()正确记录触发函数的每个blob 在Azure文件共享中,每个PDF文件都正确保存 在许多情况下,第二个context.getLogger()返回不正确的结果(来自其他文件之一),就好像在我的函数实例之间共享变量一样。请注意,对于每个PDF

不确定这个问题是否有意义,但这是我观察到的。My Azure函数使用BlobTrigger处理上载到Blob存储的PDF文件。一切正常,直到我一次上传几个blob,在这种情况下,使用下面的代码我观察到以下情况:

  • 第一个context.getLogger()正确记录触发函数的每个blob

  • 在Azure文件共享中,每个PDF文件都正确保存

  • 在许多情况下,第二个context.getLogger()返回不正确的结果(来自其他文件之一),就好像在我的函数实例之间共享变量一样。请注意,对于每个PDF,第[19]行是唯一的

  • 在我的代码中,我注意到类似的行为,其中记录了来自错误PDF的数据

编辑:要清楚,我知道当多个实例并行运行时,日志将不正常。然而,当我上传10个文件时,并没有得到第[19]行的10个唯一结果,大多数结果都是重复的,当基于X我想做Y时,这个问题在我的代码中会进一步恶化,10个调用中有9个会产生垃圾数据

Main.class

public class main {
   @FunctionName("veninv")
       @StorageAccount("Storage")
       public void blob(
           @BlobTrigger(
                   name = "blob",
                   dataType = "binary",
                   path = "veninv/{name}") 
               byte[] content,
           @BindingName("name") String blobname,
           final ExecutionContext context
           ) {

         context.getLogger().info("BlobTrigger by: " + blobname + "(" + content.length + " bytes)");

           //Writing byte[] to a file in Azure Functions file storage
               File tempfile = new File (tempdir, blobname);
               OutputStream os = new FileOutputStream(tempfile);
               os.write(content);
               os.close();

               String[] lines  = Pdf.getLines(tempfile);
               context.getLogger().info(lines[19]);
           }
    }
   public static String[] getLines(File PDF) throws Exception {
           PDDocument doc = PDDocument.load(PDF);
           PDFTextStripper pdfStripper = new PDFTextStripper();
           String text = pdfStripper.getText(doc);
           lines = text.split(System.getProperty("line.separator"));
           doc.close();
           return lines;
   }
Pdf.class

public class main {
   @FunctionName("veninv")
       @StorageAccount("Storage")
       public void blob(
           @BlobTrigger(
                   name = "blob",
                   dataType = "binary",
                   path = "veninv/{name}") 
               byte[] content,
           @BindingName("name") String blobname,
           final ExecutionContext context
           ) {

         context.getLogger().info("BlobTrigger by: " + blobname + "(" + content.length + " bytes)");

           //Writing byte[] to a file in Azure Functions file storage
               File tempfile = new File (tempdir, blobname);
               OutputStream os = new FileOutputStream(tempfile);
               os.write(content);
               os.close();

               String[] lines  = Pdf.getLines(tempfile);
               context.getLogger().info(lines[19]);
           }
    }
   public static String[] getLines(File PDF) throws Exception {
           PDDocument doc = PDDocument.load(PDF);
           PDFTextStripper pdfStripper = new PDFTextStripper();
           String text = pdfStripper.getText(doc);
           lines = text.split(System.getProperty("line.separator"));
           doc.close();
           return lines;
   }

我真的不明白这里发生了什么,所以希望得到一些帮助。

不,很难相信函数会有如此严重的问题。在您的案例中,我发现一些可能导致这种情况的潜在问题:

  • 您确定每次都要为每个文件上载到不同的唯一blob吗?您可以通过记录blobname参数进行检查
  • 由于您将文件存储在临时目录
    file tempfile=new file(tempdir,blobname)中,如果blob名称与#1中提到的相同,它将用上次写入的wins覆盖。如果可以直接从字节或流构建PDF,可以考虑在文件系统中创建中间文件而不是创建中间文件。如果我没有记错,您使用的是支持从字节[]加载的方法(请检查接受字节[]的加载方法重载)。我也回答了你有关这方面的问题
  • 检查是否存在导致此问题的静态场
  • 您不需要使用您想引入的单独队列。虽然如果实际问题得到解决,您根本不需要它,但Blob触发器已经使用内部队列,默认并发性为24,但您可以在host.json中配置它 更新:

    看起来在pdf类中,您在方法之外的某个位置将“行”声明为静态,这是此问题的根本原因。这与功能无关,而是静态的魔鬼

    下面是正确的代码(注意“lines”变量现在是该方法的局部变量):


    只是想将更改后的
    host.json
    分享给以下人员,以停止并发函数调用,似乎解决了我的问题:

    {
        "version": "2.0",
        "extensions": {
            "queues": {
                "batchSize": 1,
                "newBatchThreshold": 0
            }
        }
    }
    

    非常感谢@KrishnenduGhosh MSFT的帮助。我仍然不确定为什么并发函数调用会导致我遇到的问题,但考虑到我的程序还连接到SQL数据库和Sharepoint站点(两者都受到限制),顺序处理是最好的解决方案。

    是的。Azure函数调用可以共享变量。我需要看到所有代码都是100%确定的,但它看起来像
    对象被声明为
    静态
    ,并且可以在调用之间共享。让我们尝试将
    静态字符串[]
    更改为
    字符串[]
    ,看看问题是否消失了

    Azure功能很容易起步,很容易忘记执行环境。您的函数调用并不像看上去那样孤立。有一个父线程调用您的函数,而静态变量不是“线程安全的”。静态变量表示全局状态,因此它是全局可访问的。而且,它没有附加任何特定的对象实例。变量的“静态性”与它所在的内存空间有关,而与它的值无关。因此,可以从引用该变量的所有类实例中访问该变量


    另外,您已经通过减少并发性解决了答案中的问题,但这可能会以可伸缩性为代价。我建议进行负载测试。静态变量也很有用。许多是线程安全的,您希望在Azure函数中使用它们,例如您的httpClient或sqlClient DB连接!读取数字3。

    这些文件不是并行处理的吗?您的函数可以同时为多个请求提供服务,并且您不能期望日志井然有序。请打开文件并检查其内容。它不会被共享,变量也不会被共享。当我进入Monitor>Invocations并检查每个调用时,日志不是保存在一起吗?在任何一种情况下,当我上传10个文件时,我都希望打印10行不同的代码(不管它们的顺序如何),但有时我只收到来自同一个文件的多行重复代码。经过大量调试,我现在确信变量确实会从一个实例泄漏到另一个实例。我现在有几个例子,在不做任何事情的情况下多次记录同一个变量会显示它随机变化(基于另一个实例的数据)。我认为对于我的解决方案,我需要使用队列来防止一次处理超过1个blob。@AlexanderJ,因为在对下面的答案进行了多次讨论之后,根本原因已经清楚了,您能将最合适的答案标记为“已接受”吗得出结论,并帮助其他可能遇到此问题的人搜索类似问题。1。所有blob都有一个唯一的名称并表示唯一的文件。当我运行我的程序时,对于x个blob,我会像预期的那样在tempdir中得到x个唯一的文件。2.谢谢,我不知道,我将尝试直接加载字节[],看看它是否有任何变化。3.是的,我遇到过