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 (グループパスワード: hello world) に参加して、一緒に議論し改善してください。サポートしてくれる人が増えれば増えるほど、更新するモチベーションも高まります。よろしければ、右上隅にスターを付けることを忘れないでください。
LTSには主に以下の4種類のノードがあります。
JobClient、JobTracker、および TaskTracker ノードはすべて无状态
です。 複数のものをデプロイして動的に削除することで、負荷分散とより大きな負荷容量を実現できます。また、フレームワークは FailStore 戦略を使用して、LTS に良好な耐障害性を持たせます。
LTS 登録センターは、複数の実装 (Zookeeper、redis など) を提供し、ノード情報を公開し、マスターを選出します。 (Mongo または Mysql) はタスク キューとタスク実行ログを保存し、netty または mina は基礎となる通信を行い、fastjson、hessian2、java などの複数のシリアル化メソッドを提供します。
LTS は次のタスク タイプをサポートします。
タスクパラメータ、タスク実行時間、その他の設定の動的変更をサポート、バックグラウンドでのタスクの動的追加をサポート、Cronタスクの一時停止をサポート、実行中のタスクの手動停止(条件付き)をサポート、タスク監視統計のサポート、各ノードのタスク実行監視をサポート、JVM監視など。
以下の図は、標準的なリアルタイム タスクの実行プロセスです。
現在、バックエンドには ztajy によって提供される単純な認証機能があり、ユーザー名とパスワードは auth.cfg にあり、ユーザーが変更できます。
LTS は Spring フレームワークをまったく使用しなくても実行できますが、多くのユーザー プロジェクトが Spring フレームワークを使用していることを考慮すると、LTS はlts-spring.jar
を導入するだけで、Xml やアノテーションを含む Spring のサポートも提供します。
TaskTracker側にはアプリケーションで使用するためのビジネスロガーが用意されており、このビジネスロガーを介してビジネスログをタスクIDごとに連結し、タスクの実行状況をLTSでリアルタイムに確認することができます。 - 管理者のスケジュール。
SPI 拡張は、対応するインターフェイスを実装するだけでゼロ侵入を実現でき、現在オープンされている拡張インターフェイスは次のとおりです。
タスクを実行している TaskTracker がダウンすると、JobTracker はダウンした TaskTracker に割り当てられていたすべてのタスクを他の通常の TaskTracker ノードに即座に割り当てて実行します。
JobTrackerやTaskTrackerノード上でリソース監視やタスク監視などを行うことができ、LTS-Admin管理バックグラウンドでリアルタイムに確認することができ、合理的なリソース割り当てを行うことができます。
LTS フレームワークは、 EXECUTE_SUCCESS
、 EXECUTE_FAILED
、 EXECUTE_LATER
、およびEXECUTE_EXCEPTION
の 4 つの実行結果のサポートを提供し、再試行など、各結果に対応する処理メカニズムを採用します。
FailStore メカニズムは、ノードのフォールト トレランスに使用されます。Fail And Store は、リモート通信の不安定性によって現在のアプリケーションの動作に影響を与えません。特定の FailStore 命令については、概念の説明にある FailStore 命令を参照してください。
このプロジェクトは主に maven を使用して構築されており、現在はシェル スクリプトのパッケージ化を提供しています。 環境依存関係: Java(jdk1.6+)
Maven
ユーザーの使用方法は通常、次の 2 つのタイプに分類されます。
Maven コマンドを使用して、lts jar パッケージをローカル ウェアハウスにアップロードできます。対応するリポジトリを親 pom.xml に追加し、deploy コマンドを使用してアップロードします。具体的な引用方法については、ltsの例を参照してください。
lts の各モジュールは個別の jar パッケージにパッケージ化する必要があり、すべての lts 依存関係パッケージをインポートする必要があります。どの jar パッケージに関する具体的な参照については、lts の例を参照してください。
コンパイルと展開用に、 (cmd)windows
と(shell)linux
2 つのバージョンのスクリプトが提供されています。
ルート ディレクトリでsh build.sh
またはbuild.cmd
スクリプトを実行すると、 dist
ディレクトリにlts-{version}-bin
フォルダが生成されます。
ディレクトリ構成は以下のとおりで、bin ディレクトリには主に JobTracker と LTS-Admin の起動スクリプトが格納されています。 jobtracker
JobTracker の設定ファイルが含まれており、使用する必要がある jar パッケージは LTS- lts-admin
に関連する war パッケージおよび設定ファイルです。 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
を実行します。2 つの JobTracker ノードを起動する場合は、zoo をコピーする必要があります。たとえば、それに名前を付けます。 zoo2
、 zoo2
の下の構成ファイルを変更して、 sh jobtracker.sh zoo2 start
実行します。 jobtracker-zoo.out
ログは、logs フォルダーに生成されます。conf/lts-monitor.cfg
およびconf/lts-admin.cfg
の下の構成を変更し、 bin
の下でsh lts-admin.sh
またはlts-admin.cmd
スクリプトを実行します。起動に成功すると、 lts-admin.out
ログがログ フォルダーに生成され、ユーザーはこのアクセス アドレスを介してアクセスできます。 lts にインポートする必要がある jar パッケージにはlts-jobclient-{version}.jar
、 lts-core-{version}.jar
およびその他のサードパーティ依存の jar が含まれます。
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 ();
}
}
lts にインポートする必要がある jar パッケージにはlts-tasktracker-{version}.jar
、 lts-core-{version}.jar
およびその他のサードパーティ依存の jar が含まれます。
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 ();
}
}
パラメータの説明
一般に、JVM で必要な JobClient インスタンスは 1 つだけです。1 つの JobClient は複数のタスクを送信できるため、タスクごとに新しい JobClient インスタンスを作成しないでください。通常、同じ JVM は 1 つの TaskTracker インスタンスのみを維持しようとします。インスタンスが複数ある場合は、リソースの無駄が発生する可能性があります。複数のタスクを実行する必要がある TaskTracker に遭遇した場合は、以下の「1 つの TaskTracker が複数のタスクを実行する」を参照してください。
場合によっては、ビジネス シナリオで複数のタスクの実行が必要になることがあります。各タスクの種類の実行に TaskTracker が必要かどうか疑問に思う人もいるかもしれません。私の答えは「ノー」です。JVM を使用している場合は、TaskTracker を使用して複数のタスクを実行するのが最善です。JVM で複数の TaskTracker インスタンスを使用すると、リソースが無駄になります (もちろん、大量の特定のタスクがある場合)。 、別の 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 ();
}
}
Quartz の Cron タスクの場合、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 に対応する設定を追加することだけです。詳細については、lts-example のcom.github.ltsopensource.examples.springboot
パッケージの例を参照してください。
マシンの内部ネットワーク上に 2 つのネットワーク カードがある場合、ユーザーが LTS トラフィックを外部ネットワーク カード経由で通過させたい場合は、ホスト名のマッピング アドレスをホスト内の外部ネットワーク カード アドレスに変更する必要があることがあります。内部ネットワークも同様です。
ノード起動時にノード ID を設定すると、LTS はデフォルトで UUID をノード ID として設定します。可読性は悪くなりますが、ユーザーがノードの一意性を確保できれば、ノード ID は保証されます。 ID を自分で設定するには、 setIdentity
を設定できます。たとえば、各ノードがマシン (仮想マシン) にデプロイされている場合、ID をホスト名に設定できます。
JobLogger、JobQueue などの SPI 拡張機能をサポートします。
問題#389を参照
実務経験が3年以上あること
学歴要件学士号
期待レベル P6(上級Javaエンジニア)/P7(テクニカルエキスパート)
仕事内容
メンバーシッププラットフォームはアリババグループのユーザーシステムを担当し、グループ内のさまざまな事業分野のユーザーニーズをサポートし、グループの外部協力によるユーザーとビジネスチャネルをサポートします。 ユーザーのログインと承認、セッション システム、登録、アカウント管理、アカウント セキュリティ、および各エンドのその他の機能、基盤となるユーザー情報サービス、セッションと資格情報の管理などを含む、グループの中核となる製品ラインの 1 つであり、数百もの製品を取り揃えています。毎日数十億の通話量、数千万のピーク QPS、グローバルに分散されたハイブリッド クラウド アーキテクチャなど。
ソフトウェア エンジニアとして、当社のビジネス インフラストラクチャに重要な機能を提供するコア製品に携わっていただきます。興味や経験に応じて、グローバリゼーション、ユーザー エクスペリエンス、データ セキュリティ、機械学習の 1 つ以上の分野で働くことになります。 、システムの高可用性など。