Consul 学习笔记—服务发现
前言:
上一篇文章简单实用Consul试下服务注册,本篇继续学习Consul中的另外特性:服务发现、KV操作 ;以及对上篇文章中存在的问题进行解决
问题解决
在上一篇文章中,注册服务提示检查失败。
通过排查发现为在docker 中运行的容器中配置的心跳检查api地址配置错误:
"Consul": {
"Address": "http://host.docker.internal:8500",
"HealthCheck": "/api/healthcheck",//心跳检查api地址
"Name": "czapigoods",
"Ip": "host.docker.internal",
"Port": "5602" //未指定成当前docker运行对于端口
}
解决方法(docker修改配置方式):修改docker中配置文件appsettings.json:
- 进入docker命令行:docker exec -it 容器id /bin/bash 例如:docker exec -it f38a7a2ddfba /bin/bash
- 更新软件列表:apt-get update
- 安装vim命令:apt-get install vim
- 进入appsettings.json 修改:vim appsettings.json
- 修改appsettings中Consul.Port节点为对于docker映射端口
- 按Esc键,并输入:wq命令(退出保存修改)
- 重启对于容器效果如下
Ps:Doker相关操作后面单独详细
服务发现
服务注册问题解决了,接下来我们了解下服务如何发现;首先创建一个web项目Consul.Client并添加Consul包引用
Install-Package Consul
1、添加一个服务调用接口ICallService.cs用于调用我们添加的服务
public interface ICallService
{
/// <summary>
/// 获取 Goods Service 返回数据
/// </summary>
/// <returns></returns>
Task<string> GetGoodsService(); /// <summary>
/// 获取 Order Service 返回数据
/// </summary>
/// <returns></returns>
Task<string> GetOrderService(); /// <summary>
/// 初始化服务
/// </summary>
void InitServices();
}
2、实现该接口CallService.cs调用Goods、Order的api方法
public class CallService : ICallService
{
private readonly IConfiguration _configuration;
private readonly ConsulClient _consulClient; private ConcurrentBag<string> _serviceAUrls;
private ConcurrentBag<string> _serviceBUrls; private IHttpClientFactory _httpClient; public CallService(IConfiguration configuration, IHttpClientFactory httpClient)
{
_configuration = configuration; _consulClient = new ConsulClient(options =>
{
options.Address = new Uri(_configuration["Consul:Address"]);
}); _httpClient = httpClient;
} public async Task<string> GetGoodsService()
{
if (_serviceAUrls == null)
return await Task.FromResult("Goods Service Initializing..."); using var httpClient = _httpClient.CreateClient(); //随机获取一个服务地址调用
var serviceUrl = _serviceAUrls.ElementAt(new Random().Next(_serviceAUrls.Count())); Console.WriteLine("Goods Service:" + serviceUrl); var result = await httpClient.GetStringAsync($"{serviceUrl}/goods"); return result;
} public async Task<string> GetOrderService()
{
if (_serviceBUrls == null)
return await Task.FromResult("Order Service Initializing..."); using var httpClient = _httpClient.CreateClient(); //随机获取一个服务地址调用
var serviceUrl = _serviceBUrls.ElementAt(new Random().Next(_serviceBUrls.Count())); Console.WriteLine("Order Service:" + serviceUrl); var result = await httpClient.GetStringAsync($"{serviceUrl}/order"); return result;
} public void InitServiceList()
{
var serviceNames = new string[] { "czapigoods", "czapiorder" }; foreach (var item in serviceNames)
{
Task.Run(async () =>
{
var queryOptions = new QueryOptions
{
WaitTime = TimeSpan.FromMinutes(5)
};
while (true)
{
await InitServicesAsync(queryOptions, item);
}
});
}
}
private async Task InitServicesAsync(QueryOptions queryOptions, string serviceName)
{
//获取心跳检查服务
var result = await _consulClient.Health.Service(serviceName, null, true, queryOptions); if (queryOptions.WaitIndex != result.LastIndex)
{
queryOptions.WaitIndex = result.LastIndex; var services = result.Response.Select(x => $"http://{x.Service.Address}:{x.Service.Port}"); if (serviceName == "czapigoods")
{
_serviceAUrls = new ConcurrentBag<string>(services);
}
else if (serviceName == "czapiorder")
{
_serviceBUrls = new ConcurrentBag<string>(services);
}
}
}
}
3、接下来添加接口依赖注入、以及服务初始化调用
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); services.AddHttpClient();
//依赖注入CallService
services.AddSingleton<ICallService, CallService>();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ICallService service)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//初始化服务列表调用
service.InitServiceList();
}
}
4、使用Postman测试调用
KV操作
除了提供服务发现和健康检查的集成.Consul提供了一个易用的键/值存储.这可以用来保持动态配置,协助服务协调,领袖选举,做开发者可以想到的任何事情.
1、创建/修改
- 命令方式:consul kv put key val 如:consul kv put port 9000 --添加key为port值为9000
- Http方式:
2、查询
- 命令方式:consul kv get key 如:consul kv get port --查询key为port的KV
- Http方式:value为baisc
3、删除
- 命令方式:consul kv delete key 如:consul kv delete port --删除key为port的KV
- Http方式:
其他
网上找了下:常用服务发现框架consul、zookeeper及etcd比较:
参考:
consul手册:https://blog.csdn.net/liuzhuchen/article/details/81913562
https://www.consul.io/docs
https://www.consul.io/api/kv.html
github:
https://github.com/cwsheng/Consul.Demo.git
Consul 学习笔记—服务发现的更多相关文章
- Consul 学习笔记-服务注册
Consul简介: Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面.这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格.Consul需要 ...
- Prometheus Consul实现自动服务发现
Prometheus Consul实现自动服务发现 1.概述 Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件. Consul 由 HashiCorp公司用Go语言开发 ...
- Prometheus 通过 consul 实现自动服务发现
1.Consul 介绍 Consul 是基于 GO 语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册.服务发现和配置管理的功能.Consul 提供服务注册/发现.健康检查.Key/Valu ...
- 服务注册发现consul之三:服务发现比较:Consul vs Zookeeper vs Etcd vs Eureka
这里就平时经常用到的服务发现的产品进行下特性的对比,首先看下结论: Feature Consul zookeeper etcd euerka 服务健康检查 服务状态,内存,硬盘等 (弱)长连接,kee ...
- spring-cloud 学习二 服务发现
注册中心服务发现的例子 添加module pom文件如下 <?xml version="1.0" encoding="UTF-8"?> <pr ...
- Android学习笔记--服务(Service)
1.服务概述 1.服务是Android四大组件之一,在使用上可以分为本地服务和远程服务,本地服务是指在不影响用户操作的情况下在后台默默的执行一个耗时操作,例如下载,音频播放等.远程服务是指可以供其他应 ...
- Consul学习笔记(详细)
常见的注册中心: Netflix Eureka Alibaba Nacos HashiCorp Consul Apache Zookeeper CoreOS Etcd CNCF CoreDNS 介绍 ...
- 学习笔记:发现一个IE版本判断的好方法
web开发就不得不面对浏览器兼容性问题,特别是IE的兼容问题.在前端代码中经常要处理一些兼容格式,为了解决这个问题网上找了找识别浏览器版本的方法. 常规js方法 找到一个方法,还不错,可以识别出各 ...
- Angular5学习笔记 - 服务优化(十)
一.服务合并 二.验证效果
随机推荐
- Java实现简单混合计算器
这个计算器并不是基于逆波兰实现的,而是通过简单的递归,一层一层地计算最终求得结果. 具体的图形化界面可以参考我的另外一个篇博客:基于逆波兰表达式实现图形化混合计算器,这里我只是简单的介绍一下怎样求得算 ...
- IT人35岁危机:到底是因为爱还是责任?
互联网蚕食世界,未来属于IT人. 这是属于互联网的时代,每个人都是网络的弄潮儿,由于网络越来越被需要,互联网IT行业被推上了较高的位置,这也导致IT行业的就业环境火热,越来越多的人被IT行业广阔的发展 ...
- [程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序
题目描述 给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点. 题解 内部函数reverse实现链表beg到end的翻转 ...
- 多图证明,Java到底是值传递还是引用传递?
开篇先来曝答案,在 Java 语言中,本质只有值传递,而无引用传递,解释和证明详见正文. 说到值传递和引用传递我们不得不提到两个概念:值类型和引用类型. 1.值类型 通俗意义上来说,所谓的值类型指的就 ...
- Linux实战(7):centos7安装xrdp
系统环境:最小化安装,无安装桌面化 操作 yum更新 yum -y update 安装依赖. tigervnc-server.xrdp .GNOME Desktop yum -y install ep ...
- Node.js 从零开发 web server博客项目[日志]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- day54:django:锁和事务&Ajax&中间件Middleware
目录 1.ORM中的锁和事务 2.Ajax 3.中间件:Middleware 3.1 什么是中间件? 3.2 django请求的生命周期 3.3 中间件可以定义的5个方法 3.4 自定义中间件的流程 ...
- IdentityServer4与API单项目整合(net core 3.X)
一.创建一个空的api项目 添加identityserver4的nuget包 配置config文件 public static IEnumerable<IdentityResource> ...
- 【原创】K8S使用ceph-csi持久化存储之RBD
一.集群和组件版本 K8S集群:1.17.3+Ceph集群:Nautilus(stables)Ceph-CSI:release-v3.1snapshotter-controller:release-2 ...
- Spring学习(四)IOC详解
一.简介 概念:控制反转是一种通过描述(在 Java 中可以是 XML 或者注解)并通过第三方(Spring)去产生或获取特定对象的方式.(被动创建) 优势: ① 降低对象之间的耦合 ② 我们不需要理 ...