DmitryKoterov/dklab_realplexor — Issue #14: С++ версия сервера. Не полностью отдаёт HTML для IFRAME..
Author: degtyaryov
Created: 2012-02-01 16:16:03+00:00
State: open

Здравствуйте, Дмитрий!

Perl версия не справляется с рассылками в канал ограниченному списку пользователей, упирается в процессор и в результате принимает от PHP каждую команду за 5-8 секунд, что приводит к неработоспособности сайта. Если делать все каналы уникальными и не делать массовых рассылок, то пока справляется, но тоже близок к 100% ЦПУ.

Решил попробовать C++ версию. Протестировал на тестовом сервере, никаких проблем не обнаружил. Все прекрасно работало. А на боевом сервере возникла проблема.

Если на самом сервере выполнить:
# telnet comet.site.ru 80
get /multiplexor/?identifier=IFRAME&HOST=site.ru&version=1.32.3

получаем:
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=utf-8
Last-Modified: Thu, 12 Jan 2012 17:22:24 GMT
Expires: Wed, 08 Jul 2037 22:53:52 GMT
Cache-Control: public

Connection closed by foreign host.

А если тоже самое выполнить с сети интернет или с др. сервера того дата центра, то получаем не всё:
HTTP/1.1 200 OK
Connection: close
.................................
кусок пропущен
.................................
// Loop function.
_loopFunc: function() {
var requestId = this._makeRequestId();
if (!requestId.length) return;
var idParam = this.JS_IDENTIFIER + '=' + requestId;
var url = null, postData = null;
if (idParam.length + this.JS_WAIT_URI.length < 1700) {
// GET method is only for not too long URLs.
url = this.JS_WAIT_URI + '?' + idParam;
url += "&ncrnd=" + (new Date().getTime()); // for stupid IE
} else {
// For very long IDs list - use POST method Connection closed by foreign host.

tcpdump говорит что именно dklab_realplexor закрывает соединение:
# tcpdump -i eth0 -n host comet.site.ru and port 80 -A
21:53:41.007666 IP 192.168.1.35.59141 > 87.250.251.11.http: Flags [S], seq 3057008343, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
E..4).@.@......#X..+...P.6>.......9.................
21:53:41.291928 IP 87.250.251.11.http > 192.168.1.35.59141: Flags [S.], seq 1048287054, ack 3057008344, win 14600, options [mss 1380,nop,nop,sackOK,nop,wscale 7], length 0
E..4..@.7...X..+...#.P..>{.N.6>...9.U^.....d........
21:53:41.291978 IP 192.168.1.35.59141 > 87.250.251.11.http: Flags [.], ack 1, win 115, length 0
E..().@.@......#X..+...P.6>.>{.OP..s....
21:53:43.199071 IP 192.168.1.35.59141 > 87.250.251.11.http: Flags [P.], seq 1:66, ack 1, win 115, length 65
E..i).@.@......#X..+...P.6>.>{.OP..s....get /multiplexor/?identifier=IFRAME&HOST=site.ru&version=1.32.3
.................................
кусок пропущен
.................................
if (idParam.length + this.JS_WAIT_URI.length < 1700) {
// GET method is only for not too long URLs.
url = this.JS_WAIT_URI + '?' + idParam;
url += "&ncrnd=" + (new Date().getTime()); // for stupid IE
} else {
// For very long IDs list - use POST method
21:53:43.574874 IP 192.168.1.35.59141 > 87.250.251.11.http: Flags [.], ack 6918, win 222, length 0
E..().@.@......#X..+...P.6?.>{.TP.......
21:53:43.582515 IP 87.250.251.11.http > 192.168.1.35.59141: Flags [F.], seq 6918, ack 66, win 115, length 0
E..(.8@.7.k.X..+...#.P..>{.T.6?.P..s..........
21:53:43.582665 IP 192.168.1.35.59141 > 87.250.251.11.http: Flags [F.], seq 66, ack 6919, win 222, length 0
E..(*.@.@......#X..+...P.6?.>{.UP.......
21:53:43.869446 IP 87.250.251.11.http > 192.168.1.35.59141: Flags [.], ack 67, win 115, length 0
E..(.9@.7.k.X..+...#.P..>{.U.6?.P..s.-........
^C
20 packets captured
24 packets received by filter
0 packets dropped by kernel

Файл Realplexor/Common.h строка 99:
fh->write(content);

Вывел перед ней содержимое content - не обрезано, содержит всё, а fh->write в сокет выдает не всё.

Почему так происходит? Как это можно исправить? Заранее спасибо..

Хотелось бы ещё иметь у реалплексора некий мультикомандный интерфейс для отправки команд из PHP, python и др, при этом API даже не изменится. HTTP интерфейс принимает только одну команду и обязательно закрывает соединение. Если подключиться к серверу и без разрыва коннекта отправлять неограниченное кол-во команд, то можно будет использовать persistent соединения(php pfsockopen). Это позволит исключить 3х секундные задерки при коннекте(клиент шлёт SYN пакет) когда высокая нагрузка на сервер.