ほぼすべての PHP プログラマーがコードを公開しており、そのコードは FTP または rsync を介して同期したり、svn または git を介して更新したりすることができます。活発なプロジェクトでは、1 日に数回コードがリリースされることがありますが、詳細に注意を払う人はほとんどいないのが現実で、実際には多くの落とし穴があり、知らないうちに落とし穴にはまっている可能性があります。
適切に実装されたパブリッシング システムは、少なくともアトミック パブリッシングをサポートする必要があります。各バージョンが独立した状態を表す場合、リリース期間中は、すべてのリクエストは単一の状態でのみ実行できます。これはアトミック リリースのサポートと呼ばれます。一方、リクエストがリリース中に異なる状態にまたがる場合、それはアトミック リリースとは言えません。説明するための例を示します: include a.php の場合、リクエストに 2 つの <code>include
两个 PHP 文件,分别是 a.php
和 b.php
,当 include a.php
完成后,发布代码,接着 include b.php
,如果处理不当的话,那么就可能会导致旧版本的 a.php
和新版本的 b.php
同时存在于同一个请求之中,换句话说就是没有实现原子发布。
开源世界里有很多不错的发布代码工具,比如 ruby 社区的 capistrano,其流程大致就是发布代码到一个全新的目录,然后再软链接到真正的发布目录。
├── current -> releases/v1 └── releases ├── v1 │ ├── foo.php │ └── bar.php └── v2 ├── foo.php └── bar.php
不过鉴于 PHP 本身的特殊性,如果只是简单套用上面的流程,那么将很难实现真正的原子发布。要理清个中缘由,还需要了解一下 PHP 中的两个 Cache
的概念:
opcode cache
PHP コードを正しく公開する例を共有する cache
先聊聊 opcode cache
,基本就是 apc
或者 zend opcode
,关于它的作用,大家都已经很熟悉,不必多言,需要注意的是 apc
的 bug 很多,比如开启了 apc.enable_cli 配置后就会有很多灵异问题,所以说 opcode cache
还是尽可能使用 zend opcache
吧,如果需要缓存数据,可以用 apcu。此外 apc
和 zend opcode
对缓存键的选择有所差异:apc
选择的是文件的 inode
,zend opcode
选择的是文件的 path
。
再聊聊 PHP コードを正しく公開する例を共有する cache
,它的作用是缓冲获取文件信息的 IO 操作,大多数时候它对我们而言是透明的,以至于很多人都不知道它的存在,需要注意的是 PHP コードを正しく公開する例を共有する cache
是进程级别的,也就是说,每一个 php-fpm
进程都有自己独立的 PHP コードを正しく公開する例を共有する cache
。
假设在发布代码期间,opcode cache
或者 PHP コードを正しく公開する例を共有する cache
里的数据出现过期,那么就会出现一部分缓存是旧文件,一部分缓存是新文件的非原子发布的情况,为了避免出现这种情况,我们应该保证缓存过期时间足够长,最好是除非我们手动刷新,否则永远不过期,对应到配置上就是:关闭 apc.stat、opcache.validate_timestamps 配置,设置足够大的 PHP コードを正しく公開する例を共有する_cache_size、PHP コードを正しく公開する例を共有する_cache_ttl 配置,必要的监控总是有好处的。
相关的技术细节特别琐碎,建议大家仔细阅读如下资料:
PHP コードを正しく公開する例を共有する_cache PHP’s OPCache extension review Atomic PHP コードを正しく公開する例を共有するs at Etsy Cache invalidation for scripts in symlinked folders
在采用软链接发布代码的时候,通常遇到的第一个问题多半是新代码不生效!即便调用了 apc_clear_cache 或者 opcache_reset 方法也无效,重启 php-fpm
自然是能够解决问题,不过对脚本语言来说重启太重了!难道除了重启就没有别的办法了么?
事实上之所以会出现这样的问题,主要是因为 opcode cache
是通过 PHP コードを正しく公開する例を共有する cache
获取文件信息,即便软链接已经指向了新位置,但是如果 PHP コードを正しく公開する例を共有する cache
里还保存着旧数据的话,opcode cache
依然无法知道新代码的存在,缺省情况下,PHP コードを正しく公開する例を共有する_cache_ttl 缓存有效期是两分钟,这意味着发布代码后,可能要两分钟才能生效。为了让发布尽快生效,需要以进程为单位清除 PHP コードを正しく公開する例を共有する cache
:
<?php $key = 'php.pid_' . getmypid(); if (($rev = apc_fetch($key)) != DEPLOY_VERSION) { if($rev < DEPLOY_VERSION) { apc_store($key, DEPLOY_VERSION); } clearstatcache(true); }
如此在 apc
环境下基本就能工作了,但是在 zend opcode
环境下还可能有问题。因为在缺省情况下 opcache.revalidate_path 是关闭的,此时会缓存未解析的符号链接的值,这会导致即便软链接指向修改了,也无法生效,所以在使用 zend opcode
的时候,如果使用了软链接,视情况可能需要把 opcache.revalidate_path
PHP
a.php
と b.php
> が必要だとします。 が完了したらコードを解放し、include b.php
を正しく処理しないと、古いバージョンの a .php
が生成される可能性があります。新しいバージョンの b.php
が同じリクエスト内に同時に存在します。つまり、アトミック パブリッシングは実装されていません。 🎜🎜オープンソースの世界には、🎜ruby🎜コミュニティのcapistranoなど、優れたコード公開ツールがたくさんあります。そのプロセスは、大まかに言うと、コードを新しいディレクトリに公開してから、実際のリリースディレクトリにソフトリンクします。 🎜fastcgi_param SCRIPT_FILENAME $PHP コードを正しく公開する例を共有する_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $PHP コードを正しく公開する例を共有する_root;🎜しかし、🎜PHP🎜自体の特殊性を考慮すると、上記の処理を単純に適用しただけでは真のアトミックリリースを実現することは困難です。理由を明確にするには、🎜PHP🎜 の 2 つの
Cache
の概念も理解する必要があります: 🎜- 🎜🎜オペコード キャッシュ🎜 🎜
- 🎜🎜リアルパス キャッシュ🎜🎜
オペコード キャッシュ
について話しましょう。基本的には apc
または です。 > zend opcode
については、誰もがその役割をよく知っています。言うまでもなく、apc
には多くのバグがあることに注意してください。たとえば、apc.enable_cli 設定がオンになった後は、奇妙な問題なので、opcode Cache
はできるだけ zend opcache
を使用する必要があります。データをキャッシュする必要がある場合は、apcu を使用できます。さらに、apc
と zend opcode
ではキャッシュ キーの選択が異なります。apc
はファイルの inode
を選択します。 zend opcode
は、ファイルの path
を選択します。 🎜🎜 もう一度 PHP コードを正しく公開する例を共有する キャッシュ
について話しましょう。その機能は 🎜IO🎜 操作をバッファリングしてファイル情報を取得することです。存在しますが、PHP コードを正しく公開する例を共有する キャッシュ
はプロセス レベルであることに注意してください。つまり、各 php-fpm
プロセスには独自の独立した PHP コードを正しく公開する例を共有する キャッシュ
があります。コード> >。 🎜🎜 コードのリリース中に、opcode Cache
または PHP コードを正しく公開する例を共有する Cache
内のデータの有効期限が切れると、キャッシュの一部が古いファイルになり、キャッシュの一部は新しいファイルです。この状況を回避するには、キャッシュの有効期限を手動で更新しない限り期限切れにならないようにするのが最善です。設定は次のとおりです: close apc.stat、opcache.validate_timestamps 設定。 PHP コードを正しく公開する例を共有する_cache_size および PHP コードを正しく公開する例を共有する_cache_ttl 設定を十分な大きさに設定し、必要な監視を実行することが常に有益です。 🎜🎜関連する技術的な詳細は非常に簡単なので、次の情報を注意深く読むことをお勧めします: 🎜<?php// PHP コードを正しく公開する例を共有する:releaserun("cd {{PHP コードを正しく公開する例を共有する_path}} && if [ -h release ]; then rm release; fi"); run("ln -s $releasePath {{PHP コードを正しく公開する例を共有する_path}}/release");// PHP コードを正しく公開する例を共有する:symlinkrun("cd {{PHP コードを正しく公開する例を共有する_path}} && ln -sfn {{release_path}} current"); run("cd {{PHP コードを正しく公開する例を共有する_path}} && rm release");?>
php-fpm
を再起動すると自然に解決しますが、スクリプト言語にとって再起動は重すぎます。再起動する以外に方法はないのでしょうか? 🎜🎜実際、このような問題が発生する主な理由は、ソフト リンクが新しい場所を指していても、opcode Cache
が PHP コードを正しく公開する例を共有する Cache
を通じてファイル情報を取得するためです。ただし、古いデータがまだ PHP コードを正しく公開する例を共有する キャッシュ
に保存されている場合、opcode Cache
は新しいコードの存在を認識できません。デフォルトでは、PHP コードを正しく公開する例を共有する_cache_ttl キャッシュの有効期間は 2 分です。コードが発行されてから有効になるまでに最大 2 分かかる場合があります。リリースをできるだけ早く有効にするには、プロセス単位で PHP コードを正しく公開する例を共有する キャッシュ
をクリアする必要があります: 🎜shell> strace ln -sfn releases/foo currentsymlink("releases/foo", "current") = -1 EEXIST (File exists)unlink("current") = 0symlink("releases/foo", "current") = 0🎜これは基本的に
apc
環境で動作します。ただし、zend opcode
環境に問題がある可能性もあります。 opcache.revalidate_path はデフォルトでオフになっているため、未解決のシンボリック リンクの値がキャッシュされるため、zend opcode
を使用する場合、ソフト リンクが有効になりません。 、ソフト リンクが使用されている場合、状況に応じて opcache.revalidate_path
をアクティブにする必要がある場合があります。 🎜详细介绍参考:PHP’s OPCache extension review。
BTW:如果需要手动重置 opcode cache
,需要注意的是因为它是基于 SAPI 的概念,所以不能直接在命令行下调用 apc_clear_cache 或者 opcache_reset 方法来重置缓存,当然办法总是有的,那就是使用 CacheTool 在命令行下模拟 fastcgi
请求。
分析到这里,我们不妨反思一下:在 PHP 中原子发布之所以是一个棘手的问题,归根结底是因为软链接和缓存之间的的矛盾。不管是 opcode cache
还是 PHP コードを正しく公開する例を共有する cache
,都是 PHP 固有的缓存特性,基于客观需要无法绕开,如此说来是否有办法绕开软链接,使其成为马奇诺防线呢?答案是 NGINX 的 $PHP コードを正しく公開する例を共有する_root:
fastcgi_param SCRIPT_FILENAME $PHP コードを正しく公開する例を共有する_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $PHP コードを正しく公開する例を共有する_root;
有了 $PHP コードを正しく公開する例を共有する_root
,即便 DOCUMENT_ROOT
目录中含有软链接,NGINX 也会把软链接指向的真正的路径发给 PHP,也就是说,对 PHP 而言,软链接已经不存在了!不过作为代价,每一次请求,NGINX 都要通过相对昂贵的 IO 操作获取 $PHP コードを正しく公開する例を共有する_root
的值,通过 strace
命令我们能监控这一过程,下图从 current
到 foo
的过程:
在本例中,压测发现使用 $PHP コードを正しく公開する例を共有する_root
后,性能下降了大约 5% 左右,不过明眼人一下就能发现,虽然 $PHP コードを正しく公開する例を共有する_root
导致了 lstat
和 readlink
操作,但是 lstat
操作的次数是和目录深度成正比的,也就是说目录越深,执行的 lstat
次数越多,性能下降也就越大。如果能够降低发布目录的深度,那么可以预计还能降低一些性能损耗。
结尾介绍一下 Deployer,它是 PHP 中做得比较好的工具,有很多特色,比如支持并行发布,具体演示如下图,左边是串行,右边是并行,使用「vvv」能得到更详细信息:
不过 Deployer 在原子发布上有一点瑕疵,具体见 release/symlink
代码:
<?php// PHP コードを正しく公開する例を共有する:releaserun("cd {{PHP コードを正しく公開する例を共有する_path}} && if [ -h release ]; then rm release; fi"); run("ln -s $releasePath {{PHP コードを正しく公開する例を共有する_path}}/release");// PHP コードを正しく公開する例を共有する:symlinkrun("cd {{PHP コードを正しく公開する例を共有する_path}} && ln -sfn {{release_path}} current"); run("cd {{PHP コードを正しく公開する例を共有する_path}} && rm release");?>
在 release
的时候,它是先删除再创建,是一个两步的非原子操作,在 symlink
的时候,看上去「ln -sfn」
是单步原子操作,实际上也是错误的:
shell> strace ln -sfn releases/foo currentsymlink("releases/foo", "current") = -1 EEXIST (File exists)unlink("current") = 0symlink("releases/foo", "current") = 0
通过 strace
我们能清晰的看到,虽然表面上使用「ln -sfn」
是一步操作,但是内部依然是按照先删除再创建的逻辑执行的,实际上这里应该搭配使用「ln & mv」
:
shell> ln -sfn releases/foo current.tmpshell> mv -fT current.tmp current
先通过 ln
创建一个临时的软链接,再通过 mv
实现原子操作,此时如果使用 strace
监控,会发现 mv
的 「T」
选项实际上仅仅执行了一个 rename
操作,所以是原子的。
BTW:在使用「ln -sfn」
前后,如果使用 stat
查看新旧文件的 inode
的话,可能会发现它们拥有一样的 inode
值,看上去和我们的结论相悖,其实不然,实际上只是复用删除值而已(如果想验证,注意 Linux 会复用,Mac 不会复用)。
据说一千个人的心中就有一千个哈姆雷特,不过我希望所有的 PHP 程序员在发布 PHP 代码的时候都能采用一种方法,那就是本文介绍的方法,正确的方法。
相关推荐:
以上がPHP コードを正しく公開する例を共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

セッション関連のXSS攻撃からアプリケーションを保護するには、次の測定が必要です。1。セッションCookieを保護するためにHTTPonlyとセキュアフラグを設定します。 2。すべてのユーザー入力のエクスポートコード。 3.コンテンツセキュリティポリシー(CSP)を実装して、スクリプトソースを制限します。これらのポリシーを通じて、セッション関連のXSS攻撃を効果的に保護し、ユーザーデータを確保できます。

PHPセッションのパフォーマンスを最適化する方法は次のとおりです。1。遅延セッション開始、2。データベースを使用してセッションを保存します。これらの戦略は、高い並行性環境でのアプリケーションの効率を大幅に改善できます。

thesession.gc_maxlifettinginttinginphpdethinesthelifsessessiondata、setinseconds.1)it'sconfiguredinphp.iniorviaini_set()。 2)AbalanceSneededToAvoidPerformanceIssues andunexpectedLogouts.3)php'sgarbagecollectionisisprobabilistic、影響を受けたBygc_probabi

PHPでは、session_name()関数を使用してセッション名を構成できます。特定の手順は次のとおりです。1。session_name()関数を使用して、session_name( "my_session")などのセッション名を設定します。 2。セッション名を設定した後、session_start()を呼び出してセッションを開始します。セッション名の構成は、複数のアプリケーション間のセッションデータの競合を回避し、セキュリティを強化することができますが、セッション名の一意性、セキュリティ、長さ、設定タイミングに注意してください。

セッションIDは、機密操作の前、30分ごとにログイン時に定期的に再生する必要があります。 1.セッション固定攻撃を防ぐためにログインするときにセッションIDを再生します。 2。安全性を向上させるために、敏感な操作の前に再生します。 3.定期的な再生は長期的な利用リスクを減らしますが、ユーザーエクスペリエンスの重量を量る必要があります。

PHPのセッションCookieパラメーターの設定は、session_set_cookie_params()関数を通じて達成できます。 1)この関数を使用して、有効期限、パス、ドメイン名、セキュリティフラグなどのパラメーターを設定します。 2)session_start()を呼び出して、パラメーターを有効にします。 3)ユーザーログインステータスなど、ニーズに応じてパラメーターを動的に調整します。 4)セキュリティを改善するために、セキュアとhttponlyフラグを設定することに注意してください。

PHPでセッションを使用する主な目的は、異なるページ間でユーザーのステータスを維持することです。 1)セッションはsession_start()関数を介して開始され、一意のセッションIDを作成し、ユーザーCookieに保存します。 2)セッションデータはサーバーに保存され、ログインステータスやショッピングカートのコンテンツなど、さまざまなリクエスト間でデータを渡すことができます。

サブドメイン間でセッションを共有する方法は?一般的なドメイン名にセッションCookieを設定することにより実装されます。 1.セッションCookieのドメインをサーバー側の.example.comに設定します。 2。メモリ、データベース、分散キャッシュなど、適切なセッションストレージ方法を選択します。 3. Cookieを介してセッションIDを渡すと、サーバーはIDに基づいてセッションデータを取得および更新します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

Dreamweaver Mac版
ビジュアル Web 開発ツール

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

SublimeText3 中国語版
中国語版、とても使いやすい
