google-app-engine - 谷歌应用引擎是否支持redis发布和订阅

标签 google-app-engine redis

redis 会在 Google 应用引擎(柔性环境)上发布和订阅工作。

我正在使用 node.js

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

最佳答案

您可以将您的 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 部署您的应用程序。


我已经使用 Nodejs 在 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 long polling,有一个Beta功能叫做Session affinity,它允许您将同一用户的请求发送到同一实例。

要激活 session 亲和性,请在您的 app.yaml 上使用它(必须在所有客户端上启用 cookie):

network:
  session_affinity: true

请记住文档警告:

App Engine applications must always be tolerant of session affinity interruptions, particularly because all App Engine instances are periodically restarted. Enabling session affinity can also limit the effectiveness of App Engine's load balancing algorithms and can cause your instance to become overloaded.

您还可以使用 Google 的 Cloud Pub/Sub 并使用 Google Cloud Client Library 在您的应用程序中控制所有内容,这里是 example如何实现这一点。

关于google-app-engine - 谷歌应用引擎是否支持redis发布和订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56949064/

相关文章:

google-app-engine - GAE 和 JPA 持久性异常

database - Redis中的限制列表长度

ruby-on-rails - 在 Rails 3 中将 session 从 cookie_store 迁移到 Redis

redis - 分片 Redis 中的搜索和事务

python - Redis管道-原子获取另一个键值的值

java - 尝试运行我的项目时抛出 BeanCreationException

java - Google App Engine - Blobstore 请求用于生产而不是开发

java - 升级到 Java8 和端点 V2 后 AppEngine 出现错误

java - Google App Engine Go-Python/Java 混合应用

c# - 带有 Redis 的 OutputCache 在 Localhost 上工作,但不在 Azure WebApp 上工作