6

Tôi có một máy chủ web được viết bằng Node JS chạy trên Heroku. Máy chủ có quy trình máy chủ web và quy trình công nhân. Máy chủ web gửi thành công tin nhắn đến người lao động qua hàng đợi RabbitMQ; công nhân trả về thành công dữ liệu đã xử lý cho máy chủ web. Tôi sử dụng một Uuid được tạo ngẫu nhiên để theo dõi các tin nhắn và đảm bảo đúng thông điệp được ghép nối với đúng thông báo gốc.Cấu trúc hàng đợi thư (máy khách đến máy chủ web cho công nhân và quay lại)

Trong một dự án riêng biệt, tôi có khách hàng (trang web) giao tiếp thành công với máy chủ web. Bây giờ, tôi cần phải đặt cả hai lại với nhau.

thế nào tôi có thể làm cho nó để:

  1. Khách hàng gửi một HTTP POST.
  2. Máy chủ web nhận yêu cầu và chuyển yêu cầu đó vào hàng đợi thư.
  3. Công nhân xử lý yêu cầu và quay lại máy chủ web.
  4. Máy chủ web trả về dữ liệu chính xác cho máy khách để khách hàng có thể liên kết phản hồi với yêu cầu ban đầu.

Bước 4 là nơi tôi bị kẹt. Tôi nghĩ rằng tôi đọc ở đâu đó mà khách hàng nên liên tục thăm dò ý kiến ​​(HTTP POST?) Máy chủ web cho đến khi dữ liệu của nó đã sẵn sàng. Tôi nghĩ tôi cần trả lời khách hàng sau bước 1 để yêu cầu không hết thời gian. Bất kỳ ý tưởng/lời khuyên nào được đánh giá cao!

sơ đồ khối: enter image description here

+0

đây có phải là một quá trình chạy dài mà bạn cần cập nhật trạng thái không? Hoặc đây sẽ là phản hồi rất nhanh từ phía sau, nơi mà yêu cầu HTTP ban đầu sẽ nhận được phản hồi w/dữ liệu từ dịch vụ back-end đó? –

+0

Cập nhật trạng thái tôi nghĩ.Đôi khi back-end sẽ là 30 giây +. – user3320795

+1

vâng, đối với một cái gì đó dài hơn một giây hoặc lâu hơn, cập nhật trạng thái là cách để đi. Tôi sẽ sớm đăng câu trả lời. –

Trả lời

5

Phiên bản ngắn về những gì bạn cần làm là thông điệp hai chiều. Ứng dụng web của bạn cần phải là nhà sản xuất tin nhắn và người tiêu dùng tin nhắn. Cũng vậy với dịch vụ back-end của bạn.

Khi yêu cầu HTTP đến, máy chủ web sẽ gửi tin nhắn thông qua RabbitMQ. Back-end chọn nó tại một số điểm trong tương lai. Trong khi đó, máy chủ web gửi phản hồi lại thông qua yêu cầu HTTP nói điều gì đó đang xảy ra và người dùng sẽ được thông báo sau.

Nếu bạn đang sử dụng nhanh, nó sẽ giống như thế này:


var router = express.Router(); 
router.post("/", postJob); 

function postJob(req, res, next){ 
    req.session.inProgress = true; 

    var msg = { 
    job: "do some work" 
    }; 

    jobSender.sendJobRequest(msg, function(err){ 
    if (err) { return next(err); } 
    res.render("some-response"); 
    }); 
} 

Mã này làm cho rất nhiều giả định, như jobSender là một số loại của đối tượng đóng gói với một phương pháp để gửi một thông điệp RabbitMQ . Tôi chắc rằng bạn có thể điền thông tin chi tiết về việc gửi tin nhắn, dựa trên những gì bạn đã nói.

Điều quan trọng là trình xử lý yêu cầu HTTP gửi thông báo qua RabbitMQ và sau đó gửi phản hồi HTTP trở lại trình duyệt web.

Tại thời điểm này, trình duyệt có thể thực hiện mọi việc cần làm.

Trên back-end, khi dịch vụ khác đã hoàn thành nó làm việc, nó sẽ cần phải làm một trong hai điều:

1) cập nhật cơ sở dữ liệu chia sẻ ở đâu đó, vì vậy mà máy chủ web của bạn biết những gì làm việc có được thực hiện (và có thể đọc một status)

hoặc

2) gửi tin nhắn lại cho máy chủ web, qua RabbitMQ

tùy chọn # 1 có thể không luôn luôn là một lựa chọn tốt, vì nhiều lý do. và từ câu hỏi của bạn, bạn muốn tùy chọn # 2 anyways.

bạn sẽ cần hàng đợi thứ hai - hàng đợi mà máy chủ web đang nghe. khi máy chủ web nhận được một thông báo từ hàng đợi này, nó sẽ cập nhật cơ sở dữ liệu riêng của nó với trạng thái nhận được.

trạng thái này có thể là "hoàn thành" hoặc "đang xử lý" hoặc "lỗi" hoặc nội dung khác mà bạn thấy phù hợp.

Ví dụ: nếu bạn có thông báo "trạng thái công việc", bạn có thể có sự trừu tượng được gọi là "JobStatusReceiver" để nhận thông báo trạng thái.

Một module đơn giản như thế này có thể nhận tin nhắn từ hàng đợi tình hình công việc của bạn, và cập nhật cơ sở dữ liệu địa phương với tình trạng


var JobStatusReceiver = require("./jobStatusReceiver"); 
var someDataObject = require("someDataObject"); 

var jobStatus = { 

    listen: function(){ 
    var receiver = new JobStatusReceiver(); 
    receiver.receive(function(statusMessage){ 

     someDataObject.status = statusMessage.status; 
     someDataObject.data = statusMessage.data; 


     someDataObject.save(); 
    }); 
    } 

}; 

module.exports = jobStatus; 

lưu ý rằng điều này có thể xảy ra trong các máy chủ web, nhưng nó không phải là một phần của một Yêu cầu HTTP. thông điệp đến thông qua RabbitMQ với bộ phân tích JobStatusReceiver và không phải là một phần của yêu cầu HTTP.

đối tượng someDataObject rất có thể sẽ là đối tượng từ cơ sở dữ liệu yoru, vì vậy nó có thể được lưu lại vào cơ sở dữ liệu.

Cuối cùng, phần mà bạn cần thông báo cho người dùng về hành động đã hoàn tất, với dữ liệu, có thể xảy ra theo một số cách.

Nói chung, thật dễ dàng để thực hiện cuộc gọi AJAX đến API HTTP trên máy chủ web của bạn sau mỗi vài giây, để tìm phản hồi hợp lệ.

Về phía trình duyệt, điều này có thể đơn giản như:


var timer = setInterval(function(){ 

    $.ajax({ 
    url: "/api/check-status", 
    success: function(data){ 
     if (data.complete){ 
     clearInterval(timer); 
     doSomeOtherWork(data); 
     } 
    }) 
    }); 

}); 

và một lần nữa trong ứng dụng Express, xử lý các "/ api/check-status", bạn sẽ sử dụng "someDataObject" cùng một mô hình để kiểm tra trạng thái:


var someDataObject = require("someDataObject"); 

var router = new express.Router(); 
router.get("/", checkStatus); 

function checkStatus(req, res, next){ 

    someDataObject.load(function(err, someData){ 
    if (err) { return next(err); } 

    res.json({ 
     complete: (someData.status === "complete"), 
     data: someData.data 
    }); 

    }); 

} 

Điều này hy vọng sẽ giúp bạn đi đúng hướng. Có rất nhiều chi tiết tôi đã bỏ ra, tất nhiên, nhưng hy vọng bạn sẽ có thể điền vào các phần còn thiếu.

...

P.S .: tôi bao gồm tất cả những điều này, ngoại trừ cho trình duyệt kiểm tra các cập nhật trạng thái trên một giờ, trong khóa học RabbitMQ 4 Devs đào tạo của tôi. Đó là một gói hoàn chỉnh để thiết lập và chạy với RabbitMQ và Node.js

+0

đó là một cách tiếp cận tốt đẹp, tôi đoán rằng nó có thể được trộn lẫn với pub/tiểu mô hình thay vì gộp. – Sebastian

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