zoukankan      html  css  js  c++  java
  • 让分布式远程调用优雅些

    现在的系统越来越庞大复杂,对系统进行拆分,让各个独立模块各干各的事,已经是现有大型系统普遍采用的解决方案,美其名曰SOA,说的狭窄一点,就是原来是本地调用的,现在变成了远程调用,于是乎,各种远程调用的方案冒出来了,Remoting、WCF、REST等等,这些名词的堆积起来,让开发者有点不知所然,要花很多时间去理解和消化这些概念,而对于真正的业务编码却花不了这么多时间;为何不让这些细节隐藏起来,让远程调用如同本地调用一样方便简单呢?让中间的细节,比如通讯方式是TCP还是HTTP,序列化是SOAP还是JSON,性能效率、负载均衡等等问题,都交给架构师、框架设计师去处理吧,我们只需要关心自己的业务实现就可以,这个愿望很简单吧。

    我们设想有这么个服务,我们把它看成是.NET里的接口, 如下代码所示:

    1 namespace ClassLibrary1
    2 {
    3     public interface IClassService
    4     {
    5         string HelloWorld();
    6     }
    7 }  

    这个接口定义在ClassLibrary1.dll中,我们期望这么去调用:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using ClassLibrary1;
     5 using HTB.DevFx.Esb;
     6 
     7 namespace ConsoleApplication2
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args) {
    12             var svr = ServiceLocator.GetService<IClassService>();
    13             Console.WriteLine(svr.HelloWorld());
    14             Console.ReadLine();
    15         }
    16     }
    17 }

    以上代码定义在ConsoleApplication2.exe中。是不是很简单,我们是调用者,没必要关心谁是接口的实现者,交给IoC好了。至于这返回的svr是远程对象还是本地对象,我们更无需关心了。只管调用好了。

    当然了,在具体运行时,总该有一个实现者来实现接口吧,但以上代码找不到谁实现了这个接口。我们把实现这个接口的代码定义在CosoleApplication1.exe中,如下:

     1 using System;
     2 using ClassLibrary1;
     3 using HTB.DevFx.Remoting;
     4 
     5 namespace ConsoleApplication1
     6 {
     7     class Program
     8     {
     9         static void Main(string[] args) {
    10             RemotingHelper.RemotingServiceInitialize();
    11             Console.WriteLine("Ready....");
    12             Console.ReadLine();
    13         }
    14     }
    15 
    16     internal class ClassServiceInternal : IClassService
    17     {
    18         public string HelloWorld() {
    19             return DateTime.Now.ToString();
    20         }
    21     }
    22 }

     看,我们有一个实现,而且是internal的,这里稍微解释下Main函数里做的事情,就是让ClassServiceInternal以服务的形式发布出去,更具体的留待后文解释。

    好了,我们现在有实现者了,那怎么让调用者调用我们的实现者呢,总不能让ConsoleApplication2.exe引用ConsoleApplication1.exe吧,再说了,实现类是internal的,引用了也不能直接调用。既然IClassService都已经按服务的方式发布出去了,我们只需要远程调用就可以啦,让IoC帮我们吧,我们期望我们的IoC配置也需要尽量简单,所以在ConsoleApplication2.exe.config中,我们配置如下:

     1 <?xml version="1.0"?>
     2 <configuration>
     3     <configSections>
     4         <section name="htb.devfx" type="HTB.DevFx.Config.ConfigSectionHandler, HTB.DevFx.BaseFx" />
     5     </configSections>
     6 
     7     <htb.devfx>
     8         <objects configSet="{tag:'object'}">
     9             <object name="ClassServiceClient" type="ClassLibrary1.IClassService, ClassLibrary1" mapTo="http://localhost:8296/classService.rem" builder="@RemotingObjectBuilder" />
    10         </objects>
    11     </htb.devfx>
    12 </configuration>

    如上配置,我们期望我们的接口IClassService映射到远程服务接口http://localhost:8296/classService.rem上,这个远程地址是ConsoleApplication1.exe发布出去的。很直观很简单。当然,我们可以把它映射成本地实现,比如本地的Mock实现,这样有利于单元测试和同步开发。

    以上均得益于基于配置的IoC框架DevFx,DevFx让我们调用服务如此简单(是不是有广告的嫌疑?) 

    具体原理留待后文讲解。

    以上代码下载:测试代码 

    有关DevFx的更多细节:http://devfx.codeplex.com/ 

  • 相关阅读:
    Tensorflow源码解析2 -- 前后端连接的桥梁
    Tensorflow源码解析1 -- 内核架构和源码结构
    Python保存json文件并格式化
    如何在没有https环境下使用webrtc
    github提交代码不用输入账号密码的解决方案
    使用nodeJs在本地搭建最简单的服务
    ubuntu16.04 安装 nginx 服务器
    git pull和git pull --rebase的使用
    Linux 下各个目录的作用及内容
    阿里云服务器(Ubuntu16.04 64位)远程连接
  • 原文地址:https://www.cnblogs.com/R2/p/2244236.html
Copyright © 2011-2022 走看看