SpringBoot与MybatisPlus SpringBoot(五)

简介: SpringBoot与MybatisPlus SpringBoot(五)

十三、SpringBoot容器化部署

13.1 安装docker环境

为了节约资源,在生产环境中我们更多的是使用Docker容器部署SpringBoot应用,首先我们准备Docker环境:

1、准备一台centos7系统的虚拟机,连接虚拟机。

2、关闭虚拟机防火墙

# 关闭运行的防火墙
systemctl stop firewalld.service
# 禁止防火墙自启动
systemctl disable firewalld.service

13.2 Dockerfile制作镜像

由于在SpringBoot中嵌入了Web容器,所以在制作SpringBoot项目的镜像时无需依赖Web容器,基于JDK制作镜像即可,接下来我们使用Dockerfile制作镜像:

1、进入opt目录

cd /opt

2、使用rz命令(或者xftp)将项目Jar包上传至虚拟机

使用rz前提是下载lrsz,yum -y install lrzsz

3、编写DockerFile

# 基于JDK11
FROM openjdk:8
# 作者
MAINTAINER zj
# 拷贝到容器opt目录
ADD sb_logback.jar /opt
#保留端口
EXPOSE 8080
# 启动容器后执行的命令
CMD java -jar /opt/sb_logback.jar

4、构建镜像

docker build -t sb_logback .

5、查看所有的镜像,出现springbootdocker代表镜像构建成功

6、使用镜像创建并启动容器

docker run -d -p 8080:8080 sb_logback

7、访问查看是否启动成功

13.3 Maven插件制作镜像

除了DockerFile,我们还可以使用Maven插件制作镜像。使用方法如下:

1、开启远程docker服务

# 修改docker配置文件
vim /lib/systemd/system/docker.service
# 在ExecStart=后添加配置,远程访问docker的端口为2375
ExecStart=/usr/bin/dockerd-current -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \
     --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
     --default-runtime=docker-runc \
     --exec-opt native.cgroupdriver=systemd \
     --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
     --init-path=/usr/libexec/docker/docker-init-current \
     --seccomp-profile=/etc/docker/seccomp.json \
     $OPTIONS \
     $DOCKER_STORAGE_OPTIONS \
     $DOCKER_NETWORK_OPTIONS \
     $ADD_REGISTRY \
     $BLOCK_REGISTRY \
     $INSECURE_REGISTRY \
     $REGISTRIES
# 重启docker
systemctl daemon-reload
systemctl restart docker

2、在项目的pom文件中添加docker-maven-plugin插件

<!-- docker-maven-plugin-->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <!-- Docker路径 -->
                    <dockerHost>http://192.168.25.101:2375</dockerHost>
                    <!-- Dockerfile定义 -->
                    <baseImage>openjdk:8</baseImage>
                    <!-- 作者 -->
                    <maintainer>zj</maintainer>
                    <resources>
                        <resource>
                            <!-- 复制jar包到docker容器指定目录 -->
                            <targetPath>/opt</targetPath>
                            <!-- 从哪个包拷贝文件,target包 -->
                            <directory>${project.build.directory}</directory>
                            <!-- 拷贝哪个文件 -->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                    <workdir>/</workdir>
                    <entryPoint>["java", "-jar", "${project.build.finalName}.jar","--spring.profiles.active=dev"]</entryPoint>
                    <forceTags>true</forceTags>
                    <!-- 镜像名 -->
                    <imageName>${project.artifactId}</imageName>
                    <!-- 镜像版本 -->
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>
                </configuration>
            </plugin>

3、使用maven的package命令给项目打包

4、使用maven的docker插件制作镜像

5、查看所有的镜像

6、创建并访问容器

十四、Spring Task

定时任务即系统在特定时间执行一段代码,它的场景应用非常广泛:

  1. 购买游戏的月卡会员后,系统每天给会员发放游戏资源。
  2. 管理系统定时生成报表。
  3. 定时清理系统垃圾。
  4. ......

定时任务的实现主要有以下几种方式:

  1. Java自带的java.util.Timer类,这个类允许调度一个java.util.TimerTask任务。使用这种方式可以让程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
  2. Quartz。这是一个功能比较强大的的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
  3. Spring3.0以后自带Spring Task,可以将它看成一个轻量级的Quartz,使用起来比 Quartz简单许多,在课程中我们使用Spring Task实现定时任务

14.1 入门案例

1、创建SpringBoot项目,在启动类开启定时任务。

@SpringBootApplication
@EnableScheduling  //开启定时任务
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

2、编写定时任务类

@Component
public class MyTask {
    //定时方法,每秒实行一次
    @Scheduled(cron="* * * * * *")
    public void task1(){
        //当前时间
        System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

3、运行

14.2 Cron表达式

Spring Task依靠Cron表达式配置定时规则。Cron表达式是一个字符串,分为6或7个域,每一个域代表一个含义,以空格隔开。有如下两种语法格式:

  1. Seconds Minutes   Hours DayofMonth MonthDayofWeek    Year
  2. Seconds    Minutes   Hours    DayofMonth     MonthDayofWeek

Seconds(秒):域中可出现   , -*/ 四个字符,以及0-59的整数

  • *:表示匹配该域的任意值,在Seconds域使用*,表示每秒钟都会触发
  • ,:表示列出枚举值。在Seconds域使用5,20,表示在5秒和20秒各触发一次。
@Scheduled(cron="5,15,30,40 * * * * *") //每分钟的第5,15,30,40秒执行一次
  • -:表示范围。在Seconds域使用5-20,表示从5秒到20秒每秒触发一次
@Scheduled(cron="5-20 * * * * *")    //定时方法,每分钟的第5到20秒执行
  • /:表示起始时间开始触发,然后每隔固定时间触发一次。在Seconds域使用5/20, 表示5秒触发一次,25秒,45秒分别触发一次。
@Scheduled(cron="5/10 * * * * *")//定时方法,在当前分钟的第5开始执行,每间隔10秒执行一次

Minutes(分):域中可出现,-*/四个字符,以及0-59的整数

Hours(时):域中可出现,-*/四个字符,以及0-23的整数

DayofMonth(日期):域中可出现,-*/?LWC八个字符,以及1-31的整数

  • C:表示和当前日期相关联。在DayofMonth域使用5C,表示在5日后的那一天触发,且每月的那天都会触发。比如当前是10号,那么每月15号都会触发。
@Scheduled(cron="0 0 0 5c * * *")//今天是1号,那么本月的6号0点和以后每月的6号0点都执行
  • L:表示最后,在DayofMonth域使用L,表示每个月的最后一天触发。
@Scheduled(cron="0 0 0 L * * *")//本月的最后一天0点执行
  • W:表示工作日,在DayofMonth域用15W,表示最接近这个月第15天的工作日触发,如果15号是周六,则在14号即周五触发;如果15号是周日,则在16号即周一触发;如果15号是周二则在当天触发。注:
  1. 该用法只会在当前月计算,不会到下月触发。比如在DayofMonth域用31W,31号是周日,那么会在29号触发而不是下月1号。
  2. 在DayofMonth域用LW,表示这个月的最后一个工作日触发。

Month(月份):域中可出现,-*/四个字符,以及1-12的整数或JAN-DEC的单词缩写

@Scheduled(cron="0 0 0 * 6-8 * *")//6-8月每天晚上的0点执行

DayofWeek(星期):可出现,-*/?L#C八个字符,以及1-7的整数或SUN-SAT 单词缩写,1代表星期天,7代表星期六

  • C:在DayofWeek域使用2C,表示在2日后的那一天触发,且每周的那天都会触发。比如当前是周一,那么每周三都会触发。
  • L :在DayofWeek域使用L,表示在一周的最后一天即星期六触发。在DayofWeek域使用5L,表示在一个月的最后一个星期四触发。
  • #:用来指定具体的周数,#前面代表星期几,#后面代表一个月的第几周,比如5#3表示一个月第三周的星期四。
  • ?:在无法确定是具体哪一天时使用,用于DayofMonth和DayofWeek域。例如在每月的20日零点触发1次,此时无法确定20日是星期几,写法如下:0 0 0 20 * ?;或者在每月的最后一个周日触发,此时无法确定该日期是几号,写法如下:0 0 0 ? * 1L

Year(年份):域中可出现,-*/四个字符,以及1970~2099的整数。该域可以省略,表示每年都触发。

14.3 Cron实战案例

含义 表达式
每隔5分钟触发一次 0 0/5 * * * *
每小时触发一次 0 0 * * * *
每天的7点30分触发 0 30 7 * * *
周一到周五的早上6点30分触发 0 30 7 ? * 2-6
每月最后一天早上10点触发 0 0 10 L * ?
每月最后一个工作日的18点30分触发 0 30 18 LW * ?
2030年8月每个星期六和星期日早上10点触发 0 0 10 ? 8 1,7 2030
每天10点、12点、14点触发 0 0 10,12,14 * * *
朝九晚五工作时间内每半小时触发一次 0 0 0/30 9-17 ? * 2-6
每周三中午12点触发一次 0 0 12 ? * 4
每天12点触发一次 0 0 12 * * *
每天14点到14:59每分钟触发一次 0 * 14 * * *
每天14点到14:59每5分钟触发一次 0 0/5 14 * * *
每天14点到14:05每分钟触发一次 0 0-5 14 * * *
每月15日上午10:15触发 0 15 10 15 * ?
每月最后一天的上午10:15触发 0 15 10 L * ?
每月的第三个星期五上午10:15触发 0 15 10 ? * 6#3

14.4 @Scheduled

@Scheduled写在方法上方,指定该方法定时执行。常用参数如下:

  • cron:cron表达式,定义方法执行的时间规则。
  • fixedDelay:任务立即执行,之后每隔多久执行一次,单位是毫秒,上一次任务结束后计算下次执行的时间。
// 立即执行,任务结束后每5秒执行一次
@Scheduled(fixedDelay=5000)
public void task1() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}
  • fixedRate:任务立即执行,之后每隔多久执行一次,单位是毫秒,上一次任务开始后计算下次执行的时间。
// 立即执行,之后每5秒执行一次
@Scheduled(fixedRate=5000)
public void task2() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}
  • initialDelay:项目启动后不马上执行定时器,根据initialDelay的值延时执行。
// 项目启动3秒后执行,之后每5秒执行一次。
@Scheduled(fixedRate=5000,initialDelay = 3000)
public void task3() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}

14.5 多线程任务

Spring Task定时器默认是单线程的,如果项目中使用多个定时器,使用一个线程会造成效率低下。代码如下:

@Scheduled(cron="* * * * * *")
private void task1() throws InterruptedException {
  System.out.println(Thread.currentThread().getId()+"线程执行任务1");
  Thread.sleep(5000);
}
@Scheduled(cron="* * * * * *")
private void task2() {
  System.out.println(Thread.currentThread().getId()+"线程执行任务2");
}

任务1较浪费时间,会阻塞任务2的运行。此时我们可以给Spring Task配置线程池。

@Configuration
public class SchedulingConfig implements SchedulingConfigurer {
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
   // 创建线程池
   taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
  }
}

此时任务1不会阻塞任务2的运行。

相关文章
|
1月前
SpringBoot+Mybatis-Plus+PageHelper分页+多条件查询
SpringBoot+Mybatis-Plus+PageHelper分页+多条件查询
29 0
|
2天前
|
JSON Java 数据格式
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
|
12天前
|
Java 数据库连接 数据库
Springboot整合mybatisPlus开发
MyBatis-Plus是一个MyBatis的增强工具,旨在简化开发和提高效率。它在不修改原有MyBatis的基础上提供额外功能。要将MyBatis-Plus集成到SpringBoot项目中,首先通过Maven添加mybatis-plus-boot-starter和相应数据库驱动依赖,然后配置application.yml中的数据库连接信息,并指定Mapper类的扫描路径。Mapper接口可继承BaseMapper实现基本的CRUD操作。
|
12天前
|
XML Java 数据库连接
Springboot整合mybatisPlus操作数据库
MyBatis-Plus是MyBatis的增强工具,简化开发、提高效率。它提供官网文档,便于集成到SpringBoot项目中。集成步骤包括添加mybatis-plus-boot-starter和数据库驱动依赖,配置数据源,扫描Mapper类包。Mapper接口继承BaseMapper即可使用基本的CRUD操作。示例代码展示了Service层的增删改查实现。MyBatisPlus还支持逻辑删除、自动填充等功能,同时可与Mybatis XML配合使用,通过调整配置指定XML映射文件位置。
|
1月前
|
开发框架 Java 测试技术
XwFast,我开发了一个基于SpringBoot和MyBatisPlus的敏捷开发框架!
XwFast,我开发了一个基于SpringBoot和MyBatisPlus的敏捷开发框架!
33 1
|
1月前
|
存储 关系型数据库 MySQL
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
|
1月前
|
数据库
Springboot+mybatis-plus逆向工程生成代码器
Springboot+mybatis-plus逆向工程生成代码器
|
2月前
|
Java fastjson Apache
Spring Boot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架
Spring Boot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架
37 1
|
2月前
|
安全 算法 Java
SpringBoot+JWT+Shiro+MybatisPlus实现Restful快速开发后端脚手架
SpringBoot+JWT+Shiro+MybatisPlus实现Restful快速开发后端脚手架
29 0
|
2月前
|
Java 关系型数据库 MySQL
springboot+mybatis-plus实例demo
springboot+mybatis-plus实例demo
31 0