elastic-job 的简单使用
?
說明:這個是使用2.1.5版本
elastic-job是當當開源的的的定時任務,使用也是很簡單的,可以解決數據量的大的時候可以分片執行,多應用節點部署時候不會重復執行。
是通過zookeeper作為控制中心,進行任務分配。
?
使用手冊:http://elasticjob.io/docs/elastic-job-lite/02-guide/config-manual/
分片原理:https://www.cnblogs.com/haoxinyue/p/6919375.html
?
一. 安裝elastic-job控制臺
下載源碼:https://github.com/elasticjob/elastic-job-lite
(1) 找到elastic-job-lite 下面的elastic-job-lite-console,然后在這個文件下執行mvn打包??
mvn?clean?install?-Dmaven.test.skip=true??(2)得到elastic-job-lite-console-2.1.5.tar.gz。并上傳到linux服務器下,并且解壓,
在bin文件夾下執行nohup ./start.sh & (-p 可以指定端口號)?,端口是8899?,瀏覽器打開:ip:8899就可以訪問控制臺了,如下圖:
? ? ? ?
?已經配置過注冊中心的界面
?
二, zookeeper安裝
? ? 參考:
https://blog.csdn.net/m290345792/article/details/52576890
https://www.cnblogs.com/wangmingshun/p/7745808.html
?
三,實現job
(1)使用maven 引入jar包
<!-- 當當job--> <dependency><groupId>com.dangdang</groupId><artifactId>elastic-job-lite-core</artifactId><version>2.1.5</version> </dependency> <dependency><groupId>com.dangdang</groupId><artifactId>elastic-job-lite-spring</artifactId><version>2.1.5</version> </dependency> <!-- 當當job-->(2)編寫一個測試job
job功能要 實現SimpleJob這個類,然后重寫execute方法,在這個方法中編寫job的業務邏輯,例如
public class SimpleJobDemo2 implements SimpleJob {@Overridepublic void execute(ShardingContext shardingContext) {System.out.println(String.format("------Thread ID: %s, 任務總片數: %s, 當前分片項: %s",Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem()));/*** 實際開發中,有了任務總片數和當前分片項,查詢選擇數據進行執行* */} }?
例如分片執行的:
public class MyElasticJob implements SimpleJob {@Overridepublic void execute(ShardingContext context) {switch (context.getShardingItem()) {case 0: // do something by sharding item 0break;case 1: // do something by sharding item 1break;case 2: // do something by sharding item 2break;// case n: ... }} }?
?
?
?(3) Spring 配置(更多配置參數請參考 使用手冊)
//數據庫jndi配置,執行job 的時候會插入表,并且生成執行記 <bean id="elasticJobLog" class=""org.springframeork.jndi.JndiObjectFactoryBean"><property name="jniName"><value>${db.jndiName}</value></property> </bean><!--配置作業注冊中心 --> /** * server-lists : 連接Zookeeper服務器的列表 包括IP地址和端口號 多個地址用逗號分隔 如: host1:2181,host2:2181 * namespace :Zookeeper的命名空間 * base-sleep-time-milliseconds: 等待重試的間隔時間的初始值 單位:毫秒 * max-sleep-time-milliseconds: 等待重試的間隔時間的最大值 單位:毫秒 * max-retries : 最大嘗試次數 * **/ <reg:zookeeper id="regCenter" server-lists="XXX.XXX.XXX.X:2181" namespace="hmap-job" base-sleep-time-milliseconds="1000" max-sleep-time-milliseconds="3000" max-retries="3" /><!-- 配置作業 測試使用--> /** * id: 任務的唯一標示 * event-trace-rdb-data-source : job要操作的數據庫(可以不設置) * class:job 所在的位置 * registry-center-ref : 要指定的注冊中心* cron : job 觸發的cron表達式
* sharding-total-count : 作業分片總數
* sharding-item-parameters :分片序列號和參數用等號分隔,多個鍵值對用逗號分隔 分片序列號從0開始,不可大于或等于作業分片總數 如: 0=A,1=B
**/<job:simple id="simpleJobDemo2" event-trace-rdb-data-source="elasticJobLog" class="hmap.assist.elasticJob.SimpleJobDemo2" registry-center-ref="regCenter" cron="0/2 * * * * ?" sharding-total-count="2" sharding-item-parameters="0=A,1=B" />
(4)啟動程序,就可以在之前部署的控制臺看到job狀態
登錄的賬號密碼在打包的配置文件里,登錄后配置注冊中心? 就可以在頁面中看到job了
?
四,job執行說明:
1. 如果分片數是1??sharding-total-count = "1" zookeeper注冊中心會在多臺服務器中隨機選擇一臺執行,如果不是1,則會根據分片策略執行。參考:分片原理
? ? 2.? 注冊中心可以有多臺,但是都是以單數的形式(1,3,5),因為zookeeper 是一主多從,主的宕機,會使用選舉的形式再次確定哪個是主,哪些是從。
3. 如果設置了數據庫的jndi,并且設置了?event-trace-rdb-data-source 的值,job運行的時候會在數據庫的?OB_EXECUTION_LOG和JOB_STATUS_TRACE_LOG兩張表中生成執行記錄,不設置也不影響job的正常運行 ,例如:
?
五,問題記錄
? (1)zookeeper安裝啟動問題:
啟動會遇到問題,例如找不到jdk,具體原因在安裝目錄 bin/zookeeper.out文件中查找,找到問題并解決后在啟動
(2) 關閉應用的程序的時候,tomcat 進程還在
tomcat(sh shutdown.sh) 關閉的時候,項目不能徹底停掉,進程還在:是因為關閉的時候servlet容器發現job還有線程存在,所以不能徹底關閉
解決辦法:增加一個監聽,在contextDestroyed 方法中你用elastic-job的shutdown方法
//新建一個類實現ServletContextListener用于關閉elasticJob的線程 @WebListener public class JobServletContextListener implements ServletContextListener {private static Logger logger = LoggerFactory.getLogger(JobServletContextListener.class);@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {logger.info("Destroying Context...");try {WebApplicationContext context = (WebApplicationContext) servletContextEvent.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);String[] beanNames = context.getBeanDefinitionNames();for(String beanName:beanNames){if(beanName.contains("dangdang")&&beanName.contains("SpringJobScheduler")){logger.info("發現dangdang定時任務beanName: "+beanName);SpringJobScheduler scheduler = (SpringJobScheduler)context.getBean(beanName);scheduler.getSchedulerFacade().shutdownInstance();}}} catch (Exception e) {logger.error("Error Destroying Context", e);}} }?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/sunjiguang/p/9273871.html
總結
以上是生活随笔為你收集整理的elastic-job 的简单使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于测试url传值的问题
- 下一篇: ngrx心得体会总结