前言:

  上一篇文章简单实用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:

  1. 进入docker命令行:docker exec -it 容器id /bin/bash  例如:docker exec -it f38a7a2ddfba /bin/bash
  2. 更新软件列表:apt-get update 
  3. 安装vim命令:apt-get install vim
  4. 进入appsettings.json 修改:vim appsettings.json
  5. 修改appsettings中Consul.Port节点为对于docker映射端口
  6. 按Esc键,并输入:wq命令(退出保存修改)
  7. 重启对于容器效果如下

  

  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 学习笔记—服务发现的更多相关文章

  1. Consul 学习笔记-服务注册

    Consul简介: Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面.这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格.Consul需要 ...

  2. Prometheus Consul实现自动服务发现

    Prometheus Consul实现自动服务发现   1.概述 Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件. Consul 由 HashiCorp公司用Go语言开发 ...

  3. Prometheus 通过 consul 实现自动服务发现

    1.Consul 介绍 Consul 是基于 GO 语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册.服务发现和配置管理的功能.Consul 提供服务注册/发现.健康检查.Key/Valu ...

  4. 服务注册发现consul之三:服务发现比较:Consul vs Zookeeper vs Etcd vs Eureka

    这里就平时经常用到的服务发现的产品进行下特性的对比,首先看下结论: Feature Consul zookeeper etcd euerka 服务健康检查 服务状态,内存,硬盘等 (弱)长连接,kee ...

  5. spring-cloud 学习二 服务发现

    注册中心服务发现的例子 添加module pom文件如下 <?xml version="1.0" encoding="UTF-8"?> <pr ...

  6. Android学习笔记--服务(Service)

    1.服务概述 1.服务是Android四大组件之一,在使用上可以分为本地服务和远程服务,本地服务是指在不影响用户操作的情况下在后台默默的执行一个耗时操作,例如下载,音频播放等.远程服务是指可以供其他应 ...

  7. Consul学习笔记(详细)

    常见的注册中心: Netflix Eureka Alibaba Nacos HashiCorp Consul Apache Zookeeper CoreOS Etcd CNCF CoreDNS 介绍 ...

  8. 学习笔记:发现一个IE版本判断的好方法

    web开发就不得不面对浏览器兼容性问题,特别是IE的兼容问题.在前端代码中经常要处理一些兼容格式,为了解决这个问题网上找了找识别浏览器版本的方法.   常规js方法 找到一个方法,还不错,可以识别出各 ...

  9. Angular5学习笔记 - 服务优化(十)

    一.服务合并 二.验证效果

随机推荐

  1. python模块:excel的读和修改xlrd/xultils

    一.xlrd xlrd只能对excel进行读取,不可编辑修改.该模块属于第三方模块,需要安装模块包并引入.pip install xlrd 常用的方法: import xlrd book = xlrd ...

  2. AES字节数组加密解密流程

    AES类时微软MSDN中最常用的加密类,微软官网也有例子,参考链接:https://docs.microsoft.com/zh-cn/dotnet/api/system.security.crypto ...

  3. linux系统的默认用户

    1.可以通过cat /etc/passwd |cut -f1 -d:   可以提取/etc/passwd文件的第一个字段 2.也可以通过vipw进入vi编辑器来查看该文件每一行的第一个字段 linux ...

  4. [程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序

    题目描述 给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点. 题解 内部函数reverse实现链表beg到end的翻转 ...

  5. Windows实战(1):Nginx代理设置及负载均衡配置

    简言 以下配置实现功能: 反向代理 通过轮询的方式实现nginx负载均衡 直接看以下配置文件: #user nobody; worker_processes 1; #error_log logs/er ...

  6. 使用Spring Boot+MyBatis框架做查询操作

    一.在你建立的工程下创建 Module 选择Spring initializr创建. 二.在Type处选择: Maven Project(项目的构建工具) 三.创建依赖时勾上web,mybatis,m ...

  7. ava实现时钟小程序【代码】

    其实这个程序并不难,主要是用Java 2D画图,弄一个线程,每隔一秒,依照时针分针秒针各自的速度重新计算它们走过的角度(相对12点方向顺时针偏离的角度),利用这个角度算出它们各自端点的坐标,重绘一次表 ...

  8. 在思科三层交换机上配置DHCP,不同网段/VLAN间互通

    摘要: 描述:在三层交换机上配置DHCP,实现DHCP为PC1/PC3分配192.168.1.X网段:实现DHCP为PC2/PC4分配192.168.2.X网段:并且各个PC间要可以互相通信.(文末附 ...

  9. 5.Strom-事务型拓扑

  10. kubeadm单集群部署k8s1.15.1&flannel网络

    说明 本次实验在Windows下的VMware进行 系统配置及初始化配置在所有的主机执行 容器镜像全部替换为国内可拉取的 pod网络采用flannel 实验环境 主机名 IP地址 角色 OS CPU/ ...