はじめに
Ibco は、WeChat バックエンドで大規(guī)模に使用されている c/c++ コルーチン ライブラリで、2013 年以來、WeChat バックエンドの數(shù)萬臺のマシンで安定して実行されています。 Libco は、Tencent の 6 つの主要なオープンソース プロジェクトの 1 つとして、2013 年に初めてオープンソース化されました。最近、メジャー アップデートが行われ、https://github.com/tencent/libco で同期されています。 libco は、システムの高い同時実行機(jī)能を提供しながら、バックエンドのアジャイル同期スタイルのプログラミング モデルをサポートします。
libco によってサポートされる機(jī)能
ビジネス ロジックに侵入する必要がなく、マルチプロセスおよびマルチスレッド サービスをコルーチン サービスに変換し、同時実行機(jī)能が 100 倍向上します
CGI フレームワークをサポートし、Web サービスを簡単に構(gòu)築します (新規(guī)) ;
gethostbyname 、mysqlclient、ssl およびその他の一般的に使用される 3 番目のライブラリをサポート (新機(jī)能)
オプションの共有スタック モードにより、1 臺のマシンで數(shù)千萬の接続に簡単にアクセスできます
完全で簡潔なコルーチン プログラミング インターフェイス
– pthread のようなインターフェイス設(shè)計。コルーチンの作成と復(fù)元は、co_create や co_resume などのシンプルで明確なインターフェイスを通じて完了できます。 – コルーチン間の通信用のクラス __thread、コルーチン セマフォ co_signal (新規(guī))。言語レベルのラムダ実裝、コルーチンと組み合わせて、バックグラウンドの非同期タスクを適切に記述して実行します (新規(guī)) – epoll/kqueue に基づく小型で軽量のネットワーク フレームワーク、時間ルーレットに基づく高性能タイマー
バックグラウンド。
初期の WeChat 複雑で変化するビジネス要件と、バックエンドでの製品の迅速な反復(fù)のため、ほとんどのモジュールは半同期および半非同期モデルを採用しています。アクセス層は非同期モデルであり、ビジネス ロジック層は同期マルチプロセスまたはマルチスレッド モデルです。ビジネス ロジックの同時実行能力はわずか數(shù)十から數(shù)百です。 WeChatのビジネスが成長するにつれて、システムの規(guī)模はますます大きくなり、各モジュールはバックエンドサービス/ネットワークジッターの影響を受けやすくなります。
非同期変換の選択
WeChatバックエンドの同時実行機(jī)能を向上させるための一般的なアプローチは、既存のネットワーク上のすべてのサービスを非同期モデルに変更することです。このアプローチでは、フレームワークからビジネス ロジック コードに至るまでの膨大な作業(yè)が必要となり、完全な変換が必要となり、時間と労力がかかり、リスクが伴います。そこで私たちはコルーチンの使用を検討し始めました。
しかし、コルーチンを使用すると、次のような課題に直面します:
業(yè)界のコルーチンには、C/C++ 環(huán)境での大規(guī)模なアプリケーションの経験がありません;
コルーチンのスケジューリングを制御する方法;
次のような同期スタイルの API 呼び出しを処理する方法ソケット、mysqlclient など;
既存のグローバル変數(shù)とスレッドのプライベート変數(shù)の使用に対処する方法;
最終的に、libco を通じて上記の問題をすべて解決し、ビジネス ロジックの非侵襲的な非同期変換を?qū)g現(xiàn)しました。 libco を使用して、數(shù)百の WeChat バックエンド モジュールをコルーチンと非同期変換に変換しました。変換プロセス中、ビジネス ロジック コードは基本的に変更されませんでした。これまでのところ、WeChat バックエンドのサービスのほとんどはマルチプロセスまたはマルチスレッドのコルーチン モデルであり、以前と比べて同時実行機(jī)能が質(zhì)的に向上しており、libco は WeChat バックエンド フレームワークの基礎(chǔ)となっています。
libcoフレームワーク
libcoはフレームワーク內(nèi)でインターフェース層、システム機(jī)能フック層、イベントドリブン層の3つの層に分かれています。
同期スタイルの API 処理
同期スタイルの API、主に同期ネットワーク呼び出しの場合、libco の主なタスクは、これらの待機(jī)によるリソースの占有を排除し、システムの同時実行パフォーマンスを向上させることです。通常のネットワーク バックグラウンド サービスの場合、完全なネットワーク インタラクションを完了するために、接続、書き込み、読み取りなどの手順を?qū)g行することがあります。これらの API を同期的に呼び出すと、スレッド全體がネットワーク対話を待ってハングします。
同期プログラミングスタイルの同時実行パフォーマンスは良くありませんが、コードロジックが明確で記述が簡単であるという利點(diǎn)があり、迅速なビジネスの反復(fù)とアジャイル開発をサポートできます。既存のビジネス ロジック コードをオンラインで変更することなく同期プログラミングの利點(diǎn)を維持し続けるために、libco は革新的にネットワーク呼び出しインターフェイス (フック) を引き継ぎ、コルーチンの放棄と回復(fù)をコールバックを使用した非同期ネットワーク IO のイベントとして登録しました。 。ビジネス処理が同期ネットワーク リクエストに遭遇すると、libco レイヤーはネットワーク リクエストを非同期イベントとして登録し、このコルーチンは CPU 占有を放棄し、CPU は実行のために他のコルーチンに渡されます。 Libco は、ネットワーク イベントが発生するかタイムアウトになると、コルーチンの実行を自動的に再開します。
同期スタイル API のほとんどを Hook メソッドを通じて引き継ぎ、libco は適切な時間に実行を再開するようにコルーチンをスケジュールします。
數(shù)千萬のコルーチンのサポート
デフォルトでは、libco は各コルーチンが獨(dú)自の実行スタックを持つことを許可します。コルーチンの作成時に、固定サイズのメモリがコルーチンの実行スタックとしてヒープ メモリから割り當(dāng)てられます。フロントエンドでアクセス接続を処理するためにコルーチンを使用する場合、大規(guī)模なアクセス サービスの場合、サービスの同時実行制限はメモリによって簡単に制限されてしまいます。この目的のために、libco はスタックレス コルーチン共有スタック モードも提供します。これにより、複數(shù)のコルーチンが同じ実行スタックを共有するように設(shè)定できるようになります。同じ共有スタック內(nèi)のコルーチン間を切り替える場合、現(xiàn)在実行中のスタックの內(nèi)容をコルーチンのプライベート メモリにコピーする必要があります。このようなメモリ コピーの數(shù)を減らすために、共有スタックのメモリ コピーは、異なるコルーチン間で切り替えるときにのみ発生します。共有スタックの占有者が変更されていない場合、実行中のスタックをコピーする必要はありません。
libco コルーチンの共有コルーチン スタック モードを使用すると、十分なコルーチンを作成するだけで、単一のマシンで數(shù)千萬の接続に簡単にアクセスできます。 libco 共有スタック モードを通じて 1,000 萬個のコルーチン (E5-2670 v3 @ 2.30GHz * 2、128G メモリ) を作成すると、各 100,000 個のコルーチンが 128k メモリを使用し、安定したエコー サービス全體の合計メモリ消費(fèi)量は約 66G になります。
コルーチンのプライベート変數(shù)
マルチプロセス プログラムがマルチスレッド プログラムに変換されるとき、__thread を使用してグローバル変數(shù)をすばやく変更できます。コルーチン環(huán)境では、コルーチン変數(shù) ROUTINE_VAR を作成しました。これにより、コルーチンのワークロードが大幅に簡素化されます。コルーチン変換。
コルーチンは基本的にスレッド內(nèi)でシリアルに実行されるため、スレッドのプライベート変數(shù)を定義すると、再入性の問題が発生する可能性があります。たとえば、__thread というスレッド プライベート変數(shù)を定義する場合、當(dāng)初は各実行ロジックがこの変數(shù)に排他的にアクセスできるようにしたいと考えていました。しかし、実行環(huán)境をコルーチンに移行すると、同じスレッドのプライベート変數(shù)が複數(shù)のコルーチンで操作される可能性があり、変數(shù)侵入の問題が発生します。このため、libco の非同期変換を?qū)g行するときに、ほとんどのスレッド プライベート変數(shù)をコルーチン レベルのプライベート変數(shù)に変更しました。コルーチンのプライベート変數(shù)には次の特性があります。コードがマルチスレッドの非コルーチン環(huán)境で実行されている場合、変數(shù)はスレッド プライベートです。コードがコルーチン環(huán)境で実行されている場合、この変數(shù)はコルーチン プライベートです?;A(chǔ)となるコルーチンのプライベート変數(shù)は、実行環(huán)境を自動的に決定し、必要な値を正しく返します。
コルーチンのプライベート変數(shù)は、既存の環(huán)境を同期から非同期に変える上で決定的な役割を果たします。同時に、たった 1 行の宣言コードで済む非常にシンプルで便利なコルーチンのプライベート変數(shù)の定義メソッドを定義しました。 。
gethostbynameのフックメソッド
既存のネットワークサービスの場合、システムのgethostbyname APIインターフェイスを通じて実際のアドレスを取得するためにDNSにクエリを?qū)g行する必要がある場合があります。コルーチンの変換中に、フックのソケット ファミリ関數(shù)が gethostbyname に適用できないことがわかりました。コルーチンが gethostbyname を呼び出すと、結(jié)果が同期的に待機(jī)されるため、同じスレッド內(nèi)の他のコルーチンの実行が遅延します。 glibc の gethostbyname ソース コードを調(diào)べたところ、フックが有効にならないことがわかりました。これは主に、glibc が一般的な poll メソッドではなく、內(nèi)部でイベントを待機(jī)する __poll メソッドを定義しているためであり、同時に glibc はスレッド プライベート変數(shù)も定義しているためです。異なるコルーチンで使用される可能性があるため、切り替えにより再入が発生し、データが不正確になる可能性があります。最後に、gethostbyname コルーチンの非同期化は、Hook __poll メソッドとコルーチンのプライベート変數(shù)の定義によって解決されます。
Gethostbyname は、glibc によって提供される同期クエリ DNS インターフェイスです。業(yè)界には gethostbyname の優(yōu)れた非同期ソリューションが多數(shù)ありますが、これらの実裝にはサードパーティ ライブラリの導(dǎo)入が必要であり、非同期コールバック通知メカニズムを提供するために基礎(chǔ)となる層が必要です。 libco はフックメソッドにより、glibc ソースコードを変更することなく gethostbyname の非同期化を?qū)g現(xiàn)します。
コルーチンセマフォ
マルチスレッド環(huán)境では、スレッド間の同期要件が発生します。たとえば、あるスレッドの実行は別のスレッドのシグナルを待つ必要がありますが、この要件を解決するには通常 pthread_signal を使用します。 。 libco では、コルーチン間の同時実行要件を処理するために、コルーチン セマフォ co_signal を定義します。コルーチンは、待機(jī)中のコルーチンに通知するか、co_cond_signal および co_cond_broadcast を通じて待機(jī)中のすべてのコルーチンを起動するかを決定できます。
概要
Libco は、完全なコルーチン プログラミング インターフェイス、一般的に使用されるソケット ファミリ関數(shù)フックなどを提供する効率的な c/c++ コルーチン ライブラリであり、企業(yè)が同期プログラミング モデルを使用して迅速な反復(fù)開発を行えるようにします。過去數(shù)年間の安定した運(yùn)用により、libco は WeChat のバックエンド フレームワークの基礎(chǔ)として極めて重要な役割を果たしてきました。

ホットAIツール

Undress AI Tool
脫衣畫像を無料で

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

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

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強(qiáng)力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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