Trình tải hàng loạt Cassandra không bao giờ thoát khỏi ngoại lệ con trỏ null, vì vậy tập lệnh shell gọi của tôi không thấy lỗi


0

Tôi đã tạo một tập lệnh xử lý các tập tin trong một vòng lặp, bằng cách sử dụng một cuộc gọi quy trình. Tôi kiểm tra mã thoát của cuộc gọi đã nói để xem liệu tôi có nên di chuyển các tệp (khi thành công.) Vấn đề là, khi quá trình không thành công với một ngoại lệ, nó không bao giờ thoát. Làm cách nào để phát hiện ngoại lệ xảy ra, vì vậy tôi có thể làm cho tập lệnh chuyển sang các tệp tiếp theo?

Phần có liên quan của kịch bản

# Stream data
sstableloader -d $3 $tablepathfull

# On success, move data to target dir
if [[ $? != 0 ]]; then
    echo "Error: Table failed - $tablepathfull"
else
    echo "Table OK - $tablepathfull"
    trgtdir="$2/$hostname/$keyspacename/$typename/$timestamp/$keyspacename/$tablename"
    mkdir -p $trgtdir
    mv $tablepathfull/* $trgtdir
    rmdir $tablepathfull
fi

Nếu không có cách 'chính thức', có lẽ có thể nắm bắt được đầu ra (xem bên dưới) của lệnh gọi quy trình và chỉ cần giết quy trình một lần / nếu ngoại lệ xảy ra?

Đầu ra ngoại lệ

Exception in thread "STREAM-OUT-/XX.XX.XXX.88" Exception in thread "STREAM-OUT-/XX.XX.XXX.92" java.lang.NullPointerException
    at org.apache.cassandra.streaming.ConnectionHandler$MessageHandler.signalCloseDone(ConnectionHandler.java:249)
    at org.apache.cassandra.streaming.ConnectionHandler$OutgoingMessageHandler.run(ConnectionHandler.java:375)
    at java.lang.Thread.run(Thread.java:744)
java.lang.NullPointerException
    at org.apache.cassandra.streaming.ConnectionHandler$MessageHandler.signalCloseDone(ConnectionHandler.java:249)
    at org.apache.cassandra.streaming.ConnectionHandler$OutgoingMessageHandler.run(ConnectionHandler.java:375)
    at java.lang.Thread.run(Thread.java:744)

Ngoại lệ đó phải là thiết bị đầu cuối. Vui lòng báo cáo đây là một lỗi.
Dan D.

@DanD. Để ai, và ở đâu? Và không phải ứng dụng java mà tôi gọi là in ngoại lệ, nhưng sau đó không thoát? Âm thanh có thể xảy ra với tôi ...
natli

Bạn có thể thấy quá trình với ps sau khi nó đưa ra ngoại lệ đó không? Nó nên là một quá trình con cho kịch bản của bạn.

@Radoo Tôi có thể thấy nó trong htop
natli

Sau đó, nó sẽ là một lỗi của ứng dụng Java đó. Hành vi bình thường của một công cụ xử lý đơn giản sau khi ném ngoại lệ là thoát với mã lỗi. Tại sao nó sẽ bị khóa mãi mãi không làm gì?

Câu trả lời:


2

Cách giải quyết duy nhất tôi có thể đi kèm là sử dụng các quy trình con và tệp:

TEMP_FILE='/tmp/some_file.txt'

function load_table() {
  if [ $# -lt 2 ]; then
    printf "1" > "${TEMP_FILE}"
    return 1
  fi

  local param1="$1"
  local table_full_path="$2"
  local exit_code

  # Stream data
  sstableloader -d "${param1}" "${table_full_path}" >> "${TEMP_FILE}"
  exit_code=$?

  printf "\n%s" "${exit_code}" >> "${TEMP_FILE}"
}

function is_process_running() {
  if [ $# -eq 0 ]; then
    return 1
  fi
  local process_id="$1"

  ps aux | sed -r 's/[ ]+/ /g' | cut -d' ' -f2 | grep -q "${process_id}"
  return $?
}

function exceptions_count() {
  local count=$(tail -10 "${TEMP_FILE}" | grep -c "Exception")
  return $count
}



load_table "$3" "${tablepathfull}" &

# Given you have one subprocess only.. get the pid of the first subprocess in the list
job_pids=( $(jobs -p) )
load_table_job_pid=${job_pids[0]}

while is_process_running "${load_table_job_pid}" && exceptions_count -eq 0; do
  sleep 5
done

exit_code=0
if is_process_running "${load_table_job_pid}"; then
  local load_table_job_gid=$(ps x -o  "%p %r %y %x %c " | sed -r -e 's/[ ]+/ /g' -e 's/^[ ]+//g' | grep -E "^${load_table_job_pid} " | cut -d' ' -f2)
  kill -TERM -$load_table_job_gid >/dev/null 2>&1
  exit_code=1
else
  exit_code=$(tail -1 "${TEMP_FILE}")
fi

rm -f "${TEMP_FILE}"

# Your code
# On success, move data to target dir
if [ $exit_code -ne 0 ]; then
    echo "Error: Table failed - $tablepathfull"
else
    echo "Table OK - $tablepathfull"
    trgtdir="$2/$hostname/$keyspacename/$typename/$timestamp/$keyspacename/$tablename"
    mkdir -p $trgtdir
    mv $tablepathfull/* $trgtdir
    rmdir $tablepathfull
fi

Bạn có thể cải thiện mã bằng cách thêm số lần thử lại hoặc một cái gì đó.


Thử lại sẽ không làm được gì, vì ngoại lệ dường như xảy ra nếu có gì đó không đúng với các tệp bảng. Tôi sẽ kiểm tra kịch bản này và chấp nhận câu trả lời ngay khi sự cố xảy ra lần nữa, nhưng nó có vẻ tốt và đã dạy tôi một vài điều về bash, cảm ơn!
natli

Ồ, chỉ vì tò mò; Có grep -c "Exception" "${TEMP_FILE}"đọc toàn bộ tập tin mỗi lần không? Bởi vì các tập tin đầu ra có thể nhận được khá lớn. Nếu vậy, tôi sẽ thay thế nó tail -n 10bởi vì 10 dòng cuối cùng chắc chắn sẽ bao gồm Ngoại lệ nếu nó xảy ra.
natli

Đúng. Với phần mã bạn đã viết, tôi nghĩ rằng công cụ java không xuất ra bất cứ thứ gì. local count=$(tail -10 "${TEMP_FILE}" | grep -c "Exception")

Tôi đã cập nhật mã với bản cập nhật cuối cùng này.

Nó dường như hoạt động tốt, nhưng một ngoại lệ chưa xảy ra nên tôi không thể chắc chắn 100%. Nhưng về mặt lý thuyết nó sẽ hoạt động nên tôi mong không có vấn đề gì, cảm ơn!
natli
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.