美文网首页SpringBoot
SpringBoot(六、任务,日志,多环境配置)

SpringBoot(六、任务,日志,多环境配置)

作者: 强某某 | 来源:发表于2019-05-14 14:20 被阅读0次

任务

常见任务实现

1、常见定时任务 Java自带的java.util.Timer类

  • timer:配置比较麻烦,时间延后问题
  • timertask:不推荐

2、Quartz框架

  • 配置更简单
  • xml或者注解

3、SpringBoot使用注解方式开启定时任务

  • 1)启动类里面 @EnableScheduling开启定时任务,自动扫描
  • 2)定时任务业务类 加注解 @Component被容器扫描
  • 3)定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次/s

方式三定时注解分类

  • 1、cron 定时任务表达式 @Scheduled(cron="*/1 * * * * *") 表示每秒

    crontab 工具

  • 2、fixedRate: 定时多久执行一次(上一次开始执行时间点后xx秒再次执行;)

  • 3、fixedDelay: 上一次执行结束时间点后xx秒再次执行

  • 4、fixedDelayString: 字符串形式,可以通过配置文件指定

@SpringBootApplication
@ServletComponentScan
@MapperScan("com.techsel.mapper")
@EnableScheduling //定时任务
@EnableAsync //异步任务
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class);
    }
}
@Component
public class TestTask {
    @Scheduled(fixedRate = 2000) //代表2S执行一次
    public void show() {
        System.out.println("当前时间: "+new Date());
    }

    @Scheduled(fixedDelay = 2000)//代表上次执行完毕之后2S再次执行,如果方法内部有延时,则下次执行时间间隔会超过2s
    public void show1() {
        System.out.println("当前时间: "+new Date());
    }

    @Scheduled(fixedRateString = "2000")
//    @Scheduled(fixedDelayString = "2000")
    public void show2() {
        System.out.println("当前时间: "+new Date());
    }
}

异步任务

应用场景: 用于处理log、发送邮件、短信

步骤

  • 启动类里面使用@EnableAsync注解
  • 任务类/方法上面添加@Async注解

注意点

  • 1)要把异步任务封装到类里面,不能直接写到Controller
  • 2)增加Future<String> 返回结果 AsyncResult<String>("task执行完成");
  • 3)如果需要拿到结果 需要判断全部的 task.isDone()
@Component
@Async
public class TestAsyncTask {
    public void task1() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(1000L);
        long end=System.currentTimeMillis();
        System.out.println("任务一耗时: "+(end-begin));
    }

    public void task2() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(2000L);
        long end=System.currentTimeMillis();
        System.out.println("任务二耗时: "+(end-begin));
    }
    public void task3() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(3000L);
        long end=System.currentTimeMillis();
        System.out.println("任务三耗时: "+(end-begin));
    }


    public Future<String> task4() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(2000L);
        long end=System.currentTimeMillis();
        System.out.println("任务四耗时: "+(end-begin));
        return new AsyncResult<>("任务4");
    }
    public Future<String> task5() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(3000L);
        long end=System.currentTimeMillis();
        System.out.println("任务五耗时: "+(end-begin));
        return new AsyncResult<>("任务4");
    }
}

控制器类

@RequestMapping("/v3/task")
@RestController
public class TaskController {

    @Autowired
    private TestAsyncTask testAsyncTask;

    //该方法执行时间不包含1,2,3个任务时间,直接返回
    @GetMapping("async")
    public String async() throws InterruptedException {
        long begin=System.currentTimeMillis();
        testAsyncTask.task1();
        testAsyncTask.task2();
        testAsyncTask.task3();
        long end=System.currentTimeMillis();
        System.out.println("执行:"+(end-begin));
        return "ok";
    }

    //该方法也是异步任务只不过需要任务处理返回结果的时候使用
    //时间是多个任务中时间耗时最长的
    @GetMapping("asyncret")
    public String asyncGetRes() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Future<String> tash4= testAsyncTask.task4();
        Future<String> tash5= testAsyncTask.task5();

        for (;;) {
            if (tash4.isDone() && tash5.isDone()) {
                break;
            }
        }
        long end=System.currentTimeMillis();
        System.out.println("执行:"+(end-begin));
        return "okrest";
    }
}

如果把任务类的@Async注解添加上,则所有任务都会变成同步任务,耗时是累加和

日志记录(Logback)

Logback的核心对象

  • Logger:日志记录器
  • Appender:指定日志输出的目的地,目的地可以是控制台,文件
  • Layout:日志布局 格式化日志信息的输出

日志级别:DEBUG < INFO < WARN < ERROR

log4j.properties

===========log4j示例===========       
### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=D://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=D://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n 

===========logback============

Log4j日志转换为logback在线工具

支持log4j.properties转换为logback.xml,不支持 log4j.xml转换为logback.xml

集成步骤

  • application.yml中添加配置
#通过触发器,去控制什么时候进行热加载部署新的文件
spring:
    devtools:
        restart.trigger-file: trigger.txt
#自定义启动banner文件的路径
spring:
    banner:
        location: banner.txt
  • logback-spring.xml

放到application.yml同级目录即可

默认加载加载配置顺序 logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
     <appender name="consoleApp" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
            </pattern>
        </layout>
    </appender>
    <appender name="fileInfoApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
             <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
            </pattern>
        </encoder>
        <!-- 滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 路径 -->
            <fileNamePattern>app_log/log/app.info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <appender name="fileErrorApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
            </pattern>
        </encoder>
        
        <!-- 设置滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 路径 -->
            <fileNamePattern>app_log/log/app.err.%d.log</fileNamePattern>
            
            <!-- 控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动,
            且<maxHistory> 是1,则只保存最近1个月的文件,删除之前的旧文件 -->
             <MaxHistory>1</MaxHistory>
            
        </rollingPolicy>
    </appender>
   <root level="INFO">  
        <appender-ref ref="consoleApp"/>
        <appender-ref ref="fileInfoApp"/>
        <appender-ref ref="fileErrorApp"/>
    </root>
</configuration>
  • 类中使用
@RestController
@RequestMapping("/api/v1")
public class UserController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @GetMapping("log")
    public Object testLog(){
        logger.debug("this is debug level");
        logger.info("this is info level ");
        logger.warn("this is warn level ");
        logger.error("this is error level");
        return JsonData.buildSuccess();
    }
}
  • 通过添加lombok的slf4j的辅助实现简化
@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("执行");
        return true;
    }
}

多环境配置

区分生产,测试,开发等多种环境

步骤(在resoureces文件夹下面的config文件夹下)

  • 新建application.yml

#springboot多环境配置======begin
test:
  url: local

#指定哪个profile
# 如下下面的不开启,则使用上面的默认配置
#spring.profiles.active=dev  #dev就去找application-dev.yml,test就去找application-test.yml
#springboot多环境配置======end
  • 新建application-dev.yml
test;
  url: dev.com
  • 新建application-test.yml
test;
  url: test.com

相关文章

网友评论

    本文标题:SpringBoot(六、任务,日志,多环境配置)

    本文链接:https://www.haomeiwen.com/subject/ntusaqtx.html