2010-10-11 35 views
6

Tôi có một ứng dụng thu thập thông tin các trang web. Có vẻ như sau 20-45 phút của việc tạo HttpWebRequests, một loạt trong số họ trả về thời gian chờ. Một điều chúng tôi làm là đính kèm một chức năng ẩn danh BindIPDelegate để cung cấp cho một yêu cầu một IP cụ thể kể từ khi chúng tôi round-robin thông qua khoảng 150 IP.Sau khi thực hiện HttpWebRequests trong một thời gian, kết quả bắt đầu tính thời gian ra

Tôi đang thiết lập đối tượng HttpWebRequest với các cài đặt sau ..

  • Thiết User-Agent
  • Thiết Keep-Alive false để các IP không tái sử dụng
  • thiết TimeOut đến 60000 (60 giây)
  • thiết ReadWriteTimeout đến 60000 (60 giây)
  • thiết Proxy null
  • Setti ng Chấp nhận để /
  • Thiết CookieContainer để CookieContainer mới
  • Thiết Piplined true
  • Thiết tự động giải nén để Deflate & GZIP

ứng dụng đang sử dụng .NET 4.0 và chạy trên Windows Server 2008 R2.

Điều này chắc chắn có vẻ giống như một ứng dụng/TCP/.NET có liên quan bởi vì nếu tôi khởi động lại ứng dụng nó chạy tốt trở lại. Ngoài ra nó xuất hiện nhiều hơn hoặc ít hơn như những thời gian ra chỉ là xếp hàng chờ đợi trên một cổng địa phương hoặc một cái gì đó.

Bất kỳ ý tưởng nào?

+0

Bạn đang thực hiện cuộc gọi không đồng bộ hoặc đang chờ cuộc gọi? – WeNeedAnswers

+0

Đồng bộ, chặn cuộc gọi. –

+0

thử quay lại cuộc gọi không đồng bộ. Có thể không giải quyết được vấn đề của bạn nhưng chúng sẽ phân loại các vấn đề nhức đầu khi sử dụng httpWebRequest. Tôi sẽ nói rằng nó có cái gì đó để làm với threadpool, nhưng mà không nhìn vào mã của bạn tôi không thể nói chắc chắn. Không bao giờ làm đau Async gọi lại thay vì bắn lên chủ đề. Bạn sử dụng threadpool? – WeNeedAnswers

Trả lời

6

Bạn không nói nhiều về mã mà bạn thực sự sử dụng để thực hiện các yêu cầu nhưng, dù sao, đây là dự đoán của tôi:

  1. Bạn đang sử dụng BeginGetResponse()/EndGetResponse() với một callback và gọi lại mất quá nhiều thời gian để hoàn thành (hoặc chặn!). Điều này có thể gây ra một bế tắc trong threadpool nếu bạn đang phát hành rất nhiều yêu cầu trong một khoảng thời gian ngắn.

  2. Vì bạn không sử dụng lại các kết nối và, nếu yêu cầu xảy ra rất nhanh và không ngừng, bạn có thể hết ổ cắm (lần cuối cùng tôi thử, ~ 3k mỗi giao diện trên cửa sổ). Nếu thiết lập KeepAlive là đúng để khắc phục sự cố của bạn thì đây chính là nó.

  3. Bạn không gọi số Dispose()/Close() trên HttpWebRequest hoặc HttpWebResponse hoặc Luồng bạn nhận được từ phản hồi. Điều này có thể làm việc cho một chút cho đến khi bạn đạt đến giới hạn 2 (từ tài liệu MSDN) hoặc 6 (mặc định tệp cấu hình) trong cài đặt cấu hình ứng dụng của bạn cho (hệ thống.net/connectionQuản lý/thêm [address = "*", maxconnection = "6"]). Một cách đơn giản để kiểm tra xem đây có phải là vấn đề hay không là đặt giới hạn thành 1 và xem vấn đề có xảy ra sớm hơn trước hay không.

Btw, thiết KeepAlive false và pipelined true không có ý nghĩa.

+0

Cách dễ dàng để chẩn đoán tình trạng cạn kiệt cổng là với 'netstat'. –

+0

@Steven: vâng, trong linux tôi sẽ làm một cái gì đó như "netstat -nt". Nếu có rất nhiều CLOSE_WAIT, nó sẽ là trường hợp 3 ở trên. Nếu có rất nhiều TIME_WAIT, nó sẽ là trường hợp 2 ở trên. Việc tăng 'ulimit -n' sẽ giúp trường hợp 2, nhưng trường hợp 3 là một vấn đề về ứng dụng. – Gonzalo

+0

Windows có phiên bản được chuyển đổi của công cụ dòng lệnh Unix được tích hợp sẵn. Tuy nhiên, trong khi có một cặp mục đăng ký có thể được sử dụng để điều chỉnh giới hạn cổng, câu trả lời đúng vẫn là sửa mã để nó reuses cổng. –

0

Có thể là IDS ở đầu từ xa cho rằng bạn là kẻ tấn công và chặn bạn?

+0

Nó sẽ không tiếp tục chặn tôi? Dường như nó xảy ra trong một khoảng thời gian ngắn rồi biến mất. –

+0

Tùy thuộc vào thiết lập - bạn có thể định cấu hình thời gian bạn muốn chặn cuộc tấn công cảm nhận – arootbeer

+0

Bạn có thể chạy bất kỳ chẩn đoán nào trên máy chủ của mình không - ví dụ: TCPView xem điều gì đang phá vỡ kết nối, v.v ...? –

1

Tôi đoán đó là do các vấn đề liên quan đến ThreadPool.

0

Đoán của tôi là có thể không phải tất cả các đối tượng đang được xử lý đúng cách và một số cổng TCP đang được mở. Hãy thử để xem những gì các đối tượng thực hiện IDisposable. Ít nhất kết quả từ GetResponse và GetResponseStream là IDisposables và nên được xử lý một cách chính xác.

+0

Mọi thứ được IDisposable được gói trong một câu lệnh sử dụng. –

0

dễ dàng hơn để hiển thị ví dụ về ý nghĩa của tôi trong ý kiến ​​chứ không phải công việc của riêng tôi, nhưng những người ở microsoft thực hiện công việc ngọt ngào đến mức tôi chuyển cho bạn liên kết.

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetrequeststream.aspx

Nếu bạn làm sản lượng đầu vào nặng qua http, tôi sẽ luôn luôn đề nghị trong việc xem xét cơ chế gọi lại.

Cũng đảm bảo bạn đóng các đối tượng httpWebRequest chết tiệt đó. Bọc tất cả mọi thứ trong nhựa bọc bong bóng bằng cách sử dụng các câu "sử dụng" một cách tự do.

hoạt động đa luồng: Có cài đặt mặc định là 2 kết nối cho mỗi kết nối máy chủ.
Có thể thay đổi cài đặt đó. Nếu số lượng kết nối tối đa được sử dụng, thì các hoạt động HttpWebRequest (yêu cầu/phản hồi) sẽ được xếp hàng đợi cho đến khi có một khe kết nối.

một bài báo tôi đi qua kh¶o webservices cũng có thể ảnh hưởng đến vấn đề của bạn, như những nguyên nhân rất giống nhau, heres một liên kết:

http://support.microsoft.com/kb/821268

0

Hãy thử thêm dòng sau vào app.config của bạn, bên dưới cấu hình-tag. Tôi nghĩ rằng đây giải quyết một vấn đề tương tự tôi đã có khi làm rất nhiều http-kết nối liên tục:

<system.net> 
    <defaultProxy enabled="false"> 
    </defaultProxy> 
    <connectionManagement> 
     <remove address="*"/> 
     <add address="*" maxconnection="1000" /> 
    </connectionManagement> 
    </system.net> 

Edit: Tôi nghĩ rằng defaultProxy -tag là thẻ thực sự, thực sự rất quan trọng.

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