JavaWeb項目架構之Redis分布式日誌隊列

來源:互聯網
上載者:User

標籤:ota   開源   col   size   ring   out   外掛程式   core   技術   

架構、分布式、日誌隊列,標題自己都看著唬人,其實就是一個日誌收集的功能,只不過中間加了一個Redis做訊息佇列罷了。

前言為什麼需要訊息佇列?

當系統中出現“生產“和“消費“的速度或穩定性等因素不一致的時候,就需要訊息佇列,作為抽象層,彌合雙方的差異。

比如我們系統中常見的郵件、簡訊發送,把這些不需要及時響應的功能寫入隊列,非同步處理請求,減少回應時間。

如何??

成熟的JMS訊息佇列中介軟體產品市面上有很多,但是基於目前項目的架構以及部署情況,我們採用Redis做訊息佇列。

為什麼用Redis?

Redis中list資料結構,具有“雙端隊列”的特性,同時redis具有持久資料的能力,因此redis實現分布式隊列是非常安全可靠的。

它類似於JMS中的“Queue”,只不過功能和可靠性(事務性)並沒有JMS嚴格。Redis本身的高效能和"便捷的"分布式設計(replicas,sharding),可以為實現"分布式隊列"提供了良好的基礎。

提供者端

項目採用第三方redis外掛程式spring-data-redis,不清楚如何使用的請自行Google或者百度。

redis.properties:

#redis 配置中心 redis.host=192.168.1.180redis.port=6379redis.password=123456redis.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@Aspectpublic 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代理 <aop:aspectj-autoproxy proxy-target-class="true" />。

開源項目源碼(參考):https://gitee.com/52itstyle/spring-boot-mail

小柒

出處: https://blog.52itstyle.com

分享是快樂的,也見證了個人成長曆程,文章大多都是工作經驗總結以及平時學習積累,基於自身認知不足之處在所難免,也請大家指正,共同進步。

JavaWeb項目架構之Redis分布式日誌隊列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.