소개
회사에서 서비스를 추가한 후 통화 편의성과 향후 서비스 관리를 위해 몇 가지 서비스 프레임워크를 일반적으로 사용합니다. 여러 서비스 프레임워크를 알고 있습니다. 이러한 서비스 프레임워크의 기본 개념을 간략하게 분석하겠습니다.
생산 환경에 투입 가능
회사에서 다음 두 가지 서비스 프레임워크에 투자하는 것을 본 적이 있습니다. 프로덕션 환경이므로 안정성에 대해 너무 걱정할 필요가 없습니다.
ServiceStack https://github.com/ServiceStack/ServiceStack
ServiceStack은 사용되지 않았을 수 있지만 다른 두 개는 누구나 한 번쯤은 사용해 봤을 구성 요소, ServiceStack.Redis(Redis 액세스 도구), ServiceStack.Text(Json 직렬화 도구), ServiceStack은 서비스 프레임워크로 이를 사용하여 쉽게 서비스를 생성할 수 있으며 서비스는 http를 기반으로 합니다. 또한 클라이언트 호출이 제공되며 데이터 직렬화 방법에는 Json, xml, Binary 및 Protobuf가 포함되며 생성된 서비스에는 특정 설명이 있습니다.
1개의 http 요청에는 요청 경로와 매개변수라는 두 가지 핵심 사항이 있습니다. ServiceStack의 경우 매개변수는 객체입니다. 즉, 전달하려는 매개변수가 캡슐화되어 있습니다. 클래스 내부에 클래스에 레이블을 추가하면 레이블의 내용이 요청 경로이므로 클라이언트가 호출할 때 요청 경로와 매개변수가 반영된 다음 호출이 시작됩니다.
ServiceStack 자체에서 데모를 제공하므로 여기서는 데모를 작성하지 않겠습니다.
Hessian https://sourceforge.net/projects/hessiancsharp/
Hessian은 직렬화 도구이자 서비스 프레임워크입니다. .net을 포함한 여러 언어로 구현을 제공합니다. 이 구성 요소는 .Net 분야에서 그다지 유명하지 않은 것으로 보이며 오랫동안 업데이트되지 않았을 수 있습니다.
Hessian을 사용하는 경우 먼저 인터페이스를 정의한 다음 이를 복제해야 합니다. 서버는 이러한 인터페이스를 구현하고 클라이언트는 RealProxxy 클래스를 프록시로 사용합니다. 프록시 클래스의 Invoke 메서드에서는 호출할 메서드 이름, 매개 변수 및 기타 내용을 Invoke 메서드에서 가져와 직렬화하여 서버의 통합 URL로 전송합니다. 이 URL은 다음으로 끝납니다. hessian이므로 web.config에 있어야 합니다. 요청을 가로채는 핸들을 구성한 후 매개변수를 역직렬화하고 리플렉션을 통해 호출을 시작합니다.
전화 문의는 이 블로그를 참조하세요. http://www.cnblogs.com/lxsfg/archive/2008/08/27/1277777.html
thrift나 JSON-RPC 등 다른 서비스 프레임워크도 많이 있지만 아직 사용해본 적이 없기 때문에 여기서는 언급하지 않겠습니다.
블로그 파크의 일부 서비스 프레임워크
블로그 파크를 탐색하던 중 발견한 프레임워크는 다음 세 가지이며 모두 오픈소스입니다. 서비스 프레임워크는 좋은 프로젝트입니다. 게다가 저는 블로그 파크에 자주 가지 않습니다. 블로그 파크에는 다음 세 가지 프레임워크도 우연히 보았지만 발견하지 못했습니다. 그것들을 찾으면 댓글 영역에 글을 쓰고 모두가 함께 배울 수 있습니다.
Rabbit.Rpc http://www.cnblogs.com/ants/p/5605754.html
Hessin과 다소 비슷하지만 서비스 인터페이스도 먼저 정의됩니다. 그런 다음 서버는 인터페이스를 상속하여 특정 로직을 구현합니다. 클라이언트의 경우 인터페이스의 모든 메소드는 물론 메소드 매개변수 및 반환 값 정보도 리플렉션을 통해 추출한 다음 동적으로 프록시 클래스를 생성하는 코드를 생성합니다. 동적으로 컴파일되어 컨테이너에 저장됩니다. 생성된 프록시 클래스와 관련하여 모든 메서드에는 통합된 구현이 있습니다. 즉, Invoke 메서드를 호출하여 메서드와 매개 변수를 하위 계층으로 보내고 하위 계층 어셈블리를 서버로 보냅니다. 여기서 코드를 생성하는 방법은 더 재미있습니다. 배울 수 있습니다.
또한 이 프레임워크에는 서비스 관리도 통합되어 있습니다. 서비스는 Zookeeper에 등록되며 클라이언트는 Zookeeper를 통해 특정 서비스 주소를 얻어 호출합니다. 실제로 현시점에서는 이는 단순한 서비스 프레임워크가 아니라 서비스 거버넌스 기능도 포함하고 있습니다.
아직 코드를 간략하게 읽었을 뿐 자세한 내용을 이해하지는 못했습니다. 더 알고 싶으시면 소스코드를 읽어보시면 됩니다.
Dyd.BaseService.ServiceCenter http://git.oschina.net/chejiangyi/Dyd.BaseService.ServiceCenter
기본을 보세요 소개 모든 기능을 사용할 수 있지만, 이 프로젝트에 대한 저자의 소개에 따르면 이 프로젝트는 연구 기반이라고 합니다. 서비스를 호출하는 클라이언트도 코드를 통해 생성됩니다.
그리고 이 블로거에 대해 좀 더 소개하겠습니다. 그는 블로그 정원 http://www.cnblogs.com/chejiangyi/에도 블로그
를 운영하고 있으며 여러 개를 오픈했습니다. 그 아래의 오픈 소스 프로젝트 http://www.cnblogs.com/chejiangyi/ ://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과 유사합니다. 먼저 인터페이스를 정의한 다음 서버측에서 인터페이스를 구현해야 합니다. 여기서는 웹에서 컨트롤러를 직접 사용하도록 했습니다. API는 인터페이스를 상속하므로 특별히 정의할 필요가 없습니다. 핸들은 Web Api 액세스에 영향을 주지 않고 요청을 가로채는 데 사용되므로 이 프레임워크를 사용하더라도 http를 통해 직접 액세스하는 데 방해가 되지 않습니다. 클라이언트 호출 방법도 Hession과 유사하며,
먼저 인터페이스를 정의
합니다. 인터페이스의 다음 단계는 이를 구현하는 것입니다. 여기서는 Controller를 정의합니다. APIController를 상속하는 것 외에도 이 Controller에서는 인터페이스의 특정 논리를 구현합니다.
동시에 이 인터페이스가 있는 dll을 클라이언트에 복사합니다. 여기서는 RealProxy라는 함수를 소개합니다. .Net과 함께 사용되며 Hession 메커니즘에서도 사용됩니다.
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 요청이 형성됩니다. 여기서 기본 인터페이스 클래스 이름은 컨트롤러 이름이고 인터페이스 메서드 이름은 작업 이름입니다.
마지막으로 RestSharp를 통해 요청을 보냅니다. 마지막으로 http 결과는 메서드 반환 값에 필요한 값으로 역직렬화됩니다.
사실 서버의 경우 Web API가 인터페이스를 상속하는지 여부는 중요하지 않습니다. 그렇지 않은 경우 인터페이스의 서명은 서버의 서명과 일치해야 합니다. 웹 API의 메서드입니다.
제가 작성한 데모를 통해 방법을 조정할 수 있습니다. 이에 관심이 있는 분은 몇 가지 상황을 더 테스트해 볼 수 있습니다.
드디어
현재 많은 인터넷 기업들이 자체적인 RPC 프레임워크를 가지고 있는데, 그 중 일부는 오픈소스이고, 일부는 역사적인 문제로 인해 스스로 작성한 것이기도 합니다. 통신 방식으로는 Http 기반의 것도 있고, TCP 기반의 것도 있고, 두 프로토콜 모두 호환됩니다. 직렬화 방법도 다양합니다. 실제로 github에서 검색해 보면 훌륭한 RPC가 많이 있습니다.
RPC는 프로젝트 개발 과정의 한 단계일 뿐입니다. RPC를 사용하면 이를 기반으로 다음과 같은 많은 작업을 수행할 수 있습니다.
모든 서비스는 시작 시 서비스 센터에 등록되며, 클라이언트가 시작됩니다. 등록 센터에서 실제 주소를 가져올 때 Nginx와 같은 프록시를 거치지 않고 직접 호출합니다. 여기에서는 어떤 클라이언트를 사용할 수 있는지, 어떤 클라이언트를 사용할 수 없는지와 같이 실제 주소를 가져오는 데 몇 가지 권한 제한을 설정할 수 있습니다. 사용 가능한 클라이언트 수는 여기에서 확인할 수 있습니다.
현재 마이크로서비스는 매우 인기가 높습니다. 프런트엔드 요청은 여러 백엔드 서비스를 거칠 수 있으며, HTTP 헤더에 RequestId 및 RequestIndex를 추가할 수 있습니다. 예를 들어 A->B->C와 같이 이러한 서비스를 연결합니다. 서비스 A가 서비스 B를 호출할 때 http 헤드에 RequestId가 없는 것으로 확인되면 GuId를 통해 생성될 수 있으며 RequestIndex는 B가 서비스 C를 호출하면 RequestId가 이미 존재하므로 바로 전달되고, RequestIndex는 1 증가된다. 이 정보는 로그에 기록되며, 분석을 통해 전체 호출을 하나로 묶는다. 전체 데이터를 통해 전체 서비스의 통화 링크 다이어그램을 그릴 수 있습니다.
링크 다이어그램 외에도 각 서비스 호출을 차단할 수 있기 때문에 서비스 호출 시간을 기록할 수 있으며 링크 다이어그램과 함께 전체 서비스에 대한 정보는 다음과 같습니다. 더 완벽합니다.
위는 .NET의 여러 서비스 프레임워크에 대한 소개입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!