3. 分片功能讲解
3.1 案例需求:
1.我们现在实现这样的需求,在指定节假日,需要给平台的所有用户去发送祝福的短信
3.2.编码实现:
a.初始化数据
1.在数据库中导入xxl_job_demo.sql
数据
b.集成Druid&MyBatis
< dependency> < groupId> org.mybatis.spring.boot</ groupId> < artifactId> mybatis-spring-boot-starter</ artifactId> < version> 1.2.0</ version>
</ dependency>
< dependency> < groupId> mysql</ groupId> < artifactId> mysql-connector-java</ artifactId>
</ dependency>
< dependency> < groupId> org.projectlombok</ groupId> < artifactId> lombok</ artifactId> < scope> provided</ scope>
</ dependency>
< dependency> < groupId> com.alibaba</ groupId> < artifactId> druid</ artifactId> < version> 1.1.10</ version>
</ dependency>
spring.datasource.url=jdbc:mysql://localhost:3306/xxl_job_demo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=WolfCode_2017
@Setter @Getter
public class UserMobilePlan { private Long id; private String username; private String nickname; private String phone; private String info;
}
@Mapper
public interface UserMobilePlanMapper { @Select ( "select * from t_user_mobile_plan" ) List < UserMobilePlan > selectAll ( ) ;
}
c.业务功能实现
@XxlJob ( "sendMsgHandler" )
public void sendMsgHandler ( ) throws Exception { List < UserMobilePlan > userMobilePlans = userMobilePlanMapper. selectAll ( ) ; System . out. println ( "任务开始时间:" + new Date ( ) + ",处理任务数量:" + userMobilePlans. size ( ) ) ; Long startTime = System . currentTimeMillis ( ) ; userMobilePlans. forEach ( item-> { try { TimeUnit . MILLISECONDS . sleep ( 10 ) ; } catch ( InterruptedException e) { e. printStackTrace ( ) ; } } ) ; System . out. println ( "任务结束时间:" + new Date ( ) ) ; System . out. println ( "任务耗时:" + ( System . currentTimeMillis ( ) - startTime) + "毫秒" ) ;
}
2.任务配置信息
3.3.分片概念讲解
a.举例理解:
1.比如我们的案例中有2000+条数据,如果不采取分片形式的话,任务只会在一台机器上执行,这样的话需要20+秒才能执行完任务. 2.如果采取分片广播的形式的话,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务; 3.获取分片参数方式:
int shardIndex = XxlJobHelper . getShardIndex ( ) ;
int shardTotal = XxlJobHelper . getShardTotal ( ) ;
4.通过这两个参数,我们可以通过求模取余的方式,分别查询,分别执行,这样的话就可以提高处理的速度. 5.之前2000+条数据只在一台机器上执行需要20+秒才能完成任务,分片后,有两台机器可以共同完成2000+条数据,每台机器处理1000+条数据,这样的话只需要10+秒就能完成任务
b.案例改造成任务分片
@Mapper
public interface UserMobilePlanMapper { @Select ( "select * from t_user_mobile_plan where mod(id,#{shardingTotal})=#{shardingIndex}" ) List < UserMobilePlan > selectByMod ( @Param ( "shardingIndex" ) Integer shardingIndex, @Param ( "shardingTotal" ) Integer shardingTotal) ; @Select ( "select * from t_user_mobile_plan" ) List < UserMobilePlan > selectAll ( ) ;
}
@XxlJob ( "sendMsgShardingHandler" )
public void sendMsgShardingHandler ( ) throws Exception { System . out. println ( "任务开始时间:" + new Date ( ) ) ; int shardTotal = XxlJobHelper . getShardTotal ( ) ; int shardIndex = XxlJobHelper . getShardIndex ( ) ; List < UserMobilePlan > userMobilePlans = null ; if ( shardTotal== 1 ) { userMobilePlans = userMobilePlanMapper. selectAll ( ) ; } else { userMobilePlans = userMobilePlanMapper. selectByMod ( shardIndex, shardTotal) ; } System . out. println ( "处理任务数量:" + userMobilePlans. size ( ) ) ; Long startTime = System . currentTimeMillis ( ) ; userMobilePlans. forEach ( item-> { try { TimeUnit . MILLISECONDS . sleep ( 10 ) ; } catch ( InterruptedException e) { e. printStackTrace ( ) ; } } ) ; System . out. println ( "任务结束时间:" + new Date ( ) ) ; System . out. println ( "任务耗时:" + ( System . currentTimeMillis ( ) - startTime) + "毫秒" ) ;
}
3.任务设置