ホームページ  >  記事  >  バックエンド開発  >  PHP を使用してマイクロサービスを実装するにはどうすればよいですか?

PHP を使用してマイクロサービスを実装するにはどうすればよいですか?

慕斯
慕斯転載
2021-06-18 11:12:475207ブラウズ

この記事では、PHP を使用してマイクロサービスを実装する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PHP を使用してマイクロサービスを実装するにはどうすればよいですか?なぜサービス ガバナンスについて話す必要があるのか​​

インターネット ブラウジングがますます大規模になるにつれて、従来の MVC 単一アーキテクチャはアプリケーションの拡張に合わせて拡大し続けています。規模は拡大し続け、アプリケーションモジュールは増加し続け、アプリケーション全体はますます肥大化し、メンテナンスは困難になります。

アプリケーションごとに分割する、つまり元のアプリケーションを分割するという対策を講じる必要があります。ビジネス特性アプリケーションに応じた複数のアプリケーション。たとえば、大規模な電子商取引システムには、ユーザー システム、商品システム、注文システム、評価システムなどが含まれる場合があります。これらを個別のアプリケーションに分離できます。マルチアプリケーションアーキテクチャの特徴は、アプリケーションが独立しており、相互に呼び出しを行わないことです。

複数のアプリケーションによってアプリケーションの肥大化の問題は解決されますが、アプリケーションは互いに独立しており、一部の共通ビジネスやコードは再利用できません。

単一アプリケーション ソリューション

大規模なインターネット システムの場合、通常は複数のアプリケーションが含まれており、多くの場合、アプリケーション間に共通のサービスが存在し、アプリケーション間の呼び出し関係も存在します。さらに、大規模なインターネット システムには、ユーザーの急速な増加にどう対処するか、製品開発を迅速に繰り返すために研究開発チームを管理する方法、製品のアップグレードをより安定的に維持する方法など、他の課題もあります。

したがって、ビジネスを再利用可能にし、モジュールを拡張および保守しやすくするために、ビジネスとアプリケーションを分離できることを望んでいます。独立したサービスとして維持します。アプリケーション自体はもはやモジュールの肥大化したスタックではなく、モジュール式のサービス コンポーネントで構成されています。

#Serviceization

機能

では、

Serviceization?

## を使用することの優れた機能は何ですか? #アプリケーションはビジネスに基づいてサービスに分割されます
  • 各サービスは独立して展開できます
  • サービスは複数のアプリケーションで共有できます
  • サービスは相互に通信できます
  • システムのアーキテクチャがより明確になりました
  • コアモジュールが安定し、サービスコンポーネント単位でアップグレードされるため、頻繁なリリースによるリスクが回避されます
  • 開発と管理が便利になります
  • 別のチームのメンテナンス、明確な作業、明確な責任
  • ビジネスの再利用、コードの再利用
  • 拡張が非常に簡単
  • サービス指向が直面する課題

サービス指向化すると依存関係が複雑になり、サービス間のやり取りも増えますが、

fpm

の開発モードではメモリ常駐できないため、すべてのリクエスト プロセスが終了するまで最初からロードする必要があるため、多くの無駄なオーバーヘッドが追加されます。fpm はプロセスに基づいているため、データベース接続は再利用できず、保護することもできません。プロセスは同時実行の数も決定しますが、これは fpm 開発の単純さによってもたらされる問題でもあります。では、なぜインターネット プラットフォーム Java が今人気があるのでしょうか。 NETPHP もこの点では機能しません。 PHP は非メモリ常駐です 言うまでもありません。それ以外にも、対処しなければならない問題は数多くあります。 サービスの数はますます増えており、構成管理は複雑ですサービス間の複雑な依存関係

    サービス間の負荷分散
  • サービスの拡張
  • サービス監視
  • サービスのダウングレード
  • サービス認証
  • サービスのオンラインおよびオフライン
  • サービス ドキュメント...
  • 常駐メモリがもたらすメリットは次のようなものです。

フレームワークの初期化のみを開始します

常駐メモリの場合、初期化のみを処理します。
  • #接続の再利用. 一部のエンジニアは、接続プールが使用されていない場合に、どのように接続が行われるかを特に理解していません。リクエストが来たときに接続を送信するだけですか?これにより、バックエンド リソースの接続が過剰になります。 Redis やデータベースなどの一部の基本サービスでは、接続にコストがかかります。

  • それでは、何か良い解決策はあるのでしょうか?答えは「はい」です。多くの人がこのフレームワーク (-Swoft) を使用しています。

    Swoft
  • は、
Service Governance

機能を備えた RPC フレームワークです。 Swoft は、設定よりも規約が重要であるという Spring Boot の中心概念に基づいた、初の PHP 常駐メモリ コルーチン フルスタック フレームワークです。

Swoft は、DubboSwoft と同様の RPC サービスを使用するためのよりエレガントな方法を提供します。パフォーマンスは非常に優れており、類似していますGolangパフォーマンス。以下は、PC での Swoft パフォーマンスのストレス テストです。

abストレス テストの処理速度驚くべきことに、i78 世代 CPU、16GB メモリ 10000010,000 リクエストに fpm# で 5 秒 しかかかりませんでした。 ##開発モードでこれを達成することは基本的に不可能ですが、これは Swoft の高いパフォーマンスと安定性、

エレガントなサービス ガバナンスを証明するのに十分です ##サービスの登録と検出マイクロサービス ガバナンス プロセスには、多くの場合、開始されたサービスを consul/etcd などのサードパーティ クラスターに登録することが含まれます。この章では、Swoft フレームワークの swoft-consul コンポーネントを使用してサービス登録を実装します。ディスカバリーを例に考えてみましょう。

実装ロジック

<?php declare(strict_types=1);namespace App\Common;use ReflectionException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;use Swoft\Bean\Exception\ContainerException;use Swoft\Consul\Agent;use Swoft\Consul\Exception\ClientException;use Swoft\Consul\Exception\ServerException;use Swoft\Rpc\Client\Client;use Swoft\Rpc\Client\Contract\ProviderInterface;/**
 * Class RpcProvider
 *
 * @since 2.0
 *        
 * @Bean()
 */class RpcProvider implements ProviderInterface{    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;    /**
     * @param Client $client
     *
     * @return array
     * @throws ReflectionException
     * @throws ContainerException
     * @throws ClientException
     * @throws ServerException
     * @example
     * [
     *     &#39;host:port&#39;,
     *     &#39;host:port&#39;,
     *     &#39;host:port&#39;,
     * ]
     */
    public function getList(Client $client): array
    {        // Get health service from consul
        $services = $this->agent->services();

        $services = [
        
        ];        return $services;
    }
}

サービスサーキットブレーカー

分散環境、特にマイクロサービス構造を備えた分散システムでは、ソフトウェア システムが別のソフトウェア システムを呼び出すことは非常に困難です。リモートシステム共通です。このリモート呼び出しの呼び出し先は、別のプロセスまたはネットワーク上の別のホストである可能性があります。このリモート呼び出しとプロセスの内部呼び出しの最大の違いは、リモート呼び出しが失敗するかハングする可能性があることです。タイムアウトになるまで応答はありません。さらに悪いことに、複数の呼び出し元が同じ中断されたサービスを呼び出すと、サービスのタイムアウト待機がすぐに分散システム全体に広がり、連鎖反応が発生し、分散システム全体が大量のリソースを消費する可能性が非常に高くなります。最終的にはシステム障害につながる可能性があります。

サーキットブレーカー(Circuit Breaker)モードは、このような分散システムにおけるウォーターフォールのような連鎖反応による災害を防ぐためのものです。

基本的なサーキット ブレーカー モードでは、サーキット ブレーカーがオープン状態のときに保護サプライヤーが呼び出されないようにしますが、サプライヤーがサービスを再開した後にサーキット ブレーカーをリセットするための追加の対策も必要です。実現可能なアプローチは、サーキット ブレーカーがサプライヤーのサービスが復旧したかどうかを定期的に検出し、復旧したらステータスをクローズに設定することです。リトライ時はブレーカーが半開状態です。

ヒューズの使用はシンプルかつ強力です。

@Bre​​aker

アノテーションを使用するだけです。

Swoft

ヒューズは、サービス コールなどのあらゆるシナリオで使用できます。サードパーティにリクエストする場合はいつでも回路遮断とダウングレードが可能です<pre class="brush:php;toolbar:false;">&lt;?php declare(strict_types=1);namespace App\Model\Logic;use Exception;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Breaker\Annotation\Mapping\Breaker;/** * Class BreakerLogic * * @since 2.0 * * @Bean() */class BreakerLogic{ /** * @Breaker(fallback=&quot;loopFallback&quot;) * * @return string * @throws Exception */ public function loop(): string { // Do something throw new Exception(&amp;#39;Breaker exception&amp;#39;); } /** * @return string * @throws Exception */ public function loopFallback(): string { // Do something } }</pre>サービス電流制限

電流制限、回路遮断、ダウングレード

これは強調することはできません。十分です、確かに重要なので。サービスが失敗した場合は、ヒューズを切断する必要があります。電流制限は自分自身を守る最大のツールです。自己保護機構がなければ、接続がいくらあっても受信されます。バックエンドが処理できない場合、トラフィックが非常に大きい場合、フロントエンドは確実にハングします。 。

現在の制限は、フラッシュセールや急ぎ販売商品などの希少なリソースにアクセスする際の同時実行数とリクエストの数を制限することで、効果的にピークをカットし、トラフィック曲線を滑らかにします。電流制限の目的は、同時アクセスと同時リクエストのレートを制限すること、またはシステムを保護するために時間枠内のリクエストのレートを制限することです。レート制限に達するか超過すると、サービスは拒否されるかキューに入れられる可能性があります。そして待った。

Swoft

電流リミッターの最下層はトークン バケット アルゴリズムを使用し、最下層は

Redis

に依存して分散型電流制限を実装します。 Swoft 速度リミッターは、現在のコントローラーを制限するだけでなく、任意の Bean のメソッドを制限し、メソッドのアクセス レートを制御することもできます。以下の使用例で詳しく説明します <pre class="brush:php;toolbar:false;">&lt;?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Limiter\Annotation\Mapping\RateLimiter;/** * Class LimiterLogic * * @since 2.0 * * @Bean() */class LimiterLogic{ /** * @RequestMapping() * @RateLimiter(rate=20, fallback=&quot;limiterFallback&quot;) * * @param Request $request * * @return array */ public function requestLimiter2(Request $request): array { $uri = $request-&gt;getUriPath(); return [&amp;#39;requestLimiter2&amp;#39;, $uri]; } /** * @param Request $request * * @return array */ public function limiterFallback(Request $request): array { $uri = $request-&gt;getUriPath(); return [&amp;#39;limiterFallback&amp;#39;, $uri]; } }</pre>key これは

symfony/expression-langage

式をサポートします 速度が制限される場合は、

fallback で定義された

limiterFallback が呼び出されます。 メソッド構成センター構成センターについて話す前に、構成ファイルについて話しましょう。私たちはこのファイルに馴染みがありません。プログラム実行機能を動的に変更する機能。他の人の言葉を引用すると:

システム実行時の飛行姿勢の動的調整!

私たちの仕事は、高速飛行する航空機の部品を修理する仕事と言えるかもしれません。私たち人間は、常にすべてを制御したり予測したりできるわけではありません。私たちのシステムでは、システムの方向を制御する必要がある場合 (グレースケール制御、電流制限調整など)、調整を行うために常に制御線を確保する必要がありますが、これは変化を受け入れるインターネット業界にとって特に重要です。

スタンドアロン バージョンの場合は構成 (ファイル) と呼び、分散クラスター システムの場合は構成センター (システム) と呼びます;

分散構成センターとは

ビジネスの発展とマイクロサービスアーキテクチャのアップグレードに伴い、サービスとプログラム構成の数(さまざまなマイクロサービス、さまざまなサーバーアドレス、さまざまなパラメーター)が増加しており、従来の構成ファイル方式とデータベース方式は開発者にとって困難です。 ' 構成管理の要件を満たすことができなくなりました:

  • 安全性:配置跟随源代码保存在代码库中,容易造成配置泄漏;
  • 时效性:修改配置,需要重启服务才能生效;
  • 局限性:无法支持动态调整:例如日志开关、功能开关;

因此,我们需要配置中心来统一管理配置!把业务开发者从复杂以及繁琐的配置中解脱出来,只需专注于业务代码本身,从而能够显著提升开发以及运维效率。同时将配置和发布包解藕也进一步提升发布的成功率,并为运维的细力度管控、应急处理等提供强有力的支持。

关于分布式配置中心,网上已经有很多开源的解决方案,例如:

Apollo是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

本章以Apollo 为例,从远端配置中心拉取配置以及安全重启服务。如果对 Apollo 不熟悉,可以先看Swoft 扩展 Apollo 组件以及阅读 Apollo 官方文档。

本章以 Swoft 中使用 Apollo 为例,当 Apollo 配置变更后,重启服务(http-server / rpc-server/ ws-server)。如下是一个 agent 例子:

<?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Apollo\Config;use Swoft\Apollo\Exception\ApolloException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;/**
 * Class ApolloLogic
 *
 * @since 2.0
 *
 * @Bean()
 */class ApolloLogic{    /**
     * @Inject()
     *
     * @var Config
     */
    private $config;    /**
     * @throws ApolloException
     */
    public function pull(): void
    {
        $data = $this->config->pull(&#39;application&#39;);        
        // Print data
        var_dump($data);
    }
}

以上就是一个简单的 Apollo 配置拉取,Swoft-Apollo 除此方法外,还提供了更多的使用方法。

官方链接

  • Github
  • Doc
  • swoft-cloud/community

推荐学习:php视频教程

以上がPHP を使用してマイクロサービスを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。