由於業務需求,我們數據倉庫定時器太多了,又難管理,每次要更改定時器都得重啟服務實在麻煩。上面又讓換個框架,給了個LTS,今天開始學習哈。有問題就記錄下來,對於一個資質一般的妹子而言,寫程序簡直太難了大哭大哭大哭。LTS網站內容很全,可是還是沒教會我,是我太笨了么?
github地址: https://github.com/ltsopensource/light-task-scheduler
oschina地址: http://git.oschina.net/hugui/light-task-scheduler
1、導入maven項目
剛開始看着下載的文檔,按照一般做法Import項目發現不行,然后又折騰半天,看了pom.xml文件都比較特殊,項目都有parent項目,所以這里應該是直接導入maven項目,用maven管理比較方便。成功導入。導入之后的項目結構如圖。
2、執行測試用例
運行給的api例子,測試JobTraker,這里用到了jdbc,我把jdbc的配置地址改成可用的地址。運行,結果報錯如下:
[INFO ] [15:45:27] org.apache.zookeeper.ZooKeeper - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=30000 watcher=org.I0Itec.zkclient.ZkClient@b8cabe [INFO ] [15:45:27] org.apache.zookeeper.ClientCnxn - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) [WARN ] [15:45:28] org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException: Connection refused: no further information at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source) at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:350) at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1068)
這個錯誤的意思是連接服務失敗了,zookeeper的地址有問題,需要一個zookeeper服務!!!!!我選擇在內網的一台服務器192.168.100.214上裝了一個zookeeper,這里還需要數據庫的配置,我把LTS的數據庫放在192.168.100.213
3、安裝部署zookeeper
zookeeper的官方網站下載包 http://apache.fayea.com/zookeeper/
我下的版本是zookeeper-3.4.6.tar.gz 上傳至服務,解壓。 通過努力,修改配置文件,原來的是zoo-sample.cfg,復制創建一個zoo.cfg,修改dataDIr和dataLogDir路徑(其實也可以不修改的),zoo.cfg內容如下:
# The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. 自己配置 沒有的話創建一個 dataDir=/home/hadoop/zookeeper/data dataLogDir=/home/hadoop/zookeeper/log # the port at which the clients will connect clientPort=2181
然后啟動,zkServer.sh start,啟動成功了,太開心了。也可以再啟動一個client,zkCli.sh -server localhost:2181,測試連接成功了。
4、運行lts-example
再來測試一下lts-example中的類,都能夠順利啟動成功,JobTrakerTest日志如下:
[INFO ] [18:06:33] com.lts.core.cluster.SubscribedNodeManager - [LTS] Add {"address":"192.168.100.115:35001","available":true,"clusterName":"test_cluster","createTime":1461146782683,"group":"lts","hostName":"gyhdomain","httpCmdPort":8719,"identity":"3A7C23C32FD84A59B835CE554E685E32","ip":"192.168.100.115","nodeType":"JOB_TRACKER","port":35001,"threads":2}, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [18:06:33] com.lts.core.cluster.MasterElector - [LTS] Current node become the master node:{"address":"192.168.100.115:35001","available":true,"clusterName":"test_cluster","createTime":1461146782683,"group":"lts","hostName":"gyhdomain","httpCmdPort":8719,"identity":"3A7C23C32FD84A59B835CE554E685E32","ip":"192.168.100.115","nodeType":"JOB_TRACKER","port":35001,"threads":2}, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [18:06:33] com.lts.jobtracker.support.checker.FeedbackJobSendChecker - [LTS] Feedback job checker started!, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [18:06:34] com.lts.jobtracker.support.checker.ExecutingDeadJobChecker - [LTS] Executing dead job checker started!, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [18:06:34] com.lts.jobtracker.support.checker.ExecutableDeadJobChecker - [LTS] Executable dead job checker started!, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 我變成了節點組中的master節點了, 恭喜, 我要放大招了
JobClientTest日志
master節點變成了{"address":"192.168.100.115:0","available":true,"clusterName":"test_cluster","createTime":1461292849210,"group":"test_jobClient","hostName":"gyhdomain","httpCmdPort":8720,"identity":"0CCB00D5AA1144838B8D106708EE71C5","ip":"192.168.100.115","nodeType":"JOB_CLIENT","port":0,"threads":2},不是我,我不能放大招,要猥瑣 [INFO ] [11:31:06] com.lts.core.registry.Registry - [LTS] Register: {"address":"192.168.100.115:0","available":true,"clusterName":"test_cluster","createTime":1461295855460,"group":"test_jobClient","hostName":"gyhdomain","httpCmdPort":8722,"identity":"4D10F8AF80044E20B31E378965D8E04A","ip":"192.168.100.115","listenNodeTypes":["JOB_TRACKER","JOB_CLIENT","MONITOR"],"nodeType":"JOB_CLIENT","port":0,"threads":2}, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [11:31:06] com.lts.core.cluster.JobNode - [LTS] Start success, nodeType=JOB_CLIENT, identity=4D10F8AF80044E20B31E378965D8E04A, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 命令參數: 1:cronExpression模式,如 0 0/1 * * * ?(一分鍾執行一次), 2:指定時間模式 yyyy-MM-dd HH:mm:ss,在執行時間模式下,如果字符串now,表示立即執行 quit:退出 help:幫助 指定時間模式: [INFO ] [11:31:06] com.lts.core.cluster.SubscribedNodeManager - [LTS] Add {"address":"192.168.100.115:0","available":true,"clusterName":"test_cluster","createTime":1461295855460,"group":"test_jobClient","hostName":"gyhdomain","httpCmdPort":8722,"identity":"4D10F8AF80044E20B31E378965D8E04A","ip":"192.168.100.115","nodeType":"JOB_CLIENT","port":0,"threads":2}, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 2016-04-22 11:31:11 任務執行完成:{"job":{"cron":true,"cronExpression":"0/10 * * * * ?","extParams":{"shopId":"111"},"maxRetryTimes":0,"needFeedback":true,"priority":100,"repeatCount":0,"repeatInterval":0,"repeatable":false,"repeatedCount":0,"replaceOnExist":false,"retryTimes":0,"submitNodeGroup":"test_jobClient","taskId":"604405F235054666A5CA81F0FAF974EA","taskTrackerNodeGroup":"test_trade_TaskTracker","triggerTime":1461295870000},"msg":"執行成功了,哈哈","success":true,"time":1461295871400}
TaskTraker日志
[INFO ] [11:34:31] com.lts.example.support.TestJobRunner - [LTS] 我要執行:{"cron":true,"cronExpression":"0/10 * * * * ?","extParams":{"shopId":"111"},"maxRetryTimes":0,"needFeedback":true,"priority":100,"repeatCount":0,"repeatInterval":0,"repeatable":false,"repeatedCount":0,"replaceOnExist":false,"retryTimes":0,"submitNodeGroup":"test_jobClient","taskId":"B8C185711B88485B9631FDF4F82FB534","taskTrackerNodeGroup":"test_trade_TaskTracker","triggerTime":1461296070000}, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 [INFO ] [11:34:31] com.lts.tasktracker.runner.JobRunnerDelegate - [LTS] Job execute completed : {"cron":true,"cronExpression":"0/10 * * * * ?","extParams":{"shopId":"111"},"maxRetryTimes":0,"needFeedback":true,"priority":100,"repeatCount":0,"repeatInterval":0,"repeatable":false,"repeatedCount":0,"replaceOnExist":false,"retryTimes":0,"submitNodeGroup":"test_jobClient","taskId":"B8C185711B88485B9631FDF4F82FB534","taskTrackerNodeGroup":"test_trade_TaskTracker","triggerTime":1461296070000}, time:0 ms., lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115
5、啟動LTS服務
后台怎么看呢?文檔是這樣描述的:
1、運行下載包light-task-scheduler-master根目錄下的sh build.sh或build.cmd腳本,會在dist目錄下生成lts-{version}-bin文件夾。
2、其中bin目錄主要是JobTracker和LTS-Admin的啟動腳本。jobtracker 中是 JobTracker的配置文件和需要使用到的jar包,lts-admin是LTS-Admin相關的war包和配置文件。 lts-{version}-bin的文件結構JobTracker啟動。
3、如果你想啟動一個節點,直接修改下conf/zoo下的配置文件,然后運行 sh jobtracker.sh zoo start即可,如果你想啟動兩個JobTracker節點,那么你需要拷貝一份zoo,譬如命名為zoo2,修改下zoo2下的配置文件,然后運行sh jobtracker.sh zoo2 start即可。logs文件夾下生成jobtracker-zoo.out日志。
4、LTS-Admin啟動.修改conf/lts-monitor.cfg和conf/lts-admin.cfg下的配置,然后運行bin下的sh lts-admin.sh或lts-admin.cmd腳本即可。logs文件夾下會生成lts-admin.out日志,啟動成功在日志中會打印出訪問地址,用戶可以通過這個訪問地址訪問了。
照着文檔說的,生成dist文件夾,在cmd控制台執行build.cmd,結果報錯。
發現自己忒傻了,直接執行這個批處理文件是不行的,要進入到這個文件放的位置,再執行,成功下載jar包。執行成功。
生成了dist文件夾后,修改里面相應的配置文件,mysql和zookeeper的配置改成自己相應的地址。
admin.cfg
// 后台的用戶名密碼 console.username=admin console.password=admin # 注冊中心地址,可以是zk,也可以是redis registryAddress=zookeeper://192.168.100.214:2181 # registryAddress=redis://127.0.0.1:6379 # 集群名稱 clusterName=test_cluster # zk客戶端,可選值 zkclient, curator configs.zk.client=zkclient # ------ 這個是Admin存儲數據的地方,也可以和JobQueue的地址一樣 ------ configs.jdbc.url=jdbc:mysql://192.168.100.213:3306/lts configs.jdbc.username=root configs.jdbc.password=123456 # admin 數據使用mysql 默認 mysql, 可以自行擴展 jdbc.datasource.provider=mysql # 使用 可選值 fastjson, jackson # configs.lts.json=fastjson # 是否在admin啟動monitor服務, monitor服務也可以單獨啟動 lts.monitorAgent.enable=true #======================以下相關配置是JobTracker的JobQueue和JobLogger的相關配置 要保持和JobTracker一樣========================== ## (可選配置)jobT. 開頭的, 因為JobTracker和Admin可能使用的數據庫不是同一個 # LTS業務日志, 可選值 mysql, mongo jobT.job.logger=mysql # ---------以下是任務隊列配置----------- # 任務隊列,可選值 mysql, mongo jobT.job.queue=mysql # ------ 1. 如果是mysql作為任務隊列 (如果不配置,表示和Admin的在一個數據庫)------ # jobT.jdbc.url=jdbc:mysql://127.0.0.1:3306/lts # jobT.jdbc.username=root # jobT.jdbc.password=root # ------ 2. 如果是mongo作為任務隊列 ------ # jobT.mongo.addresses=127.0.0.1:27017 # jobT.mongo.database=lts # jobT.mongo.username=xxx #如果有的話 # jobT.mongo.password=xxx #如果有的話 # admin 數據使用mysql 默認 mysql, 可以自行擴展 # jobT.jdbc.datasource.provider=mysql
monitor.cfg
# 注冊中心地址,可以是zk,也可以是redis registryAddress=zookeeper://192.168.100.214:2181 # registryAddress=redis://127.0.0.1:6379 # 集群名稱 clusterName=test_cluster # LTS業務日志, 可選值 mysql, mongo configs.job.logger=mysql # zk客戶端,可選值 zkclient, curator configs.zk.client=zkclient # ---------以下是任務隊列配置----------- # 任務隊列,可選值 mysql, mongo configs.job.queue=mysql # ------ 1. 如果是mysql作為任務隊列 ------ configs.jdbc.url=jdbc:mysql://192.168.100.213:3306/lts configs.jdbc.username=root configs.jdbc.password=123456 # ------ 2. 如果是mongo作為任務隊列 ------ configs.mongo.addresses=127.0.0.1:27017 configs.mongo.database=lts # configs.mongo.username=xxx #如果有的話 # configs.mongo.password=xxx #如果有的話 # admin 數據使用mysql, h2 默認 h2 embedded jdbc.datasource.provider=mysql # 使用 可選值 fastjson, jackson # configs.lts.json=fastjson
這里同時修改jobTracker配置文件
# 注冊中心地址,可以是zk,也可以是redis registryAddress=zookeeper://192.168.100.214:2181 # JobTracker的監聽端口 listenPort=3502 # 集群名稱 clusterName=test_cluster # LTS業務日志, 可選值 console, mysql, mongo configs.job.logger=mysql # zk客戶端,可選值 zkclient, curator configs.zk.client=zkclient # ---------以下是任務隊列配置----------- # 任務隊列,可選值 mysql, mongo configs.job.queue=mysql # ------ 1. 如果是mysql作為任務隊列 ------ configs.jdbc.url=jdbc:mysql://192.168.100.213:3306/lts configs.jdbc.username=root configs.jdbc.password=123456 # ------ 2. 如果是mongo作為任務隊列 ------ configs.mongo.addresses=127.0.0.1:27017 configs.mongo.database=lts # configs.mongo.username=xxx #如果有的話 # configs.mongo.password=xxx #如果有的話
執行sh ./bin/lts-admin.sh start
執行成功,會一同啟動lts-monitor,如下
啟動jobTracker服務
sh ./bin/jobtracker.sh zoo start
上面打印出來的地址應該就是lts-admin的后台地址。在瀏覽器輸入localhost:8081/index.htm進入到以下頁面:
太開心了,又近了一步了,看到后台了。現在我需要做的就是,怎樣把這個集成到我自己的項目。文檔說可以打成jar包或者修改maven配置文件pom.xml集成至項目。我的項目是需要管理很多定時任務的,之前是通過cron和trigger方式添加的定時器,不方便修改和管理。
6、maven打包,引入jar包
1)在eclipse中maven打包
將要用到的項目maven打包,這里自己犯糊塗去Export-jar file,結果導不出去。其實maven-install,在target文件夾下就會生成jar文件。這里要導出lts-jobclient.jar、lts-jobtraker、lts-tasktraker.jar、lts-core.jar、lts-spring.jar…本身不是很清楚,我就干脆都maven-install.在生成jar包的過程中,有幾個一直報錯,起初不知道什么原因,原來是test報錯,所以無法生成jar包,最簡單的辦法,把@Test屏蔽掉,因為有的測試用例要在一定的前提下(比如先啟動別的服務或者修改參數)才能正常進行。去掉測試后,運行成功。生成了jar包。
我把生成的jar包加到自己的項目里,起初我是這樣弄的:
在webapp->WEB-INFO->lts->*.jar
然后再把jar包配置進去。我的項目是maven spring項目,在pom.xml里面還需加入這些jar包依賴的包,直接把lts下面的copy過來稍作修改。我想測試下.xml啟動加載,於是,我把job-client.xml加到我的服務里,在tomcat下啟動,結果,一直報錯,總是類找不到,明明我已經加了啊?
原因是我畫蛇添足,在WEB-INFO下加了個lts文件夾。對於普通的java類,編譯jar包時,就直接在導入的包中查找就可以了,但是對於web項目,由於它們是借助了tomcat或者其他的容器運行發布的,基於tomcat本身,它會在web項目中的web-inf下的lib中進行編譯jar包,而此時,之前導入的jar包卻不在這里,所以,就會爆紅了,,,解決方案,把需要的jar包拷貝進入WEB-INF下的lib就可以了。。。
問題不斷,又遇到下面這個問題,找不到方法。我用的是jdk1.7編譯、運行,跑main方法是好的,在tomcat下啟動就不行。真是傷腦筋。
2016-04-26 09:24:45,056 [LTS-HeartBeat-Fast-Ping-thread-1] ERROR [HeartBeatMonitor] - [LTS] Ping JobTracker error, lts version: 1.6.6-SNAPSHOT, current host: 192.168.100.115 java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView; at com.lts.core.commons.concurrent.ConcurrentHashSet.iterator(ConcurrentHashSet.java:45) at java.util.AbstractCollection.toArray(Unknown Source) at java.util.ArrayList.<init>(Unknown Source) at com.lts.core.commons.utils.CollectionUtils.setToList(CollectionUtils.java:93) at com.lts.core.cluster.SubscribedNodeManager.getNodeList(SubscribedNodeManager.java:80) at com.lts.core.remoting.HeartBeatMonitor.check(HeartBeatMonitor.java:173) at com.lts.core.remoting.HeartBeatMonitor.ping(HeartBeatMonitor.java:162) at com.lts.core.remoting.HeartBeatMonitor.access$400(HeartBeatMonitor.java:30) at com.lts.core.remoting.HeartBeatMonitor$4.run(HeartBeatMonitor.java:131) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source) at java.util.concurrent.FutureTask.runAndReset(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
這個錯誤的原因是jar包沖突,我自己的項目原本引用了很多jar包,這里又加入了maven配置,難免有很多包沖突。
2)Windows或者Linux下生成jar包
在Windows下執行文件夾中的build.cmd,或者在Linux下執行build.sh,編譯成功后,會在各個子模塊的target文件夾中生成jar包,可以直接引用此jar包。
為避免jar包版本不一致而產生沖突,我在加入lts的各個jar包后,逐個測試,缺少什么包就加入什么包的maven依賴,這招的確管用。如果直接加入lts的所有maven依賴,雖然有的maven配置不一樣,但是還是會產生很多重復的包,從而導致運行出錯。
7、管理后台任務
lts的example可以參考,本來我添加了一個監聽器,tomcat啟動的時候啟動taskTrack服務(這里業務需求用不上jobclient就沒管) ,結果tomcat始終啟動不起來,我就改成了tomcat啟動成功后啟動taskTracker服務,可以成功。
現在所有服務是這樣的
本機 192.168.100.115 lts-taskTracker
mysql 192.168.100.213 :3306 lts數據庫
zookeeper 192.168.100.214 :2181 zkServer服務
lts 192.168.100.215 lts-admin lts-monitor lts-jobTracker
登錄后台,添加任務,
lts-admin 登錄
lts-monitor 登錄admin后的任務管理
lts-jobClient 提交任務 后台添加任務可直接提交
lts-jobTracker 派發任務
lts-taskTracker 執行任務