Google App Engine是否支持Redis发布和订阅

时间:2019-07-09 09:08:23

标签: google-app-engine redis

Redis将在Google App Engine(灵活的环境)上发布和订阅工作。

我正在使用node.js

这个问题的原因,我知道GAE不支持websockets / realtime。

1 个答案:

答案 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');

注释:

  1. 要进行尝试,您必须通过url上的GET参数(名为“ message”的参数)发送消息。

  2. 请记住,GAE通常会在可用实例之间平均分配请求,因此并非来自同一用户的所有请求都将转到同一实例,但是,因为客户端将直接连接到redis客户端,所以这无关紧要只要停留下来并监听传入的消息(但这取决于您如何实现应用程序的逻辑)。

  3. 如果需要在服务器和客户端之间建立持久连接,请尝试使用受支持的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