浅析JavaWeb项目架构之Redis分布式日志队列

 更新时间:2018年01月19日 09:56:06   作者:小柒2012  
架构、分布式、日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Redis做消息队列罢了。下面通过本文给大家分享JavaWeb项目架构之Redis分布式日志队列,感兴趣的朋友一起看看吧

摘要:

架构、分布式、日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Redis做消息队列罢了。 为什么需要消息队列? 当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列,作为抽象层,弥合双方的差异。

架构、分布式、日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Redis做消息队列罢了。

为什么需要消息队列?

当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列,作为抽象层,弥合双方的差异。

比如我们系统中常见的邮件、短信发送,把这些不需要及时响应的功能写入队列,异步处理请求,减少响应时间。

如何实现?

成熟的JMS消息队列中间件产品市面上有很多,但是基于目前项目的架构以及部署情况,我们采用Redis做消息队列。

为什么用Redis?

Redis中list数据结构,具有“双端队列”的特性,同时redis具有持久数据的能力,因此redis实现分布式队列是非常安全可靠的。

它类似于JMS中的“Queue”,只不过功能和可靠性(事务性)并没有JMS严格。Redis本身的高性能和"便捷的"分布式设计(replicas,sharding),可以为实现"分布式队列"提供了良好的基础。

提供者端

项目采用第三方redis插件spring-data-redis,不清楚如何使用的请自行谷歌或者百度。

redis.properties:

#redis 配置中心 
redis.host=192.168.1.180
redis.port=6379
redis.password=123456
redis.maxIdle=100 
redis.maxActive=300 
redis.maxWait=1000 
redis.testOnBorrow=true 
redis.timeout=100000

redis配置:

 <!-- redis 配置 -->
  <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />
  <bean id="jedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="${redis.host}" />
    <property name="port" value="${redis.port}" />
    <property name="password" value="${redis.password}" />
    <property name="timeout" value="${redis.timeout}" />
    <property name="poolConfig" ref="jedisPoolConfig" />
    <property name="usePool" value="true" />
  </bean>
  <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
  </bean>

切面日志配置(伪代码):

/**
 * 系统日志,切面处理类
 * 创建者 小柒2012
 * 创建时间  2018年1月15日
 */
@Component
@Scope
@Aspect
public class SysLogAspect {
  @Autowired
  private RedisTemplate<String, String> redisTemplate;
  //注解是基于swagger的API,也可以自行定义
  @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
  public void logPointCut() { 
  }
  @Around("logPointCut()")
  public Object around(ProceedingJoinPoint point) throws Throwable {
    Object result = point.proceed();
    //把日志消息写入itstyle_log频道
    redisTemplate.convertAndSend("itstyle_log","日志数据,自行处理");
    return result;
  }
}

消费者端

Redis配置:

<!-- redis 配置 -->
  <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />
  <bean id="jedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="${redis.host}" />
    <property name="port" value="${redis.port}" />
    <property name="password" value="${redis.password}" />
    <property name="timeout" value="${redis.timeout}" />
    <property name="poolConfig" ref="jedisPoolConfig" />
    <property name="usePool" value="true" />
  </bean>
  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" 
          p:connection-factory-ref="jedisConnectionFactory"> 
    <property name="keySerializer"> 
      <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> 
    </property> 
    <property name="hashKeySerializer"> 
      <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> 
    </property> 
  </bean>
  <!-- 监听实现类 -->
  <bean id="listener" class="com.itstyle.market.common.listener.MessageDelegateListenerImpl"/>
  <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
  <redis:listener-container connection-factory="jedisConnectionFactory">
    <!-- topic代表监听的频道,是一个正规匹配 其实就是你要订阅的频道-->
    <redis:listener ref="listener" serializer="stringRedisSerializer" method="handleLog" topic="itstyle_log"/>
  </redis:listener-container>

监听接口:

public interface MessageDelegateListener {
  public void handleLog(Serializable message);
}

监听实现:

public class MessageDelegateListenerImpl implements MessageDelegateListener {
    @Override
    public void handleLog(Serializable message) {
      if(message == null){
        System.out.println("null");
      }else {
        //处理日志数据
      }
    }
}

Q&A

【问题一】为什么使用Redis?

上面其实已经有做说明,尽管市面上有许多很稳定的产品,比如可能大家会想到的Kafka、RabbitMQ以及RocketMQ。但是由于项目本身使用了Redis做分布式缓存,基于省事可行的原则就选定了Redis。

【问题二】日志数据如何存储?

原则上是不建议存储到关系数据库的,比如MySql,毕竟产生的日志数量是巨大的,建议存储到Elasticsearch等非关系型数据库。

【问题三】切面日志收集是如何实现的?

切面日志需要引入spring-aspects相关Jar包,并且配置使Spring采用CGLIB代理 。

开源项目源码(参考):https://gitee.com/52itstyle/spring-boot-mail

总结

以上所述是小编给大家介绍的JavaWeb项目架构之Redis分布式日志队列,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • Java8之函数式接口及常用函数式接口讲解

    Java8之函数式接口及常用函数式接口讲解

    这篇文章主要介绍了Java8之函数式接口及常用函数式接口,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java中对AtomicInteger和int值在多线程下递增操作的测试

    Java中对AtomicInteger和int值在多线程下递增操作的测试

    这篇文章主要介绍了Java中对AtomicInteger和int值在多线程下递增操作的测试,本文得出AtomicInteger操作 与 int操作的效率大致相差在50-80倍上下的结论,需要的朋友可以参考下
    2014-09-09
  • 关于postman传参的几种格式 list,map 等

    关于postman传参的几种格式 list,map 等

    这篇文章主要介绍了postman传参的几种格式 list,map等,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java使用Hutool+自定义注解实现数据脱敏

    Java使用Hutool+自定义注解实现数据脱敏

    我们在使用手机银行的时候经常能看到APP上会将银行卡的卡号中间部分给隐藏掉使用 ***** 来代替,在某些网站上查看一些业务密码时(例如签到密码等)也会使用 ***** 来隐藏掉真正的密码,那么这种方式是如何实现的呢,本文将给大家介绍使用Hutool+自定义注解实现数据脱敏
    2023-09-09
  • Java进阶核心之InputStream流深入讲解

    Java进阶核心之InputStream流深入讲解

    这篇文章主要给大家介绍了关于Java进阶核心之InputStream流的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • java模拟cookie登陆操作

    java模拟cookie登陆操作

    这篇文章主要为大家详细介绍了java模拟cookie登陆操作,模拟登陆,取得cookie以记录身份,下次请求时发送cookie以表明身份,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java连接Hbase的项目实践

    Java连接Hbase的项目实践

    HBase是基于Hadoop的高可靠、高性能、面向列的NoSQL数据库,它提供了对海量数据的存储和实时读写的能力,本文主要介绍了Java连接Hbase的项目实践,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • springboot+thymeleaf 文件上传功能的实现代码

    springboot+thymeleaf 文件上传功能的实现代码

    这篇文章主要介绍了springboot+thymeleaf 文件上传功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Spring整合Mybatis思路梳理总结

    Spring整合Mybatis思路梳理总结

    mybatis-plus是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生,下面这篇文章主要给大家介绍了关于SpringBoot整合Mybatis-plus案例及用法实例的相关资料,需要的朋友可以参考下
    2022-12-12
  • java实现可视化界面肯德基(KFC)点餐系统代码实例

    java实现可视化界面肯德基(KFC)点餐系统代码实例

    这篇文章主要介绍了java肯德基点餐系统,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05

最新评论