Laravel:.evnを変更してもQueueがsyncで実行。workも動かない。その原因
.evnを変更してもQueueがsyncで実行。workも動かない。
解決までまる3日を要しました。
しかも、解決したのは私ではなく、私のメンター。
いゃ~わからんよ、それは。と言う所だったのでしっかりと記録に残そうと思います。
やりたかった事
結論を書けば、非同期処理を仕掛けたかったわけです。
楽天市場やAmazonのランキングの取得やAPIによる出品業務など、店舗運営ではブラウザを占有されてしまうと困る時間のかかる処理が目白押しです。
そんな処理をキューイングで解決しようと仕掛けを作っていた時に事件が起こりました。
発生した大問題
起こった現象は下記4点です。
- QueueServerをDataBaseに変えてもjobsテーブルに値が入らない
- DataBaseに変えているのにsyncで実行されている
- onConnection(’database’)を指定してもjobsに値が入らない
- ワーカー(queue:work)も起動しない
解決のためにもう何ページの情報を閲覧したか。
そのどれもがエラーについてではなく、順当な構築方法に触れられたものでした。
こういったエラーの解決情報ってなかなかHITしないんですよね。
起こっていた現象を1つづつ開設していきます。
QueueServerをDataBaseに変えてもjobsテーブルに値が入らない
まず疑ったのがちゃんと設定変えてるか?と言うものでした。
Queueの読込先に関しては記載されている箇所が3か所あります。
- Laravel/.env
- Laravel/phpumit.xml
- Laravel/config/queue.php
それぞれの中身はこんな感じです。
■.env
1 2 3 4 |
BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=database |
QUEUE_DRIVER=sync を QUEUE_DRIVER=database に変更
基本的にはこの設定変更だけでQueueをテーブルに保存してくれるようですが、駄目な方もいるとの事。
そんな時は次の二つも弄ります。
■phpumit.xml
1 2 3 4 5 6 7 |
</filter> <php> <env name="APP_ENV" value="testing"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> </php> </phpunit> |
<env name=”QUEUE_DRIVER” value=”sync”/>という値が入っている事があります。
この場合は”sync”を”database”に変えます。
削除でも良いそうなので、私は削除で対応しました。
■queue.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
'default' => env('QUEUE_DRIVER', 'database'), 'connections' => [ 'sync' => [ 'driver' => 'sync', ], 'database' => [ 'connection' => 'mysql', 'driver' => 'database', 'table' => 'jobs', 'queue' => 'default', 'expire' => 60, 'retry_after' => 90, ], |
‘default’ => env(‘QUEUE_DRIVER’, ‘sync’), を ’default’ => env(‘QUEUE_DRIVER’, ‘database’),に書き換えます。
場合によっては ‘database’ => [ 内に ‘connection’ => ‘mysql’, を書き加えます。
マニュアル見ながら、お手本見ながら、検索しながらこの3か所の設定をdatabaseに書き換えましたがjobsに値が入らない!
DataBaseに変えているのにsyncで実行されている
3か所の記載を変えてもjobsに入らずでもディスパッチは動いて処理を行っています。
どうやらsyncで動いている様です。「なんなんだよ!」
syncで動いているか調べるためには【delay(60)】等として遅延動作を書いてみます。
お手本を基にこの様に処理を書きました。
■routes/web.php
1 2 3 4 5 |
Route::get('test', function () { $log = (new App\Jobs\test)->delay(60); dispatch($log); return 'ユーザー登録完了を通知するメールを送信しました。'; }); |
「60秒後に処理してね」そんな指示です。
指示しているのになのになぜか即時実行されます。
これは、プログラムがsyncで走っている証拠となるそうです。
(syncは処理を待たない)
念のため重い処理を書いてブラウザが占有されるかテストしました。
はい、ばっちり30分もブラウザを占領してくれやがりました。
非同期処理が出来ていないこと確定です。
onConnection(’database’)を指定してもjobsに値が入らない
そもそもワーカーが立ち上がっていないからjobsに流れないのではないか、そんな邪推をしてワーカーを起動してみました。
1 |
php artisan queue:work |
実験の為、次の事を行いました。
1 2 |
test::dispatch() ->onConnection('database'); |
データベースを指定して投げる方法です。
この処理をすると指定したdatabaseに値が投げられるはず…なのですが何にも全く入ってきません。
この件については先に解決した方法を書いてしまいます。(次の項目があるので)
原因を作っていたのは先日設定したララベルの自動起動設定でした。
rc.d/local で起動しているlaravelを一旦止めて、laravelサーバ再起動したところ jobs に保存されるように!
しかしこの時点でまだ指定しなくてはjobsに入らない状態です。
また、なんでこの修正で onConnectionの指定が効くようになったか詳細は不明です。
ワーカー(queue:work)も起動しない
正確にはワーカーがjobsの中身を処理しに来ない。ですが、まぁ動いていないのと同じです。
自動起動設定を止めて再起動+Connection指定でjobsに入るようになっても処理をしてくれなければ意味なしです。
そもそもSSHからの起動指示を受け付けていないのではないか。
そんな推測をし、supervisorをインストールしましたが、全く本質から外れた対応でした。
全ての原因はキャッシュでした
メンターに相談したところ「ひょっとして」と出てきた所がキャッシュ。
私の場合はLaravel/bootstrap/cache/config.phpの中に sync の記載がありました。
ここを削りLaravelを再起動させたところ、見事にjobsに値が入りました。
いゃぁ~長い道のりだった…。
でもまだworkの起動問題が残ってます。
何故なら、jobsに入ってから動かない(消えない)からです。
これは次の手順で実行すると無事起動にこぎつけました。
1 2 3 4 5 |
//先に実行 php artisan serve //php artisan serveの後に実行 php aritsan queue:work |
php aritsan queue:work 単品で動かない場合、先にserveを実行してみると解決するかもしれません。
私の場合はコレで無事に起動しました。
まとめ
いやぁ~長かった。
辛かった。
キツかった。
店舗運営には非同期処理を掛けたい事柄が沢山ありますから何とか解決できてよかったです。
つかれた~~。
-
前の記事
Laravel:The HTTP status code “1” is not valid.とエラーが出た時 2019.06.25
-
次の記事
Laravel:workerを自動起動させるSupervisor設置でハマったところ 2019.06.29
コメントを残す