1.背景
APIゲートウェイは、その役割が何であるか、の背景何であるとは何ですか?
アーキテクチャの観点からは、API Gatewayの暴露HTTPインタフェースサービス、および要求を含むことは、負荷分散をルーティングするための唯一の責任があり、ビジネス・ロジックを伴う、許可の検証、フロー制御、キャッシュとよりはありません。nginxのその位置決めが要求を転送するに似ていますが、nginxのより多くの機能は、これらのサービス契約が静止することができ、それは、RPCプロトコルなどであってもよいし、バックオフィスサービスの何百もの後ろに接続されています。
ゲートウェイは、高い性能と高効率を必要と生まれたその位置を決定します。我々はその性能を要求して、次のように続いて、サービス・インターフェースの数百人への玄関口、並行性の高いビジネスニーズのベアラが、その基本的な機能は以下のとおりです。
プロトコル変換は、
フロントからの要求に一般的であるHTTPインターフェースであるが、分散設計の文脈で、我々は、RPCプロトコルを開発したサービスに基本的にバックオフィスサービスです。これは、要求と応答の変換のための中間層としてのゲートウェイを必要とします。
HTTPプロトコルを変換するRPCされ、その後、変換されたRPCプロトコルはHTTPプロトコルで返しますリクエストルーティング
背面に接続されたゲートウェイは、負荷分散を行うために必要とバックエンド・ノードへのルート要求に遠位リクエストURLにその必要なサービスの数千を要するかもしれません統一認証
認証動作のためのビジネス・ロジックに関連していない、それが基礎となるビジネス・ロジックなしで、ゲートウェイで処理されてもよいです。監視ユニファイド
ゲートウェイは、外部サービスへの入り口であるため、我々はそのような上院、リンク時間を基準として、私たちはここに必要なデータを、監視することができますので、。フロー制御は、ヒューズが劣化
フロー制御のために、非分解ヒューズゲートウェイサービスロジック層に組み込むことができます。
そこの企業の多くは、そのサービスにアクセスするための一つの層のゲートウェイを達成するために所有することになりますが、会社全体のために、これは十分ではありません。
2.FlurryダボAPIゲートウェイ
フラリーは、軽量、非同期のストリーミング、ダボ用の高性能APIゲートウェイの研究から収集されます。そして、業界で最もゲートウェイが異なる場合、突風自体がダボ-JSONの流れを達成するためのプロトコル、HTTPプロトコルとダボシステムの変換は、httpプロトコル変換のための高性能、低メモリ要件とダボすることができます。また、サービスのメタデータモデルを提供し、サービスとしてネッティーコンテナに基づくというように非常に特徴的なものです。ここでは詳細に特性の突風を説明します:
2.1ベースネッティーコンテナ
RTが比較的高い場合、従来のゲートウェイは、主にコンテナとして使用TOMCAT、ハンドルの要求と応答にコア・スレッド・プールを持つことになり、非同期、Tomcatのその要求に応答しない、それがパフォーマンスに影響する場合があります。
反応を達成することである突風ゲートウェイ網状スレッド要求応答モデル、CPUを排出するように設計された反応性パターン仕様は、大幅に単一の要求処理に応答する能力を高めることができます。
モデルや通信プロトコルをスレッドNIOネッティーを使用して非同期のHTTPリクエストとレスポンスの最後に、フラリー実現。
各HTTP要求が最終的に非同期モードで、最終的にバックグラウンドサービス要求網状クライアントハンドラ、のいずれかによって処理され、CompletableFutureを返すであろうのみが存在する場合、結果は、遠位端結果に戻されます。
以下のいくつかの例を参照してください。
- ServerProcessHandler
public class ServerProcessHandler extends SimpleChannelInboundHandler<RequestContext> {
public void handlerPostAsync(RequestContext context, ChannelHandlerContext ctx) throws RpcException {
CompletableFuture<String> jsonResponse = asyncSender.sendAsync(context, ctx);
jsonResponse.whenComplete((result, t) -> {
long et = System.currentTimeMillis();
if (t != null) {
String errorMessage = HttpHandlerUtil.wrapCode(GateWayErrorCode.RemotingError);
doResponse(ctx, errorMessage, context.request());
} else {
doResponse(ctx, HttpHandlerUtil.wrapSuccess(context.requestUrl(), result), context.request());
}
});
}
//省略部分代码
public static void sendHttpResponse(ChannelHandlerContext ctx, String content, FullHttpRequest request) {
//将结果写回Client,返回前端
ctx.writeAndFlush(response);
}
}
2.2サービスのメタデータモデル
いわゆるサービスメタデータ情報は、反射Javaクラスに非常に類似している上記のコメントのサービスインターフェース方法は、各方法の情報入力および出力パラメータ、各パラメータフィールド情報、及び(メソッド、パラメータおよびフィールド)、リスティング情報であります情報。
メタデータの役割
サービスメタデータでは、APIパッケージには、我々はサービスを必要としなければならない、と明らかに全体のサービスのAPIの定義を知ることができません。
テスト中のこのダボサービスモックコールサービスは、ドキュメントのサイトは、ストリーミング通話、およびので、シーンが役割をつかむために再生することができます。
メタデータレジストリデータの比較
\ | サービスメタデータ | レジストリデータ |
---|---|---|
周波数変化 | 反復のサービス、および変更で、基本的には変わりません | サービスの変更上の任意の時点で、オフラインのノードを持ちます |
責任 | サービスの基本的な性質を説明して、サービス定義 | メモリアドレスリスト |
利用シナリオ | APIの依存性モードの呼び出しません(直接JSON)、ドキュメントサイト、モックテストなし | ガバナンスとサービスの呼び出し |
相互作用モデル | サービスジェネレータコンパイル情報、クライアントモードのインターフェイスは、呼び出しによって得られました | パブリッシュおよびサブスクライブ・モデルを、相互作用オンライン |
メタデータセンターの値
子供Caifenは正しいか間違って、ちょうど大人の長所と短所を見てください。メタデータ生成メカニズムの追加導入は、必然的にそれはあなたがそれを選ぶ説得しなければならない価値をどのようなそして、コスト、移行コストやその他の問題を理解し、運用および保守コストをもたらすのだろうか?上記の米国とき、メタデータサービスのテストセンターはすでに、サービスMOCK他のシーン、私たちは価値と使用シナリオに関するメタデータの中央に焦点を当て、このセクションを言及しています。
だから、ダボのサービスメタデータは、どのようなシーン、それを活用できるようにするには?ここでは詳細に説明します。
2.3ストリーミングプロトコル変換
ゲートウェイは、JSONデータの形式でサポートされている突風HTTPレストスタイルのインタフェースと送信を提供します。ダボRPCプロトコルに突風外部HTTPプロトコル要求そうする必要性は、プロトコルリターンダボ結果は、HTTPプロトコルの前端に変換バックあります。
ダボネイティブ一般化が実現します
モデルのいかなる一般化は、消費者側ダボケースのためのサービス・インターフェースAPIパッケージではありません、[キー、値ダボ要求モード・サーバ、終了要求後のサーバプロセスダボ、およびのための地図POJOのプロパティマップの各地図POJOは、消費者側への復帰の形式になります。
< - >のHttp達成するために、一般化パターンを使用してダボ変換処理を以下のように示されています。
形式に厳密に従ってHTTPリクエスト、JSONを介したデータ伝送は、POJOインタフェース属性。シーケンスは、戻りJSONのフロントエンドに結果を返します。今ダボのオープンソースモデルの汎化ゲートウェイプロトコル適合のほとんどは、プロトコル変換を行うために使用され、これらが含まれているソウルなどを。
一般化されたデータは、モードプロトコル変換処理を流れます。
JsonString -> JSONObject(Map) -> Binary
(など、GoogleのGson、アリFastJSON、など)は、サードパーティJSONマッピングフレームワークJSONオブジェクトモデル(JSONObject)、にJSON文字列は、[マップはHessian2契約でBinarayとしてシリアライズします。
汎化欠点
泛化过程数据流会经过了三次转换, 会产生大量的临时对象, 有很大的内存要求。使用反射方式对于旨在榨干服务器性能以获取高吞吐量的系统来说, 难以达到性能最佳。
同时服务端也会对泛化请求多一重 Map <-> POJO 的来回转换的过程。整体上,与普通的Dubbo调用相比有10-20%的损耗。
自定义Dubbo-Json协议
我们的需求是要打造一款高性能、异步、流式的Dubbo API网关,当然要对不能容忍上述泛化带来的序列化的痛点,针对http与dubbo协议转换,我们的要求如下:
自定义的Dubbo-Json协议参考了dapeng-soa 的流式解析协议的思想,详情请参考:dapeng-json
针对上述泛化模式转换Dubbo协议的缺点,我们在flurry-core 中的 Dubbo-Json 序列化协议做到了这点,下面我们来讲解它是如何高效率的完成JsonString到 dubbo hessian2 序列化buffer的转换的。
高性能
此协议用来在网关中作为http和rpc协议的转换,要求其能实现高效的序列化以及反序列化, 以支持网关海量请求的处理.低内存使用
虽然大部分情况下的JSON请求、返回都是数据量较小的场景, 但作为平台框架, 也需要应对更大的JSON请求和返回, 比如1M、甚至10M. 在这些场景下, 如果需要占用大量的内存, 那么势必导致巨大的内存需求, 同时引发频繁的GC操作, 也会联动影响到整个网关的性能.
Dubbo-Json参考了XML SAX API的设计思想, 创造性的引入了JSON Stream API, 采用流式的处理模式, 实现JSON 对 hessian2 的双向转换, 无论数据包有多大, 都可以在一定固定的内存规模内完成.
- 容错性好
前面我们引入了服务元数据的概念,因此在此基础上,通过元数据提供的接口文档站点,自动生成请求数据模板,每一个属性的类型精确定义,譬如必须使用正确的数据类型, 有的字段是必填的等。
那么在Json -> Hessian2Buffer的转换过程中,如果出现与元数据定义不符合的情况,就回直接报错,定位方便。
流式协议解析过程
流式协议,顾名思义就是边读取边解析,数据像水流一样在管道中流动,边流动边解析,最后,数据解析完成时,转换成的hessian协议也已全部写入到了buffer中。
这里处理的核心思想就是实现自己的Json to hessian2 buffer 的语法和此法解析器,并配合前文提及的元数据功能,对每一个读取到的json片段通过元数据获取到其类型,并使用 hessian2协议以具体的方式写入到buffer中。
JSON结构简述
首先我们来看看JSON的结构. 一个典型的JSON结构体如下
{
"request": {
"orderNo": "1023101",
"productCount": 13,
"totalAmount: 16.54
}
}
其对应Java POJO 自然就是上述三个属性,这里我们略过。下面是POJO生成的元数据信息
<struct namespace="org.apache.dubbo.order" name="OrderRequest">
<fields>
<field tag="0" name="orderNo" optional="false" privacy="false">
<dataType>
<kind>STRING</kind>
</dataType>
</field>
<field tag="1" name="productCount" optional="false" privacy="false">
<dataType>
<kind>INTEGER</kind>
</dataType>
</field>
<field tag="2" name="totalAmount" optional="false" privacy="false">
<dataType>
<kind>DOUBLE</kind>
</dataType>
</field>
</fields>
</struct>
Json解析器
相比XML而言,JSON数据类型比较简单, 由Object/Array/Value/String/Boolean/Number
等元素组成, 每种元素都由特定的字符开和结束. 例如Object以'{'以及'}'这两个字符标志开始以及结束, 而Array是'['以及']'. 简单的结构使得JSON比较容易组装以及解析。
如图,我们可以清晰的了解JSON的结构,那么对上述JSON进行解析时,当每一次解析到一个基本类型时,先解析到key,然后根据key到元数据信息中获取到其value类型,然后直接根据对应类型的hessian2序列化器将其序列化到byte buffer中。
当解析到引用类型,即 Struct类型时,我们将其压入栈顶,就和java方法调用压栈操作类似。
通过上面的步骤一步一步,每解析一步Json,就将其写入到byte buffer中,最终完成整个流式的解析过程。
拿上面json为例:
{
"request": {
"orderNo": "1023101",
"productCount": 13,
"totalAmount: 16.54
}
}
解析器每一步会解析一个单元,首先解析到request,然后根据请求附带的接口、版本等信息找到当前请求服务的元数据信息(元数据信息缓存在网关之中,定期刷新)。
- 开始解析属性,解析到 orderNo key时,通过元数据中得知其数据类型为String,然后再解析完value之后,通过调用hessian2的writeString API将其写入到hessian2序列化的byte buffer 缓存中。
- 依次解析后面的属性,当全部属性解析完成之后,解析到最后一个 } 时,此时证明数据全部解析完毕,于是hessian buffer 通过flush 将数据全部写入到bytebuffer中,请求直接发送出去。
- Dubbo服务端再接收到这个序列化的buffer之后,会像其他普通dubbo consumer调用服务的模式一样的去解析,然后反序列化为请求实体,进行业务逻辑处理。
flurry网关再接受到返回的数据时,在没有反序列化之前,其是一个hessian2的二级制字节流,我们仍然通过dubbo-json的解析模式,直接将反序列化出来的属性写为Json String
总结:
上述整个请求和响应,网关处理如下:
- request: Json -> hessian2二进制字节流
- response:hessian2二进制字节流 -> json
请求和响应中没有像泛化模式中的中间对象转换,直接一步到位,没有多余的临时对象占用内存,没有多余的数据转换,整个过程像在管道中流式的进行。
2.4 flurry网关与tomcat接入层比较
传统的dubbo服务接入层是采用tomcat作为容器来实现,每一个业务模块对应一个tomcat应用,其本身需要以来dubbo各个服务的API接口包,tomcat中启动几十个传统的dubbo consumer 服务,然后通过webmvc的模式提供http接口。
如上图所示,flurry dubbo网关不必依赖任何dubbo接口API包,而是直接通过获取服务元数据、并通过dubbo-json流式协议来调用后端服务。其本身不会耦合业务逻辑。
2.5 性能测试
测试环境
硬件部署与参数调整
机型 | 角色 | CPU | 内存 | 带宽 |
---|---|---|---|---|
CVM虚拟机 | API网关 | 8核 | 16GB | 10Mbp/s |
CVM虚拟机 X2 | Dubbo Provider | 4核 | 8GB | 10Mbp/s |
CVM虚拟机 | wrk压测机 | 8核 | 16GB | 10Mbp/s |
测试目的
对基于Y-Hessian的 异步化、流式转换的Yunji Dubbo API网关进行性能压测,了解它的处理能力极限是多少,这样有便于我们推断其上线后的处理能力,以及对照现有的Tomcat接入层模式的优势,能够节约多少资源,做到心里有数。
测试脚本
性能测试场景
网关入参0.5k请求json,深度为3层嵌套结构,服务端接收请求,返回0.5k返回包
网关入参2k请求json,深度为3层嵌套结构,服务端接收请求,返回0.5k返回包
上述场景均使用wrk在压测节点上进行5~10min钟的压测,压测参数基本为12线程256连接或者512连接,以发挥最大的压测性能。
测试结果
性能指标(量化)
场景名称 | wrk压测参数 | Avg RT | 实际QPS值 |
---|---|---|---|
0.5k数据 | -t12 -c256 | 3.77ms | 69625 |
0.5k数据 | -t12 -c 512 | 7.26ms | 71019 |
2k数据 | -t12 -c256 | 5.48ms | 46576 |
2k数据 | -t12 -c512 | 10.80ms | 46976 |
运行状况(非量化)
API网关(8c16g)运行良好,压测期间CPU占用为550%左右
两个 Dubbo Provider 服务运行良好,CPU占用为100%左右
各个角色内存运行稳定,无OOM,无不合理的大内存占用等。
3.总结
突風ダボゲートウェイセットは、非同期、フローは、高性能で、目標は以下のノードへのダボアクセス層は、ハードウェアおよびソフトウェア資源節約、より高いパフォーマンスを得るとしてTomcat一部の消費者を交換することです。
4.フォロー
突風に基づいて、フォローアップ、我々は認証管理を達成する、トラフィック制御、機能上の電流制限ヒューズ、監視、収集など
5.参考プロジェクト
突風:ダボ基づくサービス性能、非同期は、ゲートウェイ流れ
ダボ-JSONを:ダボカスタムプロトコルがサポート突風ゲートウェイシリアライゼーション/デシリアライゼーションコンポーネントとしてモードシーケンスをストリーミングします。
サイト-DOC-Yunji:統合関連のプロジェクトだけでなく、ドキュメントサイトとメタデータ
SOA-大鵬:大鵬-SOAはネッティーとカスタムライトスリフトの上に構築された軽量、高性能マイクロサービスフレームワークです。同時に、スリフトIDLから自動的に生成されたファイルのメタデータ情報サービスは、現在のフレームの重要な特徴である、他の多くの重要な機能は、サービスメタデータ情報に依存しています。最後に、ワンストップのマイクロサービスソリューションとして、大鵬-SOAはまた、ビルドユーザー迅速足場マイクロサービス・システムをサポートするツールの範囲を提供してい
大鵬-JSON:大鵬-JSONプロトコル紹介