Consul 服务的注册和发现
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 服务的注册和发现的更多相关文章
- SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(转载)
SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本) 转载请标明出处:http://blog.csdn.net/forezp/article/details ...
- go微服务框架go-micro深度学习(三) Registry服务的注册和发现
服务的注册与发现是微服务必不可少的功能,这样系统才能有更高的性能,更高的可用性.go-micro框架的服务发现有自己能用的接口Registry.只要实现这个接口就可以定制自己的服务注册和发现. go- ...
- 玩转SpringCloud(F版本) 一.服务的注册与发现(Eureka)
一.服务的注册与发现(Eureka) spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等 ...
- SpringCloud-微服务的注册与发现Eureka(二)
一.SpringCloud简介 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均 ...
- (转) 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)
一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...
- 服务的注册与发现Eureka(二)
1.服务治理概念 在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用.负载均衡.容错等,实现服务发现与注册. 2.服务的注册与 ...
- springCloud学习-服务的注册与发现(Eureka)
1.小记 这段时间有空,把springcloud的知识整理一下,好记性不如烂笔头,也让自己对springcloud有个清晰的认识.此次的整理记录主要借鉴了这位大佬的博客 https://blog.cs ...
- Spring Cloud-Eureka实现服务的注册与发现(二)
在Spring Cloud中是使用Eureka来实现服务的注册与发现的 请勿使用eureka2.x 用于生产 2.x已经停止开发了 使用1.x 最新版是1.9 我这里demo是使用1.9 详 ...
- (一)Eureka 服务的注册与发现
(一)服务的注册于发现(eureka); Eureka Server: 服务注册中心,负责服务列表的注册.维护和查询等功能 在Idea里,新建项目,选择Spring initializer. 下面的p ...
随机推荐
- 1-认识c指针
1.指针和内存 c程序在编译后,会以三种形式使用内存 1静态/全局内存 静态声明的变量分配在这里,全局变量也使用这部分内存.这些变量在程序开始运行时分配,直到程序终止时才会消失 2.自动内存 这些变量 ...
- 从键盘读入学生成绩,找出最高分, 并输出学生成绩等级(Java)
从键盘读入学生成绩,找出最高分, 并输出学生成绩等级 一.题目 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10 等级为'A' 成绩>=最高分-20 等级为'B' ...
- 攻防世界 reverser secret-galaxy-300
secret-galaxy-300 school-ctf-winter-2015 运行程序 完全没有flag的身影呀 ida查看字符串 也没有相关信息 动态调试,看运行后内存信息 发现了一串字符 al ...
- C语言宏的使用
使用条件宏进行条件编译 譬如,对于同一份代码,我想编译出两个不同的版本,在其中一个版本中去掉某一部分功能, 这时可以通过条件宏判断是否编译,例: 如果不使用条件宏进行控制,想编译两个不同版本的程序,就 ...
- 【Azure 应用程序见解】 Application Insights 对App Service的支持问题
问题描述 Web App 发布后, Application Insights 收集不到数据了 问题分析 在应用服务(App Service)中收集应用的监控数据(如Request,Exception, ...
- 庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
庐山真面目之十二微服务架构基于Docker搭建Consul集群.Ocelot网关集群和IdentityServer版本实现 一.简介 在第七篇文章<庐山真面目之七微服务架构Consul ...
- CodeForces CF862E题解
\(Part\ 1:\) 我们发现每次修改动的是\(a\)串,所以对于这个答案的公式,\(b_{i+j}\)的部分是可以求出来的.所以我们可以把公式改成如下所示: \(f(j)=|\sum_{i=1} ...
- kubernetes使用statefulset部署mongoDB 单机版 自定义配置文件、密码等
注: 官方镜像地址: https://hub.docker.com/_/mongo?tab=description docker版的mongo移除了默认的/etc/mongo.conf, 修改了db数 ...
- python基础(四):切片和索引
Python中的序列有元组.列表和字符串,因此我们都可以通过索引和切片的方式,来获取其中的元素. 索引 Python中的索引,对于正向索引,都是从0开始的.但是对于反向索引,确实从-1开始的.如图所示 ...
- Spring (三)SpringAoP
1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能 ...