【问题标题】:Aws Elastic Cache (Redis) failed to connect (jedis connection error) when acessed locally through spring boot javaAws Elasticache(Redis)通过spring boot java本地访问时连接失败(jedis连接错误)
【发布时间】:2019-11-27 17:31:22
【问题描述】:

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

弹性缓存是存储 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 elastic cache (Redis),我们必须设置代理服务器,这不是一个好习惯,那么我们如何才能轻松地在本地构建应用程序并部署在云上?

  4. 为什么 ValueOperations 在设置、放置方法时没有“删除”方法?在过期时间之前使用完缓存,如何使缓存失效?

在本地访问 AWS 缓存:

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

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

设置键值时出错:

无法获得绝地连接;嵌套异常是 redis.clients.jedis.exceptions.JedisConnectionException:无法获取 池中的资源

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

【问题讨论】:

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


    【解决方案1】:

    发布问题后,我自己尝试了一些东西。

    根据亚马逊,

    您的 Amazon ElastiCache 实例旨在通过以下方式访问 一个 Amazon EC2 实例。

    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

    对于 application.properties 中的本地:redis.hostname = localhost, redis.port = 6379

    对于云端或部署到 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来put,读取Redis缓存中的数据。和我在上面的问题中提到的一样。无需任何更改。

    问题的答案:

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

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

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

    4. 在使用 valueOperations

    5. 时,我仍然需要找到使缓存失效的方法

    【讨论】:

      猜你喜欢
      • 2018-12-29
      • 2020-10-26
      • 2016-09-15
      • 1970-01-01
      • 2020-11-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多