.NET でのいくつかのサービス フレームワークの紹介

黄舟
リリース: 2017-02-06 14:22:52
オリジナル
1955 人が閲覧しました

はじめに


会社がより多くのサービスを提供した後、通話の利便性と将来のサービス管理のために、いくつかのサービスフレームワークが一般的に使用されます。ここでは主に私が知っているいくつかのサービスフレームワークを紹介し、それらの基本的な概念を簡単に分析します。サービスフレームワークの。


本番環境に導入可能


以下の2つのサービスフレームワークは、企業が本番環境に導入しているのを見たことがあるので、安定性についてはあまり心配する必要はないでしょう。

ServiceStack https://github.com/ServiceStack/ServiceStack


ServiceStack はこれまで使用されたことがないかもしれませんが、他の 2 つのコンポーネント、ServiceStack.Redis (Redis アクセス ツール)、ServiceStack は使用したことがあるはずです。 Text (Json シリアル化ツール)、ServiceStack はサービス フレームワークであり、これを使用してサービスを簡単に作成できます。このサービスは http に基づいており、データ シリアル化メソッドには Json、xml、binary、Protobuf が含まれます。作成されたサービスには特定の説明があります。


1 http リクエストには、リクエスト パスとパラメータという 2 つの重要な要素があります。ServiceStack の場合、パラメータはオブジェクトです。つまり、渡したいパラメータはクラスにカプセル化され、ラベルがクラスに追加されます。コンテンツはリクエスト パスであるため、クライアントが呼び出すと、リクエスト パスとパラメータが反映され、呼び出しが開始されます。


ServiceStack 自体がデモを提供しているため、ここではデモを書きません。そこから学ぶことができます。

Hessian https://sourceforge.net/projects/hessiancsharp/


Hessian はシリアル化ツールであり、.net を含む複数の言語で実装を提供するサービス フレームワークです。ネット界隈ではあまり有名ではないので、長いこと更新されていないのかもしれません。

ヘシアンを使用する場合、最初にインターフェイスを定義し、次にこれらのインターフェイスをサーバー側で重複して実装する必要があります。その後、クライアントは RealProxxy クラスをプロキシとして使用します。プロキシ クラスを呼び出し、呼び出されるメソッドの名前、パラメータ、およびその他の内容を Invoke メソッドで取得し、シリアル化後にサーバー上の統一 URL に送信します。この URL はヘシアンで終わるため、設定する必要があります。 web.config のハンドル。リクエストをインターセプトした後、パラメーターを逆シリアル化して、リフレクションを通じて呼び出しを開始します。


このブログを参照してください http://www.cnblogs.com/lxsfg/archive/2008/08/27/1277777.html

thrift、JSON など、他にも多くのサービス フレームワークがあります-RPC ただし、私は使用したことがないので、ここではコメントしません。


ブログパーク内のいくつかのサービスフレームワーク

ブログパークを閲覧したときに発見したのは、以下の 3 つのフレームワークであり、すべてオープンソースです。また、サービス フレームワークを学習するのに適したプロジェクトです。ブログをよく見かけますが、以下の 3 つのフレームワークも Blog Park にあるはずですが、見つけられなかった場合は、コメント欄に書いていただければ幸いです。みんなで一緒に学べるように。

Rabbit.Rpc http://www.cnblogs.com/ants/p/5605754.html

も、最初にサービス インターフェイスを定義し、次にサーバーがそれを 2 つのコピーを作成します。インターフェイスを継承することによるクライアントの具体的なロジックは、インターフェイス内のすべてのメソッド、メソッドのパラメーター、およびリフレクションによる戻り値の情報を抽出し、コードを動的に生成してプロキシ クラスを生成し、それを動的にコンパイルすることです。そして容器に入れます。 生成されたプロキシ クラスに関しては、すべてのメソッドが統一された実装を持ちます。つまり、Invoke メソッドを呼び出してメソッドとパラメーターを最下層に送信し、最下層のアセンブリがサーバーに送信されます。ここでコードを生成する方法はもっと楽しく、学ぶことができます。


さらに、このフレームワークはサービス ガバナンスも統合しており、サービスは Zookeeper に登録され、クライアントは Zookeeper を通じて特定のサービス アドレスを取得して呼び出すことができます。 実際、現時点では、これは単なるサービス フレームワークではなく、サービス ガバナンス機能も含まれています。


私はコードをざっと読んだだけなので、詳細を完全には理解していません。詳しく知りたい場合は、ソースコードを読んでください。

Dyd.BaseService.ServiceCenter http://git.oschina.net/chejiangyi/Dyd.BaseService.ServiceCenter

基本的な機能はすべて揃っていますが、このプロジェクトについての著者の紹介がこのプロジェクトについてです研究目的のため、サービスを呼び出すクライアントもコードを通じて生成されます。詳細については、コードを参照してください。

さらに、このブロガーをさらに紹介しましょう。彼はブログパーク http://www.cnblogs.com/chejiangyi/ にもブログを持っており、その下にいくつかのオープンソース プロジェクトをオープンしています http://git.oschina .net /chejiangyi は、スケジュール サービス、構成サービス、監視サービスなどの非常に優れたプロジェクトであり、ある程度の規模のインターネット企業にとって、これらのサービスは .Net に基づいているため、より価値があります。これは、.Net 開発を使用する一部のインターネット企業にとって、優れた参考資料となるためです。

Redola.Rpc http://www.cnblogs.com/gaochundong/p/redola_yet_another_csharp_rpc_framework.html

これは私が最近発見したもので、フレームワークはActorモデルを使用し、シリアル化はprotobuf-netを使用し、送信方法はベースです。 tcp では、tcp フレームワークは独自の Cowboy.WebSockets を使用します。ただし、Actor モデルが理解できないため、ここでは詳しく説明しません。興味のある方は読んでください。著者のブログ。


私が自分で書いたサービスフレームワーク

たくさんのサービスフレームワークを読んだ後、私も自分で一つ書きました。これは単なるサービス呼び出しであり、本質的には参考として使用できます。

フレームワークの原理は Hession と似ています。最初にインターフェイスを定義し、その後サーバーがインターフェイスを実装します。ここでは、Web API のコントローラーにインターフェイスを直接継承させることにしました。リクエストをインターセプトするハンドルを明確に定義する必要がありますが、Web API アクセスには影響しないため、このフレームワークを使用しても、http を使用して直接アクセスできなくなります。クライアントの呼び出し方法も Hession と同様で、プロキシを定義してからパラメータを収集する必要があります

インターフェースの次のステップは Web API を使用します。コントローラーを定義します。このコントローラーでは、APIController を継承するだけでなく、インターフェースの固有のロジックも実装されます。

.NET でのいくつかのサービス フレームワークの紹介

同時に、このインターフェイスが配置されている dll をクライアントにコピーします。 ここでは、.Net に付属するプロキシ クラスであり、Hession で使用されるメカニズムでもある RealProxy という関数を紹介します。

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using Newtonsoft.Json;
using RestSharp;
namespace SimleRPC
{
    public class SimpleProxy : RealProxy
    {
        private readonly Uri _uri;
        public SimpleProxy(Type type, Uri uri) : base(type)
        {
            this._uri = uri;
        }
        public override IMessage Invoke(IMessage msg)
        {
            //msg参数包含调用方法的信息,这里通过封装,使信息更丰富一些
            IMethodCallMessage methodMessage = new MethodCallMessageWrapper((IMethodCallMessage)msg);
            MethodInfo methodInfo = (MethodInfo)methodMessage.MethodBase;
            ParameterInfo[] paramsInfo = methodInfo.GetParameters();  //获取方法调用参数
            //拼装path  类名即controller名, 方法名即action名  这样就表示出具体的url
            string path = "/api/" + methodInfo.DeclaringType.Name + "/" + methodInfo.Name;
            //请求类型,post or get
            bool isHttpGet = methodInfo.CustomAttributes.Any(customAttributeData => customAttributeData.AttributeType.Name == "HttpGetAttribute");
            var client = new RestClient(_uri);
            var request = new RestRequest(path, isHttpGet ? Method.GET : Method.POST);
            //构建参数
            //web api对于传参的一切规则  参考 http://www.cnblogs.com/babycool/p/3922738.html    http://www.cnblogs.com/landeanfen/p/5337072.html 两篇博客
            if (isHttpGet)
            {
                //这里默认get请求的参数都是基本类型
                for (int i = 0; i < paramsInfo.Length; i++)
                {
                    request.AddParameter(paramsInfo[i].Name, methodMessage.Args[i]);
                }
            }
            else
            {
                //对于post请求,要么没有参数(当然基本没有这种情况),要么只有一个参数(这些是受web api的限制)
                if (paramsInfo.Length > 0)
                {
                    request.AddJsonBody(methodMessage.Args[0]);
                }
            }
            // 发送请求 拿到结果
            IRestResponse response = client.Execute(request);
            var content = response.Content;
            Type returnType = methodInfo.ReturnType;     //获取调用方法返回类型,根据类型反序列化结果
            object returnValue;
            if (IsBaseType(returnType))
            {
                returnValue = Convert.ChangeType(content, returnType);
            }
            else
            {
                returnValue = JsonConvert.DeserializeObject(content, returnType); //如果是一个对象,则用json进行反序列化
            }
            return new ReturnMessage(returnValue, methodMessage.Args, methodMessage.ArgCount, methodMessage.LogicalCallContext, methodMessage);
        }
        /// <summary>
        /// 判断是否是基础类型(int long  double), string 是引用类型,但是也归到基础类型里面
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private static bool IsBaseType(Type type)
        {
            if (type == typeof(string) || type.IsPrimitive)
                return true;
            return false;
        }
    }
}
ログイン後にコピー

すべてのメソッド呼び出しは Invoke メソッドを呼び出します。Invoke メソッドでは、パラメーター、戻り値の型など、呼び出しメソッドの特定の情報を取得できます。 次に、リフレクションとアセンブリを通じて、HTTP リクエストが形成されます。ここで、デフォルトのインターフェイス クラス名はコントローラーの名前であり、インターフェイス メソッド名はアクションの名前です。 .NET でのいくつかのサービス フレームワークの紹介

最後に、RestSharp を通じてリクエストを送信します。 最後に、http の結果がメソッドの戻り値に必要な値に逆シリアル化されます。

実際、サーバーにとって、Web API がインターフェースを継承するかどうかは問題ではありません。継承しない場合、インターフェースの署名は Web API のメソッドの署名と一致する必要があります。

.NET でのいくつかのサービス フレームワークの紹介

この方法は、私が書いたデモを通じて調整できます。これに興味がある人は、さらにいくつかの状況をテストできます。

ついに


現在、多くのインターネット企業が独自の RPC フレームワークを持っていますが、その中にはオープンソースのものもあれば、歴史的な問題により独自に作成されたものもあります。通信方法には、HTTP ベースのもの、TCP ベースのもの、および 2 つあります。両方のプロトコルと互換性があります。 シリアル化の方法もいろいろありますが、ここでは 5 つだけ挙げました。実際、github で検索すると、優れた RPC がたくさんあります。


RPC は、プロジェクト開発プロセスの一段階にすぎません。 RPC を使用すると、これに基づいて次のような多くのことを実行できます。


サービス ガバナンス すべてのサービスは、開始時にサービス センターに登録されます。登録センターでは、Nginx などのプロキシを経由せずに直接呼び出して、実際のアドレスを取得する際に、どのクライアントを使用できるか、どのクライアントを使用できるかなどのいくつかの許可制限を設定できます。ここでダボを参照できます。


HTTP リクエスト パス マイクロサービスは現在、非常に人気があります。フロントエンド リクエストは、http ヘッダーに RequestId と RequestIndex を追加して、これらのサービスを結び付けることができます。 B ->C の場合、サービス A がサービス B を呼び出すときに、http ヘッドに RequestId がないことが判明すると、GuId を通じて RequestId を生成でき、RequestIndex が 1 増加します。サービス B がサービス C を呼び出すとき、次の理由により、 RequestId はすでに存在します。直接渡されます。次に、RequestIndex を 1 ずつ増やして、この情報をログに記録します。分析を通じて、呼び出し全体が結合され、サービス全体の呼び出しリンク図が作成されます。完全データで描画可能です。


リンク図に加えて、各サービス呼び出しをインターセプトできるため、リンク図を使用すると、サービス全体の情報がより完全になります。

上記は .NET でのいくつかのサービス フレームワークの紹介です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート