2009-07-07 26 views
8

Tôi hiện đang cố gắng triển khai một máy chủ HTTP đơn giản cho một số loại máy bay comet-kỹ thuật (yêu cầu XHR bỏ phiếu dài). Như JavaScript là rất nghiêm ngặt về yêu cầu crossdomain Tôi có một vài câu hỏi:Hiểu mod_proxy và Apache 2 để viết máy sao chổi

  1. Như tôi hiểu bất kỳ người lao động apache bị chặn trong khi phục vụ một yêu cầu, vì vậy văn bản cho "kịch bản" như một trang web thông thường sẽ chặn apache, khi tất cả công nhân có yêu cầu phục vụ. -> Không làm việc!
  2. Tôi đã đưa ra ý tưởng bằng cách viết một máy chủ HTTP đơn giản riêng để phục vụ cho các yêu cầu bỏ phiếu dài này. Máy chủ này không nên chặn, vì vậy mỗi nhân viên có thể xử lý nhiều yêu cầu cùng một lúc. Vì trang web của tôi cũng chứa nội dung/hình ảnh vv và máy chủ của tôi không cần nội dung máy chủ, tôi bắt đầu anh ta trên một cổng khác 80. Vấn đề bây giờ là tôi không thể tương tác giữa JavaScript và apet-server của tôi chạy trên một cổng khác, vì một số hạn chế crossdomain. -> Không làm việc!
  3. Sau đó, tôi đã đưa ra ý tưởng sử dụng mod_proxy để ánh xạ máy chủ của tôi trên tên miền phụ mới. Tôi thực sự không thể tìm ra cách hoạt động của mod_proxy nhưng tôi có thể tưởng tượng rằng tôi biết có tác dụng tương tự như cách tiếp cận đầu tiên của tôi?

Cách tốt nhất để tạo loại kết hợp loại trang web cổ điển này và các yêu cầu XHR bỏ phiếu dài này là gì? Tôi có cần tự mình thực hiện việc phân phối nội dung trên máy chủ của mình không?

Trả lời

3

Tôi chắc chắn rằng việc sử dụng mod_proxy sẽ chặn một nhân viên trong khi yêu cầu đang được xử lý.

Nếu bạn có thể sử dụng 2 IP, có một giải pháp khá dễ dàng. Giả sử IP A là 1.1.1.1 và IP B là 2.2.2.2 và giả sử tên miền của bạn là example.com.

Đây là cách nó sẽ làm việc:

-Configure Apache để lắng nghe trên cổng 80, nhưng chỉ trên IP A.

-Bắt đầu máy chủ khác của bạn trên cổng 80, nhưng chỉ trên IP B.

-Định cấu hình yêu cầu XHR ở trên tên miền phụ của miền của bạn, nhưng với cùng một cổng. Vì vậy, các hạn chế tên miền chéo không ngăn cản chúng. Vì vậy, trang web của bạn là example.com và các yêu cầu XHR truy cập xhr.example.com chẳng hạn.

-Configure DNS của bạn để giải quyết example.com để IP A, và xhr.example.com giải quyết để IP B.

-You're thực hiện.

Giải pháp này sẽ hoạt động nếu bạn có 2 máy chủ và mỗi máy chủ có IP và máy chủ sẽ hoạt động tốt nếu bạn có một máy chủ có 2 IP.

Nếu bạn không thể sử dụng 2 IP, tôi có thể có một giải pháp khác, tôi sẽ kiểm tra xem nó có áp dụng được cho trường hợp của bạn hay không.

+0

Tôi quan tâm đến ý tưởng với chỉ sử dụng một IP. – TheHippo

+1

Tôi không nghĩ rằng mô hình bảo mật của trình duyệt cho phép mã được tải từ example.com để gửi XHR tới xhr.example.com. Bạn phải chơi trò chơi với document.domain và IFrames, và sau đó nó không thể di chuyển được. - http: //www.fettig.net/weblog/2005/11/28/cách thực hiện-xmlhttprequest-connections-to-another-server-in-your-domain/của bạn –

3

Đây là một vấn đề khó khăn. Ngay cả khi bạn vượt qua các vấn đề bảo mật mà bạn đang gặp phải, bạn sẽ phải giữ một kết nối TCP mở cho mọi ứng dụng khách hiện đang xem một trang web. Bạn sẽ không thể tạo chuỗi để xử lý từng kết nối và bạn sẽ không thể "chọn" tất cả các kết nối từ một chuỗi. Đã làm điều này trước đây, tôi có thể nói với bạn rằng nó không phải dễ dàng. Bạn có thể muốn xem xét libevent, trong đó memcached sử dụng cho một kết thúc tương tự.

Tính đến thời điểm bạn có thể thoát khỏi việc đặt thời gian chờ lâu và cho phép Apache có một số lượng lớn công nhân, hầu hết trong số đó sẽ không hoạt động. Lựa chọn cẩn thận và cấu hình của mô-đun công nhân Apache sẽ kéo dài điều này đến hàng ngàn người dùng đồng thời, tôi tin. Tuy nhiên, tại một số thời điểm, nó sẽ không tăng thêm nữa.

Tôi không biết cơ sở hạ tầng của bạn là gì, nhưng chúng tôi có các hộp cân bằng tải trong giá đỡ mạng được gọi là F5. Chúng có thể được cấu hình để gửi các yêu cầu cho một đường dẫn nhất định trong miền ảo tới một máy chủ cụ thể. Vì vậy, bạn có thể yêu cầu example.com/xhr/foo ánh xạ tới một máy chủ cụ thể để xử lý các yêu cầu sao chổi này. Thật không may, đây không phải là một giải pháp phần mềm, mà là một giải pháp phần cứng khá đắt tiền.

Dù sao, bạn có thể cần một số loại hệ thống cân bằng tải (hoặc có thể bạn đã có), và có lẽ nó có thể được cấu hình để xử lý tình huống này tốt hơn Apache có thể. Tôi đã gặp vấn đề nhiều năm trước, nơi tôi muốn khách hàng sử dụng hệ thống máy chủ-khách hàng với giao thức nhị phân độc quyền để có thể truy cập máy chủ của chúng tôi trên cổng 80 vì họ liên tục gặp sự cố với tường lửa trên cổng tùy chỉnh mà hệ thống đã sử dụng. Những gì tôi cần là một proxy có thể sống trên cổng 80 và hướng lưu lượng truy cập đến Apache hoặc máy chủ ứng dụng tùy thuộc vào vài byte đầu tiên của những gì xuất hiện từ phía máy khách. Tôi tìm kiếm một giải pháp và không tìm thấy gì phù hợp. Tôi đã xem xét việc viết một mô-đun Apache, một plugin cho DeleGate, v.v., nhưng cuối cùng được dịch vụ proxy cảm biến nội dung tùy chỉnh. Điều đó, tôi nghĩ, là trường hợp xấu nhất cho những gì bạn đang cố gắng làm.

0

Để trả lời câu hỏi cụ thể về mod-proxy: , bạn có thể thiết lập mod_proxy để phân phối nội dung do máy chủ (hoặc dịch hoặc localhost).

Tôi đã thực hiện điều này trong môi trường sản xuất và hoạt động rất, rất tốt. Apache chuyển tiếp một số yêu cầu tới Tomcat thông qua nhân viên AJP, và những người khác đến một máy chủ ứng dụng GIS thông qua proxy mod. Như những người khác đã chỉ ra, an ninh cross-site có thể ngăn cản bạn làm việc trên một tên miền phụ, nhưng không có lý do tại sao bạn không thể yêu cầu proxy để mydomain.com/application


Để nói về cụ thể của bạn vấn đề - tôi nghĩ thực sự bạn đang bị sa lầy trong việc xem xét vấn đề là "yêu cầu sống lâu" - tức là giả sử rằng khi bạn thực hiện một trong những yêu cầu đó là nó, toàn bộ quá trình cần phải dừng lại. Dường như bạn đang cố gắng giải quyết vấn đề với kiến ​​trúc ứng dụng thông qua các thay đổi đối với kiến ​​trúc hệ thống. Trong thực tế những gì bạn cần làm là xử lý các yêu cầu nền chính xác như vậy; và đa thread nó:

  • khách hàng làm cho các yêu cầu dịch vụ từ xa "thực hiện nhiệm vụ X với dữ liệu A, B và C"
  • dịch vụ của bạn nhận được yêu cầu: nó vượt qua nó lên một lịch trình mà phát hành một vé/mã thông báo duy nhất cho yêu cầu.Dịch vụ sau đó trả lại mã thông báo này cho khách hàng "cảm ơn, nhiệm vụ của bạn nằm trong hàng đợi chạy theo mã thông báo Z"
  • Khách hàng sau đó treo vào mã thông báo này, hiển thị hộp "đang tải/vui lòng chờ" và thiết lập hẹn giờ mà cháy nói, lập luận, mỗi
  • Khi cháy hẹn giờ, khách hàng làm cho một yêu cầu đến dịch vụ từ xa "có bạn nhận được các kết quả cho công việc của tôi, nó là Z thẻ" thứ hai
  • bạn dịch vụ nền thể sau đó kiểm tra với trình lên lịch của bạn và có thể sẽ trả về một tài liệu trống "không, chưa hoàn thành" hoặc kết quả
  • Khi máy khách nhận được kết quả, nó có thể đơn giản xóa bộ hẹn giờ và hiển thị chúng.

Miễn là bạn thoải mái hợp lý với luồng (bạn phải là nếu bạn cho biết bạn đang viết máy chủ HTTP của riêng mình, điều này không quá phức tạp - trên đầu trang của http phần người nghe:

  • Đối tượng lập lịch biểu - đối tượng đơn lẻ, thực sự chỉ cần kết thúc một ngăn xếp "Đầu tiên, đầu tiên", công việc mới có thể được rút ngay từ đầu: chỉ cần thực hiện chắc chắn rằng mã để phát hành một công việc là chủ đề an toàn (ít bạn nhận được hai công việc kéo công việc tương tự từ ngăn xếp). lịch trình, yêu cầu công việc tiếp theo: nếu có một công việc sau đó thực hiện công việc gửi kết quả, nếu không chỉ ngủ trong một khoảng thời gian, hãy bắt đầu lại.

Bằng cách này, bạn sẽ không bao giờ chặn Apache lâu hơn nhu cầu, vì tất cả những gì bạn đang làm là các yêu cầu cho "do x" hoặc "cho tôi kết quả cho x". Có thể bạn sẽ muốn xây dựng một số tính năng an toàn ở một vài điểm - chẳng hạn như xử lý các tác vụ thất bại và đảm bảo có thời gian chờ ở phía máy khách để nó không chờ đợi vô thời hạn.

0

Đối với số 2: bạn có thể gặp các hạn chế crossdomain bằng cách sử dụng JSONP.

0

HaiBa lựa chọn:

  1. Use nginx. Điều này có nghĩa là bạn chạy 3 máy chủ: nginx, Apache và máy chủ của riêng bạn.
  2. Khởi động máy chủ của bạn trên cổng riêng.
  3. Sử dụng Apache mod_proxy_http (làm gợi ý của riêng bạn).

Tôi đã xác nhận mod_proxy_http (Apache 2.2.16) hoạt động proxy một ứng dụng Comet (được hỗ trợ bởi Atmosphere 0.7.1) chạy trong GlassFish 3.1.1.

ứng dụng thử nghiệm của tôi với nguồn đầy đủ là ở đây: https://github.com/ceefour/jsfajaxpush

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