LTS (light-task-scheduler) ส่วนใหญ่จะใช้เพื่อแก้ปัญหาการกำหนดเวลางานแบบกระจาย และสนับสนุนงานแบบเรียลไทม์ งานที่กำหนดเวลาไว้ และงาน Cron มีความสามารถในการขยายขนาด ความสามารถในการขยายขนาด ความทนทาน และความเสถียรที่ดี และเรายังหวังว่าผู้ที่ชื่นชอบโอเพ่นซอร์สจะมีส่วนร่วมร่วมกัน
ที่อยู่ Github: https://github.com/ltsopensource/light-task-scheduler
ที่อยู่ออสชิน่า: http://git.oschina.net/hugui/light-task-scheduler
ตัวอย่าง: https://github.com/ltsopensource/lts-examples
ที่อยู่เอกสาร (ภายใต้การอัปเดตจะมีผลบังคับในภายหลัง): https://www.gitbook.com/book/qq254963746/lts/details
ที่อยู่ทั้งสองจะได้รับการอัปเดตพร้อมกัน หากคุณสนใจกรุณาเข้าร่วมกลุ่ม QQ: 109500214 (รหัสผ่านกลุ่ม: สวัสดีชาวโลก) เพื่อพูดคุยและปรับปรุงร่วมกัน ยิ่งมีคนสนับสนุนมากเท่าไร ก็ยิ่งมีแรงจูงใจในการอัปเดตมากขึ้นเท่านั้น หากคุณต้องการ อย่าลืมติดดาวที่มุมขวาบนด้วย
LTS ส่วนใหญ่มีโหนดสี่ประเภทดังต่อไปนี้:
โหนด JobClient, JobTracker และ TaskTracker ล้วน无状态
สามารถปรับใช้หลายรายการและลบแบบไดนามิกเพื่อให้เกิดความสมดุลของโหลดและความจุโหลดที่มากขึ้น และเฟรมเวิร์กใช้กลยุทธ์ FailStore เพื่อทำให้ LTS มีความทนทานต่อข้อผิดพลาดที่ดี
ศูนย์ลงทะเบียน LTS มีการใช้งานหลายอย่าง (Zookeeper, Redis ฯลฯ) ศูนย์ลงทะเบียนจะเปิดเผยข้อมูลโหนดและเลือกผู้เชี่ยวชาญ (Mongo หรือ Mysql) จัดเก็บคิวงานและบันทึกการดำเนินการงาน netty หรือ mina ทำการสื่อสารพื้นฐาน และจัดให้มีวิธีการซีเรียลไลซ์เซชันหลายวิธี เช่น fastjson, hessian2, java เป็นต้น
LTS รองรับประเภทงาน:
รองรับการปรับเปลี่ยนพารามิเตอร์งานแบบไดนามิก เวลาดำเนินการงาน และการตั้งค่าอื่น ๆ รองรับการเพิ่มงานแบบไดนามิกในพื้นหลัง รองรับการระงับงาน Cron รองรับการหยุดการทำงานด้วยตนเอง (แบบมีเงื่อนไข) รองรับสถิติการตรวจสอบงาน รองรับการตรวจสอบการดำเนินการของแต่ละโหนด , การตรวจสอบ JVM เป็นต้น
รูปด้านล่างคือกระบวนการดำเนินงานแบบเรียลไทม์มาตรฐาน
ขณะนี้แบ็กเอนด์มีฟังก์ชันการตรวจสอบสิทธิ์แบบง่ายที่จัดทำโดย ztajy ชื่อผู้ใช้และรหัสผ่านอยู่ใน auth.cfg และผู้ใช้สามารถแก้ไขได้
LTS สามารถทำได้โดยไม่ต้องใช้ Spring Framework เลย แต่เมื่อพิจารณาว่าโปรเจ็กต์ผู้ใช้จำนวนมากใช้ Spring Framework นั้น LTS ยังให้การสนับสนุน Spring รวมถึง Xml และคำอธิบายประกอบ เพียงแนะนำ lts-spring.jar
เครื่องบันทึกธุรกิจมีให้ที่ฝั่ง TaskTracker เพื่อใช้งานโดยแอปพลิเคชัน บันทึกธุรกิจสามารถส่งไปยัง JobTracker ได้ บันทึกธุรกิจเหล่านี้สามารถต่อกันด้วยรหัสงาน และสามารถดูการดำเนินงานแบบเรียลไทม์ใน LTS - กำหนดการของผู้ดูแลระบบ
ส่วนขยาย SPI สามารถบรรลุการบุกรุกเป็นศูนย์ เพียงใช้อินเทอร์เฟซที่เกี่ยวข้องเท่านั้น และสามารถใช้อินเทอร์เฟซส่วนขยายแบบเปิดในปัจจุบันได้
เมื่อ TaskTracker ที่กำลังดำเนินการงานนั้นหยุดทำงาน JobTracker จะจัดสรรงานทั้งหมดที่กำหนดให้กับ TaskTracker ที่หยุดทำงานทันทีไปยังโหนด TaskTracker ปกติอื่น ๆ เพื่อดำเนินการทันที
การตรวจสอบทรัพยากร การตรวจสอบงาน ฯลฯ สามารถทำได้บนโหนด JobTracker และ TaskTracker และสามารถดูได้ในพื้นหลังการจัดการ LTS-Admin แบบเรียลไทม์เพื่อดำเนินการจัดสรรทรัพยากรอย่างเหมาะสม
กรอบงาน LTS ให้การสนับสนุนผลลัพธ์การดำเนินการสี่รายการ ได้แก่ EXECUTE_SUCCESS
, EXECUTE_FAILED
, EXECUTE_LATER
และ EXECUTE_EXCEPTION
และใช้กลไกการประมวลผลที่สอดคล้องกันสำหรับผลลัพธ์แต่ละรายการ เช่น การลองใหม่
กลไก FailStore ใช้สำหรับการยอมรับข้อบกพร่องของโหนด Fail And Store จะไม่ส่งผลกระทบต่อการทำงานของแอปพลิเคชันปัจจุบันเนื่องจากความไม่เสถียรของการสื่อสารระยะไกล สำหรับคำแนะนำ FailStore เฉพาะ โปรดดูคำแนะนำ FailStore ในคำอธิบายแนวคิด
โปรเจ็กต์ส่วนใหญ่สร้างขึ้นโดยใช้ maven และปัจจุบันจัดเตรียมแพ็คเกจเชลล์สคริปต์ การพึ่งพาสภาพแวดล้อม: Java(jdk1.6+)
Maven
การใช้งานของผู้ใช้โดยทั่วไปจะแบ่งออกเป็น 2 ประเภท คือ
คุณสามารถอัพโหลดแพ็คเกจ lts jar ไปยังคลังสินค้าในเครื่องผ่านคำสั่ง maven เพิ่มพื้นที่เก็บข้อมูลที่เกี่ยวข้องในไฟล์พาเรนต์ pom.xml และอัปโหลดด้วยคำสั่งปรับใช้ สำหรับวิธีการอ้างอิงเฉพาะ โปรดดูตัวอย่างในหน่วย lts
แต่ละโมดูลของ lts จะต้องได้รับการบรรจุในแพ็คเกจ jar แยกกัน และแพ็คเกจการพึ่งพา lts ทั้งหมดจะต้องถูกนำเข้า สำหรับการอ้างอิงเฉพาะถึงแพ็คเกจ jar คุณสามารถดูตัวอย่างในหน่วย lts
มีสคริปต์สองเวอร์ชัน (cmd)windows
และ (shell)linux
สำหรับการคอมไพล์และการปรับใช้:
การรันสคริปต์ sh build.sh
หรือ build.cmd
ในไดเร็กทอรีรากจะสร้างโฟลเดอร์ lts-{version}-bin
ในไดเร็กทอรี dist
ต่อไปนี้เป็นโครงสร้างไดเร็กทอรี ซึ่งไดเร็กทอรี bin ส่วนใหญ่จะมีสคริปต์เริ่มต้นของ JobTracker และ LTS-Admin jobtracker
มีไฟล์การกำหนดค่าของ JobTracker และแพ็คเกจ jar ที่จำเป็นต้องใช้ lts-admin
คือแพ็คเกจ war และไฟล์การกำหนดค่าที่เกี่ยวข้องกับ LTS-Admin โครงสร้างไฟล์ของ lts-{version}-bin
-- lts - $ { version }- bin
|-- bin
| |-- jobtracker . cmd
| |-- jobtracker . sh
| |-- lts - admin . cmd
| |-- lts - admin . sh
| |-- lts - monitor . cmd
| |-- lts - monitor . sh
| |-- tasktracker . sh
|-- conf
| |-- log4j . properties
| |-- lts - admin . cfg
| |-- lts - monitor . cfg
| |-- readme . txt
| |-- tasktracker . cfg
| |-- zoo
| |-- jobtracker . cfg
| |-- log4j . properties
| |-- lts - monitor . cfg
|-- lib
| |-- *. jar
|-- war
|-- jetty
| |-- lib
| |-- *. jar
|-- lts - admin . war
conf/zoo
จากนั้นรัน sh jobtracker.sh zoo start
หากคุณต้องการเริ่มต้นโหนด JobTracker สองโหนด คุณจะต้องคัดลอกสวนสัตว์ เป็นต้น ตั้งชื่อมัน zoo2
แก้ไขไฟล์การกำหนดค่าภายใต้ zoo2
จากนั้นรัน sh jobtracker.sh zoo2 start
บันทึก jobtracker-zoo.out
ถูกสร้างขึ้นในโฟลเดอร์บันทึกconf/lts-monitor.cfg
และ conf/lts-admin.cfg
จากนั้นรันสคริปต์ sh lts-admin.sh
หรือ lts-admin.cmd
ภายใต้ bin
บันทึก lts-admin.out
จะถูกสร้างขึ้นในโฟลเดอร์บันทึก หากการเริ่มต้นสำเร็จ ที่อยู่การเข้าถึงจะถูกพิมพ์ลงในบันทึก ผู้ใช้สามารถเข้าถึงผ่านที่อยู่การเข้าถึงนี้ได้ แพ็กเกจ jar ที่ต้องอิมพอร์ตไปยัง lts ได้แก่ lts-jobclient-{version}.jar
, lts-core-{version}.jar
และ jars อื่น ๆ ที่ขึ้นอยู่กับบุคคลที่สาม
JobClient jobClient = new RetryJobClient ();
jobClient . setNodeGroup ( "test_jobClient" );
jobClient . setClusterName ( "test_cluster" );
jobClient . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
jobClient . start ();
// 提交任务
Job job = new Job ();
job . setTaskId ( "3213213123" );
job . setParam ( "shopId" , "11111" );
job . setTaskTrackerNodeGroup ( "test_trade_TaskTracker" );
// job.setCronExpression("0 0/1 * * * ?"); // 支持 cronExpression表达式
// job.setTriggerTime(new Date()); // 支持指定时间执行
Response response = jobClient . submitJob ( job );
< bean id = "jobClient" class = "com.github.ltsopensource.spring.JobClientFactoryBean" >
< property name = "clusterName" value = "test_cluster" />
< property name = "registryAddress" value = "zookeeper://127.0.0.1:2181" />
< property name = "nodeGroup" value = "test_jobClient" />
< property name = "masterChangeListeners" >
< list >
< bean class = "com.github.ltsopensource.example.support.MasterChangeListenerImpl" />
</ list >
</ property >
< property name = "jobFinishedHandler" >
< bean class = "com.github.ltsopensource.example.support.JobFinishedHandlerImpl" />
</ property >
< property name = "configs" >
< props >
<!-- 参数 -->
< prop key = "job.fail.store" > leveldb </ prop >
</ props >
</ property >
</ bean >
@ Configuration
public class LTSSpringConfig {
@ Bean ( name = "jobClient" )
public JobClient getJobClient () throws Exception {
JobClientFactoryBean factoryBean = new JobClientFactoryBean ();
factoryBean . setClusterName ( "test_cluster" );
factoryBean . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
factoryBean . setNodeGroup ( "test_jobClient" );
factoryBean . setMasterChangeListeners ( new MasterChangeListener []{
new MasterChangeListenerImpl ()
});
Properties configs = new Properties ();
configs . setProperty ( "job.fail.store" , "leveldb" );
factoryBean . setConfigs ( configs );
factoryBean . afterPropertiesSet ();
return factoryBean . getObject ();
}
}
แพ็กเกจ jar ที่ต้องอิมพอร์ตไปยัง lts ได้แก่ lts-tasktracker-{version}.jar
, lts-core-{version}.jar
และ jars อื่น ๆ ที่ขึ้นอยู่กับบุคคลที่สาม
public class MyJobRunner implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
try {
// TODO 业务逻辑
// 会发送到 LTS (JobTracker上)
jobContext . getBizLogger (). info ( "测试,业务日志啊啊啊啊啊" );
} catch ( Exception e ) {
return new Result ( Action . EXECUTE_FAILED , e . getMessage ());
}
return new Result ( Action . EXECUTE_SUCCESS , "执行成功了,哈哈" );
}
}
TaskTracker taskTracker = new TaskTracker ();
taskTracker . setJobRunnerClass ( MyJobRunner . class );
taskTracker . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
taskTracker . setNodeGroup ( "test_trade_TaskTracker" );
taskTracker . setClusterName ( "test_cluster" );
taskTracker . setWorkThreads ( 20 );
taskTracker . start ();
< bean id = "taskTracker" class = "com.github.ltsopensource.spring.TaskTrackerAnnotationFactoryBean" init - method = "start" >
< property name = "jobRunnerClass" value = "com.github.ltsopensource.example.support.MyJobRunner" />
< property name = "bizLoggerLevel" value = "INFO" />
< property name = "clusterName" value = "test_cluster" />
< property name = "registryAddress" value = "zookeeper://127.0.0.1:2181" />
< property name = "nodeGroup" value = "test_trade_TaskTracker" />
< property name = "workThreads" value = "20" />
< property name = "masterChangeListeners" >
< list >
< bean class = "com.github.ltsopensource.example.support.MasterChangeListenerImpl" />
</ list >
</ property >
< property name = "configs" >
< props >
< prop key = "job.fail.store" > leveldb </ prop >
</ props >
</ property >
</ bean >
@ Configuration
public class LTSSpringConfig implements ApplicationContextAware {
private ApplicationContext applicationContext ;
@ Override
public void setApplicationContext ( ApplicationContext applicationContext ) throws BeansException {
this . applicationContext = applicationContext ;
}
@ Bean ( name = "taskTracker" )
public TaskTracker getTaskTracker () throws Exception {
TaskTrackerAnnotationFactoryBean factoryBean = new TaskTrackerAnnotationFactoryBean ();
factoryBean . setApplicationContext ( applicationContext );
factoryBean . setClusterName ( "test_cluster" );
factoryBean . setJobRunnerClass ( MyJobRunner . class );
factoryBean . setNodeGroup ( "test_trade_TaskTracker" );
factoryBean . setBizLoggerLevel ( "INFO" );
factoryBean . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
factoryBean . setMasterChangeListeners ( new MasterChangeListener []{
new MasterChangeListenerImpl ()
});
factoryBean . setWorkThreads ( 20 );
Properties configs = new Properties ();
configs . setProperty ( "job.fail.store" , "leveldb" );
factoryBean . setConfigs ( configs );
factoryBean . afterPropertiesSet ();
// factoryBean.start();
return factoryBean . getObject ();
}
}
คำอธิบายพารามิเตอร์
โดยทั่วไป จำเป็นต้องมีอินสแตนซ์ JobClient เพียงอินสแตนซ์เดียวใน JVM อย่าสร้างอินสแตนซ์ JobClient ใหม่สำหรับแต่ละงาน ซึ่งจะทำให้สิ้นเปลืองทรัพยากรอย่างมาก เนื่องจาก JobClient หนึ่งรายการสามารถส่งงานได้หลายรายการ โดยทั่วไป JVM เดียวกันจะพยายามรักษาอินสแตนซ์ TaskTracker เพียงอันเดียว หากมีอินสแตนซ์มากกว่านั้น อาจทำให้สิ้นเปลืองทรัพยากร เมื่อพบ TaskTracker ที่ต้องทำงานหลายอย่าง โปรดดูที่ "One TaskTracker ทำงานหลายอย่าง" ด้านล่าง
บางครั้ง สถานการณ์ทางธุรกิจจำเป็นต้องมีการดำเนินงานหลายอย่าง บางคนอาจถามว่างานแต่ละประเภทต้องใช้ TaskTracker ในการดำเนินการหรือไม่ คำตอบของฉันคือไม่ หากคุณอยู่ใน JVM วิธีที่ดีที่สุดคือใช้ TaskTracker เพื่อรันหลายงาน เนื่องจากการใช้ TaskTracker หลายอินสแตนซ์ใน JVM เป็นการสิ้นเปลืองทรัพยากร (แน่นอน เมื่อคุณมีงานบางอย่างจำนวนมาก คุณสามารถใช้โหนด TaskTracker แยกต่างหากเพื่อดำเนินการงานนี้ได้) แล้วเราจะใช้ TaskTracker เพื่อทำงานหลายอย่างได้อย่างไร ด้านล่างนี้เป็นตัวอย่างอ้างอิงที่ฉันให้ไว้
/**
* 总入口,在 taskTracker.setJobRunnerClass(JobRunnerDispatcher.class)
* JobClient 提交 任务时指定 Job 类型 job.setParam("type", "aType")
*/
public class JobRunnerDispatcher implements JobRunner {
private static final ConcurrentHashMap < String /*type*/ , JobRunner >
JOB_RUNNER_MAP = new ConcurrentHashMap < String , JobRunner >();
static {
JOB_RUNNER_MAP . put ( "aType" , new JobRunnerA ()); // 也可以从Spring中拿
JOB_RUNNER_MAP . put ( "bType" , new JobRunnerB ());
}
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
Job job = jobContext . getJob ();
String type = job . getParam ( "type" );
return JOB_RUNNER_MAP . get ( type ). run ( job );
}
}
class JobRunnerA implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
// TODO A类型Job的逻辑
return null ;
}
}
class JobRunnerB implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
// TODO B类型Job的逻辑
return null ;
}
}
โดยทั่วไป เมื่อเขียน TaskTracker คุณเพียงแค่ต้องทดสอบว่าตรรกะการใช้งานของ JobRunner นั้นถูกต้องหรือไม่ แต่คุณไม่ต้องการเริ่ม LTS สำหรับการทดสอบระยะไกล เพื่ออำนวยความสะดวกในการทดสอบ LTS จึงจัดเตรียมวิธีการทดสอบทางลัดของ JobRunner เพียงรวม com.github.ltsopensource.tasktracker.runner.JobRunnerTester
เข้ากับคลาสการทดสอบของคุณเอง และใช้เมธอด initContext
และ newJobRunner
เช่นตัวอย่างใน lts-examples:
public class TestJobRunnerTester extends JobRunnerTester {
public static void main ( String [] args ) throws Throwable {
// Mock Job 数据
Job job = new Job ();
job . setTaskId ( "2313213" );
JobContext jobContext = new JobContext ();
jobContext . setJob ( job );
JobExtInfo jobExtInfo = new JobExtInfo ();
jobExtInfo . setRetry ( false );
jobContext . setJobExtInfo ( jobExtInfo );
// 运行测试
TestJobRunnerTester tester = new TestJobRunnerTester ();
Result result = tester . run ( jobContext );
System . out . println ( JSON . toJSONString ( result ));
}
@ Override
protected void initContext () {
// TODO 初始化Spring容器
}
@ Override
protected JobRunner newJobRunner () {
return new TestJobRunner ();
}
}
สำหรับงาน Cron ของ Quartz คุณจะต้องเพิ่มโค้ดบางส่วนลงในการกำหนดค่า Spring เพื่อเชื่อมต่อกับแพลตฟอร์ม LTS
< bean class = " com.github.ltsopensource.spring.quartz.QuartzLTSProxyBean " >
< property name = " clusterName " value = " test_cluster " />
< property name = " registryAddress " value = " zookeeper://127.0.0.1:2181 " />
< property name = " nodeGroup " value = " quartz_test_group " />
</ bean >
@ SpringBootApplication
@ EnableJobTracker // 启动JobTracker
@ EnableJobClient // 启动JobClient
@ EnableTaskTracker // 启动TaskTracker
@ EnableMonitor // 启动Monitor
public class Application {
public static void main ( String [] args ) {
SpringApplication . run ( Application . class , args );
}
}
สิ่งที่เหลืออยู่คือการเพิ่มการกำหนดค่าที่เกี่ยวข้องใน application.properties สำหรับรายละเอียด โปรดดูตัวอย่างภายใต้แพ็คเกจ com.github.ltsopensource.examples.springboot
ใน lts-example
เมื่อเครื่องมีการ์ดเครือข่ายสองตัวบนเครือข่ายภายใน บางครั้งหากผู้ใช้ต้องการให้การรับส่งข้อมูล LTS ผ่านการ์ดเครือข่ายภายนอก เขาจำเป็นต้องเปลี่ยนที่อยู่การจับคู่ของชื่อโฮสต์เป็นที่อยู่การ์ดเครือข่ายภายนอกในโฮสต์ เช่นเดียวกับเครือข่ายภายใน
หากตั้งค่า ID โหนดเมื่อโหนดเริ่มทำงาน LTS จะตั้งค่า UUID เป็น ID โหนดตามค่าเริ่มต้น ความสามารถในการอ่านจะลดลง แต่สามารถรับประกันความเป็นเอกลักษณ์ของแต่ละโหนดได้ หากผู้ใช้สามารถรับประกันความเป็นเอกลักษณ์ของโหนดได้ ID ด้วยตัวเองเขาสามารถ setIdentity
เพื่อตั้งค่าได้ เช่น ถ้าแต่ละโหนดถูกใช้งานบนเครื่อง (เครื่องเสมือน) ก็สามารถตั้งค่าเอกลักษณ์เป็นชื่อโฮสต์ได้
รองรับส่วนขยาย SPI สำหรับ JobLogger, JobQueue ฯลฯ
ดูฉบับที่ #389
ประสบการณ์การทำงานมากกว่าสามปี
ข้อกำหนดทางการศึกษา ปริญญาตรี
ระดับความคาดหวัง P6 (วิศวกร Java อาวุโส)/P7 (ผู้เชี่ยวชาญด้านเทคนิค)
รายละเอียดงาน
แพลตฟอร์มสมาชิกมีหน้าที่รับผิดชอบระบบผู้ใช้ของ Alibaba Group รองรับความต้องการของผู้ใช้ในสายธุรกิจต่างๆ ภายในกลุ่ม และสนับสนุนผู้ใช้และช่องทางธุรกิจของความร่วมมือภายนอกของกลุ่ม รวมถึงการเข้าสู่ระบบและการอนุญาตของผู้ใช้ ระบบเซสชั่น การลงทะเบียน การจัดการบัญชี ความปลอดภัยของบัญชีและฟังก์ชั่นอื่น ๆ ในแต่ละด้าน บริการข้อมูลผู้ใช้พื้นฐาน การจัดการเซสชั่นและข้อมูลประจำตัว ฯลฯ เป็นหนึ่งในสายผลิตภัณฑ์หลักของกลุ่มที่มีหลายร้อยผลิตภัณฑ์ ปริมาณการโทรนับพันล้านครั้งต่อวัน QPS สูงสุดหลายสิบล้านครั้ง และสถาปัตยกรรมไฮบริดคลาวด์ที่กระจายทั่วโลก ฯลฯ
ในฐานะวิศวกรซอฟต์แวร์ คุณจะทำงานกับผลิตภัณฑ์หลักของเราที่มีฟังก์ชันการทำงานที่สำคัญสำหรับโครงสร้างพื้นฐานทางธุรกิจของเรา คุณอาจทำงานในด้านใดด้านหนึ่งต่อไปนี้: โลกาภิวัตน์ ประสบการณ์ผู้ใช้ ความปลอดภัยของข้อมูล การเรียนรู้ของเครื่อง , ระบบมีความพร้อมใช้งานสูง และอื่นๆ