前もって言う
40 歳の建築家 Nien の読者コミュニティ(50 歳以上) では、多くの友人が Alibaba、NetEase、Youzan、Xiyin、Baidu、Didi などの一流インターネット企業の面接資格を取得しています。
つい昨日、ニエンは小規模パートナーの履歴書を指導し、「高同時実行 Netty ゲートウェイ プロジェクト」を書きました。素晴らしいプロジェクトです。
面接の機会を増やし、大手メーカーからより多くのオファーを得るために、Nien はこのプロジェクトの構造と実際の操作を紹介するビデオの章を 9 月に公開することにしました。それが「第 33 章: 10Wqps の高同時実行性」Netty Gateway です。アーキテクチャと実践運用』は今月末にリリースされる予定です。また、あなたの履歴書が輝きを増し、完全に生まれ変わることを保証するために、マンツーマンの履歴書ガイダンスも提供します。
ポスターは以下の通りです。
Nien のビデオと併せて、いくつかの産業グレードおよび生産グレードのゲートウェイ ケースが建築およびデザイン資料として整理されます。
この記事はCtrip Gatewayのアーキテクチャ設計です。これは、非常に優れた産業グレードおよび生産グレードのゲートウェイ ケースです。
毎日200億のトラフィック、Ctripゲートウェイのアーキテクチャ設計
ソリューションの作成者: Butters 氏は、ネットワーク アーキテクチャ、API ゲートウェイ、負荷分散、サービス メッシュなどの分野に重点を置く Ctrip ソフトウェア テクノロジの専門家です。
『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』の PDF は、公式アカウント [Technical Freedom Circle] から入手してください。
記事ディレクトリ
I. 概要
多くの企業のアプローチと同様に、Ctrip API Gateway はマイクロサービス アーキテクチャとともに導入されたインフラストラクチャであり、その初期バージョンは 2014 年にリリースされました。企業内でのサービス化が急速に進むにつれて、ゲートウェイはアプリケーションを外部ネットワークに公開するための標準ソリューションになりつつあります。その後の「ALL IN Wireless」、国際化、さまざまな場所でのマルチアクティブ化、ゲートウェイなどのプロジェクトは、同社の公共事業とインフラストラクチャの共通の進化とともに発展を続けてきました。2021年7月現在、全体のアクセスサービス数は3,000を超え、1日の平均処理トラフィックは200億件に達します。
技術ソリューションの面では、同社のマイクロサービスの初期開発はNetflixOSSの影響を深く受けており、ゲートウェイ部分はZuul 1.0を参考に開発されており、その核心は以下の4点に集約される。
- サーバー端:Tomcat NIO + AsyncServlet
- ビジネス プロセス: 独立したスレッド プール、段階的な責任連鎖モデル
- クライアント側: Apache HttpClient、同期呼び出し
- コアコンポーネント: Archaius (動的構成クライアント)、Hystrix (サーキットブレーカーおよび電流制限)、Groovy (ホットアップデートサポート)
注: 画像をクリックすると鮮明な画像が表示されます。
ご存知のとおり、同期呼び出しはスレッドをブロックし、システムのスループット能力は IO によって大きく影響されます。
業界リーダーとして、Zuul は設計時にこの問題を考慮しています: Hystrix の導入により、リソースの分離と電流制限が達成され、障害 (遅い IO) が特定の範囲に制限されます; サーキット ブレーカー戦略と組み合わせることで、一部のスレッド リソースが最終的には、局所的な異常が全体の状況に影響を与えないという目標を達成することを目指します。
しかしながら、当社の事業が発展し続けるにつれて、上記の戦略の効果は徐々に薄れていきます。その理由は主に次の 2 つです。
- 海外へのビジネス: ゲートウェイは海外アクセス層として機能するため、一部のトラフィックを中国に転送する必要があり、遅い IO が標準的になります。
- サービス規模の拡大: ローカル例外が常態化しており、マイクロサービスの異常な急増と相まって、スレッド プールが長期間にわたって正常とは言えない状態になる可能性があります。
完全非同期変換は、近年 Ctrip の API ゲートウェイの中核となっている作業であり、この記事でもこれに焦点を当て、ゲートウェイにおける当社の取り組みと実際の経験について説明します。
重要なポイントには、パフォーマンスの最適化、ビジネス形態、技術アーキテクチャ、ガバナンスの経験などが含まれます。
2. 高性能ゲートウェイコア設計
2.1. 非同期プロセスの設計
完全な非同期 = サーバー側の非同期 + ビジネス プロセスの非同期 + クライアント側の非同期
サーバーとクライアントには Netty フレームワークを使用します。このフレームワークの NIO/Epoll + Eventloop は本質的にイベント駆動型の設計です。
私たちの変革の中核となる部分は、ビジネス プロセスを非同期化することです。一般的な非同期シナリオには次のようなものがあります。
- ビジネス IO イベント: リクエストの検証、ID 認証、リモート呼び出しなど
- 自己 IO イベント: たとえば、メッセージの最初の xx バイトが読み取られます。
- リクエスト転送: TCP 接続、HTTP リクエストを含む
経験上、非同期プログラミングは、主に次のような設計、読み取り、書き込みの点で同期プログラミングよりも若干難しいです。
- プロセス設計と状態遷移
- 一般的な例外やタイムアウトを含む例外処理
- ビジネスコンテキストやトレースログを含むコンテキスト配信
- スレッドのスケジューリング
- フロー制御
特に Netty のコンテキスト内では、ByteBuf のライフサイクル設計が完璧でない場合、メモリ リークが簡単に発生する可能性があります。
これらの問題に焦点を当て、対応する周辺フレームワークを設計し、開発を容易にするためにビジネスコードの同期/非同期の差異を平滑化するために最善を尽くしましたが、同時に、プログラム全体の安全性を確保するために安全性とフォールトトレランスをデフォルトにしました。
ツールとしてはRxJavaを使用しており、その主な処理を下図に示します。
注: 画像をクリックすると鮮明な画像が表示されます。
- 多分
- RxJava の組み込みコンテナ クラスは、正常終了、1 つだけ返されたオブジェクト、および例外の 3 つの状態を表します。
- 例外処理、タイムアウト、スレッド スケジューリング、その他のパッケージが組み込まれており、応答性が高く、ステート マシン全体の設計に便利です。
- Maybe.empty()/Maybe.just(T)、同期シナリオに適しています
- アスペクト ロジックのカプセル化を容易にするツール クラス RxJavaPlugins
- フィルター
- ビジネス ロジックの独立した部分、同期および非同期ビジネスの統合インターフェイスを表し、Maybe を返します。
- 非同期シナリオ (リモート呼び出しなど) は均一にカプセル化されます。スレッドの切り替えが関係する場合は、maybes.obesrveOn(eventloop) を介して切り替えます。
- 非同期フィルターはデフォルトでタイムアウトを増やし、弱い依存関係として処理し、エラーを無視します。
public interface Processor<T> {
ProcessorType getType();
int getOrder();
boolean shouldProcess(RequestContext context);
//对外统一封装为Maybe
Maybe<T> process(RequestContext context) throws Exception;
}
public abstract class AbstractProcessor implements Processor {
//同步&无响应,继承此方法
//场景:常规业务处理
protected void processSync(RequestContext context) throws Exception {
}
//同步&有响应,继承此方法,健康检测
//场景:健康检测、未通过校验时的静态响应
protected T processSyncAndGetReponse(RequestContext context) throws Exception {
process(context);
return null;
};
//异步,继承此方法
//场景:认证、鉴权等涉及远程调用的模块
protected Maybe<T> processAsync(RequestContext context) throws Exception
{
T response = processSyncAndGetReponse(context);
if (response == null) {
return Maybe.empty();
} else {
return Maybe.just(response);
}
};
@Override
public Maybe<T> process(RequestContext context) throws Exception {
Maybe<T> maybe = processAsync(context);
if (maybe instanceof ScalarCallable) {
//标识同步方法,无需额外封装
return maybe;
} else {
//统一加超时,默认忽略错误
return maybe.timeout(getAsyncTimeout(context), TimeUnit.MILLISECONDS,
Schedulers.from(context.getEventloop()), timeoutFallback(context));
}
}
protected long getAsyncTimeout(RequestContext context) {
return 2000;
}
protected Maybe<T> timeoutFallback(RequestContext context) {
return Maybe.empty();
}
}
- 全体的なプロセス
- 責任の連鎖の設計に従って、それは受信、送信、エラー、ログの 4 つの段階に分割されます。
- 各ステージは 1 つ以上のフィルターで構成されます
- フィルタは順番に実行され、例外が発生すると中断されます。インバウンド期間中、応答を返すフィルタも中断をトリガーします。
public class RxUtil{
//组合某阶段(如Inbound)内的多个filter(即Callable<Maybe<T>>)
public static <T> Maybe<T> concat(Iterable<? extends Callable<Maybe<T>>> iterable) {
Iterator<? extends Callable<Maybe<T>>> sources = iterable.iterator();
while (sources.hasNext()) {
Maybe<T> maybe;
try {
maybe = sources.next().call();
} catch (Exception e) {
return Maybe.error(e);
}
if (maybe != null) {
if (maybe instanceof ScalarCallable) {
//同步方法
T response = ((ScalarCallable<T>)maybe).call();
if (response != null) {
//有response,中断
return maybe;
}
} else {
//异步方法
if (sources.hasNext()) {
//将sources传入回调,后续filter重复此逻辑
return new ConcattedMaybe(maybe, sources);
} else {
return maybe;
}
}
}
}
return Maybe.empty();
}
}
public class ProcessEngine{
//各个阶段,增加默认超时与错误处理
private void process(RequestContext context) {
List<Callable<Maybe<Response>>> inboundTask = get(ProcessorType.INBOUND, context);
List<Callable<Maybe<Void>>> outboundTask = get(ProcessorType.OUTBOUND, context);
List<Callable<Maybe<Response>>> errorTask = get(ProcessorType.ERROR, context);
List<Callable<Maybe<Void>>> logTask = get(ProcessorType.LOG, context);
RxUtil.concat(inboundTask) //inbound阶段
.toSingle() //获取response
.flatMapMaybe(response -> {
context.setOriginResponse(response);
return RxUtil.concat(outboundTask);
}) //进入outbound
.onErrorResumeNext(e -> {
context.setThrowable(e);
return RxUtil.concat(errorTask).flatMap(response -> {
context.resetResponse(response);
return RxUtil.concat(outboundTask);
});
}) //异常则进入error,并重新进入outbound
.flatMap(response -> RxUtil.concat(logTask)) //日志阶段
.timeout(asyncTimeout.get(), TimeUnit.MILLISECONDS, Schedulers.from(context.getEventloop()),
Maybe.error(new ServerException(500, "Async-Timeout-Processing"))
) //全局兜底超时
.subscribe( //释放资源
unused -> {
logger.error("this should not happen, " + context);
context.release();
},
e -> {
logger.error("this should not happen, " + context, e);
context.release();
},
() -> context.release()
);
}
}
2.2. ストリーミング転送とシングルスレッド
HTTP を例にとると、メッセージは最初の行/ヘッダー/本文の 3 つのコンポーネントに分割できます。
Ctrip では、ゲートウェイ層のビジネスにはリクエストボディは関与しません。
全量を保存する必要がないため、リクエストヘッダーを解析した後、直接ビジネスプロセスに入ることができます。
同時に、リクエストボディのボディ部分を受信した場合:
①リクエストが上流に転送されている場合は、直接転送します。
② それ以外の場合は、一時的に保存し、ビジネス プロセスの完了後に最初の行/ヘッダーと一緒に送信する必要があります。
③上流レスポンスの処理も同様です。
HTTP メッセージを完全に解析する方法と比較すると、次のように処理されます。
- ビジネス プロセスに早く入るということは、アップストリームがリクエストをより早く受け取ることを意味し、ゲートウェイ層によって生じる遅延を効果的に削減できます。
- 本体のライフサイクルが圧縮されるため、ゲートウェイ自体のメモリ オーバーヘッドが削減されます。
パフォーマンスは向上しましたが、ストリーミングによりプロセス全体の複雑さも大幅に増加しました。
注: 画像をクリックすると鮮明な画像が表示されます。
非ストリーミング シナリオでは、Netty サーバー側のエンコードとデコード、受信ビジネス ロジック、Netty クライアント側のエンコードとデコード、送信ビジネス ロジックのサブプロセスは互いに独立しており、それぞれが完全な HTTP オブジェクトを処理します。ストリーミング処理では、リクエストが同時に複数のプロセスに存在する可能性があり、次の 3 つの課題が生じます。
- スレッドの安全性の問題: 各プロセスが異なるスレッドを使用する場合、コンテキストの同時変更が関係する可能性があります。
- 多段階連携: たとえば、Netty Server がリクエスト受信の途中で接続中断に遭遇し、すでに上流に接続されている場合、上流側のプロトコル スタックは完了しないため、それに応じて接続を閉じる必要があります。
- エッジ シーンの処理: たとえば、リクエストが完全に送信されなかったときにアップストリームが 404/413 を返した場合、送信を続行してプロトコル スタックを完了し、接続の再利用を許可するか、それともプロセスを早期に終了するかを選択する必要があります。リソースを節約しながら、同時に接続を放棄するには? 別の例として、アップストリームがリクエストを受信しましたが応答しませんでした。このとき、Netty サーバーが突然切断されました。Netty クライアントも切断されますか? 等
これらの課題に対処するために、私たちはシングルスレッドのアプローチを採用しました。
- オンライン ドキュメントはイベントループにバインドされており、Netty サーバー/ビジネス プロセス/Netty クライアントは同じイベントループで実行されます。
- IO ライブラリのために非同期フィルターが独立したスレッド プールを使用する必要がある場合は、後処理を元に戻す必要があります。
- プロセス内のリソース (接続プールなど) に対して必要なスレッド分離を実行します。
シングルスレッド方式により同時実行性の問題が回避され、多段連携やエッジシーンの問題に対処する際、システム全体が一定の状態となり、開発の難しさとリスクが効果的に軽減されます。また、スレッド切り替えの削減によりパフォーマンスも向上します。ある程度まで。ただし、ワーカー スレッドの数 (通常は CPU コアの数と同じ) が少ないため、イベントループ内での IO 操作は完全に回避する必要があります。そうしないと、システムのスループットに重大な影響を及ぼします。
2.3 その他の最適化
- 内部変数の遅延ロード
要求された Cookie/クエリおよびその他のフィールドについては、必要がない場合、文字列解析は事前に実行されません。
- オフヒープメモリとゼロコピー
以前のストリーミング転送設計と組み合わせることで、システム メモリの使用量がさらに削減されます。
- ZGC
プロジェクトがTLSv1.3にアップグレードされてから、JDK11が導入され(JDK8のサポートが遅れ、8u261バージョン、2020.7.14)、新世代のガベージコレクションアルゴリズムも試しられ、実際のパフォーマンスは確かに人々の期待どおりでした。 。CPU 使用率は増加しましたが、全体的な GC 時間は大幅に減少しました。
注: 画像をクリックすると鮮明な画像が表示されます。
- カスタマイズされたHTTPコーデック
HTTP プロトコルの長い歴史とオープンさにより、少なくともリクエストの成功率に影響を与え、最悪の場合 Web サイトのセキュリティに脅威をもたらす多くの「悪い慣行」が出現しました。
- 交通管理
リクエスト本文が大きすぎる (413)、URI が長すぎる (414)、非 ASCII 文字 (400) などの問題の場合、一般的な Web サーバーは直接拒否し、対応するステータス コードを返すことを選択します。この種の問題はビジネス プロセスをスキップするため、統計、サービスの場所、トラブルシューティングの点で何らかの問題が発生します。コーデックを拡張することにより、問題のあるリクエストもルーティング プロセスを完了できるため、非標準トラフィックの管理問題の解決に役立ちます。
- リクエストのフィルタリング
たとえば、密輸のリクエスト (Netty 4.1.61.Final で修正、2021 年 3 月 30 日にリリース)。コーデックを拡張し、カスタム検証ロジックを追加することで、セキュリティ パッチをより迅速に適用できます。
3. ゲートウェイビジネス形態
インバウンド トラフィックの独立した統合されたエントリ ポイントとして、企業にとってのゲートウェイの価値は主に次の 3 つの側面で実証されます。
- さまざまなネットワーク環境の分離: 一般的なシナリオには、イントラネットと外部ネットワーク、実稼働環境とオフィスエリア、IDC 内のさまざまなセキュリティ ドメイン、専用回線などが含まれます。
- 自然な公共ビジネスの側面: セキュリティ、認証、クライミング防止、ルーティング、グレースケール、電流制限、サーキット ブレーカー、ダウングレード、監視、警報、トラブルシューティングなど。
注: 画像をクリックすると鮮明な画像が表示されます。
- 効率的かつ柔軟なフロー制御
次に、いくつかの細分化されたシナリオを示します。
- プライベートプロトコル
クローズド クライアント (APP) では、フレームワーク層がユーザーによって開始された HTTP リクエストをインターセプトし、プライベート プロトコル (SOTP) を通じてサーバーに送信します。
場所の選択に関しては、① DNS ハイジャックを防ぐためにサーバー経由で IP を割り当て、② 接続を予熱し、③ カスタマイズされた場所の選択戦略を採用し、ネットワークの状態、環境、その他の要因に応じて自動的に切り替えることができます。
インタラクションモードとしては、①プロトコル本体を軽量化する、②暗号化・圧縮・多重化を統一的に行う、③ゲートウェイが入り口でプロトコルを一律変換するため、業務に影響を与えない、といった点が挙げられる。
- リンクの最適化
重要なのは、アクセス層を導入してリモート ユーザーが近くにアクセスできるようにし、過剰なハンドシェイク オーバーヘッドの問題を解決することです。同時に、アクセス層と IDC の両方が制御可能であるため、ネットワーク リンクの選択、プロトコル インタラクション モードなどの点で最適化の余地がさらに広がります。
- もっと違う場所に住もう
比例割り当てや近接アクセス ポリシーとは異なり、リモート マルチアクティブ モードでは、基になるデータの競合を防ぐために、ゲートウェイ (アクセス レイヤ) はビジネス ディメンション (userId など) の shardingKey に従ってトラフィックをシャントする必要があります。
注: 画像をクリックすると鮮明な画像が表示されます。
4. ゲートウェイ管理
以下の図は、オンライン ゲートウェイの動作状況をまとめたものです。当社のビジネスプロセスに垂直に対応:さまざまなチャネル(APP、H5、ミニプログラム、サプライヤーなど)およびさまざまなプロトコル(HTTP、SOTPなど)からのトラフィックがロードバランシングを通じてゲートウェイに分散され、一連のビジネスを通じて処理されますロジックはバックエンド サービスに転送されます。第 2 章の改善により、水平ビジネスはパフォーマンスと安定性の点で大幅に向上しました。
注: 画像をクリックすると鮮明な画像が表示されます。
一方、複数のチャネル/プロトコルが存在するため、オンライン ゲートウェイはサービスに基づいて独立したクラスターを展開します。初期の頃は、ビジネス上の差異 (ルーティング データや機能モジュールなど) は独立したコード ブランチによって管理されていましたが、ブランチの数が増加するにつれて、全体的な運用とメンテナンスの複雑さは増加し続けました。システム設計では、複雑さがリスクを意味することもよくあります。したがって、マルチプロトコルおよびマルチロールのゲートウェイを統合した方法で管理する方法、および新しいサービス用にカスタマイズされたゲートウェイを低コストで迅速に構築する方法が、私たちの次の段階の作業の焦点になりました。
この図は、ソリューションを直観的に示しています。1 つ目は、オンライン コードが 1 つのフレームワークの下で実行できるようにプロトコルで互換性処理を実行することです。2 つ目は、オンライン ゲートウェイのさまざまな特性を均一に管理するコントロール プレーンを導入することです。
4.1 マルチプロトコル互換性
マルチプロトコル対応の手法は新しいものではなく、TomcatのHTTP/1.0、HTTP/1.1、HTTP/2.0の抽象処理を参考にすることができます。HTTP には各バージョンで多くの新機能が追加されていますが、通常、ビジネス開発を行っているときにこれらの変更を認識することはできませんが、その鍵は HttpServletRequest インターフェイスの抽象化にあります。
Ctrip では、オンライン ゲートウェイがステートレス プロトコルをリクエスト/レスポンス モードで処理し、メッセージ構造もメタデータ、拡張ヘッダー、サービス メッセージの 3 つの部分に分割できるため、同様の試みを容易に行うことができます。関連する作業は次の 2 点に要約できます。
- プロトコル アダプテーション層: さまざまなプロトコル、対話モード、TCP 接続の処理などのエンコードとデコードをシールドするために使用されます。
- 共通の中間モデルとインターフェイスを定義する: ビジネス プログラミングは中間モデルとインターフェイスを重視しており、プロトコルに対応するビジネス属性にさらに注意が払われます。
注: 画像をクリックすると鮮明な画像が表示されます。
4.2 ルーティングモジュール
ルーティング モジュールは、コントロール プレーンの 2 つの主要コンポーネントのうちの 1 つであり、ゲートウェイとサービス間のマッピング関係を管理することに加えて、サービス自体は次のモデルで要約できます。
{
//匹配方式
"type": "uri",
//HTTP默认采用uri前缀匹配,内部通过树结构寻址;私有协议(SOTP)通过服务唯一标识定位。
"value": "/hotel/order",
"matcherType": "prefix",
//标签与属性
//用于portal端权限管理、切面逻辑运行(如按核心/非核心)等
"tags": [
"owner_admin",
"org_framework",
"appId_123456"
],
"properties": {
"core": "true"
},
//endpoint信息
"routes": [{
//condition用于二级路由,如按app版本划分、按query重分配等
"condition": "true",
"conditionParam": {
},
"zone": "PRO",
//具体服务地址,权重用于灰度场景
"targets": [{
"url": "http://test.ctrip.com/hotel",
"weight": 100
}
]
}]
}
4.3 モジュールの配置
モジュールのスケジューリングは、コントロール プレーンのもう 1 つの重要なコンポーネントです。ゲートウェイの処理フローには複数の段階があります (図のピンク色で示されています)。サーキット ブレーカー、電流制限、ロギングなどの一般的な機能に加えて、実行時にさまざまなゲートウェイが実行する必要があるビジネス機能がコントロール プレーンによって均一に割り当てられます。これらの機能はゲートウェイ内に独立したコードモジュールを持ち、コントロールプレーンはこれらの機能に対応する実行条件、パラメータ、グレースケール、エラー処理方法を追加定義します。このスケジューリング方法により、モジュール間の分離もある程度保証されます。
注: 画像をクリックすると鮮明な画像が表示されます。
{
//模块名称,对应网关内部某个具体模块
"name": "addResponseHeader",
//执行阶段
"stage": "PRE_RESPONSE",
//执行顺序
"ruleOrder": 0,
//灰度比例
"grayRatio": 100,
//执行条件
"condition": "true",
"conditionParam": {
},
//执行参数
//大量${}形式的内置模板,用于获取运行时数据
"actionParam": {
"connection": "keep-alive",
"x-service-call": "${request.func.remoteCost}",
"Access-Control-Expose-Headers": "x-service-call",
"x-gate-root-id": "${func.catRootMessageId}"
},
//异常处理方式,可以抛出或忽略
"exceptionHandle": "return"
}
5. まとめ
ゲートウェイは、さまざまな技術交換プラットフォームで常に大きな関心の的であり、多くの成熟したソリューションがあります。使いやすく、以前に開発された Zuul 1.0、高パフォーマンスの Nginx、高度な統合を備えた Spring Cloud Gateway、そしてますます人気が高まっているイスティオなど
最終的な選択は依然として各企業のビジネス背景とテクノロジーエコシステムに依存します。
したがって、Ctripでは独自の研究開発の道を選択しました。
テクノロジーは常に発展しており、パブリック ゲートウェイとビジネス ゲートウェイの関係、新しいプロトコル (HTTP3 など) の適用、ServiceMesh との関連付けなども含め、私たちも模索を続けています。
最後に: 質問がある場合は、古いアーキテクチャにアドバイスを求めることができます。
建築の道は山あり谷あり
アーキテクチャは高度な開発とは異なります。アーキテクチャに関する質問はオープン/オープンであり、アーキテクチャに関する質問に対する標準的な回答はありません。
このため、多くの友人は多大なエネルギーとお金を費やしたにも関わらず、残念ながら一生のうちにアーキテクチャのアップグレードを完了することができません。
したがって、アーキテクチャのアップグレード/変革のプロセスにおいて、どうしても効果的な解決策が見つからない場合は、40 歳の建築家 Nien に助けを求めることができます。
少し前まで小さなパートナーだった彼は、専攻を超えて Java を担当しており、現在はアーキテクチャ変更の問題に直面していますが、Nien からの数回の指導の後、Java アーキテクト + ビッグデータ アーキテクトのオファーを獲得することに成功しました。したがって、キャリア上で困難に直面した場合は、経験豊富な建築家に助けを求める方がスムーズです。
推奨読書
「100 億回の訪問、キャッシュ アーキテクチャの設計方法」
「Alibaba 2: ノードは何台導入していますか?」1000W の同時実行を導入するにはどうすればよいですか? 》
「Meituan 2 Sides: Five Nines 高可用性 99.999%。それを達成するにはどうすればよいですか?」》
「NetEase 側: シングルノード 2000Wtps、Kafka はどうやってそれを行うのですか?」》
「バイト側: トランザクション補償とトランザクション再試行の関係は何ですか?」》
「NetEase 側: Mysql への 25Wqps の高スループット書き込み、100W データが 4 秒で書き込まれます。これを実現するにはどうすればよいですか?」》
「10億レベルのショートビデオをどのように構成するか? 」》
「爆上げ、「自慢」に頼ってJD.comを乗り切る、月給4万」
「あまりに過酷なので、『自慢』に頼ってSFエクスプレスを乗り切り、月収は3万です」
「爆発しました...Jingdongは片側で40の質問を要求し、それを通過した後、それは500,000以上でした」
「質問するのはもううんざりです...アリは命を懸けて27の質問をしました、そしてそれを通過した後の質問は60万以上です」
「Baiduは狂ったように3時間要求しました、Dachangはオファーを受け取りました、男は本当に冷酷です!」》
「Ele.me は残酷すぎる: 高度な Java に直面して、それがどれほど困難で残酷な作業であるか」
「Byte による 1 時間のクレイジーな質問の後、その男はオファーを受け取りました。それはとても残酷です!」》
" Didi のオファーを受け入れる: この男の 3 つの経験から、何を学ぶ必要がありますか? 》
『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』PDF は、下記公式アカウント【Technical Freedom Circle】から入手してください ↓↓↓