Мы разрабатываем приложение для реального времени и используем модуль push-потока nginx для части веб-сокетов. Во-первых, данные отправляются от клиента в сценарий php, который выполняет некоторую аутентификацию и сохраняет необходимую информацию в базе данных, а затем отправляет информацию в nginx, который позже отправляет ее подписанным пользователям по определенным сокетам. Довольно часто бывают ситуации, когда из этого скрипта в локальный nginx отправляется более 30 http-запросов (что я не совсем уверен, это плохо?).
Вопрос
Можно ли отправлять информацию с php на nginx без http запросов? Есть ли способ, которым мой php-скрипт может общаться с nginx? Как лучше всего справляться с такого рода коммуникациями? Является ли отправка более 30 запросов HTTP на скрипт php хорошей практикой?
Я читал о некоторых решениях AMQP, но не нашел информации, где nginx является потребителем сообщений от rabbitmq.
Я с удовольствием предоставлю любую дополнительную информацию, если что-то не понятно.
Я предполагаю следующее:
Текущий рабочий процесс:
ОП концерн:
Эффективность взаимодействия php-сценария командной строки с серверным сценарием Nginx по протоколу http, который может быть излишним, поскольку обмен данными происходит на одном и том же сервере.
Предложение 1
Предложение 2
Объедините ваш php-скрипт командной строки с серверным сценарием Nginx и создайте для него веб-интерфейс. Текущий пользователь командной строки войдет в веб-страницу, чтобы контролировать процесс, который они использовали для этого с помощью инструмента командной строки.
Pro: Нет больше межсценариев / межпроцессного взаимодействия. Весь рабочий процесс в одном процессе. Это может быть более масштабируемым и в будущем, так как несколько пользователей могут войти через веб-интерфейс и управлять процессом удаленно. Кроме того, они не требуют учетных записей уровня ОС.
Против: Может потребоваться больше времени на разработку. (Но вам нужно поддерживать только одну кодовую базу вместо двух.)
Почему бы вам не рассмотреть возможность использования socket.io а Amazon SNS?
В нашей инфраструктуре, когда мы хотим отправить уведомление конкретному клиенту, подписанному на канал socket.io, мы отправляем полезную нагрузку в раздел Amazon SNS. Эта полезная нагрузка имеет атрибут «канал» и «сообщение» для отправки клиенту. Я даю лишь фрагмент из нашего кода, который легко понять
$msg = array(
'channel' => $receiver->getCometChannel(), //Channel id of the client to send the message
'data' => json_encode($payload) //The message to send to the client
);
$client = $this->getSNSObject();
$client->publish(array(
'TopicArn' => $topicArn,
'Message' => json_encode($msg)
));
У нас есть скрипт node.js, который создает конечную точку на порту 8002 (Http: // IP_адрес: 8002 / получить) Когда Amazon SNS получает полезную нагрузку от бэкэндов PHP, он перенаправляет эту полезную нагрузку на эту конечную точку, и затем единственное, что нужно сделать, — это обработать полезную нагрузку и отправить сообщение соответствующему клиенту через socket.js. Здесь идет сценарий node.js:
var fs = require('fs');
var options = {
pfx:fs.readFileSync('/etc/ssl/certificate.pfx') //optional, for SSL support for socket.js
};var io = require('socket.io')(8001);// open the socket connection
io.sockets.on('connection', function(socket) {
socket.on('subscribe', function(data) { socket.join(data.channel); });
socket.on('unsubscribe', function(data) { socket.leave(data.channel); });
socket.on('message', function (data) {
io.sockets.in(data.channel).emit('message', data.message);
});
})
var http=require('http');
http.createServer(function(req, res) {
if(req.method === 'POST' && req.url === '/receive') {
return client(req, res);
}
res.writeHead(404);
res.end('Not found.');
}).listen(8002);
var SNSClient = require('aws-snsclient');
var client = SNSClient(function(err, message) {
try{
var body=JSON.parse(message.Message)
var channel=body.channel,data=(body.data);
console.log(channel);
io.sockets.in(channel).emit('message', {channel: channel, data: data});
} catch(e) {
console.log(e);
}
});
Может быть, это кажется сложным, но я идея ясна.
Позвольте мне ответить шаг за шагом:
Это не проблема, пока вы не удовлетворены скоростью. У вас есть две возможные проблемы с этим решением:
a. high timing to reestablish http connection each request;
b. when concurrent requests reach its maximum nginx can skip some of your requests;
Как вы сказали, лучше всего использовать интерфейс запросов. Но я не уверен, есть ли способ справиться с этим на стороне nginx (мне не совсем понятна технология, которую вы используете на стороне nginx).
Также вы можете использовать длинное соединение для отправки запросов в nginx, что уменьшит задержку из-за проблемы (а), но может вызвать некоторые новые проблемы.
Как насчет использования PHP-FPM, подключенного к Nginx через доменные сокеты Unix с использованием протокола FastCGI? Это самый быстрый способ сделать IPC между Nginx и PHP — очень мало накладных расходов на ввод-вывод по сравнению с интернет-сокетом.
Еще одним решением, которое мы пробовали ранее, было развертывание сервера ejabberd (вы можете настроить его) для написания небольшого клиента javascript с использованием клиента strophe. http://blog.wolfspelz.de/2010/09/website-chat-made-easy-with-xmpp-and.html?m=1 хороший пост в блоге на эту тему. Если вы хотите разработать приложение чата, я бы пошел на эту опцию.
Еще одно преимущество: ваши пользователи также могут использовать клиенты xmpp для подключения к вашей чат-платформе.