Consul 是Hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul是分布式的,高可用的,可横向扩展的。

Consul 的主要特点有:
    Service Discovery : 服务注册与发现,Consul 的客户端可以做为一个服务注册到 Consul,也可以通过 Consul 来查找特定的服务提供者,并且根据提供的信息进行调用。

Health Checking: Consul 客户端会定期发送一些健康检查数据和服务端进行通讯,判断客户端的状态、内存使用情况是否正常,用来监控整个集群的状态,防止服务转发到故障的服务上面。

KV Store: Consul 还提供了一个容易使用的键值存储。这可以用来保持动态配置,协助服务协调、建立 Leader 选举,以及开发者想构造的其它一些事务。

Secure Service Communication: Consul 可以为服务生成分布式的 TLS 证书,以建立相互的 TLS 连接。 可以使用 intentions 定义允许哪些服务进行通信。 可以使用 intentions 轻松管理服务隔离,而不是使用复杂的网络拓  扑和静态防火墙规则。

Multi Datacenter: Consul 支持开箱即用的多数据中心,这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。

Consul 角色
 Server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其它数据中心通讯。 每个数据中心的 Server 数量推荐为 3 个或是 5 个。

Client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。

Consul 旨在对 DevOps 社区和应用程序开发人员友好,使其成为现代、弹性基础架构的理想选择。

首先下载Consul服务组件:官网下载:https://www.consul.io/downloads

启动Consul:

根据启动后的http显示端口8500端口:

通过浏览器查看 Consul服务中心是否启动成功,地址:http://localhost:8500,如果成功,效果如下:

然后创建一个服务端实例工程:

添加必要的测试类:

using System;
using System.Collections.Generic;
using System.Text; namespace Demo
{
/// <summary>
/// 用户模型。
/// </summary>
public class User
{
/// <summary>
/// 获取或者设置用户主键。
/// </summary>
public int ID { get; set; } /// <summary>
/// 获取或者设置用户姓名。
/// </summary>
public string Name { get; set; } /// <summary>
/// 获取或者设置用户账号名称。
/// </summary>
public string Account { get; set; } /// <summary>
/// 获取或者设置用户密码。
/// </summary>
public string Password { get; set; } /// <summary>
/// 获取或者设置用户的电子邮箱地址。
/// </summary>
public string Email { get; set; } /// <summary>
/// 获取或者设置用户角色。
/// </summary>
public string Role { get; set; } /// <summary>
/// 获取或者设置用户的登录时间。
/// </summary>
public DateTime LoginTime { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text; namespace Demo
{
/// <summary>
/// 用户服务的接口定义。
/// </summary>
public interface IUserService
{
/// <summary>
/// 查找指定主键的用户实例对象。
/// </summary>
/// <param name="id">用户的主键。</param>
/// <returns>返回查找到的用户实例对象。</returns>
User FindUser(int id); /// <summary>
/// 获取所有用户的实例集合。
/// </summary>
/// <returns>返回所有的用户实例。</returns>
IEnumerable<User> UserAll();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Demo
{
/// <summary>
/// 实现用户服务接口的实现类型。
/// </summary>
public class UserService : IUserService
{
private IList<User> dataList; /// <summary>
/// 初始化类型的实例
/// </summary>
public UserService()
{
dataList = new List<User>()
{
new User {ID=1,Name="张三",Account="5435435345",Password="4535435435",Email="4535345345", Role="Admin", LoginTime=DateTime.Now},
new User {ID=2,Name="李四",Account="5435435345",Password="5435345345",Email="543534535", Role="Admin", LoginTime=DateTime.Now.AddDays(-5) },
new User { ID = 3, Name = "王二", Account = "45354", Password = "3245345", Email = "54353455", Role = "Admin", LoginTime = DateTime.Now.AddDays(-30) },
new User { ID = 4, Name = "麻子", Account = "45354", Password = "4534535", Email = "453534534", Role = "Admin", LoginTime = DateTime.Now.AddDays(-90) },
new User { ID = 5, Name = "陈五", Account = "54353", Password = "5435345", Email = "5435345345", Role = "Admin", LoginTime = DateTime.Now.AddMinutes(-50) }
};
} /// <summary>
/// 查找指定主键的用户实例对象。
/// </summary>
/// <param name="id">用户的主键。</param>
/// <returns>返回查找到的用户实例对象。</returns>
public User FindUser(int id)
{
return dataList.FirstOrDefault(user => user.ID == id);
} /// <summary>
/// 获取所有用户的实例集合。
/// </summary>
/// <returns>返回所有的用户实例。</returns>
public IEnumerable<User> UserAll()
{
return dataList;
}
}
}
using Consul;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Text; namespace Demo
{
/// <summary>
/// Consul 静态扩展类。
/// </summary>
public static class ConsulExtension
{
/// <summary>
///类型初始化器,初始化 Consul 网址和数据中心。
/// </summary>
static ConsulExtension()
{
Uri = new Uri("http://localhost:8500");
DataCenter = "dc1";
} /// <summary>
/// 获取或者设置 Consul 的网址。
/// </summary>
public static Uri Uri { get; set; } /// <summary>
/// 获取或者设置数据中心。
/// </summary>
public static string DataCenter { get; set; } /// <summary>
/// 向 Consul 服务中心注册服务实例。
/// </summary>
/// <param name="configuration">配置对象。</param>
/// <param name="consulServiceName">在 Consul 服务中心注册的服务类别名称,多个实例的 ID 可以属于一个服务类别名称。</param>
/// <param name="serviceID">服务实例的主键值,必须唯一。</param>
public static void ConsulRegist(this IConfiguration configuration, string consulServiceName, string serviceID)
{
if (string.IsNullOrEmpty(consulServiceName) || string.IsNullOrWhiteSpace(consulServiceName))
{
throw new ArgumentNullException("consulServiceName is null");
}
if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
{
throw new ArgumentNullException("serviceID is null.");
} using (ConsulClient client = new ConsulClient(config =>
{
config.Address = Uri;
config.Datacenter = DataCenter;
}))
{
string ip = configuration["ip"];
int port = int.Parse(configuration["port"]);
int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]); client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = serviceID,
Name = consulServiceName,
Address = ip,
Port = port,
Tags = new string[] { weight.ToString() },
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(12),
HTTP = $"http://{ip}:{port}/API/Health/Index",
Timeout = TimeSpan.FromSeconds(5),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)
}
}).Wait();
Console.WriteLine($"注册服务:{ip}:{port}--Weight:{weight}");
};
} /// <summary>
/// 向 Consul 服务中心注销服务实例。
/// </summary>
/// <param name="applicationLifetime">配置对象。</param>
/// <param name="serviceID">服务实例的主键值,必须唯一。</param>
public static void ConsulDown(this IApplicationLifetime applicationLifetime, string serviceID)
{
if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
{
throw new ArgumentNullException("serviceID is null");
}
applicationLifetime.ApplicationStopped.Register(() =>
{
using (var consulClient = new ConsulClient(config => { config.Address = Uri; config.Datacenter = DataCenter; }))
{
Console.WriteLine("服务已经退出");
consulClient.Agent.ServiceDeregister(serviceID);
}
});
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; namespace ConsulAPIDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HealthController : ControllerBase
{
private IConfiguration _configuration; /// <summary>
/// 初始化该类型的新实例。
/// </summary>
/// <param name="configuration">配置接口。</param>
public HealthController(IConfiguration configuration)
{
_configuration = configuration;
} /// <summary>
/// 要调用的接口。
/// </summary>
[HttpGet]
[Route("Index")]
public IActionResult Index()
{
Console.WriteLine($"This is HealhController {_configuration["port"]} Invoke");
return Ok();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Demo;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; namespace ConsulAPIDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
/// <summary>
/// 用户的 API 类型。
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
#region 私有字段 private readonly ILogger<UsersController> _logger;
private readonly IUserService _userService;
private IConfiguration _configuration; #endregion #region 构造函数 /// <summary>
/// 初始化该类型的新实例。
/// </summary>
/// <param name="logger">日志记录器。</param>
/// <param name="userService">用户服务接口。</param>
/// <param name="configuration">配置服务。</param>
public UsersController(ILogger<UsersController> logger, IUserService userService, IConfiguration configuration)
{
_logger = logger;
_userService = userService;
_configuration = configuration;
} #endregion #region 实例方法 /// <summary>
/// 获取一条记录
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[Route("Get")]
public User Get(int id)
{
return _userService.FindUser(id);
} /// <summary>
/// 获取所有记录。
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("All")]
//[Authorize]
public IEnumerable<User> Get()
{
Console.WriteLine($"This is UsersController {this._configuration["port"]} Invoke"); return this._userService.UserAll().Select((user => new User
{
ID = user.ID,
Name = user.Name,
Account = user.Account,
Password = user.Password,
Email = user.Email,
Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
LoginTime = user.LoginTime
})); ;
} /// <summary>
/// 超时处理
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("Timeout")]
public IEnumerable<User> Timeout()
{
Console.WriteLine($"This is Timeout Start");
//超时设置。
Thread.Sleep(3000); Console.WriteLine($"This is Timeout End"); return this._userService.UserAll().Select((user => new User
{
ID = user.ID,
Name = user.Name,
Account = user.Account,
Password = user.Password,
Email = user.Email,
Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
LoginTime = user.LoginTime
})); ;
} #endregion
}
}
}

startup里面的配置:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Demo;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; namespace ConsulAPIDemo
{
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.AddSingleton<IUserService, UserService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, Microsoft.Extensions.Hosting.IApplicationLifetime applicationLifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
#region Consul 注册,需要增加的 string serviceID = $"Service:{Configuration["ip"]}:{Configuration["port"]}---{Guid.NewGuid()}";
string consuleServiceName = "PatrickLiuService"; //注册服务。
Configuration.ConsulRegist(consuleServiceName, serviceID); //注销服务
applicationLifetime.ConsulDown(serviceID); #endregion
app.UseHttpsRedirection();
app.UseMvc(); }
}
}

编译一下,根据不同端口启动api接口服务:

API端口设置为2000:

API端口设置为3000:

注册四个实例:

上面整个过程已经完成了服务的注册,至于发现自己可以测一下,自己关掉一个服务,Consul会自动检查各个服务的健康度,如果哪个服务出现异常,consul会自动剔除异常服务。

参考文档:https://www.cnblogs.com/PatrickLiu/p/13939135.html

Consul 服务的注册和发现的更多相关文章

  1. SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(转载)

    SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本) 转载请标明出处:http://blog.csdn.net/forezp/article/details ...

  2. go微服务框架go-micro深度学习(三) Registry服务的注册和发现

    服务的注册与发现是微服务必不可少的功能,这样系统才能有更高的性能,更高的可用性.go-micro框架的服务发现有自己能用的接口Registry.只要实现这个接口就可以定制自己的服务注册和发现. go- ...

  3. 玩转SpringCloud(F版本) 一.服务的注册与发现(Eureka)

    一.服务的注册与发现(Eureka) spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等 ...

  4. SpringCloud-微服务的注册与发现Eureka(二)

    一.SpringCloud简介 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均 ...

  5. (转) 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)

    一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...

  6. 服务的注册与发现Eureka(二)

    1.服务治理概念 在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用.负载均衡.容错等,实现服务发现与注册. 2.服务的注册与 ...

  7. springCloud学习-服务的注册与发现(Eureka)

    1.小记 这段时间有空,把springcloud的知识整理一下,好记性不如烂笔头,也让自己对springcloud有个清晰的认识.此次的整理记录主要借鉴了这位大佬的博客 https://blog.cs ...

  8. Spring Cloud-Eureka实现服务的注册与发现(二)

    在Spring Cloud中是使用Eureka来实现服务的注册与发现的 请勿使用eureka2.x  用于生产 2.x已经停止开发了  使用1.x  最新版是1.9  我这里demo是使用1.9  详 ...

  9. (一)Eureka 服务的注册与发现

    (一)服务的注册于发现(eureka); Eureka Server: 服务注册中心,负责服务列表的注册.维护和查询等功能 在Idea里,新建项目,选择Spring initializer. 下面的p ...

随机推荐

  1. IPFS是什么?IPFS与Filecoin有什么关系?

    Filecoin 基于 IPFS 的去中心化存储网络,是 IPFS 上唯一的激励层,是一个基于区块链技术发行的通证.Filecoin 翻译过来就是文件币,简称为 FIL. 在 FIlecoin 网络中 ...

  2. GoldenEye靶机work_through暨CVE-2013-3630复现

    前言 备考OSCP,所以接下来会做一系列的OSCP向靶机来练手 靶机描述 I recently got done creating an OSCP type vulnerable machine th ...

  3. Java中的泛型 - 细节篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的泛型 - 细节篇>,希望对大家有帮助,谢谢 细心的观众朋友们可能发现了,现在的标题不再是入门篇,而是各种详细篇,细节篇: 是因为之 ...

  4. Myabtis-Plus之QueryWrapper常用方法

    AbstractWrapper 下的方法及使用 方法名 说明 使用 allEq(Map<R, V> params) 全部 =(或个别 isNull) allEq(params,true) ...

  5. 一文带你剖析LiteOS互斥锁Mutex源代码

    摘要:多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的临界资源,只能被独占使用.LiteOS使用互斥锁来避免这种冲突,互斥锁是一种特殊的二值性信号量,用于实现对临界资源的独占 ...

  6. 北航OO第四单元作业总结(4.1~4.3)及课程总结

    前言 在学习过JML规格描述语言之后,本单元进行了UML(Unified Modeling Language)的学习.和JML单纯用语言描述的形式不同,UML通过可视化的图形形式,对一系列有关类的元素 ...

  7. Spring MVC(七篇)

    (一)Spring MVC简介 (二)SpringMVC核心控制器 (三)Spring MVC Controller接口控制器详解(一) (三)Spring MVC Controller接口控制器详解 ...

  8. (四)Struts2的Action(深入讲解版)

    Struts2的Action 开发者需要提供大量的Action,并在struts.xml中配置Action.Action类里包含了对用户请求的处理逻辑,因为我们也称Action为业务控制器. 一.编写 ...

  9. Java(152-170)【继承、super、this、抽象类】

    1.继承的概述 继承是多态的前提 继承主要解决的问题是共性抽取 2.继承的格式 在继承的关系中,子类可以当做父类看待 代码复用的效果 package cn.itcast.day09.demo01; / ...

  10. JavaScript中的new,bind,call,apply的简易实现

    Function原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this 关键字密切相关,相当一部分人对它们的理解还是比较浅显,所谓js基础扎实,绕 ...