护士节快乐

众所周知,微服务架构是由一众微服务组成,项目中调用其他微服务接口更是常见的操作。为了便于调用外部接口,我们的常用思路一般都是封装一个外部接口的客户端,使用时候直接调用相应的方法。webservice或WCF的做法就是引用服务,自动生成客户端。在webapi2.0里,我们都会手动封装一个静态类。那么在.netcore3.1的微服务时代,我们该如何处理这个问题呢?----思路都是一样的,封装一个外部服务,并且使用依赖注入和 HttpFactory工厂等.netcore特有的方式提升性能。接下来我们一步一步说下详细的步骤:

第1步:--创建项目

为了便于构建生成nuget包,我们一般都每个外部服务创建一个独立的项目;如下图:

在解决方案里,我们创建了一个项目名为:"MuXue.Zyiz.Template.OuterClient",(项目起名一般为 公司名.部门名.项目名.xxx)。

第2步:创建一个IServiceCollection扩展服务,便于将服务注册信息。(重点)

    public static  class MsgApiClientServiceCollectionExtensions    {public static IServiceCollection AddMsgApiClient(this IServiceCollection services, IConfiguration MsgClientConfiguration)        {            services.Configure(MsgClientConfiguration)                    .AddHttpClient()                    .ConfigureHttpClient(config=> {                        config.BaseAddress = new Uri(MsgClientConfiguration.GetSection("url").Value);                        config.Timeout = TimeSpan.FromSeconds(30);                        });return services;        }    }

该段代码虽然很短,但是最关键的部分:

代码的执行过程如下:

(1)  services首先注册一个操作配置文件的实例 :

services.Configure(MsgClientConfiguration)

(2) 添加HttpClientFactory工厂并且关联到services里,并将Client强制类型为IMsgApiClient(自定义的外部微服务接口名称) :

.AddHttpClient();//IMsgApiClient为接下来要创建的客户端

(3)设置HttpClient的相关配置参数:

 .ConfigureHttpClient(config=> {                        config.BaseAddress = new Uri(MsgClientConfiguration.GetSection("url").Value);//外部微服务接口域名                        config.Timeout = TimeSpan.FromSeconds(30);  // 接口调用超时时间                        });

还有如下注意点:

(1)以静态类和静态方法方式;

(2) this IServiceCollection services ,这个参数我就不多解释了。

(3) 一般我们都需要读取appsettings.json配置文件里的参数所以这里接收了一个参数---IConfiguration MsgClientConfiguration  ;当然如果你不需要读取配置参数,也可以忽略这个参数;

第3步:写外部接口调用的具体逻辑代码:

(1)创建一个接口,比如IMsgApiClient

 /// /// 企业微信消息发送客户端/// public interface IMsgApiClient    {/// /// 调用接口接口:向微信发送消息/// /// hrcode,多个以|隔开/// 消息内容///         Taskstring>> SendWxWorkMsgAsync(string hrcodeStr, string msg);    }

(2)实现该接口:

  /// /// 调用外部接口:向SD发送消息/// /// hrcode,多个以|隔开/// 消息内容/// public async Taskstring>> SendWxWorkMsgAsync(string hrcodeStr, string msg)        {            Result<string> result = new Result<string>();string funName = "【调用外部接口:微信企业消息推送接口】";try            {//具体的业务逻辑---根据自身业务来写                MsgApiResult sendRet = await ZyizHttpClientExtensions.PostData>(_client, _logger, "/api/weixin/work/messages/send", msgReq);if (sendRet != null)                {                    _logger.LogInformation($"{funName},{hrcodeStr}推送消息成功");                    result.state = true;                    result.data = sendRet.Return_data.MessageId;                }else                {                    result.state = false;                    result.error_msg = sendRet.Return_msg;                    _logger.LogError($"{funName}:{hrcodeStr}推送消息失败:{sendRet.Return_msg}");                }            }catch (Exception ex)            {                result.state = false;                result.error_code = ErrorCode.OuterApiError;                result.error_msg = funName + "调用外部接口异常:。" + ex.Message;                _logger.LogError(ex, $"{funName}向{hrcodeStr}推送消息处理异常:{ex.Message}");            }return result;        }

针对HttpClient的Post方法我特意封装了一个通用方法,如下:(可以根据自身项目自行改造)

 /// /// HttpClient扩展方法/// public class ZyizHttpClientExtensions    {/// /// httpclient-post方法的简单处理,封装成一个方法,便于调用/// /// /// /// /// http://xxx.com/后面之后的地址/// 一个对象/// /// /// public async static  Task PostData(HttpClient _client, ILogger _logger,string actionUrl, dynamic param, string ContentType = "application/json", string BearerToken = "")        {string funName = "PostData";string paramStr = JsonConvert.SerializeObject(param);string jrclientguid = Guid.NewGuid().ToString("n");try            {                _logger.LogInformation($"{funName}开始,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---------");                HttpResponseMessage response;using (HttpContent httpContent = new StringContent(paramStr, Encoding.UTF8))                {if (!string.IsNullOrWhiteSpace(BearerToken))                    {                        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", BearerToken);                    }                    httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType);                    response = await _client.PostAsync(actionUrl, httpContent);                }if (response != null && response.IsSuccessStatusCode)                {                    Type t = typeof(T);if (typeof(T) == typeof(string))                    {string respStr = await response.Content.ReadAsStringAsync();return (T)Convert.ChangeType(respStr, typeof(T));                    }else                    {string respStr = response.Content.ReadAsStringAsync().Result;                        T resp = JsonConvert.DeserializeObject(respStr);return resp;                    }                }else                {return default(T);                }            }catch (Exception ex)            {                _logger.LogError(ex,$"{funName}报错啦,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---,ex={ex.Message}" );throw;            }finally            {                _logger.LogInformation($"{funName}结束,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---------");            }        }    }

第4步:将服务注入容器:代码在Startup类的ConfigureServices方法里:

 services.AddZyizMVC(Env)               .AddZyizDbContext(Configuration).AddMsgApiClient(Configuration.GetSection(nameof(MsgApiClient)))//就是这行

第5步:使用:在Controller或其他地方都可以使用;

(1)首先在构造函数里注册:

  private readonly ILogger _logger;private IMsgApiClient _IMsgApiClient;public HealthController(ILogger logger,    IMsgApiClient iMsgApiClient)        {            _logger = logger;            _IMsgApiClient = iMsgApiClient;        }

(2)调用方法:

/// /// 发消息/// ///         [HttpGet]public async Taskstring>> POk()        {            Result<string> result = new Result<string>();            result = await _IMsgApiClient.SendWxWorkMsgAsync("100001002", "我是沐雪,请明天来我办公室一趟!");//result.state = true;//result.data = "连接成功";return result;        }

END

往期经典回顾

【知识点】C#语言基础原理及优缺点.NET Core中Quartz.NET的依赖注入.NetCore + Docker在Windows系统中的安装与部署在.NetCore中实现流式大文件上传

httpclient依赖_.NetCore 3.1高性能微服务架构:封装调用外部服务的接口方法HttpClient客户端思路分析...相关推荐

  1. 什么是微服务架构?什么是服务注册与服务发现?

    文章目录 基础名词 分布式 高可用 集群 什么是微服务 服务注册与服务发现 SpringCloud Alibaba 服务关系以及调用关系 服务注册中心 Nacos服务发现的领域模型 Nacos元数据 ...

  2. Spring Cloud构建微服务架构(五)服务网关

    通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: alt 我们使用Spring Cloud Netflix中的Eureka实 ...

  3. 微服务架构下,解决数据库跨库查询的一些思路

    开局先总结一下:现在很多厂都进行了微服务的开发模式,但是呢,业务的拆分的时候如果存在交叉是一件非常头大的事情,所以大家写微服务尽量不要交叉的写,比如新增用户如果已经存在在userservice里面了那 ...

  4. 微服务跨数据库联合查询_微服务架构下,解决数据库跨库查询的一些思路

    加关注,不迷路! 前言 在服务做微服务改造后,原先单库join查询已经不能满足要求,每个拆分的微服务对应一个数据库实例,而且部署在不同的服务器上,那么解决"跨库查询"就势在必行了. ...

  5. Spring Cloud构建微服务架构(一)服务注册与发现

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  6. Spring Cloud Alibaba 系统保护:微服务架构雪崩效应与服务限流

    前面我们介绍了 OpenFeign 微服务间通信与 Spring Cloud Gateway 网关通信,这些是日常业务中的正常处理情况,但是在微服务环境下受制于网络.机器性能.算法.程序各方面影响,运 ...

  7. Spring Cloud构建微服务架构(二)服务消费者

    Ribbon Ribbon是一个基于HTTP和TCP客户端的负载均衡器.Feign中也使用Ribbon,后续会介绍Feign的使用. Ribbon可以在通过客户端中配置的ribbonServerLis ...

  8. 保利管道微服务1_.netcore 3.1高性能微服务架构:webapi规范

    点击上方蓝字一起上车吧- 1 01 定义 1.基础接口:单一职责原则,每个接口只负责各自的业务,下接db,通用性强. 2.聚合接口:根据调用方需求聚合基础接口数据,业务性强. 1 02 协议 1. 客 ...

  9. Spring Cloud搭建微服务架构----使用Zipkin做服务链路追踪

    2019独角兽企业重金招聘Python工程师标准>>> 实例主要有三个工程组成: Server-zipkin:通过ZipkinServer功能,实现收集调用数据,展示: Servic ...

最新文章

  1. reshape功能介绍_函数 reshape 的用法
  2. 目前的Android恶意软件分类
  3. hdu4998 旋转坐标系
  4. ActionT和FuncT委托
  5. 不服来战!青藤发起“雷火引擎”公测赛 百万赏金寻顶尖白帽
  6. 伺服驱动器生产文件_直流伺服系统的组成和控制原理详解
  7. 真正解决ASP.NET每一个页面首次访问超级慢的问题 (转载)
  8. 江苏省计算机二级用英语,江苏省计算机二级考试(VB)最新大纲及要求(国外英语资料).doc...
  9. Datalogic得利捷引领工业4.0时代 携SG4 FIELDBUS安全光幕亮相两大国际工业展
  10. 关于epub格式电子书和PC上的ePub阅读器...
  11. 【电力拖动自动控制系统】感应/异步电机动态模型完全手把手推导
  12. matlab解微分方程例子,MATLAB解微分方程 [轉] | 學步園
  13. 当你在进行SDK安装更新时,遇到了一些不能安装的项目时,你可以酱紫····
  14. 使用PRSice进行多基因风险评分分析
  15. 分布式配置中心设计——思维导图总结
  16. 费纸箱手工制作机器人_如何DIY用纸盒制作机器人方法图解
  17. frl啥意思_轻钢笔记《FRL60/60/60是什么意思?》
  18. 设置移动光猫外置路由器(上网+iptv正常使用)
  19. 走出软件作坊:三五个人十来条枪 如何成为开发正规军 链接[收藏]
  20. 计算机联锁里面的熔断器,TYJL-Ⅱ型计算机联锁故障分析与处理

热门文章

  1. 布朗的计算机排名,布朗大学计算机工程硕士排名第26(2020年TFE Times排名)
  2. wpf tabcontrol嵌套自动跳转上层_Python Selenium包应对嵌套网页的方法和简单 js 脚本运行的实现...
  3. 达梦数据库代码导出_达梦数据库常见问题-命令行工具-导入导出工具
  4. 鸿蒙JSFA 使用 WebView
  5. apm飞控制作_传统直接转矩控制
  6. scrapy保存、中断、继续执行爬虫程序
  7. jupyter lab插件无法打开,且报错Error: 500 (Internal Server Error)
  8. 反转dataframe
  9. python实现字符串匹配算法BF,BF改,KMP
  10. jmeter java 关联_使用Jmeter进行数据关联和并发用户