アプリケーション シナリオ
なぜそれを使用する必要があるのですか? 利点は何ですか?これは最初に言っておきます。あるものが何をするのか、何に適しているのかを理解して初めて、それを自分のプロジェクトにうまく統合できます。それをどこで使用するかがわかります。学習した後に使用しない場合は、それは、あなたがそれを知らないことを意味します。私たちは通常、次のような質問をもっと検討する必要があります: xx テクノロジーと組み合わせることができる、どのようなプロジェクト機能を構築できますか?この xx テクノロジーはこのビジネス シナリオで実現可能ですか? 「この○○技術を学んだら何ができるの?今の会社では使っていないから学んでも無駄だ」ではなく、そんな気分で○○技術を学ぶのはとても辛いはずです。
キューは時間のかかる操作を最初に実行するのではなく、最初に埋められてから非同期に処理されることは誰もが知っているため、ユーザーは電子メールやテキスト メッセージの送信などの時間のかかる操作を感じることができません。はい、埋め込みポイントが終了し、操作が終了し、消費キューはすべてサーバー上で実行されるためです。これは主に、SMS または電子メール通知、メッセージを購読するためのサードパーティ インターフェイスへのアクセス、およびモールでの一部のフラッシュ セールス活動で使用され、これらはすべてキューと組み合わせて完了できます。
Beanstalkd の概要
Beanstalkd は、高性能、軽量の分散メモリ キュー、C コード、典型的な Memcached のような設計、プロトコル、および使用法です。 memcached を使用したことのあるユーザーは、Beanstalkd に親しみを感じるでしょう。
Beantalkd の本来の設計意図は、時間のかかるリクエストを非同期で実行し、時間内に結果を返して、同時性の高いネットワーク リクエストの下でのリクエストの応答遅延を軽減することです。
Ubuntu のインストール
sudo apt-get install beanstalkd ログイン後にコピー
構成ファイル
vim /etc/default/beanstalkd ログイン後にコピー
ステータスの表示
service beanstalkd status
# 命令回显 #
root@:/www/server/php/72/etc# service beanstalkd status
● beanstalkd.service - Simple, fast work queue
Loaded: loaded (/lib/systemd/system/beanstalkd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2018-10-16 10:42:28 CST; 6 days ago
Docs: man:beanstalkd(1)
Main PID: 7033 (beanstalkd)
Tasks: 1 (limit: 4634)
CGroup: /system.slice/beanstalkd.service
└─7033 /usr/bin/beanstalkd -l 0.0.0.0 -p 11300 -b /var/lib/beanstalkd
Oct 16 10:42:28 ip-10-93-2-137 systemd[1]: Started Simple, fast work queue. ログイン後にコピー
接続の永続性を構成する
ip 0.0.0.0 を使用してすべての接続を許可し、セキュリティ グループまたはファイアウォールを構成して接続を制限し、-b パラメータを解放し (デフォルトでは永続性なし)、メモリ キューメッセージは永続化するためにハードディスクの binlog に記録でき、電源がオフになったときにキュー メッセージを再読み取ることができます。
vim /etc/default/beanstalkd
BEANSTALKD_LISTEN_ADDR=0.0.0.0
BEANSTALKD_LISTEN_PORT=11300
BEANSTALKD_EXTRA="-b /var/lib/beanstalkd" ログイン後にコピー
beanstalkd タスクのステータス
ステータス コメント #遅延中 #遅延ステータス準備完了 準備完了ステータス 予約済み コンシューマはタスクを読み出して処理します #埋め込み 予約ステータス 削除 ステータスの削除 管理工具
亲测了很多网上能找到的 beanstalkd 工具,这两款是我最中意的了,一个命令行,一个 web 的。
命令行:https://github.com/src-d/beanstool
web 界面:https://github.com/ptrofimov/beanstalk_console
编程语言客户端
PHP 客户端
https://packagist.org/packages/pda/pheanstalk
composer require pda/pheanstalk ログイン後にコピー
写入 job
<?php
//创建队列消息
require_once('./vendor/autoload.php');
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1',11300);
$tubeName = 'email_list';
$jobData = [
'email' => '123456@163.com',
'message' => 'Hello World !!',
'dtime' => date('Y-m-d H:i:s'),
];
$pheanstalk->useTube( $tubeName)->put( json_encode( $jobData ) ); ログイン後にコピー
消费 job
<?php
ini_set('default_socket_timeout', 86400*7);
ini_set( 'memory_limit', '256M' );
// 消费队列消息
require_once('./vendor/autoload.php');
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1',11300);
$tubeName = 'email_list';
while ( true )
{
// 获取队列信息, reserve 阻塞获取
$job = $pheanstalk->watch( $tubeName )->ignore( 'default' )->reserve();
if ( $job !== false )
{
$data = $job->getData();
/* TODO 逻辑操作 */
/* 处理完成,删除 job */
$pheanstalk->delete( $job );
}
} ログイン後にコピー
default_socket_timeout 这个参数是一定要加的,php 默认一般是 60s,假如您没有在代码里面设置,采用默认的话(60s),60s 之内如果没有 job 产生,脚本就会报 socket 错误,我写的是 7 天超时,您可以根据业务去调整,记住一定要配置,网上很多搜的 consumer 脚本都没有配置这个,根本不能投入生产环境使用,这是我亲自实践的结果。
关于 while true 是否死循环,很明确告诉你是死循环,但是不会一直耗性能的那样执行下去,它会在 reserve 这里阻塞不动,直到有消息产生才会往下走,所以大可放心使用,我的项目代码里面是使用了方法调用方法自身去实现循环的。
就是这样的代码,供参考:
public function watchJob()
{
$job = $this->pheanstalk->watch( config( 'tube' ) )->ignore( 'default' )->reserve();
if ( $job !== false )
{
$job_data = $job->getData();
$this->subscribe( $job_data );
$this->pheanstalk->delete( $job );
/* 继续 Watch 下一个 job */
$this->watchJob();
}
else
{
$this->log->error( 'reserve false', 'reserve false' );
}
} ログイン後にコピー
监控 beanstalkd 状态
<?php
//监控服务状态
require_once('./vendor/autoload.php');
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1',11300);
$isAlive = $pheanstalk->getConnection()->isServiceListening();
var_dump( $isAlive ); ログイン後にコピー
可以配合 email 做一个报警邮件,脚本每分钟去执行,判断状态是 false,就给管理员发送邮件报警。
一些相关命令
查看 beanstalkd 服务内存占用
top -u beanstalkd ログイン後にコピー
后台运行 consumer 脚本
nohup php googlehome_subscribe.php & ログイン後にコピー
查看 consumer 脚本运行时间
ps -A -opid,stime,etime,args | grep consumer.php ログイン後にコピー
手工重启 consumer 脚本
ps auxf|grep 'googlehome_subscribe.php'|grep -v grep|awk '{print $2}'|xargs kill -9
nohup php googlehome_subscribe.php & ログイン後にコピー
一些总结
php 要把错误日志打开,方便收集 consumer 脚本 crash 的 log,脚本跑出一些致命的 error 一定要及时修复,因为一旦有错就会挂掉,这会影响你脚本的可用性,后期稳定之后可以上 supervisor 这种进程管理程序来管控脚本生命周期。
一些网络请求操作,一定要 try catch 到所有错误,一旦没有 catch 到,脚本就崩。我用的是 Guzzle 去做的网络请求,下面是我 catch 的一些错误,代码片段供参考。
try
{
/* TODO: 逻辑操作 */
}
catch ( ClientException $e )
{
$results['mid'] = $this->mid;
$results['code'] = $e->getResponse()->getStatusCode();
$results['reason'] = $e->getResponse()->getReasonPhrase();
$this->log->error( 'properties-changed ClientException', $results );
}
catch ( ServerException $e )
{
$results['mid'] = $this->mid;
$results['code'] = $e->getResponse()->getStatusCode();
$results['reason'] = $e->getResponse()->getReasonPhrase();
$this->log->error( 'properties-changed ServerException', $results );
}
catch ( ConnectException $e )
{
$results['mid'] = $this->mid;
$this->log->error( 'properties-changed ConnectException', $results );
} ログイン後にコピー
job 消费之后一定要删除掉,如果长时间不删除,php 客户端会有 false 返回,是因为有 DEADLINE_SOON 这个超时错误产生,所以处理完任务,一定要记得删除,这一点跟 kafka 不一样,beanstalkd 需要开发者自己去删除 job。
推荐教程:《PHP教程 》
以上がPHP7本番環境キューBeanstalkdの正しい利用姿勢の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
2023-03-03 16:08:02
2023-03-03 16:02:01
2023-03-03 15:58:01
2020-07-31 13:42:10
2020-07-31 13:29:12
2020-07-31 11:58:22
2020-07-31 11:38:07
2020-07-31 11:24:55
2020-07-31 11:15:48
2020-07-31 10:55:17