ホームページ > バックエンド開発 > PHPチュートリアル > QQ メンバーの AMS プラットフォームの PHP7 アップグレードの実践(毎日 1 億件のリクエスト)

QQ メンバーの AMS プラットフォームの PHP7 アップグレードの実践(毎日 1 億件のリクエスト)

WBOY
リリース: 2016-06-23 13:03:30
オリジナル
1069 人が閲覧しました

声明: この記事は CSDN に投稿されたものであり、いかなる形式であっても許可なく複製することは禁止されています。

著者: Xu Hanbin、Wang Mohan、Liao Shengmao、Kuang Suwen、Liao Zengkang、Wu Zemin、上記はテンセントの付加価値製品部門プラットフォーム開発センターの PHP7 アップグレード R&D プロジェクト チームの中心メンバーです。

編集者: Qian Shuguang は、アーキテクチャとアルゴリズムの分野に重点を置いています。レポートや提出物を探している場合は、qianshg@csdn.net に電子メールを送信してください。多くのメンバーが含まれる「CSDN シニア アーキテクト グループ」もあります。有名なインターネット企業の著名な建築家を歓迎します。グループへの参加を申請するには、WeChat qshuguang2008 を追加してください。名前、会社名、役職をメモしてください。

推奨: PHP Developer's Encyclopedia - PHP Knowledge Graph

QQ メンバー アクティビティ オペレーション プラットフォーム (AMS) は、QQ メンバーの付加価値運営ビジネスの重要なキャリアの 1 つであり、大規模なアクティビティの運営を担当する Web システムです。 AMSは主にPHP言語で実装されたイベント運営プラットフォームで、1日あたりのCGIリクエストは約3億件、ピーク時には8億件に達します。ただし、比較的長い間、基本ソフトウェアの古いバージョンである PHP5.2+Apache2.0 (2008 テクノロジ) を使用してきました。特に昨年以来、AMS ビジネスと QQ 会員の付加価値サービスの急速な成長により、パフォーマンスのプレッシャーはますます大きくなってきています。

そこで、2015 年 5 月から、PHP の最下層をアップグレードする計画を開始し、最終的な目標は PHP7 にアップグレードすることです。当時、PHP7 はまだ研究開発段階にあり、すでに議論や事前研究が始まっていました。

1. PHP7 の学習と事前調査 1. HHVM と JIT

2015 年、PHP パフォーマンス最適化計画では、Facebook によってオープンソース化された HHVM (HipHop Virtual Machine) がさらに重要な役割を果たしました。 HHVM は Facebook のオープンソース PHP 仮想マシンです)。 HHVM は、JIT (Just In Time、ジャストインタイム コンパイルとは、ソフトウェア最適化技術の 1 つで、実行時にバイトコードをマシンコードにコンパイルすることを指します) コンパイル方法やその他の技術を使用して、PHP コードの実行パフォーマンスを大幅に向上させます。 PHP5 バージョンのネイティブ PHP コードの実行パフォーマンスは 5 ~ 10 倍向上すると噂されています。

HHVM は Facebook から生まれました。Facebook の初期のコードの多くは PHP を使用して開発されました。しかし、ビジネスの急速な発展に伴い、PHP の実行効率がますます明らかな問題になってきました。実行効率を最適化するために、Facebook は 2008 年に PHP 実行エンジンである HipHop の使用を開始しました。これは元々、Facebook の大量の PHP コードを C++ に変換してパフォーマンスを向上させ、リソースを節約するために設計されました。 HipHop を使用した PHP コードのパフォーマンスは数倍向上しました。その後、Facebook は HipHop プラットフォームをオープンソース化し、徐々に現在の HHVM に発展させました。

HHVM が PHP パフォーマンス最適化ソリューションになったとき、PHP7 はまだ研究開発段階にありました。 HHVM については、パフォーマンスを大幅に向上させることができますが、サービスの運用と保守、および PHP 構文の互換性にある程度のコストがかかります。しばらくの間、JIT は非常に人気のあるものとなり、多くの技術学生がパフォーマンスを最適化するために PHP7 も JIT を使用するべきだと提案しました。

2015 年 7 月、私は中国 PHPCON に参加し、Hui Xinchen による PHP7 カーネルに関する技術的な共有を聞きました。実際、2013 年に、Hui Xinchen (PHP7 カーネル開発者) と Dmitry (他の PHP 言語カーネル開発者の 1 人) が PHP5.5 バージョンで JIT を試みたことがありました (リリースされませんでした)。 PHP5.5 の本来の実行プロセスは、字句解析および構文解析を通じて PHP コードをオペコード バイトコードにコンパイルすることです (形式はアセンブリに似ています)。次に、Zend エンジンがこれらのオペコード命令を読み取り、1 つずつ解析して実行します。

そして、オペコードリンクの後に型推論 (TypeInf) を導入し、実行前に JIT を通じて ByteCode を生成しました。

その結果、JIT導入後のベンチマーク(テストプログラム)では、PHP5.5と比較して8倍のパフォーマンスが向上し、非常に良好な結果が得られました。しかし、この最適化を実際のプロジェクト WordPress (オープンソースのブログ プロジェクト) に適用したところ、パフォーマンスの向上はほとんどありませんでした。その理由は、テスト プロジェクトのコード量が比較的少なく、JIT によって生成されるマシン コードが大きくないのに対し、実際の WordPress プロジェクトによって生成されるマシン コードが大きすぎるため、CPU キャッシュ ヒット率が低下するためです (CPUキャッシュミス)。

つまり、JIT はあらゆるシナリオで石を金に変えるツールではなく、ビジネス シナリオから切り離されたパフォーマンス テストの結果が必ずしも代表的であるとは限りません。

WordPress が公開した PHP7 と HHVM の公式パフォーマンス比較から、この 2 つは基本的に同じレベルであることがわかります。

2. PHP7 のパフォーマンスの最適化

PHP7 は、PHP5.6 に比べて大きな変更が加えられた比較的低レベルのアップグレードです。

(1) 基本的な変更。変数を構造体から共用体に変更してメモリ領域を節約し、メモリ割り当てと管理における CPU オーバーヘッドを間接的に削減します。

(2) 一部の基本変数 (zend_array、zend_string など) は、CPU キャッシュミスの確率を減らすためにメモリ空間を継続的に割り当てる方法を採用しています。 CPU キャッシュとメモリからデータを取得する CPU の効率の差は 100 倍にもなる可能性があります。おおよその例を挙げると、メモリからのデータの読み取りとディスクからのデータの読み取りにおけるシステムの効率は、ページ フォールト割り込みの発生と同様に大きく異なります。

(3) マクロ定義とインライン関数を通じて、コンパイラに作業の一部を事前に完了させます。プログラム実行時にメモリを確保する必要がなく、関数と同様の機能を実現できますが、スタックのプッシュや関数呼び出しのポップなどのオーバーヘッドがないため、効率は比較的高くなります。

… …

PHP7 のより詳細な概要については、興味のある学生は次を参照してください: 「PHP7 のイノベーションとパフォーマンスの最適化」

3. AMS プラットフォーム テクノロジ選択の背景

PHP のパフォーマンス向上に関するオプション2015 年に直接使用できる HHVM と、2015 年末に正式版としてリリースされた PHP7 を選択できます。 Member AMS は、4 年間の継続的なアップグレードと最適化を経て、800 を超えるビジネス機能コンポーネント、および PHP で記述されたさまざまな公開基本ライブラリとスクリプトが蓄積され、コード サイズが比較的多い Web システムです。も比較的大きいです。

PHP バージョンのコードの下位互換性に対する要求は比較的高いため、ビジネス シナリオに関する限り、PHP7 の優れた構文と下位互換性はまさに必要なものです。したがって、アップグレード ソリューションとして PHP7 を選択しました。

2. PHP7 のアップグレードが直面するリスクと課題

すでにオンラインになっている大規模な公開 Web サービスにとって、基本的な公開ソフトウェアのアップグレードは、それがうまく行われたとしても、通常は報われない仕事である可能性があります。ただし、アップグレードに問題が発生した場合、より重い責任を負う必要があると感じます。アップグレードのリスクを最小限に抑えるには、まずアップグレードの課題とリスクを理解する必要があります。

そこで、アップグレードの課題とリスクのリストをまとめました。

(1) 2008 年から 2009 年までの 2 つの基本ソフトウェア バージョンである Apache2.0 と PHP5.2 は、比較的古いものです。バージョン アップグレードの期間は 7 ~ 8 年と比較的長く、そのため互換性の問題は比較的大きな課題となります。実際、当社の既存の PHP サービスの多くは、比較的低いバージョンである PHP5.2 および PHP5.3 に留まっています。

(2) AMS は、多数の自社開発の tphplib 拡張機能を使用しています。tphplib は、以前は PHP5.3 および PHP5.2 のバージョンのみをコンパイルしていましたが、社内では長い間メンテナンスされていませんでした。一部の拡張機能はスレッド セーフをサポートしていませんでした。以前の Apache ではプリフォーク モードが使用されていたため、スレッド セーフがサポートされています。また、高い同時実行性をサポートするために、Apache2.4 のイベント モード (プリフォークとワーカーの後に 2014 年半ばに開始されたマルチプロセス スレッド管理モード) を使用したいと考えています。

(3) PHP5.2 から PHP7 までの範囲は大きすぎます。PHP は公式に 99% の下位互換性があると主張していますが、コードのサイズは比較的大きく、そのリスクはまだ不明です。

(4) 新しいソフトウェアが直面するリスク Apache や PHP などの基本ソフトウェアを最新バージョンにアップグレードすると、これらのバージョンの一部の機能には未知のリスクや欠陥が存在する可能性があります。

実際、同時実行性の高さの点で Nginx と Apache のパフォーマンスを単純に比較すると、Nginx の方が優れていると考える学生もいるかもしれません。しかし、PHP の CGI に関する限り、Nginx+php-ftpm と Apache+mod_php の間に大きな違いはありません。一方、私たちは Apache を長年使用しているため、技術的な知識と経験が蓄積されているため、最良の選択ではないかもしれませんが、当社のビジネス シナリオに特有の、より適切な選択です。

3. バージョンアップ実施プロセス 1. ハイスパンのバージョンアップ方法

2008 年の Apache2.0 から 2016 年の Apache2.4 に直接アップグレードします。このスパンは大きすぎ、http の構成も含めます。 conf を使用します。 ファイルには多くの違いがあり、更新が必要な部分が多く、未知のリスクも存在します。したがって、私たちのアプローチは、まず Apache2.0 から Apach2.2 へのアップグレードを試み、構成を調整し、安定性を観察してから、さらに Apache2.4 を試すことです。幸いなことに、Apache (httpd) は特別なオープン ソース コミュニティであり、Apache の 2 つのブランチ バージョン (2.2 および 2.4) を同時に保守しているため、Apache 2.2 であっても比較的新しいバージョンがあります。

そこで、まず PHP5.2+Apache2.2 をアップグレードし、互換性をテストおよび観察し、両者がスムーズにアップグレードできることを確認した後、Apache2.4 アップグレード計画を開始しました。

PHP5.2 のアップグレードでも同じ考えを採用し、最初に PHP5.2 を PHP5.6 にアップグレードし (当時、PHP7 はまだベータ版でした)、次に PHP5.6 から PHP7 にアップグレードしました。さまざまな問題を段階的に解決する方法をよりスムーズにします。

したがって、私たちのアップグレード計画は次のようになります:

Apache2.4 は動的 MPM モードにコンパイルされ (httpd 構成によるプリフォーク/ワーカー/イベント モードの切り替えをサポート)、既存のネットワーク リスクに応じてリアルタイムでダウングレードされます。

Prefork、Worker、Event の大まかな紹介:

(1) prefork、マルチプロセス モード、1 つのプロセスが 1 つのユーザー リクエストを処理し、コストが比較的高くなります。ただし、安定性を最大限に高めるために、スレッド セーフのサポートは必要ありません。

(2) ワーカー、マルチプロセスおよびマルチスレッド モード。スレッドは軽量でコストが低いため、1 つのプロセスに複数のワーカー スレッドが含まれ、1 つのワーカー スレッドが 1 つのユーザー リクエストを処理します。ただし、KeepAlive シナリオでは、ワーカー リソースがクライアントによって占有され、他のリクエストに応答できなくなります (空の待機)。

(3) イベント、マルチプロセスおよびマルチスレッド モード。1 つのプロセスには複数のワーカー スレッドも含まれ、1 つのワーカー スレッドは 1 つのユーザー リクエストを処理します。ただし、KeepAlive シナリオでワーカー スレッドが占有されるという問題は解決され、これらの KeepAlive 接続は専用のスレッドを通じて管理され、特定の処理のためにワーカーに「作業」が割り当てられます。

イベント モードの公式紹介:

http://httpd.apache.org/docs/2.4/mod/event.html

(一部の学生はイベント モードが https をサポートしていないという印象を持っているかもしれません。その記述は実際には2 年以上前のいくつかの国内技術ブログによると、現在のバージョンはサポートされています。詳細については、公式の紹介を参照してください)

動的切り替えモードを有効にする方法は、httpd のコンパイル時に

–enable-mpms- を追加することです。 shared=all

PHP5.2 から PHP5.6 へのアップグレードは比較的簡単です。 私たちの主な作業は次のとおりです:

(1) 使用されなくなった古い拡張機能をクリーンアップ

(2) スレッドを解決しました。安全性の問題

(3) cmem などの API を新しいバージョンにコンパイルします

(4) PHP コードの構文は PHP5.6 に基づいて互換性があります (実際にはほとんど変更ありません)

(5) 一部の拡張機能の同期調整。 apc 拡張機能は zend_opcache と apcu になりました。以前の apc にはコンパイル キャッシュとユーザー メモリ操作の機能が含まれていましたが、新しいバージョンの PHP では 2 つの独立した拡張機能に分割されました。

PHP5.6 から PHP7.0 へのアップグレードは多くの作業が必要であり、比較的複雑であるため、各段階でアップグレード計画を策定しました。

(1) 技術的な事前調査、PHP7 アップグレードの準備。

(2) 環境のコンパイルと構築、関連するコンパイル パッケージをダウンロードし、完全なコンパイル環境とテスト環境を構築します。 (コンパイル環境には依然として so への依存関係がさらに必要です)

(3) アップグレードとテストとの互換性。 PHP7 拡張機能の再コンパイルとコードの互換性作業、AMS 機能の検証、パフォーマンス ストレス テスト。

(4) オンラインでグレースケール。これを pkg インストール パッケージとしてパッケージ化し、関連するインストール シェル インストール実行コード (ソフト リンクと一部の so 依存関係の解決を含む) を作成します。次に、グレースケールを既存のネットワークにインストールして観察します。

(5) 正式にリリースされました。グレースケール範囲を拡張し、完全にアップグレードします。

PHP5.2 から PHP5.6 へのアップグレード中に多くの問題を事前に解決しているため、PHP7 のアップグレードにおける主な困難は、tphplib 拡張機能のコンパイルとアップグレードにあります。

関係する主な作業には以下が含まれます:

(1) PHP5.6 から PHP7.0 の比較的大規模な変換とアップグレードへの拡張 (ワークロードが比較的大きい場合)

(2) apcu 互換の名前変更メモリ操作機能。 PHP5 では、これまで使用していた apc 接頭辞付き関数は使用できなくなり、apcu 接頭辞付き関数 (apcu 拡張が必要) に同期的に変更されます。

(3) 構文の互換性のアップグレード。実際、作業負荷は大きくなく、PHP5.6 から PHP7 へのアップグレードでは大きな変更はありません。

私たちは、2016 年 4 月中旬頃に PHP7 と Apache のコンパイルを完了し、4 月下旬にライブ ネットワーク グレースケールを実行し、5 月上旬にライブ ネットワーク クラスターの 1 つに完全にリリースしました。

2. アップグレード プロセス中のエラー デバッグ方法

PHP7 拡張機能をアップグレードして再コンパイルするときに、実行結果が期待どおりでない場合、またはプロセスがコア化されている場合、エラー ログに多くのエラーが表示されず、分析に役立ちません。問題。ほとんどの問題を特定して分析するには、次の方法を使用できます:

(1) var_dump/exit

徐々に情報を出力し、PHP コード層から exit を実行すると、異常に実行された PHP 関数の場所を徐々に特定できます。 、PHP 関数名に基づいて、拡張機能内の実装関数を確認して問題を見つけます。この方法は比較的単純ですが、効率的ではありません。

(2) gdb –p/gdb c

このメソッドは主にプロセスコアシナリオを分析するために使用されます。私たちが使用するコンパイル方法は、gdb – p を使用して mod_php (PHP を Apache のサブまたはブロックに) 変換することです。 Apache サービス プロセスを監視します。 Command:ps aux | grephttpd

gdbdebug指定されたプロセス:

command:gdb-p

uusecapture cを使用してから、コアにつながる可能性のあるWebリクエストを作成します。通常、Apache はマルチプロセス モードになっており、問題を再現しやすくするために、http.con のパラメータを変更し、起動プロセスの数を 1 に変更できます (これを実現するには、下の図の複数のパラメータを調整する必要があります)単一プロセスと単一スレッドの開始のみ) 目的​​)。もちろん、Apache 自体はシングルプロセス デバッグ モードをサポートしているため、より簡単な方法もあります。

./apachectl -k start -X -e debug

これにより、gdb –p を使用したデバッグが簡単になります。

(3) strace コマンドを使用して、Apache プロセスが具体的に何をしているのかを確認し、内部の実行内容から分析して問題点を特定します。

strace -Ttt -v -s1024 -f -p pid (プロセス ID)

注: これらのコマンドを実行するときは、権限の問題に注意してください。root 権限が必要になる場合があります。

4. PHP5.6からPHP7.0への拡張とアップグレードの実践記録 (1) zval php7の誕生は、zval構造の変更から始まりました。一部の zval** を zval* に変更する必要があります。 PHP7 が zval を直接操作する場合、zval* も zval に変更する必要があり、Z_*P() も Z_*() に変更する必要があり、ZVAL_*(var, …) も ZVAL_*(&var, ...) なので注意してください。& 記号を使用してください。PHP7 では zval* を使用する必要がほとんどないため、多くの場所で & も削除する必要があります。 メモリを割り当てる ALLOC_ZVAL、ALLOC_INIT_ZVAL、MAKE_STD_ZVAL マクロは削除されました。ほとんどの場合、zval* は zval に変更する必要があり、INIT_PZVAL マクロは削除されています。

/* 7.0zval结构源码 *//* value字段,仅占一个size_t长度,只有指针或double或者long */typedef union _zend_value {    zend_long         lval;                /* long value */    double            dval;                /* double value */    zend_refcounted  *counted;    zend_string      *str;    zend_array       *arr;    zend_object      *obj;    zend_resource    *res;    zend_reference   *ref;    zend_ast_ref     *ast;    zval             *zv;    void             *ptr;    zend_class_entry *ce;    zend_function    *func;    struct {        uint32_t w1;        uint32_t w2;    } ww;} zend_value;struct _zval_struct {    zend_value        value;            /* value */    union {        。。。    } u1;/* 扩充字段,主要是类型信息 */    union {        … …    } u2;/* 扩充字段,保存辅助信息 */};
ログイン後にコピー

(2) 整数型

直接切り替え: long->zend_long

/* 定义 */typedef int64_t zend_long;/* else */typedef int32_t zend_long;
ログイン後にコピー

(3) String 型

PHP5.6 バージョンは文字列を表すために char* + len を使用します。PHP7 は .0 でカプセル化されています。そして、zend_string 型を定義します:
struct _zend_string {    zend_refcounted_h gc;    zend_ulong        h;                /* hash value */    size_t            len;    char              val[1];};
ログイン後にコピー
zend_string と char* の間の変換:

zend_string *str;char *cstr = NULL;size_t slen = 0;//.../* 从zend_string获取char* 和 len的方法如下 */cstr = ZSTR_VAL(str);slen = ZSTR_LEN(str);/* char* 构造zend_string的方法 */zend_string * zstr = zend_string_init("test",sizeof("test"), 0);
ログイン後にコピー

拡張メソッド、パラメーターを解析するときに、文字列が使用されている箇所の 's' を 'S' に置き換えます:

/* 例如 */zend_string *zstr;if (zend_parse_parameters(ZEND_NUM_ARGS() , "S", &zstr) == FAILURE){    RETURN_LONG(-1);}
ログイン後にコピー

(4) カスタム オブジェクト

ソースコード:
/* php7.0 zend_object 定义 */struct _zend_object {    zend_refcounted_h gc;    uint32_t          handle;    zend_class_entry  *ce;    const zend_object_handlers  *handlers;    HashTable        *properties;    zval              properties_table[1];};
ログイン後にコピー
zend_object は可変長構造体です。したがって、カスタムオブジェクトの構造では、zend_object を最後の項目として配置する必要があります:

/* 例子 */struct clogger_object {    CLogger *logger;    zend_object  std;// 放在后面};/* 使用偏移量的方式获取对象 */static inline clogger_object *php_clogger_object_from_obj(zend_object *obj) {    return (clogger_object*)((char*)(obj) - XtOffsetOf(clogger_object, std));}#define Z_USEROBJ_P(zv) php_clogger_object_from_obj(Z_OBJ_P((zv)))/* 释放资源时 */void tphp_clogger_free_storage(zend_object *object TSRMLS_DC){    clogger_object *intern = php_clogger_object_from_obj(object);    if (intern->logger)    {        delete intern->logger;        intern->logger = NULL;    }    zend_object_std_dtor(&intern->std);}
ログイン後にコピー

(5) 配列

7.0中的hash表定义如下,给出了一些注释:/* 7.0中的hash表结构 */typedef struct _Bucket { /* hash表中的一个条目 */zval              val;   /* 删除元素zval类型标记为IS_UNDEF */zend_ulong        h;                /* hash value (or numeric index)   */zend_string      *key;              /* string key or NULL for numerics */} Bucket;        typedef struct _zend_array HashTable;    struct _zend_array {    zend_refcounted_h gc;    union {        struct {            ZEND_ENDIAN_LOHI_4(                zend_uchar    flags,                zend_uchar    nApplyCount,                zend_uchar    nIteratorsCount,                zend_uchar    reserve)        } v;        uint32_t flags;    } u;    uint32_t          nTableMask;    Bucket           *arData; /* 保存所有数组元素 */    uint32_t          nNumUsed; /* 当前用到了多少长度, */    uint32_t          nNumOfElements; /* 数组中实际保存的元素的个数,一旦nNumUsed的值到达nTableSize,PHP就会尝试调整arData数组,让它更紧凑,具体方式就是抛弃类型为UDENF的条目 */    uint32_t          nTableSize; /* 数组被分配的内存大小为2的幂次方(最小值为8) */    uint32_t          nInternalPointer;    zend_long         nNextFreeElement;    dtor_func_t       pDestructor;};
ログイン後にコピー

このうち、PHP7 では、キーのトラバースを含む配列を操作するための一連のマクロが zend_hash.h に定義されています。 、値のトラバース、キーと値のトラバースなど。簡単な例を次に示します。
/* 数组举例 */zval *arr;zend_parse_parameters(ZEND_NUM_ARGS() , "a", &arr_qos_req);if (arr){    zval *item;    zend_string *key;    ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(arr), key, item) {        /* ... */    }}/* 获取到item后,可以通过下面的api获取long、double、string值 */zval_get_long(item) zval_get_double(item) zval_get_string(item)
ログイン後にコピー
PHP5.6 バージョンでは、キーは zend_hash_find によって検索され、結果はクエリの zval ** 変数に与えられます。が見つからない場合は、自分でメモリを割り当てて項目を初期化し、デフォルト値を設定する必要があります。

2. PHP7 での API の変更点

(1) 重複パラメータ PHP5.6 の多くの API は、特に文字列操作の場合、変数をコピーする必要があるかどうかを示すために重複パラメータを入力する必要があります。 .0 ではキャンセルされました。文字列関連の操作については、重複するパラメータがある限り、直接削除してください。 zval_string 構造は PHP7.0 で定義されているため、文字列操作に重複した値は必要なくなりました。PHP5.6 では、zend_string_init を直接使用して、文字列は zval に格納され、メモリが格納されます。 zval 手動割り当てが必要です。 関連する API は次のように要約されます:

引用

add_index_string、add_index_stringl、add_assoc_string_ex、add_assoc_stringl_ex、add_assoc_string、add_assoc_stringl、add_next_index_string、add_next_index_stringl、add_get_assoc_string_ex、 stringl_ ex、add_get_assoc_string、add_get_assoc_stringl、add_get_index_string、add_get_index_stringl、add_property_string_ex、add_property_stringl_ex、add_property_string、 add_property_stringl, ZVAL_STRING , ZVAL_STRINGL, RETVAL_STRING, RETVAL_STRINGL, RETURN_STRING, RETURN_STRINGL

(2) MAKE_STD_ZVAL

PHP5.6 では、zval 変数を作成するには、まずポインタを宣言してから、ヒープ上に割り当てる必要があります。 MAKE_STD_ZVAL を使用してスペースを割り当てます。 PHP7.0 では、変数はスタック上に割り当てられるようになり、使用される場所で MAKE_STD_ZVAL を直接定義する必要がなくなりました。

(3) ZEND_RSRC_DTOR_FUNC

パラメータ名 rsrc を res

/* PHP5.6 */typedef struct _zend_rsrc_list_entry {    void *ptr;    int type;    int refcount;} zend_rsrc_list_entry;typedef void (*rsrc_dtor_func_t)(zend_rsrc_list_entry *rsrc TSRMLS_DC);#define ZEND_RSRC_DTOR_FUNC(name)        void name(zend_rsrc_list_entry *rsrc TSRMLS_DC)/* PHP7.0 */struct _zend_resource {    zend_refcounted_h gc;/*7.0中对引用计数做了结构封装*/    int               handle;    int               type;    void             *ptr;};typedef void (*rsrc_dtor_func_t)(zend_resource *res);#define ZEND_RSRC_DTOR_FUNC(name) void name(zend_resource *res)
ログイン後にコピー
に変更します PHP7.0 では、zend_rsrc_list_entry 構造体が新しいバージョンではパラメータ名を変更するだけで済みます。

(4) セカンダリ ポインタ マクロ、つまり Z_*_PP

PHP7.0 ではすべての PP マクロがキャンセルされており、ほとんどの場合、対応する P マクロが直接使用できます。

(5) zend_object_store_get_object はキャンセルされます

公式 wiki によると、オブジェクトを取得するには次のマクロを定義できます:

static inline user_object *user_fetch_object(zend_object *obj) {    return (user_object *)((char*)(obj) - XtOffsetOf(user_object, std));}/* }}} */ #define Z_USEROBJ_P(zv) user_fetch_object(Z_OBJ_P((zv)))
ログイン後にコピー
(6) zend_hash_exists、zend_hash_find

For all For文字列パラメーターを必要とする関数の場合、PHP5.6 のメソッドは 2 つのパラメーター (char* + len) を渡すことになっており、zend_string は PHP7.0 で定義されているため、必要な zend_string 変数は 1 つだけです。

戻り値はzend_bool型になります:
/* 例子 */zend_string * key;  key = zend_string_init("key",sizeof("key"), 0);zend_bool res_key = zend_hash_exists(itmeArr, key);
ログイン後にコピー

Quote

【参考】

1. php5からphpng: http://yaoguais.com/?s=md/php/php7-vm.md

2 . PHP 拡張機能の開発とカーネル アプリケーション: http://www.walu.cc/phpbook/10.1.md

3. PHP 7 の新しいハッシュテーブルの実装とパフォーマンスの向上: http://gywbd.github.io/posts/2014 /12/php7-new-hashtable-implementation.html

4. PHP7 の zval の詳細: https://github.com/laruence/php7-internal/blob/master/zval.md

5. 公式wiki: https://wiki.php.net/phpng-upgrading

6. PHP マニュアル: http://php.net/manual/zh/index.php

7. PHP7 は、サードパーティの拡張機能をラップするためにリソースを使用します。実装とソースコードの解釈: https://mengkang.net/684.html

5. AMS プラットフォームを PHP7 にアップグレードした場合のパフォーマンス最適化の結果

ライブ ネットワーク サービスは非常に重要で機密性の高い環境であり、良くてもユーザー エクスペリエンスに影響を与え、最悪の場合ライブ ネットワーク事故を引き起こす可能性があります。そのため、4 月下旬に PHP7 のコンパイルとテストを完了した後、AMS マシンの 1 台でグレースケール バージョンを起動し、数日間観察した後、徐々にグレースケールの範囲を拡大し、5 月上旬にアップグレードを完了しました。

これは、複数のアクティビティ カウンターの AMS クエリのストレス テスト結果と、ピーク時の同じ TGW トラフィック シナリオにおけるライブ ネットワーク CGI マシンの CPU 負荷データです。

ビジネス ストレス テストとlive network 結果から判断すると、パフォーマンスが 2 倍になったという公式発表と基本的に一致しています。

AMS プラットフォームには多くの CGI マシンがあり、PHP7 のアップグレードと適用によりパフォーマンスが向上し、ハードウェア リソースのコストを効果的に節約できます。さらに、Apache2.4 のイベント モードを通じて、同時実行をサポートする Apache の機能も強化されました。

VI. 概要

私たちの PHP7 アップグレード R&D プロジェクト チームは、これまで比較的長期間にわたる継続的な努力と進歩を経て、最終的に 2016 年 4 月下旬に現在のネットワークでグレースケールを開始し、5 月上旬にクラスターで完全にアップグレードしました。 . により、AMS イベント運用プラットフォームのパフォーマンスが大幅に向上します。

PHP7 の革新性は、PHP 言語自体にとって非常に重要で価値のあるものであり、これにより、PHP はますます優れた言語になるだろうと私はさらに確信しています。同時に、私たちのビジネスにパフォーマンスの向上をもたらしてくれた PHP コミュニティの開発者に感謝したいと思います。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート