0
0
Lập trình
Admin Team
Admin Teamtechmely

Kiểm tra lỗi trong Apache NiFi: Phát hiện và Khắc phục

Đăng vào 7 tháng trước

• 6 phút đọc

Giới thiệu

Trong lĩnh vực CNTT, việc thu thập, xử lý và chuyển giao dữ liệu là những quy trình quan trọng. Nhưng nếu những quy trình này bị hỏng do những lỗi khó chịu trong mã nguồn thì sao? Trong bài viết này, chúng ta sẽ khám phá những lỗi được phát hiện bởi công cụ phân tích tĩnh PVS-Studio trong dự án Apache NiFi.

Apache NiFi là một công cụ mã nguồn mở miễn phí được phát triển ban đầu bởi Cơ quan An ninh Quốc gia Hoa Kỳ. Năm 2014, nó đã trở thành mã nguồn mở và gia nhập hệ sinh thái Apache. NiFi thường được sử dụng trong các dự án big data ngày nay, đặc biệt là khi kết hợp với Hadoop.

Lưu ý: Chúng tôi đã kiểm tra dự án Apache Hadoop. Bạn có thể đọc bài viết này trên blog của chúng tôi.

Những ưu điểm của Apache NiFi

NiFi có giao diện trực quan đơn giản, nơi dữ liệu có thể được di chuyển như trên một sơ đồ: bạn chỉ cần kéo và thả các khối (processor) và kết nối chúng bằng các mũi tên. Điều này cho phép các quản trị viên, nhà phân tích và lập trình viên cấu hình các luồng dữ liệu mà không cần kiến thức sâu về hệ thống. NiFi có thể làm việc với nhiều nguồn khác nhau: tập tin SFTP, nhật ký syslog, cơ sở dữ liệu (qua JDBC), Kafka, HDFS, Elasticsearch và nhiều nguồn khác.

Phương pháp kiểm tra

Vì dự án sử dụng hệ thống xây dựng Maven, chúng tôi đã sử dụng plugin PVS-Studio để phân tích mã nguồn. Chúng tôi cần thêm một vài dòng vào tệp pom.xml để phân tích mã nguồn. Đầu tiên, chúng tôi đã kích hoạt kho plugin của PVS-Studio:

xml Copy
<pluginRepositories>
  <pluginRepository>
    <id>pvsstudio-maven-repo</id>
    <url>https://wcdn.pvs-studio.com/java/pvsstudio-maven-repository/</url>
  </pluginRepository>
</pluginRepositories>

Sau đó, chúng tôi đã áp dụng plugin và cấu hình các thiết lập cần thiết cho phân tích:

xml Copy
<pluginManagement>
  <plugins>
    <plugin>
      <groupId>com.pvsstudio</groupId>
      <artifactId>pvsstudio-maven-plugin</artifactId>
      <version>7.38.96564</version>
      <configuration>
        <analyzer>
          <outputType>json</outputType>
          <outputFile>PVS-Studio.json</outputFile>
          <analysisMode>GA,OWASP</analysisMode>
        </analyzer>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>

Chúng tôi đã sử dụng các thiết lập sau trong cấu hình phân tích:

  • <outputType> là định dạng mà trình phân tích sử dụng để lưu kết quả phân tích (trong trường hợp của chúng tôi, đó là báo cáo ở định dạng json);
  • <outputFile> là đường dẫn nơi báo cáo phân tích được lưu (trong trường hợp của chúng tôi, đó là thư mục gốc của dự án);
  • <analysisMode> là các nhóm quy tắc chẩn đoán được bật cho phân tích dự án (trong trường hợp của chúng tôi, đó là các quy tắc từ các nhóm Phân tích Tổng quát và OWASP).

Sau khi thay đổi tệp pom.xml và xây dựng dự án, tất cả những gì còn lại là chạy lệnh sau:

bash Copy
mvn pvsstudio:pvsAnalyze

Lưu ý: Để biết thêm thông tin về plugin PVS-Studio cho hệ thống xây dựng Maven, vui lòng tham khảo tài liệu.

Các cảnh báo và lỗi thường gặp

Lỗi 1: Biểu thức không hợp lệ

java Copy
public void communicate() throws IOException {
  final String line = reader.readLine();
  final String[] splits = line.split(" "); 
  if (splits.length < 0) {
    throw new IOException(....);
  ....
}

Cảnh báo PVS-Studio: V6007 Biểu thức 'splits.length < 0' luôn sai.

Trong đoạn mã này, một ngoại lệ được ném ra nếu độ dài của mảng là... nhỏ hơn không. Các lập trình viên có lẽ muốn kiểm tra xem độ dài của mảng có bằng không hay không, nhưng điều này sẽ không xảy ra... Tại sao? Bởi vì, ngay cả khi chuỗi không có khoảng trắng, String.split() sẽ trả về một mảng chỉ chứa chuỗi gốc.

Lỗi 2: Điều kiện lặp lại

java Copy
protected Map<String, String> getAttributes(
  final TarArchiveInputStream stream
) throws IOException {
  for (final Entry<Object, Object> entry : props.entrySet()) {
    final Object keyObject = entry.getKey();
    final Object valueObject = entry.getValue();
    if (!(keyObject instanceof String)) {            // <=
      throw new IOException(
        "Flow file attributes object contains key of type "
        + keyObject.getClass().getCanonicalName()
        + " but expected java.lang.String");
    } else if (!(keyObject instanceof String)) {     // <=
      throw new IOException(
        "Flow file attributes object contains value of type "
        + keyObject.getClass().getCanonicalName()
        + " but expected java.lang.String");
    }
    final String key = (String) keyObject;
    final String value = (String) valueObject;
    result.put(key, value);
  }
}

Cảnh báo PVS-Studio: V6003 Mẫu sử dụng 'if (A) {...} else if (A) {...}' đã được phát hiện.

Lỗi 3: Biểu thức luôn đúng

java Copy
public void setOutputPorts(
  final Set<RemoteProcessGroupPortDescriptor> ports, 
  final boolean pruneUnusedPorts
) {
  final Iterator<StandardRemoteGroupPort> itr = outputPorts.values().iterator();
  int prunedCount = 0;
  while (itr.hasNext()) {
    final StandardRemoteGroupPort port = itr.next();
    if (....) {
      port.setTargetExists(false);
      port.setTargetRunning(false);
      if (port.getConnections().isEmpty()) {
        itr.remove();
        logger.info(
          "Pruning unused Output Port {} from {}", port, this
        );
      }
    }
  }
  if (prunedCount == 0) {  // <=
    logger.debug(
      "There were no Output Ports to prune from {}", this
    );
  } else {....}
}

Cảnh báo PVS-Studio: V6007 Biểu thức 'prunedCount == 0' luôn đúng.

Lỗi 4: Sử dụng tham chiếu trước khi kiểm tra

java Copy
public void revertReceivedTo(Relationship r, Throwable t) {
  String errorMessage = Throwables.getMessage(t, null, 950);
  String stackTrace = Throwables.stringStackTrace(t);
  for (FlowFile f : toFail) {
    if (t != null && r != null) {
      ....
    }
  ....
}

Cảnh báo PVS-Studio: V6060 Tham chiếu 't' đã được sử dụng trước khi nó được kiểm tra với null.

Mẹo về hiệu suất

  • Thực hiện kiểm tra thường xuyên: Đảm bảo chạy công cụ phân tích tĩnh thường xuyên để phát hiện lỗi sớm.
  • Tối ưu hóa mã: Cố gắng viết mã rõ ràng và ngắn gọn, tránh lặp lại.
  • Giữ mã sạch: Sử dụng các nguyên tắc lập trình tốt để duy trì mã sạch và dễ bảo trì.

Kết luận

Chúng ta đã xem xét một số lỗi thú vị được phát hiện bởi PVS-Studio trong dự án Apache NiFi. Mỗi bài viết trên blog của chúng tôi về việc kiểm tra các dự án xác nhận rằng ai cũng có thể mắc lỗi và điều quan trọng nhất là phát hiện và giải quyết kịp thời các vấn đề này.

Nếu bạn thấy những ví dụ về lỗi được phát hiện bởi PVS-Studio trong Apache NiFi thú vị, bạn có thể phân tích dự án của riêng mình miễn phí bằng cách nhận giấy phép tại đây.

Mã sạch đến với bạn!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào