如何从本地机器上运行的 Django App 连接到 ElastiCache 实例 (Redis)

Posted

技术标签:

【中文标题】如何从本地机器上运行的 Django App 连接到 ElastiCache 实例 (Redis)【英文标题】:How to connect to ElastiCache instance (Redis) from Django App running on local machine 【发布时间】:2022-01-05 02:35:49 【问题描述】:

我正在努力寻找一种解决方案来正确设置在我的本地计算机上运行的 Django 应用程序和我的 ElastiCache 实例之间的连接

让我重新开始。

配置:

我在 AWS EC2 实例上部署了一个 Django 应用程序,并使用 docker-compose-yml 文件运行。我正在使用 ElastiCache 和 Redis 作为我的缓存。

我的问题:

我可以从我的 EC2 实例成功连接到我的 ElastiCache 实例。我可以使用 Redis 并创建密钥等。一切正常。

当我使用我的 EC2 实例中的 docker-compose.yml 文件运行它时,我能够从我的 Django 应用程序连接到 ElastiCache。

我还可以使用以下命令在我的 ElastiCache 上从本地计算机上使用 Redis,方法是使用以下命令与我的 EC2 实例创建一种桥接:

ssh -f -N -L 6379:my_elasticache_amazon_url:6379 ec2-user@my_ec2_instance_url

然后我运行以下命令并可以访问redis:

redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> 

但我无法从本地计算机上运行的 Django 应用访问 ElastiCache!在将其部署到 EC2 实例上之前,我需要为开发和测试目的设置此连接。

我在哪里:

我尝试使用 Django 应用程序中的 URL 直接连接到 ElastiCache,但由于 AWS 中的安全组设置为仅接受来自 EC2 实例的连接,因此不允许访问。

redis.exceptions.ConnectionError: Error 111 connecting to my_elasticache_url:6379. Connection refused.

我尝试将 127.0.0.1 & localhost 作为连接的 URL,因为我使用前面的命令在本地计算机和 EC2 实例之间建立了链接,但它不起作用,我有同样的错误:

redis.exceptions.ConnectionError: Error 111 connecting to 127.0.0.1:6379. Connection refused.

我已经尝试在我的 docker-compose 文件中设置 network_mode: "host",但它不起作用,因为我有一些端口绑定。

资源:

我的 Django 应用程序中用于连接到 Redis 的代码行:

import redis
import os

r = redis.Redis(
    host=os.environ.get('CLUSTER_HOST', default="127.0.0.1"), port=6379, db=0)

my_key = r.get('my_key')

我本地机器上的端口监听命令:

lsof -nP +c 15 | grep LISTEN 
ssh   22744 username  7u   IPv6 0x254006fa8c767523   0t0     TCP [::1]:6379 (LISTEN)
ssh   22744 username  8u   IPv4 0x254006fa9cfbe91b   0t0     TCP 127.0.0.1:6379 (LISTEN)

这是我的docker-compose.yml 文件:

version: '3.9'

x-database-variables: &database-variables
  POSTGRES_DB: $POSTGRES_DB
  POSTGRES_USER: $POSTGRES_USER
  POSTGRES_PASSWORD: $POSTGRES_PASSWORD
  ALLOWED_HOSTS: $ALLOWED_HOSTS

x-app-variables: &app-variables
  <<: *database-variables
  POSTGRES_HOST: $POSTGRES_HOST
  SPOTIPY_CLIENT_ID: $SPOTIPY_CLIENT_ID
  SPOTIPY_CLIENT_SECRET: $SPOTIPY_CLIENT_SECRET
  SECRET_KEY: $SECRET_KEY
  CLUSTER_HOST: $CLUSTER_HOST
  DEBUG: 1

services:
  website:
    build:
      context: .
    restart: always
    volumes:
      - static-data:/vol/web
    environment: *app-variables
    depends_on:
      - postgres

  postgres:
    image: postgres
    restart: always
    environment: *database-variables
    volumes:
      - db-data:/var/lib/postgresql/data

  proxy:
    build:
      context: ./proxy
    restart: always
    depends_on:
      - website
    ports:
      - 80:80
      - 443:443
      - 6379:6379
    volumes:
      - static-data:/vol/static
      - ./files/templates:/var/www/html
      - ./proxy/default.conf:/etc/nginx/conf.d/default.conf
      - ./etc/letsencrypt:/etc/letsencrypt

volumes:
  static-data:
  db-data:

我的 ElastiCache 实例的安全组的入站规则:

我的 EC2 实例的安全组的入站规则:

【问题讨论】:

【参考方案1】:

我找到了一个使用 AWS *** 的解决方案,如 this tutorial 中所述。

您只需设置一个链接到 ElastiCache 的 *** 网络,然后您可以设置权限以允许特定用户连接到它(或者您可以将其公开)。之后,您只需按照文档末尾的说明从本地计算机连接到 ***。

然后,您可以像在我的 EC2 实例上一样使用 Redis。

来自您的机器:

redis-cli -c -h your-elasticache-name.l5ljap.0001.use2.cache.amazonaws.com -p 6379

来自您的 Django 应用:

import redis

r = redis.Redis(
    host=your-elasticache-name.l5ljap.0001.use2.cache.amazonaws.com, port=6379, db=0)

提示:不要忘记连接可以访问互联网的路由器,否则您将无法在连接到 *** 后立即从您的机器连接到互联网(例如,当您在应用中发出 API 请求时,这可能会很烦人)。

【讨论】:

以上是关于如何从本地机器上运行的 Django App 连接到 ElastiCache 实例 (Redis)的主要内容,如果未能解决你的问题,请参考以下文章

Django 在服务器上找不到静态文件,但在本地机器上工作正常

如何连接本地机器和 Docker 容器?

在 OS 10.9 服务器上部署 Django

从 django app docker 连接到本地 mysql 数据库

如何使用 Django 在 HTML 按钮上执行 file.py?

如何在不同的机器上连接流星和 mongoDB