ジョブワーカの
信頼性とポータビリティを高めるために
Fukuoka.go#15 2020 @online
# 速習 Go JWDK
Yuichi Watanabe at Nulab Inc.
## Go JWDKとは何か
### 概要
-
正式名は Go Job Worker Development Kit 。頭文字を取って Go JWDK。
-
ジョブキューやワーカの開発を手助けするライブラリ。
- ジョブキュー自体の解説はこちら
- 2020/3/2 現在、アルファバージョンをGitHubの組織アカウントで公開中。
-
所謂ジョブキューの1つのパターンである、competing consumers の実装を提供する。
-
competing consumersとは
-
キューに登録されたメッセージ(以下、ジョブ)は、キューを参照するいずれかのコンシューマ(以下、ワーカ)へ、少なくとも一回は配信されるパターン。
-
-
-
Pull型のジョブの配信モデルをサポート。
-
永続ストレージにRDBを使用したジョブキューの他に、
既存のミドルウェアやパブリッククラウドの
マネージドサービスを接続先として透過的に使用可能。
### Go JWDKの開発動機
-
信頼性とポータビリティに優れたジョブキュー・ワーカの仕組み作り。
- ジョブワーカを実装するにあたって勘所となる機能の汎用化。
- ジョブのロス防止、障害発生時のリカバリ、負荷削減など...
-
ジョブキューの基盤となる多様なクラウドサービス、ミドルウェア、データストレージを透過的に扱うことで、開発、運用、製品提供で発生する様々な制約に対して柔軟に対応したい。
仮にヌーラボのサービスを例にすると...
クラウドサービスとして提供している backlog.com と、ユーザ自身でオンプレミスやパブリッククラウドにセルフホストするパッケージ版、開発者のローカルマシン等、環境の差異における制約。それらの多様なコンテキストによって、最適な基盤を選定する余地を作る。
- ジョブワーカを実装するにあたって勘所となる機能の汎用化。
- ジョブキューの導入を検討する際、様々なミドルウェアやマネージドサービスへ手軽に接続して動作を試したい。
### Go JWDKの主な機能
-
重複排除
- 任意の設定により、キュー内のジョブの重複を排除する。
- 任意の設定により、キュー内のジョブの重複を排除する。
-
再配信
- 指定した回数だけ、正常に完了しなかったジョブを再配信する。
- 指定した回数だけ、正常に完了しなかったジョブを再配信する。
-
並列実行
- ワーカプール方式であらかじめ指定した数のゴルーチンで並行に処理する。
- ワーカプール方式であらかじめ指定した数のゴルーチンで並行に処理する。
-
ハートビートフック
- 処理中のジョブをハートビート(一定の間隔)で監視して任意の処理を実行する。
- 処理中のジョブをハートビート(一定の間隔)で監視して任意の処理を実行する。
-
デッドレターキュー
- 最大再配信数を越えたジョブを任意のキューへ退避する。
- 最大再配信数を越えたジョブを任意のキューへ退避する。
-
グレイスフルシャットダウン
- ワーカプロセス再起動時のジョブの途中終了を防止する。
- ワーカプロセス再起動時のジョブの途中終了を防止する。
-
FIFO
- 任意の設定により、ジョブキューからジョブを先入れ先出しする。
### Go JWDKの主な機能
-
ランダム性を持つ指数バックオフ
- リトライタイミングの重複を防止。
- リトライタイミングの重複を防止。
-
ワーカプロセスのスケールアウト
-
ワーカプロセス自体を複数並べてスケールアウトすることも可能。
(同一のキューを参照してもジョブは多重取得されない)
-
-
ジョブの永続化ストレージの選択
-
ジョブの永続化先として以下のRDBをストレージとして選択できる。
-
MySQL, Postgres, SQLite3
-
-
-
既存ミドルウェア・パブリッククラウドのメッセージグサービスの使用
-
共通のインタフェースにより、既存のミドルウェアや、パブリッククラウドのマネージドサービスを接続先として透過的に使用できる。
-
Amazon SQS, ActiveMQ
-
-
-
プライマリ・セカンダリ間の自動フェイルオーバ
-
プライマリの接続先がダウンした場合、セカンダリの接続先にジョブをエンキューする。
-
## Go JWDKの使い方
### ジョブワーカを実装するための基本的なAPI
ジョブワーカを実装するための基本的なAPIは、以下 jobworker/JobWorker に定義されている。
API | Discription |
---|---|
Enqueue | 単一のジョブを登録する。 |
EnqueueBatch | 複数のジョブを一括登録する。 |
Register | 参照するキュー名とジョブを処理するワーカの実態を登録する。 |
RegisterFunc | 参照するキュー名とジョブを処理となる関数を登録する。 |
Work | キューの読み取りとジョブの処理のループを開始する。 |
Shutdown | グレイスフルシャットダウンする。 |
RegisterOnShutdown | Shutdown実行時のイベントフックとなる関数を登録する。 |
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### ワーカプロセスの実装
package main
import (
...
// Amazon SQSへの接続するためのコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
go func() {
// キューの監視とジョブの処理のループを開始する。
// ブロックされるので新たなゴルーチン内で実行する。
err := w.Work(&jw.WorkSetting{
// Jobの並列実行数を設定する。
WorkerConcurrency: 5,
})
}()
...
...
// シグナル受信用のチャンネルを定義する。
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
// シグナルを受け取るまでブロックする。
<-quit
// シャットダウンのタイムアウトを設定する。
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,time.Minute)
defer cancel()
// Shutdown関数で処理中のジョブが完了するまで
// ブロッキングする。
err := w.Shutdown(ctx)
}
// Worker interface を実装する
// type Worker interface {
// Work(*Job) error
// }
type HelloWorker struct {
}
func (HelloWorker) Work(job *jw.Job) error {
log.Println("[HelloWorker]", job.Payload().Content)
return nil
}
Amazon SQSのコネクタを使用したワーカプロセスの実装例
### エンキューの実装
Amazon SQSのコネクタを使用したエンキューの実装例
package main
import (
...
// Amazon SQSへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 単一のジョブを「hello」キューへ追加する
ctx := context.Background()
err := w.Enqueue(ctx, jw.EnqueueInput{
Queue: "hello",
Content: `{"msg:": "foo"}`,
})
...
...
// 複数のジョブを「hello」キューへ一括で追加する
ctx = context.Background()
r, err := w.EnqueueBatch(ctx, jw.EnqueueBatchInput{
Queue: "hello",
Id2Content: map[string]string{
"60b72": `{"msg:": "foo"}`,
"5f10c": `{"msg:": "bar"}`,
"9c85c": `{"msg:": "baz"}`,
},
})
}
### エンキューの実装
Amazon SQSのコネクタを使用したエンキューの実装例
package main
import (
...
// Amazon SQSへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// sqsのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
})
// 単一のジョブを「hello」キューへ追加する
ctx := context.Background()
err := w.Enqueue(ctx, jw.EnqueueInput{
Queue: "hello",
Content: `{"msg:": "foo"}`,
})
...
...
// 複数のジョブを「hello」キューへ一括で追加する
ctx = context.Background()
r, err := w.EnqueueBatch(ctx, jw.EnqueueBatchInput{
Queue: "hello",
Id2Content: map[string]string{
"60b72": `{"msg:": "foo"}`,
"5f10c": `{"msg:": "bar"}`,
"9c85c": `{"msg:": "baz"}`,
},
})
}
### プライマリ/セカンダリの設定
package main
import (
...
// Amazon SQSへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// MySQLへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/db-connector/mysql"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// mysqlのコネクタの実態を生成する。
mysql, err := jw.Open("mysql", map[string]interface{}{
"DSN": os.Getenv("DSN"),
})
// sqsとmysqlのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
Secondary: mysql,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
...
プライマリにAmazon SQS、セカンダリにMySQLのコネクタを使用した実装例
### プライマリ/セカンダリの設定
package main
import (
...
// Amazon SQSへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/aws-sqs-connector"
// MySQLへの接続を提供するコネクタを提供する。
_ "github.com/go-jwdk/db-connector/mysql"
// ジョブを処理するワーカの実装に必要なAPIを提供する。
jw "github.com/go-jwdk/jobworker"
)
func main() {
// sqsのコネクタの実態を生成する。
sqs, err := jw.Open("sqs", map[string]interface{}{
"Region": os.Getenv("REGION"),
})
// mysqlのコネクタの実態を生成する。
mysql, err := jw.Open("mysql", map[string]interface{}{
"DSN": os.Getenv("DSN"),
})
// sqsとmysqlのコネクタを渡してJobWorkerの実態を生成する。
w, err := jw.New(&jw.Setting{
Primary: sqs,
Secondary: mysql,
})
// 参照するキューの名前とJobの処理を実装したワーカを紐つけて
// 登録する。
w.Register("hello", &HelloWorker{})
...
プライマリにAmazon SQS、セカンダリにMySQLのコネクタを使用した実装例
## Go JWDKのアーキテクチャ
-
ジョブワーカ
-
コネクタを使用して、ジョブの追加・更新、サブスクリプションの発行・停止、を制御する。
-
-
コネクタ
-
各ジョブキューへ接続するための部品。
-
ジョブ追加・更新、サブスクリプションの発行を行うAPIを提供する。
-
-
ジョブ
-
ジョブの実態。
-
処理に必要なパラメータ(コンテンツ、メタデータ)を保持する。
-
-
サブスクリプション
-
各ジョブキューの購読の実態。
-
ジョブキューに追加されたジョブは
サブスクリプションを経由して
ジョブワーカに配信される。
-
-
ジョブキュー
-
RDB、ActiveMQ、Amazon SQS等の
ジョブキューの実態。
-
### Go JWDK を構成する主要な要素
### パッケージの依存関係
-
ジョブワーカを開発するためのAPIや各コネクタ等の主要なパッケージはリポジトリ単位で分割。
-
-
MySQL, Postgres, SQLite3
-
-
各コネクタは go-jwdk/jobworker で定義した、Connector、Subscription インタフェースを実装。
### ジョブの処理フロー
### ジョブの処理フロー
### ジョブの処理フロー
### ジョブの処理フロー
### ジョブの処理フロー
### ジョブの処理フロー
## Go JWDKのこれから
### ベータリリースに向けた整備
### モニタリング画面の提供
### サポートするコネクタの追加
-
ユニットテストの拡充
-
CIの整備
-
ベンチマークの計測
-
多岐にわたるコネクタ毎のパラメータのドキュメント化
-
RDBの独自実装のキューに対してのモニタリング画面の提供。
-
Amazon SQSやActiveMQをキューとして使用した場合は、それら自身のモニタリング画面を使用してキューの詳細を閲覧できる。しかし、RDBの独自実装のキューを使用した場合は、RDBに接続しなければキューの詳細は閲覧できない。
-
-
AWS以外のパブリッククラウドや他のミドルウェアのメッセージングサービスをサポート。
worker.Shutdown(ctx)
👋👋👋
速習 Go JWDK 〜 ジョブワーカの信頼性とポータビリティを高めるために
By Yuichi Watanabe
速習 Go JWDK 〜 ジョブワーカの信頼性とポータビリティを高めるために
- 1,462