LTS (Light-Task-Scheduler) wird hauptsächlich zur Lösung verteilter Aufgabenplanungsprobleme verwendet und unterstützt Echtzeitaufgaben, geplante Aufgaben und Cron-Aufgaben. Es verfügt über eine gute Skalierbarkeit, Skalierbarkeit, Robustheit und Stabilität und wird von vielen Unternehmen verwendet. Wir hoffen auch, dass Open-Source-Enthusiasten gemeinsam einen Beitrag leisten können.
Github-Adresse: https://github.com/ltsopensource/light-task-scheduler
Oschina-Adresse: http://git.oschina.net/hugui/light-task-scheduler
Beispiele: https://github.com/ltsopensource/lts-examples
Dokumentadresse (unter Aktualisierung, diese wird später gelten): https://www.gitbook.com/book/qq254963746/lts/details
Beide Adressen werden gleichzeitig aktualisiert. Wenn Sie interessiert sind, treten Sie bitte der QQ-Gruppe bei: 109500214 (Gruppenpasswort: Hallo Welt), um gemeinsam zu diskutieren und Verbesserungen vorzunehmen. Je mehr Leute es unterstützen, desto größer ist die Motivation, es zu aktualisieren. Wenn Sie möchten, denken Sie daran, in der oberen rechten Ecke zu markieren.
LTS verfügt hauptsächlich über die folgenden vier Arten von Knoten:
Die Knoten JobClient, JobTracker und TaskTracker sind alle无状态
. Es können mehrere bereitgestellt und dynamisch gelöscht werden, um einen Lastausgleich und eine größere Ladekapazität zu erreichen. Das Framework verwendet die FailStore-Strategie, um LTS eine gute Fehlertoleranz zu verleihen.
Das LTS-Registrierungszentrum bietet mehrere Implementierungen (Zookeeper, Redis usw.). Das Registrierungszentrum stellt Knoteninformationen bereit und wählt Master. (Mongo oder MySQL) speichert Aufgabenwarteschlangen und Aufgabenausführungsprotokolle, Netty oder Mina übernehmen die zugrunde liegende Kommunikation und bieten mehrere Serialisierungsmethoden wie FastJson, Hessian2, Java usw.
LTS unterstützt Aufgabentypen:
Unterstützt die dynamische Änderung von Aufgabenparametern, der Aufgabenausführungszeit und anderen Einstellungen, unterstützt das dynamische Hinzufügen von Aufgaben im Hintergrund, unterstützt das Anhalten von Cron-Aufgaben, unterstützt das manuelle Stoppen ausgeführter Aufgaben (bedingt), unterstützt Aufgabenüberwachungsstatistiken und unterstützt die Aufgabenausführungsüberwachung jedes Knotens , JVM-Überwachung usw.
Die folgende Abbildung zeigt einen standardmäßigen Echtzeit-Aufgabenausführungsprozess.
Derzeit verfügt das Backend über eine einfache Authentifizierungsfunktion, die von ztajy bereitgestellt wird. Der Benutzername und das Passwort befinden sich in auth.cfg und können vom Benutzer geändert werden.
LTS benötigt das Spring-Framework überhaupt nicht, aber angesichts der Tatsache, dass viele Benutzerprojekte das Spring-Framework verwenden, bietet LTS auch Unterstützung für Spring, einschließlich XML und Anmerkungen. Führen Sie einfach lts-spring.jar
ein.
Auf der TaskTracker-Seite steht ein Business-Logger zur Verfügung, über den Business-Logger an den JobTracker übermittelt werden können. Diese Business-Logger können nach Aufgaben-IDs verkettet werden und die Ausführung der Aufgabe kann in Echtzeit angezeigt werden im LTS-Admin-Zeitplan.
Durch die SPI-Erweiterung kann lediglich die entsprechende Schnittstelle implementiert werden, und die derzeit offenen Erweiterungsschnittstellen können verwendet werden
Wenn der TaskTracker, der die Aufgabe ausführt, abstürzt, weist der JobTracker alle dem heruntergefahrenen TaskTracker zugewiesenen Aufgaben sofort anderen normalen TaskTracker-Knoten zur Ausführung zu.
Ressourcenüberwachung, Aufgabenüberwachung usw. können auf JobTracker- und TaskTracker-Knoten durchgeführt und in Echtzeit im LTS-Admin-Verwaltungshintergrund angezeigt werden, um eine angemessene Ressourcenzuweisung durchzuführen.
Das LTS-Framework bietet Unterstützung für vier Ausführungsergebnisse, EXECUTE_SUCCESS
, EXECUTE_FAILED
, EXECUTE_LATER
und EXECUTE_EXCEPTION
, und übernimmt für jedes Ergebnis entsprechende Verarbeitungsmechanismen, wie z. B. Wiederholungsversuche.
Der FailStore-Mechanismus wird für die Fehlertoleranz des Knotens verwendet. Aufgrund der Instabilität der Remote-Kommunikation hat dies keinen Einfluss auf den Betrieb der aktuellen Anwendung. Spezifische FailStore-Anweisungen finden Sie in den FailStore-Anweisungen in der Konzeptbeschreibung.
Das Projekt wird hauptsächlich mit Maven erstellt und bietet derzeit die Paketierung von Shell-Skripten. Umgebungsabhängigkeiten: Java(jdk1.6+)
Maven
Die Benutzernutzung wird im Allgemeinen in zwei Arten unterteilt:
Sie können das LTS-JAR-Paket über den Maven-Befehl in das lokale Warehouse hochladen. Fügen Sie das entsprechende Repository in der übergeordneten pom.xml hinzu und laden Sie es mit dem Befehl „deploy“ hoch. Spezifische Zitiermethoden finden Sie in den Beispielen in lts.
Jedes Modul von LTS muss in ein separates JAR-Paket gepackt werden und alle LTS-Abhängigkeitspakete müssen importiert werden. Spezifische Hinweise zu den JAR-Paketen finden Sie in den Beispielen in lts.
Für die Kompilierung und Bereitstellung stehen zwei Versionsskripte zur Verfügung (cmd)windows
und (shell)linux
:
Wenn Sie das Skript sh build.sh
oder build.cmd
im Stammverzeichnis ausführen, wird der Ordner lts-{version}-bin
im Verzeichnis dist
generiert.
Das Folgende ist seine Verzeichnisstruktur, wobei das bin-Verzeichnis hauptsächlich die Startskripte von JobTracker und LTS-Admin enthält. jobtracker
enthält die Konfigurationsdatei von JobTracker und das zu verwendende JAR-Paket lts-admin
ist das Kriegspaket und die Konfigurationsdatei für LTS-Admin. Dateistruktur von 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
und führen Sie dann sh jobtracker.sh zoo start
aus. Wenn Sie zwei JobTracker-Knoten starten möchten, müssen Sie beispielsweise einen Zoo kopieren und benennen zoo2
, ändern Sie die Konfigurationsdatei unter zoo2
und führen Sie dann sh jobtracker.sh zoo2 start
aus. Das jobtracker-zoo.out
Protokoll wird im Protokollordner generiert.conf/lts-monitor.cfg
und conf/lts-admin.cfg
und führen Sie dann das Skript sh lts-admin.sh
oder lts-admin.cmd
unter bin
aus. lts-admin.out
wird im Protokollordner erstellt. Wenn der Start erfolgreich ist, wird die Zugriffsadresse im Protokoll ausgedruckt. Zu den JAR-Paketen, die in LTS importiert werden müssen, gehören lts-jobclient-{version}.jar
, lts-core-{version}.jar
und andere abhängige JAR-Dateien von Drittanbietern.
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 ();
}
}
Zu den JAR-Paketen, die in LTS importiert werden müssen, gehören lts-tasktracker-{version}.jar
, lts-core-{version}.jar
und andere abhängige JARs von Drittanbietern.
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 ();
}
}
Parameterbeschreibung
Im Allgemeinen wird in einer JVM nur eine JobClient-Instanz benötigt. Erstellen Sie nicht für jede Aufgabe eine neue JobClient-Instanz. Dies führt zu einer erheblichen Ressourcenverschwendung, da ein JobClient mehrere Aufgaben senden kann. Dieselbe JVM versucht im Allgemeinen, nur eine TaskTracker-Instanz zu verwalten. Wenn mehr Instanzen vorhanden sind, kann dies zu einer Verschwendung von Ressourcen führen. Wenn Sie auf einen TaskTracker stoßen, der mehrere Aufgaben ausführen muss, lesen Sie bitte weiter unten „Ein TaskTracker führt mehrere Aufgaben aus“.
Manchmal erfordern Geschäftsszenarien die Ausführung mehrerer Aufgaben. Einige Leute fragen sich möglicherweise, ob für die Ausführung jedes Aufgabentyps ein TaskTracker erforderlich ist. Meine Antwort lautet: Nein. Wenn Sie sich in einer JVM befinden, ist es am besten, einen TaskTracker zum Ausführen mehrerer Aufgaben zu verwenden, da die Verwendung mehrerer TaskTracker-Instanzen in einer JVM eine Verschwendung von Ressourcen darstellt (natürlich, wenn Sie eine große Menge bestimmter Aufgaben haben). , können Sie einen separaten TaskTracker-Knoten verwenden, um diese Aufgabe auszuführen. Wie können wir also einen TaskTracker implementieren, um mehrere Aufgaben auszuführen? Unten ist das Referenzbeispiel, das ich gegeben habe.
/**
* 总入口,在 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 ;
}
}
Im Allgemeinen müssen Sie beim Schreiben von TaskTracker nur testen, ob die Implementierungslogik von JobRunner korrekt ist, Sie möchten LTS jedoch nicht für Remote-Tests starten. Um das Testen zu erleichtern, stellt LTS die Shortcut-Testmethode von JobRunner bereit. Integrieren Sie einfach com.github.ltsopensource.tasktracker.runner.JobRunnerTester
in Ihre eigene Testklasse und implementieren Sie initContext
und newJobRunner
. Wie das Beispiel in 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 ();
}
}
Für die Cron-Aufgaben von Quartz müssen Sie nur etwas Code zur Spring-Konfiguration hinzufügen, um eine Verbindung zur LTS-Plattform herzustellen.
< 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 );
}
}
Jetzt müssen Sie nur noch die entsprechende Konfiguration in application.properties hinzufügen. Weitere Informationen finden Sie im Beispiel unter com.github.ltsopensource.examples.springboot
in lts-example.
Wenn der Computer über zwei Netzwerkkarten im internen Netzwerk verfügt und der Benutzer möchte, dass der LTS-Verkehr über die externe Netzwerkkarte geleitet wird, muss er manchmal die Zuordnungsadresse des Hostnamens in die externe Netzwerkkartenadresse im Host ändern Gleiches gilt für das interne Netzwerk.
Wenn die Knoten-ID beim Start des Knotens festgelegt wird, legt LTS standardmäßig eine UUID als Knoten-ID fest. Die Lesbarkeit ist schlecht, aber die Einzigartigkeit jedes Knotens kann garantiert werden, wenn der Benutzer die Einzigartigkeit des Knotens sicherstellen kann Er kann die ID selbst festlegen und setIdentity
festlegen. Wenn beispielsweise jeder Knoten auf einer Maschine (einer virtuellen Maschine) bereitgestellt wird, kann die Identität auf den Hostnamen festgelegt werden
Unterstützt SPI-Erweiterungen für JobLogger, JobQueue usw.
Siehe Problem Nr. 389
Die Berufserfahrung beträgt mehr als drei Jahre
BildungsvoraussetzungenBachelor-Abschluss
Erwartungsniveau P6 (Senior Java Engineer)/P7 (Technischer Experte)
Stellenbeschreibung
Die Mitgliederplattform ist für das Benutzersystem der Alibaba Group verantwortlich, unterstützt die Benutzeranforderungen verschiedener Geschäftsbereiche innerhalb der Gruppe und unterstützt die Benutzer- und Geschäftskanäle der externen Zusammenarbeit der Gruppe. Es umfasst Benutzeranmeldung und -autorisierung, Sitzungssystem, Registrierung, Kontoverwaltung, Kontosicherheit und andere Funktionen an beiden Enden, zugrunde liegende Benutzerinformationsdienste, Sitzungs- und Anmeldeinformationsverwaltung usw. und ist eine der Kernproduktlinien der Gruppe, die Hunderte umfasst Milliarden von Anrufen pro Tag, Spitzen-QPS von mehreren zehn Millionen und eine global verteilte Hybrid-Cloud-Architektur usw.
Als Softwareentwickler arbeiten Sie an unseren Kernprodukten, die wichtige Funktionen für unsere Geschäftsinfrastruktur bereitstellen. Abhängig von Ihren Interessen und Ihrer Erfahrung können Sie in einem oder mehreren der folgenden Bereiche arbeiten: Globalisierung, Benutzererfahrung, Datensicherheit, maschinelles Lernen , hohe Systemverfügbarkeit und mehr.