2016-07-19 5 views
2

두 개의 Java Servlets (DataFetcherServletUploaderServlet)이 있습니다. 두 서블릿은 서로 다른 두 가지 자바 메소드를 호출하며, 각각의 자바 메소드는 JNI를 통해 해당 Matlab 함수를 호출하며 각 함수는 별도의 Java jar 파일로 컴파일되어 라이브러리로 사용됩니다. 응용 프로그램은 AJAX에 의해 바탕 화면 느낌을 생성합니다. UploaderServlet의 경우, 사용자는이 서블릿에 엑셀 파일을 업로드 할 수 있습니다. 파싱 된 데이터는 Java 메소드로 전달되어 컴파일 된 Matlab 함수를 호출하여 이미지 (현재 5000 개가 넘는 이미지)를 생성하고 저장합니다. 시간이 많이 걸리는 경우 배경에서 실행하려면 ExecutorService을 사용합니다. 그러나 DataFetcherServlet을 보낸 새로운 요청은 이미지 생성 부분이 완료 될 때까지 차단 된 다른 컴파일 된 Matlab 함수를 호출합니다. 요청이 다른 서블릿으로 보내 졌음에도 불구하고 왜 새 요청을 차단하는지 알 수 없습니다.다른 Matlab 함수를 동시에 Java에서 실행할 수없는 이유는 무엇입니까?

DataFetcherServlet.java

public class DataFetcherServlet extends HttpServlet { 

    @Inject 
    private CdfReader reader; // An EJB to get a data array from Matlab 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
     try { 
      String filePath = "path/to/file"; 
      Object[] result = reader.read(filePath); // reader.read() is just a wrapper around the method in the jar file mentioned above that actually calls the matlab function to return an array of number 
      MWNumericArray array = (MWNumericArray)result[0] // This will block while the other Matlab function is generating the images. 
      . 
      . 
      . 
     } catch (MWException ex) { 
      Logger.getLogger(DataFetcherServlet.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

UploaderServlet.java

public class UploaderServlet extends HttpServlet { 
    @Inject 
    private ExcelIonImageGenerator generator; // An EJB to call Matlab to generate the images 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
     try { 
      String dir = "path/to/parent/directory"; 
      Path excel = Paths.get(dir+ "excel", part.getSubmittedFileName()); // Path to where the uploaded excel file is stored 
      if (!Files.exists(excel)) 
       Files.copy(part.getInputStream(), excel); 
      // ExcelExtractor is a helper class to parse the excel file. 
      Double[][] ranges = ExcelExtractor.extractSheet(WorkbookFactory.create(excel.toFile())); 
      // This will call a Java library method which in turns call the Matlab function 
      // to generate the images (over 5000 in this case) 
      // See the code for this method below. 
      generator.generate(dir+ "images" + File.separator, ranges); 
     } catch (MWException | InvalidFormatException ex) { 
      Logger.getLogger(UploaderServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

ExcelIonImageGenerator.java

import com.mathworks.toolbox.javabuilder.*; // Matlab SDK needed to integrate with Java 
import java.util.concurrent.*; 
import java.util.logging.*; 
import javax.annotation.PreDestroy; 
import javax.ejb.Stateless; 
import save_ion_image_for_all_ranges_in_spreadsheet.Class1; // The jar file which contains code to call Matlab code through JNI 

@Stateless 
public class ExcelIonImageGenerator { 
    private final Class1 clazz1; 
    private ExecutorService pool; 

    public ExcelIonImageGenerator() throws MWException { 
     clazz1 = new Class1(); 
     pool = Executors.newFixedThreadPool(1); 
    } 

    public void generate(String path, Double[][] ranges) throws MWException { 
     // Submit this task to the ExecutorService so it can be processed 
     // in a different thread than the caller thread 
     pool.submit(() -> generateHelper(path, ranges, clazz1), 1); 
    } 

    private void generateHelper(String path, Double[][] ranges, Class1 clazz) { 
     try { 
      // This method was generated by Matlab tool, it calls the native 
      // Matlab code through JNI, and it will block any request that will call 
      // other Matlab functions until it finishes. 
      clazz.save_ion_image_for_all_ranges_in_spreadsheet(path, ranges); 
     } catch (MWException ex) { 
      Logger.getLogger(ExcelIonImageGenerator.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 
+0

주 MATLAB 실행은 단일 스레드에서 발생하기 때문에? –

+0

가능할 수 있습니다. 우리는 서버에 matlab 런타임을 설치했습니다. 그러나 일부 사용자가 일부 matlab 기능을 실행하는 동안 모든 사용자가 차단됩니다 – Dummy

+0

예, 다른 사용자를 차단합니다. Matlab 인스턴스를 여러 개 (예 : 사용자 당 하나씩) 실행하고 명령을 적절하게 라우트하거나 [Matlab Production Server] (http://uk.mathworks.com/products/matlab-production-server/)와 같은 것을 사용해야합니다. –

답변

2

당신은 세 가지 옵션이 있습니다

  1. Matlab을 호출하는 Java 응용 프로그램의 여러 프로세스를 시작합니다. 단일 프로세스의 호출은 프로세스 전체 잠금을 갖는 동일한 MCR을 사용하지만 다른 프로세스의 호출은 별도의 MCR 계산 엔진에서 실행됩니다.
  2. Matlab Production Server을 사용하면 기본적으로 여러 MCR의 사용이 용이합니다. 별도의 라이센스와 설치가 필요한 툴킷입니다.
  3. 특정 성능 문제가있는 경우가 아니면 MCR/컴파일 된 코드를 실행하지 않아도됩니다. 실제로 서버에 Matlab을 설치하고 동일한 Java 프로세스에서 여러 인스턴스 (헤드리스 등)를 실행하고 이들과 통신 할 수 있습니다. MatlabControl 또는 새 공식 MATLAB Engine API for Java을 통해

MatlabCentral에는 answer from MathWorks Support Team이 매우 훌륭하므로 MCR의 이러한 제한 사항을 자세히 설명합니다.

+1

고맙습니다. 웹 응용 프로그램을 실행하고 있기 때문에 주먹 옵션을 사용할 수 없으므로 smame 사용자를 위해 많은 프로세스를 만들면 프로세스가 메모리가 많이 필요하므로 응용 프로그램을 종료 할 수 있습니다. 우리는 얼마나 많은 사용자가 응용 프로그램을 사용할 것인지 알지 못합니다. 같은 시간. 두 번째 옵션으로 살펴볼 수 있습니다. 옵션 3은 현재 가장 실용적인 옵션입니다. 진심으로 당신의 도움에 감사드립니다. – Dummy