java - 通过 Spring Boot java 本地访问时,Aws Elasticache (Redis) 无法连接(jedis 连接错误)

标签 java spring amazon-web-services amazon-elasticache

我正在开发一个 Spring Boot 应用程序,我必须将 OTP 存储在弹性缓存 (Redis) 中。

Is elastic cache right choice to store OTP?

使用Redis存储OTP

要在本地连接到 Redis,我使用了“sudo apt-get install Redis-server”。已安装并成功运行。

我创建了一个 Redisconfig,在其中向应用程序配置文件询问端口和主机名。在这里,我想我将使用此主机名和端口连接到 aws 弹性缓存,但现在我在本地运行。

public class RedisConfig {

@Value("${redis.hostname}")
private String redisHostName;

@Value("${redis.port}")
private int redisPort;

@Bean
protected JedisConnectionFactory jedisConnectionFactory() {
    return new JedisConnectionFactory();
}

@Bean
public RedisTemplate<String,Integer> redisTemplate() {
    final RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(jedisConnectionFactory());
    return redisTemplate;
}

现在我使用RedisTemplate和valueOperation来放置、读取Redis缓存中的数据

public class MyService {

    private RedisTemplate<String, Integer> redisTemplate;

    private ValueOperations<String, Integer> valueOperations;

    public OtpService(RedisTemplate<String, Integer> redisTemplate) {
        super();
        this.redisTemplate = redisTemplate;
        valueOperations = redisTemplate.opsForValue();
    }

    public int generateOTP(String key) throws Exception {
        try {
            Random random = new Random();
            int otp = 1000 + random.nextInt(9000);
            valueOperations.set(key, otp, 120, TimeUnit.SECONDS);
            return otp;
        } catch (Exception e) {
            throw new Exception("Exception while setting otp" + e.getMessage()) ;
        }
    }

    public int getOtp(String key) {
        try {
            return  valueOperations.get(key);
        } catch (Exception e) {
            return 0;
        }
    }
}

现在这就是我所做的,并且在本地完美运行。

我有问题:

  1. 当我在 EC2 实例中部署应用程序时,我需要进行哪些更改。我们需要在代码中配置主机名和端口吗?

  2. 如果我们需要配置,有没有办法在本地测试部署时会发生什么?我们可以以某种方式模拟该环境吗?

  3. 我读到,要在本地访问aws弹性缓存(Redis),我们必须设置代理服务器,这不是一个好的做法,那么我们如何轻松地在本地构建应用程序并部署在云端?

  4. 为什么 ValueOperations 有 set、put 方法却没有“delete”方法?在过期时间之前使用完缓存后,如何使缓存失效?

本地访问AWS缓存:

当我尝试通过将帖子和主机名放入 JedisConnectionFactory 实例的创建中来访问 aws 弹性缓存 (Redis) 时

    @Bean
    protected JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHostName, redisPort);
        JedisConnectionFactory factory = new JedisConnectionFactory(configuration);
        return factory;
    }

我在设置键值时遇到错误:

Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

我试图解释我做了什么以及我需要知道什么? 如果有人知道详细提到事情的任何博客、资源,请指导我。

最佳答案

发布问题后,我自己尝试了一些事情。

根据亚马逊,

Your Amazon ElastiCache instances are designed to be accessed through an Amazon EC2 instance.

To connect to Redis locally on Linux, 

Run "sudo apt-get install Redis-server". It will install redis server.
Run "redis-cli". It will run Redis on localhost:6379 successfully run.

在java中连接到服务器(spring boot)

Redisconfig

For local in application.properties: redis.hostname = localhost, redis.port = 6379

For cloud or when deployed to ec2: redis.hostname = "amazon Elastic cache endpoint", redis.port = 6379

public class RedisConfig {

@Value("${redis.hostname}")
private String redisHostName;

@Value("${redis.port}")
private int redisPort;

@Bean
protected JedisConnectionFactory jedisConnectionFactory() {
    RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHostName, redisPort);
    JedisConnectionFactory factory = new JedisConnectionFactory(configuration);
    return factory;
}

@Bean
public RedisTemplate<String,Integer> redisTemplate() {
    final RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(jedisConnectionFactory());
    return redisTemplate;
}

有了这个,无论您是在本地运行还是在云上运行,只需更改 URL,一切都会完美运行。

此后使用RedisTemplate和valueOperation放入,读取Redis缓存中的数据。正如我在上面的问题中提到的。无需任何更改。

问题的答案:

  1. 在 EC2 实例中部署时,我们需要更改主机名。

  2. 在本地运行 Redis 服务器与在 EC2 上部署应用程序时运行 Redis 完全相同,无需更改,使用我正在使用的 Redis 配置。

  3. 是的,不要创建代理服务器,这违背了缓存的理念。使用 Redis 服务器在本地运行并更改主机名

  4. 在使用valueOperations时,我仍然需要找到一种使缓存失效的方法

关于java - 通过 Spring Boot java 本地访问时,Aws Elasticache (Redis) 无法连接(jedis 连接错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57100289/

相关文章:

java - 如何捕获 JSP 文件中的异常?

spring - 使用 Spring 分离表示层和业务层

jquery - 405 method not allowed 错误出现在开始时然后消失

java - Spring 安全: sporadic NullPointerException

amazon-web-services - AWS Elastic Load Balancer 占用端口

java - 如何从 Java 进行同步\异步 native 调用

java - 调用 EntityManager.persist() 时出现未知实体

java - 如何在 hibernate 过滤器中使用 session.commit?

php - 新手-创建可以存储图片并返回url的服务器-iOS

python - S3FS python,凭证内联