gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 24 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章浅析JavaWeb项目架构之Redis分布式日志队列由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

摘要:

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

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

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

为什么需要消息队列?

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

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

如何实现?

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

为什么用Redis?

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

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

提供者端 。

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

redis.properties:

?
1
2
3
4
5
6
7
8
9
#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配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 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>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
  * 系统日志,切面处理类
  * 创建者 小柒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配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 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>

监听接口:

?
1
2
3
public interface MessageDelegateListener {
   public void handleLog(Serializable message);
}

监听实现:

?
1
2
3
4
5
6
7
8
9
10
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分布式日志队列,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。

原文链接:https://yq.aliyun.com/articles/368401 。

最后此篇关于浅析JavaWeb项目架构之Redis分布式日志队列的文章就讲到这里了,如果你想了解更多关于浅析JavaWeb项目架构之Redis分布式日志队列的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com