浅谈Redis在微服务架构中的几种应用场景

本文介绍在SpringCloud中使用Redis作为Pub/Sub异步通信、缓存或主数据库和配置服务器的三种场景应用。

Redis可以广泛用于微服务架构。它可能是您应用程序以多种不同方式利用的少数流行软件解决方案之一。根据要求,它可以充当主数据库,缓存或消息代理。虽然它也是一个键/值存储,但我们可以将它用作微服务体系结构中的配置服务器或发现服务器。虽然它通常被定义为内存中的数据结构,但我们也可以在持久模式下运行它。

这里我将向您展示一些使用Redis与Spring Boot和Spring Cloud框架之上构建的微服务的示例。这些应用程序将使用Redis Pub / Sub异步通信,使用R​​edis作为缓存或主数据库,最后使用Redis作为配置服务器。

Redis作为配置服务器

如果您已经使用Spring Cloud构建了微服务,那么您可能对Spring Cloud Config有一些经验。它负责为微服务提供分布式配置模式。

不幸的是,Spring Cloud Config不支持Redis作为属性源的后端存储库。这就是我决定分叉Spring Cloud Config项目并实现此功能的原因。

我希望我的实现很快将被包含在官方的Spring Cloud版本中,但是,现在,您可以使用我的fork repo来运行它。我们怎么用呢?非常简单。让我们来看看。

Spring Boot的当前SNAPSHOT版本2.2.0.BUILD-SNAPSHOT与我们用于Spring Cloud Config的版本相同。在构建Spring Cloud Config Server时,我们只需要包含这两个依赖项,如下所示。

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>config-service</artifactId>
<groupId>pl.piomin.services</groupId>
<version>1.0-SNAPSHOT</version>
<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    <version>2.2.0.BUILD-SNAPSHOT</version>
  </dependency>
</dependencies>

默认情况下,Spring Cloud Config Server使用Git存储库后端。我们需要激活 redis配置文件以强制它使用Redis作为后端。如果您的Redis实例侦听的地址不是localhost:6379您需要使用spring.redis.*属性覆盖自动配置的连接设置 。这是我们的bootstrap.yml文件。

spring:
 application:
  name: config-service
 profiles:
  active: redis
 redis:
  host: 192.168.99.100

应用程序主类应注释@EnableConfigServer:

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
  public static void main(String[] args) {
    new SpringApplicationBuilder(ConfigApplication.class).run(args);
  }
}

在运行应用程序之前,我们需要启动Redis实例。这是将其作为Docker容器运行并在端口6379上公开的命令。

$ docker run -d --name redis -p 6379:6379 redis

每个应用程序的配置必须在密钥{spring.application.name}或{spring.application.name}-${spring.profiles.active[n]}。我们必须使用与配置属性名称对应的键创建哈希。

我们的示例应用程序driver-management使用三个配置属性:server.port用于设置HTTP侦听端口,spring.redis.host用于更改用作消息代理和数据库的默认Redis地址,以及sample.topic.name用于设置用于我们的微服务之间的异步通信的主题的名称。这是我们为driver-management使用RDBTools可视化而创建的Redis哈希的结构。

在Redis CLI 中运行HGETALL ,返回:

>> HGETALL driver-management
{
  "server.port": "8100",
   "sample.topic.name": "trips",
   "spring.redis.host": "192.168.99.100"
}

在Redis中设置键值并使用redis配置文件运行Spring Cloud Config Server之后,我们需要在客户端启用分布式配置功能。要做到这一点,我们只需要包含对每个微服务的spring-cloud-starter-config依赖pom.xml。

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

使用最新稳定的Spring Cloud:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Greenwich.SR1</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

应用程序的名称是spring.application.name在启动时从属性中获取的,因此我们需要提供以下bootstrap.yml文件。

spring:
 application:
  name: driver-management

Redis作为消息代理

现在我们可以在基于微服务的体系结构中继续使用Redis的第二个用例 - 消息代理。我们将实现一个典型的异步系统。

微服务trip-management在创建新行程后以及完成当前行程后向Redis Pub / Sub发送通知。通知由订阅特定频道的driver-management和接收 。

我们的应用非常简单。我们只需要添加以下依赖项,以便提供REST API并与Redis Pub / Sub集成。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

我们应该使用频道channel名称和发布者注册bean。TripPublisher负责向目标主题发送消息。

@Configuration
public class TripConfiguration {
  @Autowired
    RedisTemplate<?, ?> redisTemplate;
  @Bean
    TripPublisher redisPublisher() {
    return new TripPublisher(redisTemplate, topic());
  }
  @Bean
    ChannelTopic topic() {
    return new ChannelTopic("trips");
  }
}

TripPublisher使用RedisTemplate将消息发送到的话题。在发送之前,它会使用Jackson2JsonRedisSerializer对来自对象的每条消息转换为JSON字符串。

public class TripPublisher {
  private static final Logger LOGGER = LoggerFactory.getLogger(TripPublisher.class);
  RedisTemplate<?, ?> redisTemplate;
  ChannelTopic topic;
  public TripPublisher(RedisTemplate<?, ?> redisTemplate, ChannelTopic topic) {
    this.redisTemplate = redisTemplate;
    this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Trip.class));
    this.topic = topic;
  }
  public void publish(Trip trip) throws JsonProcessingException {
    LOGGER.info("Sending: {}", trip);
    redisTemplate.convertAndSend(topic.getTopic(), trip);
  }
}

我们已经在发布者方面实现了逻辑。现在,我们可以继续在消费接受方面的代码事先。

我们有两个微服务driver-management,passenger-management,它们监听trip-management微服务发送的通知 。我们需要定义RedisMessageListenerContainerbean并设置消息监听器实现类。

@Configuration
public class DriverConfiguration {
  @Autowired
    RedisConnectionFactory redisConnectionFactory;
  @Bean
    RedisMessageListenerContainer container() {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.addMessageListener(messageListener(), topic());
    container.setConnectionFactory(redisConnectionFactory);
    return container;
  }
  @Bean
    MessageListenerAdapter messageListener() {
    return new MessageListenerAdapter(new DriverSubscriber());
  }
  @Bean
    ChannelTopic topic() {
    return new ChannelTopic("trips");
  }
}

负责处理传入通知的类需要实现该 MessageListener接口。收到消息后, DriverSubscriber将其从JSON反序列化到对象并更改驱动程序的状态。

@Service
public class DriverSubscriber implements MessageListener {
  private final Logger LOGGER = LoggerFactory.getLogger(DriverSubscriber.class);
  @Autowired
    DriverRepository repository;
  ObjectMapper mapper = new ObjectMapper();
  @Override
    public void onMessage(Message message, byte[] bytes) {
    try {
      Trip trip = mapper.readValue(message.getBody(), Trip.class);
      LOGGER.info("Message received: {}", trip.toString());
      Optional<Driver> optDriver = repository.findById(trip.getDriverId());
      if (optDriver.isPresent()) {
        Driver driver = optDriver.get();
        if (trip.getStatus() == TripStatus.DONE)
                  driver.setStatus(DriverStatus.WAITING); else
                  driver.setStatus(DriverStatus.BUSY);
        repository.save(driver);
      }
    }
    catch (IOException e) {
      LOGGER.error("Error reading message", e);
    }
  }
}

Redis作为主数据库

虽然使用Redis的主要目的是内存中缓存或作为键/值存储,但它也可以充当应用程序的主数据库。在这种情况下,以持久模式运行Redis是值得的。

$ docker run -d --name redis -p 6379:6379 redis redis-server --appendonly yes

实体使用哈希散列操作和mmap结构存储在Redis中。每个实体都需要一个哈希键和id。

@RedisHash("driver")
public class Driver {
  @Id
    private long id;
  private String name;
  @GeoIndexed
    private Point location;
  private DriverStatus status;
  // setters and getters ...
}

幸运的是,Spring Data Redis为Redis集成提供了一个众所周知的存储库模式。要启用它,我们应该使用@EnableRedisRepositories注释配置类或主类。使用Spring存储库模式时,我们不必自己构建对Redis的任何查询。

@Configuration
@EnableRedisRepositories
public class DriverConfiguration {
  // logic ...
}

使用Spring Data存储库,我们不必构建任何Redis查询,只需遵循Spring Data的约定下的名称方法。为了我们的示例目的,我们可以使用Spring Data中实现的默认方法。这是存储库接口的声明driver-management。

public interface DriverRepository extends CrudRepository<Driver, Long> {}

不要忘记通过使用@EnableRedisRepositories注释主应用程序类或配置类来启用Spring Data存储库。

@Configuration
@EnableRedisRepositories
public class DriverConfiguration {
  ...
}

结论

正如我在前言中提到的,Redis在微服务架构中有各种用例。我刚刚介绍了如何与Spring Cloud和Spring Data一起使用它来提供配置服务器,消息代理和数据库。Redis通常被认为是缓存存储,但我希望在阅读本文之后,您将改变主意。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Redis数据库的应用场景介绍

    一.MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: 1)MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间. 2)Memcached与MySQL数据库数据一致性问题. 3)Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支

  • Redis数据库的使用场景介绍(避免误用Redis)

    Redis 是目前 NoSQL 领域的当红炸子鸡,它象一把瑞士军刀,小巧.锋利.实用,特别适合解决一些使用传统关系数据库难以解决的问题.但是 Redis 不是银弹,有很多适合它解决的问题,但是也有很多并不适合它解决的问题.另外,Redis 作为内存数据库,如果用在不适合的场合,对内存的消耗是很可观的,甚至会让系统难以承受. 我们可以对系统存储使用的数据以两种角度分类,一种是按数据的大小划分,分成大数据和小数据,另一种是按数据的冷热程度划分,分成冷数据和热数据,热数据是指读或写比较频繁的数据,反之

  • redis适合场景八点总结

    redis适合什么场景? 1.缓存 缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多. 2.排行榜 很多网站都有排行榜应用的,如京东的月度销量榜单.商品按时间的上新排行榜等.Redis提供的有序集合数据类构能实现各种复杂的排行榜应用. 3.计数器 什么是计数器,如电商网站商品的浏览量.视频网站视频的播放数等.为了保证数据实时效,每次浏览都得给

  • Redis的11种Web应用场景简介

    下面列出11种Web应用场景,在这些场景下可以充分的利用Redis的特性,大大提高效率. 1.在主页中显示最新的项目列表 Redis使用的是常驻内存的缓存,速度非常快.LPUSH用来插入一个内容ID,作为关键字存储在列表头部.LTRIM用来限制列表中的项目数最多为5000.如果用户需要的检索的数据量超越这个缓存容量,这时才需要把请求发送到数据库. 2.删除和过滤 如果一篇文章被删除,可以使用LREM从缓存中彻底清除掉. 3.排行榜及相关问题 排行榜(leader board)按照得分进行排序.Z

  • Redis介绍和使用场景详解

    本篇文章主要介绍了Redis介绍和使用场景,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 (1)持久化数据库的缺点 平常我们使用的关系型数据库有Mysql.Oracle以及SqlServer等,在开发的过程中,数据通常都是通过Web提供的数据库驱动来链接数据库进行增删改查. 那么,我们日常使用的数据库的数据都储存在哪里呢?我们以Mysql为例. 打开我们Mysql所在的文件夹目录下的data文件夹,如下所示: 我们可以发现,里面都是我们创建的数据库,打开其中一个,可

  • 项目中应用Redis+Php的场景

    前言 一些案例中有的同学说为什么不可以用string类型,string类型完全可以实现呀 我建议你看下我的专栏文章<Redis高级用法>,里面介绍了用hash类型的好处 商品维度计数 对商品喜欢数,评论数,鉴定数,浏览数进行计数 说起电商,肯定离不开商品,而附带商品有各种计数(喜欢数,评论数,鉴定数,浏览数,etc) Redis的命令都是原子性的,你可以轻松地利用INCR,DECR等命令来计数. 采用Redis 的类型: Hash. 如果你对redis数据类型不太熟悉,可以参考 http://

  • 深入解析Redis中常见的应用场景

    前言 Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景.下面话不多说了,来一起看看详细的介绍吧. Redis特性 一个产品的使用场景肯定是需要根据产品的特性,先列举一下Redis的特点: 读写性能优异 持久化 数据类型丰富 单线程 数据自动过期 发布订阅 分布式 这里我们通过几个场景,不同维度说下Redis的应用. 高性能适合当做缓存 缓存是Redis最常见的应用场景,之所有这么使

  • 浅谈Redis在微服务架构中的几种应用场景

    本文介绍在SpringCloud中使用Redis作为Pub/Sub异步通信.缓存或主数据库和配置服务器的三种场景应用. Redis可以广泛用于微服务架构.它可能是您应用程序以多种不同方式利用的少数流行软件解决方案之一.根据要求,它可以充当主数据库,缓存或消息代理.虽然它也是一个键/值存储,但我们可以将它用作微服务体系结构中的配置服务器或发现服务器.虽然它通常被定义为内存中的数据结构,但我们也可以在持久模式下运行它. 这里我将向您展示一些使用Redis与Spring Boot和Spring Clo

  • 浅谈Redis高并发缓存架构性能优化实战

    目录 场景1: 中小型公司Redis缓存架构以及线上问题实战 场景2: 大厂线上大规模商品缓存数据冷热分离实战 场景3: 基于DCL机制解决热点缓存并发重建问题实战 场景4: 突发性热点缓存重建导致系统压力暴增 场景5: 解决大规模缓存击穿导致线上数据库压力暴增 场景6: 黑客工资导致缓存穿透线上数据库宕机 场景7: 大V直播带货导致线上商品系统崩溃原因分析 场景8: Redis分布式锁解决缓存与数据库双写不一致问题实战 场景9: 大促压力暴增导致分布式锁串行争用问题优化 场景10: 利用多级缓

  • 浅谈Spring Boot 微服务项目的推荐部署方式

    如果开发过spring boot的程序,应该都知道,使用spring boot官方的maven打包插件(spring-boot-maven-plugin) 来打包,打出来的jar包一般有40M以上. 如果公司的服务器上传带宽不高,那么手动上传一个jar或者jenkins部署一次jar,都是非常痛苦的........ 但是,如果打包的时候不引入lib,那么打出来的jar包一般只有几十k而已,非常小,想怎么传就怎么传......... 本文会提供一个bash启动脚本,只需要稍做更改,即可适应你的程序

  • 微服务架构之服务注册与发现功能详解

    目录 微服务的注册与发现 1.服务注册 2.服务发现 3.注册中心 4.现下的主流注册中心 4.1 Eureka 4.1.1 介绍 4.1.2 整体架构 4.1.3 接入Spring Cloud 4.2 ZooKeeper 4.2.1 介绍 4.2.2 整体架构 4.2.3 接入Dubbo生态 4.3 Consul 4.3.1 介绍 4.3.2 整体架构 4.3.3 生态对接 4.4 总结对比 详解微服务架构及其演进史 微服务全景架构全面瓦解 微服务架构拆分策略详解 微服务的注册与发现 我们前面

  • Spring Cloud微服务架构的构建:分布式配置中心(加密解密功能)

    前言 要会用,首先要了解.图懒得画,借鉴网上大牛的图吧,springcloud组建架构如图: 微服务架构的应用场景: 1.系统拆分,多个子系统 2.每个子系统可部署多个应用,应用之间负载均衡实现 3.需要一个服务注册中心,所有的服务都在注册中心注册,负载均衡也是通过在注册中心注册的服务来使用一定策略来实现. 4.所有的客户端都通过同一个网关地址访问后台的服务,通过路由配置,网关来判断一个URL请求由哪个服务处理.请求转发到服务上的时候也使用负载均衡. 5.服务之间有时候也需要相互访问.例如有一个

  • 解析SpringCloud简介与微服务架构

    1. 微服务架构 1.1 微服务架构理解 微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦.你可以将其看作是在架构层次而非获取服务的类上应用很多SOLID原则.微服务架构是个很有趣的概念,它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持. 概念:把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等

  • 详解微服务架构及其演进史

    目录 1 传统单体系统介绍 1.1 单体系统的问题 1.2 单体系统的优点 1.3 单体服务到微服务的发展过程 2 关于微服务 2.1 单一职责 2.2 轻量级通信 2.3 独立性 2.4 进程隔离 2.5 混合技术栈和混合部署方式 2.6 简化治理 2.7 安全可靠,可维护. 3 微服务演进史 3.1 第一阶:简单服务通信模块 3.2 第二阶:原始通信时代 3.3 第三阶:TCP时代 3.4 第四阶:第一代微服务(Spring Cloud/RPC) 3.5 第五阶:第二代微服务 3.6 第六阶

  • 微服务架构之服务注册与发现实践示例详解

    目录 1 服务注册中心 4种注册中心技术对比 2 Spring Cloud 框架下实现 2.1 Spring Cloud Eureka 2.1.1 创建注册中心 2.1.2 创建客户端 2.2 Spring Cloud Consul 2.2.1 Consul 的优势 2.2.2 Consul的特性 2.2.3 安装Consul注册中心 2.2.4 创建服务提供者 3 总结 微服务系列前篇 详解微服务架构及其演进史 微服务全景架构全面瓦解 微服务架构拆分策略详解 微服务架构之服务注册与发现功能详解

  • 浅谈架构模式变迁之从分层架构到微服务架构

    前言 谈到软件系统设计的方法论,在代码层面,有我们熟悉的23种设计模式(design pattern),对应到架构层面,则有所谓的架构模式(architecture pattern).它们分别从微观和宏观的角度指导着我们设计出良好的软件系统,因此,作为一个软件工程师,我们不仅要熟悉设计模式,对常见的架构模式也要熟稔于心.正如看到一个设计模式的名字脑里就能浮现出大致的结构图,当我们看到一个架构模式的名字时,也要马上想到对应的架构图及其基本特点.比如,当谈到分层架构时,我们就应该想起它的架构图是怎样

  • 浅谈SpringCloud实现简单的微服务架构

    Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路器.数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署.Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂.易部署和易维护的分布式系统开发工具包. 接下

随机推荐