2012-07-12 30 views
15

Tôi hơi bối rối về cách Go xử lý các yêu cầu đồng thời trên Google App Engine. Vì vậy, tôi hy vọng một người nào đó có thể cung cấp một số rõ ràng.Cách Go xử lý yêu cầu đồng thời trên Google App Engine

Dưới đây là những sự kiện mà tôi đã thu thập được:

  1. Go là single ren trên App Engine. - this is because it is possible to do arbitrary pointer arithmetic by creating race conditions with multiple threads

  2. Goroutines are multiplexed onto multiple OS threads so if one should block, such as while waiting for I/O, others continue to run.

  3. [App Engine has a] 10 concurrent limit [which] is enforced through a limit on concurrent threads on every runtime. Most of such cases, our scheduler will try to spin up a new instance.

Nếu Go là single ren trên App Engine sau đó trỏ 3 là tranh luận. Điều này lá 1 và 2. Nếu Go trên App Engine là đơn luồng và chủ đề được yêu cầu để tiếp tục thực hiện trong khi chặn cho I/O, thì có vẻ như một phiên bản App Engine Go sẽ chặn tất cả các goroutines trong khi chờ I/O.

Điều này có đúng không? Nếu không đồng bộ của Go thực sự hoạt động như thế nào trên App Engine?

Để giúp định lượng mọi thứ. Nếu tôi giữ kết nối trong 30 giây. Làm thế nào có thể kết nối đồng thời có thể một AE Go duy nhất dụ duy trì?

Cảm ơn bạn.

EDIT: đây là yêu cầu tính năng sẽ cho phép Phiên bản đi xử lý nhiều hơn 10 yêu cầu đồng thời Allow configurable limit of concurrent requests per instance. Hãy gắn dấu sao cho nó.

+7

Đặt GOMAXPROCS = 1 (đó là những gì GAE làm) chỉ có nghĩa là sẽ luôn có chính xác một chuỗi hoạt động thực thi goroutines. Bạn vẫn có thể có một vài chủ đề bị chặn (chúng không được tính). Cũng lưu ý rằng thư viện Go sử dụng epoll ở chế độ nền, do đó I/O không thể chặn toàn bộ luồng (nhưng có một số cách khác để chặn luồng trong Go). Tôi không biết bất cứ điều gì về giới hạn chung 10 thread trên GAE mặc dù. – tux21b

+1

Giới hạn yêu cầu đồng thời hiện có thể định cấu hình (tối đa 80), xem http://stackoverflow.com/a/37364981/943833 – Roganartu

Trả lời

21

Ví dụ về Máy ứng dụng Go cho phép 10 yêu cầu đồng thời, nhưng chỉ chạy một chuỗi CPU. Thực tế, nhiều yêu cầu có thể được xử lý đồng thời, nhưng chỉ một yêu cầu có thể thực hiện công việc CPU tại một thời điểm. Nếu một yêu cầu là, chờ đợi cho một cuộc gọi API kho dữ liệu để trả về, một yêu cầu khác là miễn phí để được xử lý bởi cùng một cá thể.

Tuyên bố của bạn "Nếu Go là chuỗi đơn trên App Engine thì điểm 3 là tranh luận". không đúng. Vẫn có giới hạn 10 yêu cầu trong chuyến bay đồng thời cho một phiên bản Go App Engine duy nhất. Các tài liệu là một chút lỏng lẻo với các từ khi nó nói về "chủ đề".

+3

** Câu trả lời này cần tuyên truyền lớn hơn nhiều ** Tôi đã hiểu rằng các yêu cầu hàng đợi Thời gian chạy đi, do đó yêu cầu đến sẽ phải đợi cho đến khi yêu cầu hiện tại được xử lý hoàn toàn. Rõ ràng là một yêu cầu duy nhất có thể sinh ra nhiều thói quen và hoạt động đồng thời, nhưng không phải là nhiều thói quen có thể. – mjibson

+0

Các tài liệu nói "nhiều yêu cầu có thể được xử lý đồng thời bởi một trường hợp nhất định", nhưng tôi chưa bao giờ đạt được điều đó cho đến khi tôi đọc lại nó ngay bây giờ, đã dừng lại ở giới hạn đơn luồng. – mjibson

+0

Cảm ơn David. Tôi vẫn còn một chút không rõ ràng về yêu cầu điều tiết. Tôi lấy [phản ứng của Takashi ở đây] (http://stackoverflow.com/a/11443482/236564) để có nghĩa là tất cả các trường hợp bị giới hạn bởi 10 chủ đề đồng thời thay vì yêu cầu. Dường như điều này có thể đã thay đổi gần đây. Điều đó có đúng với Go không? Nếu nó thực sự là chủ đề, những gì sẽ là một giới hạn thực tế cho số lượng yêu cầu đồng thời một ví dụ F1 Go có thể xử lý? –

4

Tôi phải thừa nhận rằng tôi không có kiến ​​thức bên trong về AppEngine. Đây là tất cả suy đoán và đoán, nhưng tôi nghĩ nó có phần hợp lý.

Ứng dụng của bạn sẽ không bao giờ đạt đến giới hạn mười chuỗi. Điều này là do có rất ít lý do cho các chủ đề được tạo ra. Đầu tiên, số lượng goroutine tối đa chạy cùng một lúc được đặt thành một đến enforce memory safety. Thứ hai, không giống như một chương trình đi bình thường, công cụ ứng dụng không thực sự cần tạo các syscalls. Thời gian duy nhất nó là để kết nối mạng. Tất cả IO trong appengine có thể được kết hợp thành một chuỗi epoll. Điều này có nghĩa là tất cả những gì bạn cần là hai luồng tại bất kỳ thời điểm nào. Sau đó, bạn có thể thêm một chuỗi thứ ba hoặc thứ ba trong trường hợp mỗi lần bạn cần chạy các syscalls khác như phân bổ bộ nhớ và chấp nhận/đóng các kết nối. Đây là những syscalls nhanh chặn trong một khoảng thời gian rất ngắn. Ngay cả với các syscalls khác, bạn vẫn còn rất xa giới hạn mười sợi.

Đồng thời không bị ảnh hưởng bởi vì cuối cùng, mọi thứ bạn làm trong appengine đều đọng xuống để đợi thứ gì đó trên mạng quay trở lại. Bạn không cần nhiều luồng để làm nhiều việc cùng một lúc.

+0

Cảm ơn bạn Stephen đã rất hữu ích. –

+0

@KyleFinley, nếu bạn không quá quen thuộc với "nội dung epoll" đó, tôi khuyên bạn ít nhất nên lướt qua công cụ cổ điển ["Vấn đề C10K"] (http://www.kegel.com/c10k.html) . – kostix

+0

@kostix Bài viết thú vị. Cảm ơn bạn. –

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