zoukankan      html  css  js  c++  java
  • 19.docker 安装 RocketMq 并配置log4j2来收集日志

    一.安装docker RocketMq

    1.创建 nameSrv 数据挂载文件夹

    mkdir -p data/rocketMQ/data/namesrv/logs
    mkdir -p data/rocketMQ/data/namesrv/store

     2.查看RocketMq镜像来源

    docker search rocketmq
    

      

     3.找个star 最多的,我选择的是rocketmqinc/rocketmq

    docker pull rocketmqinc/rocketmq
    

      

     4.启动 namesrv 服务

    docker run -d -p 9876:9876 -v /data/rocketMQ/data/namesrv/logs:/root/logs -v /data/rocketMQ/data/namesrv/store:/root/store --name rmqnamesrv -e "MAX_POSSIBLE_HEAP=100000000" docker.io/rocketmqinc/rocketmq sh mqnamesrv

     

     5.安装 broker

    创建 broker 配置文件挂载文件夹

    mkdir -p /data/rocketMQ/data/broker/logs
    mkdir -p /data/rocketMQ/data/broker/store
    mkdir -p /data/rocketMQ/data/broker/conf/
    

      

     6.新增 broker 配置文件,在 /data/rocketMQ/data/broker/conf 目录下创建 broker.conf 文件,内容如下:

    brokerClusterName = DefaultCluster
    brokerName = broker-a
    brokerId = 0
    deleteWhen = 04
    fileReservedTime = 48
    brokerRole = ASYNC_MASTER
    flushDiskType = ASYNC_FLUSH
    #自己的ip brokerIP1 = 192.168.88.50

      

     

     7.运行 broker 容器

    docker run -d -p 10911:10911 -p 10909:10909 -v /data/rocketMQ/data/broker/logs:/root/logs -v /data/rocketMQ/data/broker/store:/root/store -v /data/rocketMQ/data/broker/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf --name rmqbroker --link rmqnamesrv:rmqnamesrv -e "NAMESRV_ADDR=192.168.88.50:9876" -e "MAX_POSSIBLE_HEAP=200000000" rocketmqinc/rocketmq:4.4.0 sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf
    

      

     8.安装控制台

    docker search rocketmq-console
    

      同样选择一个,我选择styletang/rocketmq-console-ng 

     9.获取控制台

    docker pull styletang/rocketmq-console-ng
    

      

    10.启动控制台镜像

    #注意红色地址采用的是上面nameSrv 配置的
    docker run -d -p 8080:8080 -e "JAVA_OPTS=-Drocketmq.config.namesrvAddr=192.168.88.50:9876 -Drocketmq.config.isVIPChannel=false" -t styletang/rocketmq-console-ng

      

     浏览器登录

    http://192.168.88.50:8080
    

    二.配置springboot log4j2配置文件

     1.在RocketMq平台新增主题 Log4j2ToRocketMq

     2.spring-boot 项目 log4j2.xml 配置

    由于log4j2暂时没有支持RocketMq,决定扩展AbstractAppender来实现自己的RocketMqAppender

    首先maven部分

          <!--RocketMQ-->
            <dependency>
                <groupId>org.apache.rocketmq</groupId>
                <artifactId>rocketmq-spring-boot-starter</artifactId>
                <version>2.0.4</version>
            </dependency>
            <!--log4j2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-log4j2</artifactId>
            </dependency>        
    

      RocketMqAppender 实现,后续优化

    package com.company.project.appenders;
    
    import org.apache.logging.log4j.core.Filter;
    import org.apache.logging.log4j.core.Layout;
    import org.apache.logging.log4j.core.LogEvent;
    import org.apache.logging.log4j.core.appender.AbstractAppender;
    import org.apache.logging.log4j.core.appender.AppenderLoggingException;
    import org.apache.logging.log4j.core.config.plugins.Plugin;
    import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
    import org.apache.logging.log4j.core.config.plugins.PluginElement;
    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    import org.apache.logging.log4j.core.layout.PatternLayout;
    import org.apache.rocketmq.client.producer.DefaultMQProducer;
    import org.apache.rocketmq.common.message.Message;
    
    import java.io.Serializable;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    
    /**
     * 自定义Appender,继承 AbstractAppender 只需要覆盖自已想要的方法即可<br>
     * 类上面的注解是用来设置配置文件中的标签。
     */
    @Plugin(name = "RocketMqAppender", category = "Core", elementType = "appender", printObject = true)
    public final class RocketMqAppender extends AbstractAppender implements Serializable {
    
        private static final long serialVersionUID = -5120699436731845929L;
        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
        private final Lock readLock = rwLock.readLock();
        private static DefaultMQProducer producer;
        private static String rocketMqNameserver;
        private static String rocketMqProducerGroup;
        private static String rocketMqMsgTopic;
        private static String rocketMqMsgTag;
    
        //需要实现的构造方法,直接使用父类就行
        private RocketMqAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final boolean ignoreExceptions, String server, String group, String topic, String tag) {
            super(name, filter, layout, ignoreExceptions);
            initRocketMq(server, group, topic, tag);
        }
    
        private void initRocketMq(String server, String group, String topic, String tag) {
            if(this.producer==null){
                this.rocketMqNameserver = server;
                this.rocketMqProducerGroup = group;
                this.rocketMqMsgTopic = topic;
                this.rocketMqMsgTag = tag;
                this.producer = new DefaultMQProducer(this.rocketMqProducerGroup);
                producer.setNamesrvAddr(this.rocketMqNameserver);
                try {
                    producer.shutdown();
                    producer.start();
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }
    
        @Override
        public void append(LogEvent logEvent) {
            readLock.lock();
            try {
                final byte[] bytes = getLayout().toByteArray(logEvent);//日志二进制文件,输出到指定位置就行
                //下面这个是要实现的自定义逻辑
                //String strLog = new String(bytes);
                //System.out.println(strLog);
                if (producer != null) {
                    Message msg = new Message(this.rocketMqMsgTopic, this.rocketMqMsgTag, bytes);
                    producer.sendOneway(msg);
                    msg = null;
                }
            } catch (Exception ex) {
                if (!ignoreExceptions()) {
                    throw new AppenderLoggingException(ex);
                }
            } finally {
                readLock.unlock();
            }
        }
    
        // 下面这个方法可以接收配置文件中的参数信息
        @PluginFactory
        public static RocketMqAppender createAppender(@PluginAttribute("name") String name,
                                                      @PluginAttribute("server") String server,
                                                      @PluginAttribute("group") String group,
                                                      @PluginAttribute("topic") String topic,
                                                      @PluginAttribute("tag") String tag,
                                                      @PluginElement("Filter") final Filter filter,
                                                      @PluginElement("Layout") Layout<? extends Serializable> layout,
                                                      @PluginAttribute("ignoreExceptions") boolean ignoreExceptions) {
            if (name == null || server == null || group == null || topic == null) {
                LOGGER.error("PluginAttribute error");
                return null;
            }
            if (layout == null) {
                layout = PatternLayout.createDefaultLayout();
            }
            return new RocketMqAppender(name, filter, layout, ignoreExceptions, server, group, topic, tag);
        }
    }
    

      log4j2.xml 配置文件

    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!--
    	自定义命名格式:
    	%d:发生时间,%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2020-02-20 22:10:28,921
    	%F:输出所在的类文件名
    	%t:线程名称
    	%p:日志级别
    	%c:日志消息所在类名
    	%m:消息内容
    	%M:输出所在函数名
    	%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
    	%l:执行的函数名(类名称:行号)com.core.LogHelper.aroundService(LogHelper.java:32)
    	%n:换行
    	%i:从1开始自增数字
    	%-5level:输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
    	“${sys:user.home}”是HOME目录 如:C:Usersheave, 此处指定任意目录如:D:logs
    -->
    <!--设置log4j2自身log级别为warn,每间隔30秒数自动检测配置是否发生修改,并重新配置-->
    <configuration status="warn" monitorInterval="30">
        <Properties>
            <!-- 日志显示模板,显示内容的格式如下 -->
            <!-- [21:55:33:047] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing Spring embedded WebApplicationContext -->
            <Property name="log_pattern" value="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p][%t] - %l - %m%n"/>
            <!-- 保存日志文件目录 -->
            <!--<Property name="file_path" value="${sys:user.home}/logs"/>-->
            <Property name="file_path" value="/tmp/spring-boot-web"/>
            <!-- 日志文件的最大容量,超过该值就进行备份 -->
            <Property name="file_max_size" value="30MB"/>
            <!-- 备份的文件夹名称 如下为:2020-02 -->
            <Property name="backup_folder" value="$${date:yyyy-MM}"/>
            <!-- 备份文件的后缀,日志文件超过file_max_size会备份到filePattern指定的目录下 -->
            <Property name="backup_file_suffix" value="-%d{yyyy-MM-dd}-%i.log"/>
        </Properties>
        <!--定义appender-->
        <appenders>
            <!--控制台的输出配置-->
            <console name="Console" target="SYSTEM_OUT">
                <!-- 设置控制台只输出INFO及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
                <!--输出日志的格式-->
                <PatternLayout pattern="${log_pattern}"/>
            </console>
    
            <!-- 所有的日志信息会打印到此文件中,append=false每次启动程序会自动清空 -->
            <!-- <File name="all" fileName="${file_path}/all.log" append="true">
                <PatternLayout pattern="${log_pattern}"/>
            </File>-->
    
            <!--
            该RollingFile存储INFO级别的日志,
            默认存储到 fileName 文件中
            超过SizeBasedTriggeringPolicy的设定值,则存储到 filePattern 文件中
            -->
            <RollingFile name="RollingFileInfo" fileName="${file_path}/info.log"
                         filePattern="${file_path}/${backup_folder}/info${backup_file_suffix}">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
                <!-- 写入日志文件的模板 -->
                <PatternLayout pattern="${log_pattern}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="${file_max_size}"/>
                </Policies>
                <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
                <DefaultRolloverStrategy max="20"/>
            </RollingFile>
            <RollingFile name="RollingFileWarn" fileName="${file_path}/warn.log"
                         filePattern="${file_path}/${backup_folder}/warn${backup_file_suffix}">
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="${log_pattern}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="${file_max_size}"/>
                </Policies>
            </RollingFile>
            <RollingFile name="RollingFileError" fileName="${file_path}/error.log"
                         filePattern="${file_path}/${backup_folder}/error${backup_file_suffix}">
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="${log_pattern}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="${file_max_size}"/>
                </Policies>
            </RollingFile>
    
            <!-- 这个就是自定义的Appender -->
            <RocketMqAppender
                    name="RocketMqInfo"
                    server="192.168.88.50:9876"
                    group="SpringBootWeb-ProducerGroup"
                    topic="Log4j2ToRocketMq"
                    tag="spring-boot-web">
                <PatternLayout pattern="${log_pattern}" />
            </RocketMqAppender>
        </appenders>
        <!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
        <loggers>
            <!--过滤掉spring和hibernate的一些无用的debug信息-->
            <logger name="org.springframework" level="INFO"/>
            <logger name="org.mybatis" level="INFO">
                <!-- 添加如下设置,控制台会再打印一次 -->
                <AppenderRef ref="Console"/>
            </logger>
            <root level="INFO">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFileInfo"/>
                <appender-ref ref="RollingFileWarn"/>
                <appender-ref ref="RollingFileError"/>
                <appender-ref ref="RocketMqInfo"/>
            </root>
        </loggers>
    </configuration>
    

      

    三.消费MQ队列消息

    package com.company.project.mq;
    
    import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
    import org.apache.rocketmq.spring.core.RocketMQListener;
    import org.springframework.stereotype.Service;
    
    @Service
    @RocketMQMessageListener(consumerGroup = "SpringBootWeb-ConsumerGroup", topic = "Log4j2ToRocketMq")
    public class RocketConsumer implements RocketMQListener<String> {
    
        @Override
        public void onMessage(String message) {
            //System.err.println("接收到消息:" + message);
            //System.err.println("接收到消息一条" );
        }
    }
    

      

    参考:

    https://www.cnblogs.com/moxiaodan/p/13800016.html

  • 相关阅读:
    时间插件--daterangepicker使用和配置详解
    AdminLTE 前端框架
    vue element-ui 绑定@keyup事件无效
    Plugin/Preset files are not allowed to export objects,webpack报错/babel报错的解决方法
    webpack学习
    指令
    【Nuxt】配置路由
    【面试】常见面试题
    安装虚拟机
    【linux】基础知识
  • 原文地址:https://www.cnblogs.com/ff111/p/15191441.html
Copyright © 2011-2022 走看看