Tôi đang viết máy chủ TCP trong Qt để phục vụ các tệp lớn. Ứng dụng logic là như sau:Máy chủ QTcpS chậm với nhiều khách hàng đồng thời
- Tôi đã subclassed QTcpServer và reimplemented incomingConnection (int)
- Trong incomingConnection, tôi là tạo ra thể hiện của "Streamer" class
- "Streamer" đang sử dụng QTcpSocket đó là khởi tạo với setSocketDescriptor từ incomingConnection
- Khi dữ liệu từ client đến, tôi gửi lại phản ứng ban đầu từ bên trong readyRead() khe, và sau đó tôi kết nối bytesWritten tín hiệu ổ cắm của (qint64) để bytesWritten khe Streamer của()
bytesWritten trông giống như sau:
Streamer.h:
...
private:
QFile *m_file;
char m_readBuffer[64 * 1024];
QTcpSocket *m_socket;
...
Streamer.cpp
...
void Streamer::bytesWritten() {
if (m_socket->bytesToWrite() <= 0) {
const int bytesRead = m_file->read(m_readBuffer, 64 * 1024);
m_socket->write(m_readBuffer, bytesRead);
}
}
...
Vì vậy, về cơ bản tôi chỉ ghi dữ liệu mới khi tất cả dữ liệu đang chờ được đầy đủ bằng văn bản. Tôi nghĩ đó là cách không đồng bộ nhất để làm điều đó.
Và mọi thứ hoạt động chính xác, ngoại trừ nó khá chậm khi có nhiều khách hàng đồng thời.
Với khoảng 5 khách hàng - Tôi đang tải về từ máy chủ với tốc độ khoảng 1 MB/s (tối đa kết nối internet của nhà tôi)
Với khoảng 140 khách hàng - tốc độ tải về là khoảng 100-200 KB/s .
Kết nối internet của máy chủ là 10 Gbps và với 140 khách hàng sử dụng nó là khoảng 100 Mb/giây, vì vậy tôi không nghĩ đó là vấn đề.
sử dụng bộ nhớ Server với 140 khách hàng - 100 MB bộ 2GB có sẵn
sử dụng CPU Server - tối đa 20%
Tôi đang sử dụng cổng 800.
Khi có được 140 khách hàng trên cổng 800 và tốc độ tải xuống thông qua nó là 100-200 KB/s, tôi đã chạy bản sao riêng biệt trên cổng 801 và tải xuống ở mức 1 MB/giây mà không gặp sự cố nào.
Tôi đoán là bằng cách nào đó, sự kiện gửi đi của Qt (hoặc bộ nhận dạng socket?) Quá chậm để xử lý tất cả các sự kiện đó.
Tôi đã thử:
- Biên soạn toàn bộ Qt và ứng dụng của tôi với O3
- Cài đặt libglib2.0-dev và biên dịch lại Qt (vì QCoreApplication sử dụng QEventDispatcherGlib hoặc QEventDispatcherUNIX, vì vậy tôi muốn xem có bất kỳ sự khác biệt nào không)
- Tạo ra một vài luồng và trongConnect (int) bằng streamer-> moveToThread() tùy thuộc vào số lượng khách hàng hiện tại chủ đề cụ thể - mà không thực hiện bất kỳ thay đổi (mặc dù tôi đã quan sát thấy rằng tốc độ là độ khác nhau nhiều hơn nữa)
- quá trình lao động Spawning sử dụng
Code:
main.cpp:
#include <sched.h>
int startWorker(void *argv) {
int argc = 1;
QCoreApplication a(argc, (char **)argv);
Worker worker;
worker.Start();
return a.exec();
}
in main():
...
long stack[16 * 1024];
clone(startWorker, (char *)stack + sizeof(stack) - 64, CLONE_FILES, (void *)argv);
và sau đó bắt đầu một QLoc alServer trong quá trình chính và truyền socketDescriptors từ incomingConnection (int socketDescriptor) đến các quy trình công nhân. Nó hoạt động chính xác, nhưng tốc độ tải xuống vẫn chậm.
Cũng thử:
- fork() - quá trình ing trong incomingConnection() - đó gần như bị giết server :)
- Tạo chủ đề riêng biệt cho từng khách hàng - tốc độ giảm xuống còn 50-100 KB/s
- sử dụng QThreadPool với QRunnable - có sự khác biệt
tôi đang sử dụng Qt 4.8.1
Tôi hết ý tưởng.
Có liên quan đến Qt hoặc có thể là điều gì đó có cấu hình máy chủ không?
Hoặc có lẽ tôi nên sử dụng ngôn ngữ/khuôn khổ/máy chủ khác nhau? Tôi cần máy chủ TCP sẽ phục vụ các tập tin, nhưng tôi cũng cần phải thực hiện một số nhiệm vụ cụ thể giữa các gói, vì vậy tôi cần phải thực hiện phần đó bản thân mình.
Cách sử dụng đĩa máy chủ? Nó có thể là nút cổ chai? –
Nó hoàn toàn có thể. Có vẻ như phần cứng máy chủ có thể bị lỗi. Tôi sẽ chắc chắn vào thứ hai, và tôi sẽ cho bạn biết. Cảm ơn! – AdrianEddy
Nút cổ chai chắc chắn là hoạt động của đĩa IO. Trên 80 tệp đã mở dẫn đến tải trên máy chủ> 1 và tốc độ tải xuống khoảng 150 KB/s. Có bất cứ điều gì tôi có thể thay đổi trong chương trình của tôi, hoặc tôi phải chơi với cấu hình/phần cứng máy chủ? – AdrianEddy