donet 微服务开发 学习-consul 消费端开发
donet 微服务开发 学习-consul 消费端开发
- 目的介绍
- 编写服务消费者
- 创建类库RestTools
- 编写控制台进行消费
- 测试结果:
- 简化服务的注册
目的介绍
donet 微服务开发 学习
编写服务消费者
创建类库RestTools
创建消息返回类ResponseEntity.cs
public class ResponseEntity<T>
{/// <summary>/// 返回状态码/// </summary>public HttpStatusCode StatusCode { get; set; }/// <summary>/// 返回的json反序列化出来的对象/// </summary>public T Body { get; set; }/// <summary>/// 响应的报文头/// </summary>public HttpResponseHeader Headers { get; set; }
}
创建转发消息类RestTemplate.cs
public class RestTemplate
{private String consulServerUrl;public RestTemplate(String consulServerUrl){this.consulServerUrl = consulServerUrl;}/// <summary>/// 获取服务的一个IP地址/// </summary>/// <param name="serviceName">consul服务IP</param>/// <returns></returns>private async Task<String> ResolveRootUrlAsync(String serviceName){using (var consulClient = new ConsulClient(c => c.Address = new Uri(consulServerUrl))){var services = (await consulClient.Agent.Services()).Response;var agentServices = services.Where(s => s.Value.Service.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase)).Select(s => s.Value);//TODO:注入负载均衡策略var agentService = agentServices.ElementAt(Environment.TickCount % agentServices.Count());//根据当前TickCount对服务器个数取模,“随机”取一个机器出来,避免“轮询”的负载均衡策略需要计数加锁问题return agentService.Address + ":" + agentService.Port;}}/// <summary>/// //把http://apiservice1/api/values转换为http://192.168.1.1:5000/api/values/// </summary>private async Task<String> ResolveUrlAsync(String url){Uri uri = new Uri(url);String serviceName = uri.Host;//apiservice1String realRootUrl = await ResolveRootUrlAsync(serviceName);return uri.Scheme + "://" + realRootUrl + uri.PathAndQuery;}/// <summary>/// Get请求转换/// </summary>/// <typeparam name="T"></typeparam>/// <param name="url">请求地址</param>/// <param name="requestHeaders">请求头</param>/// <returns></returns>public async Task<ResponseEntity<T>> GetForEntityAsync<T>(String url, HttpRequestHeaders requestHeaders = null){using (HttpClient httpClient=new HttpClient()){HttpRequestMessage requestMsg = new HttpRequestMessage();if (requestHeaders!=null){foreach (var header in requestHeaders){httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);}}requestMsg.Method = HttpMethod.Get;//http://apiservice1/api/values转换为http://192.168.1.1:5000/api/valuesrequestMsg.RequestUri = new Uri(await ResolveUrlAsync(url));var result = await httpClient.SendAsync(requestMsg);ResponseEntity<T> responseEntity = new ResponseEntity<T>();responseEntity.StatusCode = result.StatusCode;String bodyStr = await result.Content.ReadAsStringAsync();responseEntity.Body = JsonConvert.DeserializeObject<T>(bodyStr);responseEntity.Headers = responseEntity.Headers;return responseEntity;}}
}
编写控制台进行消费
static void Main(string[] args)
{RestTemplate rest = new RestTemplate("http://127.0.0.1:8500");//RestTemplate把服务的解析和发请求以及响应反序列化帮我们完成ResponseEntity<String[]> resp = rest.GetForEntityAsync<String[]>("http://apiservice1/api/values").Result;Console.WriteLine(resp.StatusCode);Console.WriteLine(String.Join(",",resp.Body));Console.ReadKey();
}
测试结果:
简化服务的注册
每次启动、注册服务都要指定一个端口,本地测试集群的时候可能要启动多个实例,很麻烦.
在ASP. Net Core中只要设定端口为0,那么服务器会随机找一个可用的端口绑定(测试一下).,但是没有找到读取到这个随机端口号的方法.因此自己写:
新建Tools.cs工具类
public class Tools
{/// <summary>/// 产生一个介于minPort-maxPort之间的随机可用端口/// </summary>/// <param name="minPort"></param>/// <param name="maxPort"></param>/// <returns></returns>public static int GetRandAvailablePort(int minPort = 1024, int maxPort = 65535){Random r = new Random();while (true){int port = r.Next(minPort, maxPort);if (!IsPortInUsed(port)){return port;}}}/// <summary>/// 判断port端口是否在使用中/// </summary>/// <param name="port"></param>/// <returns></returns>private static bool IsPortInUsed(int port){IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();IPEndPoint[] ipsTCP = ipGlobalProperties.GetActiveTcpListeners();if (ipsTCP.Any(p=>p.Port==port)){return true;}IPEndPoint[] ipsUDP = ipGlobalProperties.GetActiveUdpListeners();if (ipsUDP.Any(p=>p.Port==port)){return true;}TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();if (tcpConnInfoArray.Any(conn=>conn.LocalEndPoint.Port==port)){return true;}return false;}
}
使用方法
public static IWebHost BuildWebHost(string[] args)
{var config = new ConfigurationBuilder().AddCommandLine(args).Build();String ip = config["ip"];String port = config["port"];if (port=="0"){port = Tools.GetRandAvailablePort().ToString();}return WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().UseUrls($"http://{ip}:{port}").Build();
}
在程序启动的时候如果port=0或者没有指定port,则自己调用GetRandAvailablePort获取可用端口。
donet 微服务开发 学习-consul 消费端开发相关推荐
- donet 微服务开发 学习-Docker环境搭建 win7 docker 环境配置
donet 微服务开发 学习-Docker环境搭建 win7 docker 环境配置 目的介绍 下载安装 安装 Docker Quickstart Terminal 目的介绍 donet 微服务开发 ...
- SpringCloud微服务架构学习(二)常见的微服务架构
SpringCloud微服务架构学习(二)常见的微服务架构 1.Dubbo 阿里开源微服务框架 官网地址:http://dubbo.apache.org/en-us/ 简介: Dubbo是阿里巴巴SO ...
- Spring clud 微服务框架学习
Spring clud 微服务框架学习 什么是微服务? 微服务是一种架构风格:服务组件化.业务分离让每个模块独立.服务跟服务之间接口调用,服务之间不会相互影响.轻量级通信机制:接口调用很快. 微服务的 ...
- kratos mysql_kratos微服务框架学习笔记一(kratos-demo)
本文将为您描述kratos微服务框架学习笔记一(kratos-demo),教程操作步骤: 目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服 ...
- 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存
文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...
- GraphQL 渐进学习 09-graphql-apollo-client-vue-客户端开发
GraphQL 渐进学习 09-graphql-apollo-client-vue-客户端开发 软件环境 vue > 2.5.x 目标 创建 graphql 客户端 封装请求处理 基于 toke ...
- 微服务架构学习与思考(05):微服务架构适用场景分析
一.简述 在实际开发中,需要考虑多种因素,来决定采取哪种架构模式才适合当前业务发展情况. 毕竟微服务也不能"包治百病",不要把它当做万能药.企业研发哪里得病了,觉得只要把" ...
- Polyworks脚本开发学习笔记(十)-互动式开发及出错控制
Polyworks脚本开发学习笔记(十)-互动式开发及出错控制 第八章组合的各种命令,完成了一个对所选的测点名称进行命名的任务.但是,由于任务中没有交互环节,只能机械地将 曲面点 - 包边点改为Flu ...
- Polyworks脚本开发学习笔记(一)-脚本开发环境
Polyworks脚本开发学习笔记(一)-脚本开发环境 背景 Polyworks的扫描尺寸测量分析模块是我工作中经常用到的一个模块,我不是做测量的,但是利用Polyworks对扫描获得的点云来进行尺寸 ...
- 【JAVA微服务架构项目前后端分离开发-MyMooc教育在线学习平台】
类似于中国Mooc的在线学习平台 文章目录 类似于中国Mooc的在线学习平台 一.项目描述 二.后台管理员系统细讲 三.前台用户系统细讲 四.前端技术点总结 五.后端技术点总结 六.遇到问题及解决方法 ...
最新文章
- python 中 if __name__ == '__main__' 判断的作用
- BZOJ 1711: [Usaco2007 Open]Dining吃饭
- Android ViewPager和Fragment实现顶部导航界面滑动效果
- 远控免杀专题(23)-SharpShooter免杀
- 四则运算题目生成程序(基于控制台)
- OAM创始团队:揭秘OAMKubernetes实现核心原理
- mysql 视图 局部变量_mysql创建视图和存储过程,变量
- 字符串:1.存储结构
- java配置testng_如何使用TestNG JAVA Reflection设置测试方法执行的优先级
- .NET网络编程学习(一)
- 软件设计 -- 流程图的重要性
- python编程语言-初学者最容易学的六种编程语言
- 问题六十三:怎么用ray tracing画sphere sweeping图形
- 【xpath】多个xpath Element对象,提取结果是一样的
- Intellij Idea 主题下载(Eclectide Monokai)
- Centos校准时间
- 怎么样才能进入BAT公司的研发部门
- 基于51单片机的DAC0832波形发生器
- Idea 合并分支只选取部分文件的办法
- Python代码实现中国日报网双语文章订阅至邮箱