zoukankan      html  css  js  c++  java
  • .NET Core 服务调用 RPC

    一、REST & RPC

      微服务之间的接口调用通常包含两个部分,序列化和通信协议。

      常见的序列化协议包括json、xml、hession(二进制序列化 + http协议)、protobuf、text、bytes等;

      通信比较流行的是http、soap、websockect、TCP,RPC通常基于TCP实现,常用框架例如Dubbo,Netty、Spring Cloud、Thrift、gRpc。

    附:TCP、HTTP协议的区别:https://www.jianshu.com/p/f4db4eb065bd

      REST:

      严格意义上说接口很规范,操作对象即为资源,对资源的四种操作(post、get、put、delete),并且参数都放在URL上,但是不严格的说Http+json、Http+xml,常见的http api都可以称为Rest接口。采用 Http 进行通讯,优点是开放、标准、简单、兼容性升级容易。

      RPC:

      即我们常说的远程过程调用,就是像调用本地方法一样调用远程方法,通信协议大多采用二进制方式。RPC 虽然效率略高,但是耦合性强,如果兼容性处理不好的话,一旦服务器端接口升级,客户端就要更新,即使是增加一个参数,而 rest 则比较灵活。

      最佳实践:

      对内一些性能要求高的场景用 RPC,对内其他场景以及对外用 Rest。比如付款接口用 RPC 性能会更高一些。 

    二、REST实例

    在Controller中调用实例:

        [Route("api/[controller]")]
        [ApiController]
        public class AreaController : ControllerBase
        {
    
            private readonly IBasAreService _AreaService;
    
            public AreaController(IBasAreService AreaService)
            {
                _AreaService = AreaService;
            }
    
            // GET api/values
            /// <summary>
            /// 取所有的省份
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public async Task<IEnumerable<BasAreaDto>> GetAreasAsync()
            {
                return  await _AreaService.GetAreaByParentCode("-1");
            }
    
            // GET api/area/H
            [Route("{fcode}")]
            [HttpGet]
            [ProducesResponseType((int)HttpStatusCode.OK)]
            public async Task<ActionResult<IEnumerable<BasAreaDto>>> GetAreaByParentCode(string fcode)
            {
                if (string.IsNullOrEmpty(fcode))
                {
                    return BadRequest();
                }
                var item = await _AreaService.GetAreaByParentCode(fcode);
    
                if (item != null)
                {
                    return item;
                }
    
                return NotFound();
            }
      ……

    三、RPC实例

      Thrift 【θrɪft】 是apache的,可以构建28种语言包括C#,可以无缝结合、高效服务。也可以使用gRpc,不过从网上的性能对比来看,Thrift性能要优于gRpc 2倍以上。对比参考文章:https://yq.aliyun.com/articles/268867

      3.1 Thrift的实例

      1)下载Thrigt,地址:http://thrift.apache.org/download

       根据网上说的,解压之后修改名为thrift.exe,因为这样方便点,后面要敲命令行的。

      2)编写一个xxx.thrift文件,这是他的中间语言

      

    namespace csharp Blake.Test.Contracts
    
    service PaymentService { 
        TrxnResult Save(1:TrxnRecord trxn) 
    }
    
    enum TrxnResult { 
        SUCCESS = 0, 
        FAILED = 1, 
    }
    
    struct TrxnRecord { 
        1: required i64 TrxnId; 
        2: required string TrxnName; 
        3: required i32 TrxnAmount; 
        4: required string TrxnType; 
        5: optional string Remark; 
    }
    

      执行命令行操作,如果发现录入命令时机器上无法操作,我重新下载一个就好了。

    thrift.exe -gen csharp TestRpcService.thrift

       3)创建三个项目,一个类库,一个client控制台,一个Service控制台。为了图省事,大家别见笑。

      

       a)服务端的实现代码

      

        public class PaymentServiceImpl : PaymentService.Iface
        {
            public TrxnResult Save(TrxnRecord trxn)
            {
                
                Console.WriteLine("Log : TrxnName:{0}, TrxnAmount:{1}, Remark:{2}", trxn.TrxnName, trxn.TrxnAmount, trxn.Remark);
                return TrxnResult.SUCCESS;
            }
        }
    class Program
        {
            private const int port = 8885;
    
            static void Main(string[] args)
            {
                Console.WriteLine("[Welcome] PaymentService RPC Server is lanuched...");
                TServerTransport transport = new TServerSocket(port);
                var processor = new PaymentService.Processor(new PaymentServiceImpl());
                TServer server = new TThreadedServer(processor, transport);
                // lanuch
                server.Serve();
            }
        }

      b)客户端代码

            static void Main(string[] args)
            {
                TestMethod();
                Console.ReadLine();
            }
    
            private static void TestMethod()
            {
                using (TTransport transport = new TSocket("localhost", 8885))
                {
                    using (TProtocol protocol = new TBinaryProtocol(transport))
                    {
                        using (var serviceClient = new PaymentService.Client(protocol))
                        {
                            transport.Open();
                            TrxnRecord record = new TrxnRecord
                            {
                                TrxnId = 123123123,
                                TrxnName = "Blake",
                                TrxnAmount = 12,
                                TrxnType = "",
                                Remark = "已付款成功!"
                            };
                            var result = serviceClient.Save(record);
    
                            Console.WriteLine($"结果为: {result}");
    
                        }
                    }
                }
            }    

      c)执行结果

       因为我用的net core3.1,一开始应用包除了问题,后来搜到apache-thrift-netcore。

    四、总结

      该文章主要是介绍一个RPC和REST的区别和应用场景,同时简单的介绍一下Thrift的使用。这样就可以从代码看出REST的简单好多,没有依赖。

  • 相关阅读:
    基于 Android NDK 的学习之旅-----序言
    音乐播放时跳动的音符
    WebView中实现文件下载功能
    Android组件——使用DrawerLayout仿网易新闻v4.4侧滑菜单
    android webview中的音乐的暂停与播放
    Android 使用Fragment界面向下跳转并一级级返回
    Fragment使用LocalBroadcastManager接收广播消息
    android WebView总 结
    解决方式:QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins
    Android学习十九:ContentProvider初步
  • 原文地址:https://www.cnblogs.com/kokyu02/p/12500485.html
Copyright © 2011-2022 走看看