2012-01-12 33 views
22

Tôi đang gỡ lỗi một số mã Java sử dụng Apache POI để lấy dữ liệu ra khỏi tài liệu Microsoft Office. Thỉnh thoảng, nó gặp phải một tài liệu lớn và POI bị treo khi hết bộ nhớ. Tại thời điểm đó, nó cố gắng để xuất bản các lỗi để RabbitMQ, để các thành phần khác có thể biết rằng bước này không thành công và có những hành động thích hợp. Tuy nhiên, khi nó cố gắng xuất bản lên hàng đợi, nó nhận được com.rabbitmq.client.AlreadyClosedException (clean connection shutdown; reason: Attempt to use closed channel).Tại sao kênh RabbitMQ của tôi tiếp tục đóng?

Dưới đây là đoạn mã xử lý lỗi:

try { 
    //Extraction and indexing code 
} 
catch(Throwable t) { 
    // Something went wrong! We'll publish the error and then move on with 
    // our lives 
    System.out.println("Error received when indexing message: "); 
    t.printStackTrace(); 
    System.out.println(); 
    String error = PrintExc.format(t); 
    message.put("error", error); 

    if(mime == null) { 
     mime = "application/vnd.unknown"; 
    } 

    message.put("mime", mime); 
    publish("IndexFailure", "", MessageProperties.PERSISTENT_BASIC, message); 
} 

Để hoàn chỉnh, đây là phương pháp xuất bản:

private void publish(String exch, String route, 
    AMQP.BasicProperties props, Map<String, Object> message) throws Exception{ 
    chan.basicPublish(exch, route, props, 
     JSONValue.toJSONString(message).getBytes()); 
} 

tôi không thể tìm thấy bất kỳ mã bên trong khối try xuất hiện để đóng kênh RabbitMQ . Có bất kỳ hoàn cảnh nào trong đó kênh có thể bị đóng hoàn toàn không?

CHỈNH SỬA: Tôi nên lưu ý rằng sự cố đã nhận được được nhấn bởi cuộc gọi basicPublish bên trong xuất bản.

+0

cách bạn giải quyết vấn đề này? –

Trả lời

30

Kênh AMQP bị đóng trên lỗi kênh. Hai điều phổ biến mà có thể gây ra một lỗi kênh:

  • Đang cố gắng để xuất bản một thông điệp tới một cuộc trao đổi mà không tồn tại
  • Đang cố gắng để xuất bản một tin nhắn với các thiết lập cờ ngay lập tức mà không có một hàng đợi với một bộ người tiêu dùng đang hoạt động

Tôi sẽ xem xét thiết lập ShutdownListener trên kênh bạn đang cố gắng sử dụng để xuất bản thư bằng cách sử dụng addShutdownListener() để nắm bắt sự kiện tắt máy và xem điều gì đã gây ra sự cố.

+6

Nó chỉ ra rằng kết nối AMQP đã được đóng bởi JVM khi nó hết bộ nhớ. Tuy nhiên, vì lý do nào đó, trình lắng nghe tắt trên kênh không kích hoạt khi kết nối bị đóng. – quanticle

11

Một lý do khác trong trường hợp của tôi là do nhầm lẫn, tôi đã nhận được một tin nhắn hai lần. Điều này dẫn đến lỗi RabbitMQ trong nhật ký như sau sau lần xác nhận thứ hai.

=ERROR REPORT==== 11-Dec-2012::09:48:29 === 
connection <0.6792.0>, channel 1 - error: 
{amqp_error,precondition_failed,"unknown delivery tag 1",'basic.ack'} 

Sau khi tôi xóa xác nhận trùng lặp thì các lỗi đã biến mất và kênh không đóng nữa và cũng đã thoát khỏi chế độ này.

+0

Kịch bản đôi ack đó là một điểm rất tốt. Khó nhìn thấy vấn đề. Cảm ơn vì bình luận, tôi hoàn toàn giúp tôi. – cramhead

4

Tôi muốn thêm thông tin này cho những người dùng khác sẽ được tìm kiếm cho chủ đề này

Một lý do khác có thể cho nhận một ngoại lệ Đã đóng kênh là khi nhà xuất bản và Người tiêu dùng đang truy cập vào kênh/Queue với khai hàng đợi khác nhau/thiết lập

Publisher

channel.queueDeclare("task_queue", durable, false, false, null); 

Worker

channel.queueDeclare("task_queue", false, false, false, null); 

Từ trang web RabbitMQ

RabbitMQ doesn't allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that 
0

Tôi cũng gặp sự cố này.Lý do cho trường hợp của tôi là, đầu tiên tôi xây dựng hàng đợi với độ bền = false và trong tệp nhật ký tôi đã có thông báo lỗi này khi tôi chuyển sang độ bền thành true:

"inequivalent arg 'durable' for queue 'logsQueue' in vhost '/': received 'true' but current is 'false'"

Sau đó, tôi đã thay đổi tên của hàng đợi và nó làm việc cho tôi. Tôi giả định rằng máy chủ RabbitMQ giữ hồ sơ của hàng đợi được xây dựng ở đâu đó và nó không thể thay đổi trạng thái từ bền sang không bền và ngược lại.

Một lần nữa tôi đã bền = false cho hàng đợi mới và lần này tôi đã nhận lỗi này

"inequivalent arg 'durable' for queue 'logsQueue1' in vhost '/': received 'false' but current is 'true'"

giả định của tôi là đúng. Khi tôi liệt kê hàng đợi trong máy chủ rabbitMQ bằng cách:

rabbitmqctl list_queues 

Tôi đã thấy cả hai hàng đợi trong máy chủ.

Để tóm tắt, 2 giải pháp là: 1. đổi tên tên của hàng đợi mà không phải là một giải pháp tốt 2. đặt lại RabbitMQ bởi:

rabbitmqctl stop_app 
rabbitmqctl reset 
rabbitmqctl start_app 
+0

Khi hàng đợi được khai báo, thuộc tính của nó là không thay đổi. Tại sao không chỉ xóa hàng đợi sau đó thay đổi các thuộc tính hàng đợi? Khởi động lại toàn bộ nhà môi giới chỉ để thay đổi các thuộc tính của một hàng đợi có vẻ hơi quyết liệt – Daniel

Các vấn đề liên quan