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的简单好多,没有依赖。

  • 相关阅读:
    1104 Sum of Number Segments (20 分)(数学问题)
    1092 To Buy or Not to Buy (20 分)(hash散列)
    1082 Read Number in Chinese (25 分)(字符串处理)【背】
    1105 Spiral Matrix (25 分)(模拟)
    初识网络安全及搭建网站(内网)
    HTML5开发者需要了解的技巧和工具汇总(转)
    native+web开发模式之web前端经验分享
    移动平台3G手机网站前端开发布局技巧汇总(转)
    Asp.net 中图片存储数据库以及页面读取显示通用方法详解附源码下载
    使用H3Viewer来查看VS2010的帮助文档
  • 原文地址:https://www.cnblogs.com/kokyu02/p/12500485.html
Copyright © 2011-2022 走看看