Redis将在Google App Engine(灵活的环境)上发布和订阅工作。
我正在使用node.js
这个问题的原因,我知道GAE不支持websockets / realtime。
答案 0 :(得分:1)
您可以将Redis实例连接到Google App Engine Flex应用程序实例,您只需要知道它们都必须位于同一区域,并且同一网络具有授权访问权限即可。您可以按照文档的step by step tutorial来实现。
我将在此处描述一般步骤:
1 .- 。创建Redis实例。记下Redis实例的区域,IP地址和端口。
2 .- 。创建一个HTTP服务器应用程序,该应用程序从与Redis实例位于同一区域的App Engine灵活环境实例建立与Redis实例的连接。您的“ app.yaml”将如下所示:
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app
runtime_config:
python_version: 3
# update with Redis instance host IP, port
env_variables:
REDISHOST: redis-ip
REDISPORT: 6379
# update with Redis instance network name
network:
name: default
3 .- 。使用gcloud app deploy
部署应用程序。
我已经尝试过使用Node.js在GAE Flex上进行redis的发布/订阅行为,并为我完成了以下工作:
在服务器端:
'use strict';
const redis = require('redis');
const http = require('http');
const nconf = require('nconf');
const express = require('express');
const app = express();
// Read in keys and secrets. Using nconf use can set secrets via
// environment variables, command-line arguments, or a keys.json file.
nconf.argv().env().file('keys.json');
// Connect to a redis server provisioned over at
// Redis Labs. See the README for more info.
const pub = redis.createClient(
nconf.get('redisPort') || '6379',
nconf.get('redisHost') || '127.0.0.1',
{
'auth_pass': nconf.get('redisKey'),
'return_buffers': true
}
).on('error', (err) => console.error('ERR:REDIS:', err));
app.get('/', (req, res) => {
// subscribe to the publisher
// publisher publish a message and exit
pub.publish('notification', '{\'message\': '+req.query.message +'}', function(){
res.send('message sent:'+ req.query.message);
});
});
const server = app.listen(8080, () => {
const host = server.address().address;
const port = server.address().port;
console.log(`Example app listening at http://${host}:${port}`);
});
key.json 是类似的东西(我使用redislab创建redis实例):
{
"redisHost": "redis-23123.c124.us-central1-1.gce.cloud.redislabs.com",
"redisPort": 99999,
"redisKey": "random-bunch-of-letters-for-password"
}
在客户端:
'use strict';
const redis = require('redis');
const nconf = require('nconf');
nconf.argv().env().file('keys.json');
const sub = redis.createClient(
nconf.get('redisPort') || '6379',
nconf.get('redisHost') || '127.0.0.1',
{
'auth_pass': nconf.get('redisKey'),
'return_buffers': true
}
).on('error', (err) => console.error('ERR:REDIS:', err));
sub.on('message', function (channel, message) {
console.log('Message: ' + message + ' on channel: ' + channel + ' is arrive!');
});
sub.subscribe('notification');
注释:
要进行尝试,您必须通过url上的GET参数(名为“ message”的参数)发送消息。
请记住,GAE通常会在可用实例之间平均分配请求,因此并非来自同一用户的所有请求都将转到同一实例,但是,因为客户端将直接连接到redis客户端,所以这无关紧要只要停留下来并监听传入的消息(但这取决于您如何实现应用程序的逻辑)。
如果需要在服务器和客户端之间建立持久连接,请尝试使用受支持的Websockets。如果您使用类似“ socket.io”之类的东西来回溯到 http长轮询,则有一个名为会话关联性的 Beta 功能,该功能可让您将同一用户的请求发送到同一实例。
要激活会话亲缘关系,请在您的app.yaml上使用它(必须在所有客户端上启用cookie):
network:
session_affinity: true
请记住,文档警告:
App Engine应用程序必须始终容忍会话关联性 中断,尤其是因为所有App Engine实例都是 定期重启。启用会话关联性还可以限制 App Engine的负载平衡算法的有效性,并且可能导致 您的实例变得超载。
您还可以使用Google的 Cloud Pub / Sub ,并使用Google Cloud Client Library在您的应用程序中控制一切,这是实现这一目标的example。