@[toc]
一、注册核心的概念
- 概念
可能注册微服务地址【ip: 端口】的组件就是注册核心。
如图: -
目标
保障微服务的动静伸缩性。二、注册核心的应用场景
- 场景
次要场景是在微服务中应用。
如图:
-
三、注册核心的技术选型
-
类型
- zookeeper
- consul
- etcd
- eureka
- 特点
| Feature | Consul | zookeeper | etcd | euerka |
| — | — | — | — | — |
| 服务健康检查 | 服务状态,内存,硬盘等 | (弱)长连贯,keepalive | 连贯心跳 | 可配反对 |
| 多数据中心 | 反对 | – | – | – |
| kv 存储服务 | 反对 | 反对 | 反对 | – |
| 一致性 | raft | paxos | raft | – |
| cap | ca | cp | cp | ap |
| 应用接口(多语言能力) | 反对 http 和 dns | 客户端 | http/grpc | http(sidecar)|
| watch 反对 | 全量 / 反对 long polling | 反对 | 反对 long polling | polling 反对 long polling/ 大部分增量 |
| 本身监控 | metrics | – | metrics | metrics |
| 平安 | acl /https | acl | https 反对(弱)| – |
| spring cloud 集成 | 反对 | 反对 | 反对 | 反对 | -
Consul 的三个概念
- server:存储微服务地址【ip:端口】
- client:连贯 Consul
- agent:后盾服务
- 利用架构集成原理
如图:
四、注册核心的我的项目落地
-
工具
- Consul
网盘下载地址:
链接:https://pan.baidu.com/s/1zN4P…
提取码:lnk7 - demo 我的项目
- Consul
-
步骤
-
Consul 运行命令
# 在根目录下启动运行 consul.exe agent -dev #在开发模式下启动命令 consul agent -server -bootstrap-expect [节点数据量] -data-dir d:/consul/data [数据存储地址]
运行后果如下:
-
demo 我的项目
-
nuget 装置
Consul
-
appsettings.json 增加配置信息
{ ...... "ConsulRegistry": { "Name": "testService", "RegistryAddress": "http://127.0.0.1:8500", "HealthCheckAddress": "/HealthCheck" } }
-
新增配置实体类,通过 json 文件映射到实体配置类
public class ServiceRegistryConfig { /// <summary> /// 服务 ID /// </summary> public string Id {get;set;} /// <summary> /// 服务名称 /// </summary> public string Name {get;set;} /// <summary> /// 服务标签 /// </summary> public string[] Tags { get; set;} /// <summary> /// 服务地址 /// </summary> public string Address {get; set;} /// <summary> /// 服务端口号 /// </summary> public int Port {get; set;} /// <summary> /// 服务注册地址 /// </summary> public string RegistryAddress {get; set;} /// <summary> /// 服务健康检查地址 /// </summary> public string HealthCheckAddress {get; set;} }
-
微服务注册
-
创立服务注册实现类
public class ServiceRegistry : IServiceRegistry {public void Register(ServiceRegistryConfig serviceRegistryConfig) { //1 建设 consul 客户端的连贯 var consulClient = new ConsulClient(configuration => {configuration.Address = new Uri(serviceRegistryConfig.RegistryAddress); }); //2 创立 consul 服务注册对象 var registration = new AgentServiceRegistration() { ID = serviceRegistryConfig.Id, Name = serviceRegistryConfig.Name, Address = serviceRegistryConfig.Address, Port = serviceRegistryConfig.Port, Tags = serviceRegistryConfig.Tags, // 健康检查 Check = new AgentServiceCheck() { // 设置健康检查超时工夫 Timeout = TimeSpan.FromSeconds(10), // 服务进行 5 秒后登记服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(50), // 健康检查地址 HTTP = serviceRegistryConfig.HealthCheckAddress, // 健康检查间隔时间 Interval = TimeSpan.FromSeconds(10) } }; // 服务注册 consulClient.Agent.ServiceRegister(registration); // 敞开连贯开释资源 consulClient.Dispose();} /// <summary> /// 注册核心登记 /// </summary> /// <param name="serviceRegistryConfig"></param> public void Deregister(ServiceRegistryConfig serviceRegistryConfig) { var consulClient = new ConsulClient(configuration => {configuration.Address = new Uri(serviceRegistryConfig.Address); }); consulClient.Agent.ServiceDeregister(serviceRegistryConfig.Id); } }
-
创立服务注册看接口类
public interface IServiceRegistry {void Register(ServiceRegistryConfig serviceRegistryConfig); void Deregister(ServiceRegistryConfig serviceRegistryConfig); }
-
创立服务注册扩大类
//consul 服务注册类 public static class ConsulExtensions { /// <summary> /// 注册核心扩大 /// </summary> /// <param name="services"></param> /// <param name="Configuration"></param> /// <returns></returns> public static IServiceCollection AddConsul(this IServiceCollection services, IConfiguration Configuration) { // 将 json 文件映射到实体类 services.Configure<ServiceRegistryConfig>(Configuration.GetSection("ConsulRegistry")); services.AddSingleton<IServiceRegistry, ServiceRegistry>(); return services; } } // 服务启动时注册服务 public static class ConsulApplicationBuilderExtension {public static IApplicationBuilder UseConsulRegistry(this IApplicationBuilder app) { // 获取配置信息 var serviceNode = app.ApplicationServices.GetRequiredService<IOptions<ServiceRegistryConfig>>().Value; // 获取生命周期 var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>(); // 获取服务注册实力 var consulRegistry = app.ApplicationServices.GetRequiredService<IServiceRegistry>(); // 获取服务地址信息 var features = app.Properties["server.Features"] as FeatureCollection; var address = features.Get<IServerAddressesFeature>().Addresses.First(); var uri = new Uri(address); // 服务注册 serviceNode.Id = Guid.NewGuid().ToString(); serviceNode.Address = $"{uri.Scheme}://{uri.Host}"; serviceNode.Port = uri.Port; serviceNode.HealthCheckAddress = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceNode.HealthCheckAddress}"; consulRegistry.Register(serviceNode); // 服务器敞开时登记服务 lifetime.ApplicationStopping.Register(() => {consulRegistry.Deregister(serviceNode); }); return app; } } // 在 startup 类中 ConfigureServices 办法中注册服务 services.AddConsul(Configuration); // 在 startup 类中 Configure 办法启动服务 app.UseConsulRegistry();
运行后果如下:
-
-
微服务发现
-
在 appsettings.json 文件中新增 Consul 注册地址配置
...... "ConsulDiscoverys": {"RegistryAddress": "http://127.0.0.1:8500"} .....
-
新建配置类
public class ServiceDiscoveryConfig {public string RegistryAddress { get; set;} }
-
新增服务发现接口类
public interface IConsulDiscovery {Task<List<ServiceUrl>> Discovery(string ServiceName); }
-
新增服务发现实现类
public class ConsulDiscovery : IConsulDiscovery { private readonly IConfiguration Configuration; public ConsulDiscovery(IConfiguration _Configuration) {Configuration = _Configuration;} /// <summary> /// 服务发现 /// </summary> /// <param name="ServiceName"> 服务名称 </param> /// <returns> 返回一个汇合 </returns> public async Task<List<ServiceUrl>> Discovery(string ServiceName) {List<ServiceUrl> list = new List<ServiceUrl>(); ServiceDiscoveryConfig serviceDiscoveryConfig = new ServiceDiscoveryConfig(); serviceDiscoveryConfig = Configuration.GetSection("ConsulDiscoverys").Get< ServiceDiscoveryConfig >(); //1 建设连贯 var consulClient = new ConsulClient(Options => {Options.Address = new Uri(serviceDiscoveryConfig.RegistryAddress); }); // 2 依据服务名称获取注册的服务地址 var queryResult = await consulClient.Catalog.Service("ServiceName"); // 3 将注册的地址注入汇合中 foreach (var item in queryResult.Response) {list.Add(new ServiceUrl() {Url = item.Address+":"+ item.ServicePort}); } return list; } }
-
在扩大类中新增发现服务的扩大
public static IServiceCollection AddConsulDiscovery(this IServiceCollection services) {services.AddSingleton<IConsulDiscovery, ConsulDiscovery>(); return services; }
-
在 Startup 类 ConfigureServices 办法中进行注册
// 服务发现 services.AddConsulDiscovery();
-
在控制器构造函数中注入下服务发现的接口
private readonly IConsulDiscovery consulDiscovery; public HomeController(IConsulDiscovery _consulDiscovery) {consulDiscovery = _consulDiscovery;} ..... // 而后在其余办法中依据服务名称获取服务地址;留神:返回值是一个汇合。
-
-
-
五、注册核心 Consul 的高可用
-
集群搭建【最好有 3 个实例】
-
步骤
-
节点 1
# 1、新建配置文件,门路:D:/Assembly/Consul/node1/basic.json {"datacenter": "dc1", "data_dir": "D:/Assembly/Consul/node1", "log_level": "INFO", "server": true, "node_name": "node1", "ui": true, "bind_addr": "127.0.0.1", "client_addr": "127.0.0.1", "advertise_addr": "127.0.0.1", "bootstrap_expect": 3, "ports":{ "http": 8500, "dns": 8600, "server": 8300, "serf_lan": 8301, "serf_wan": 8302}} # 2、运行命令 # 2、切换到 consul 根目录下:consul.exe agent -config-file=D:/Assembly/Consul/node1/basic.json
-
节点 2
# 1、新建配置文件,门路:D:/Assembly/Consul/node2/basic.json {"datacenter": "dc1", "data_dir": "D:/Assembly/Consul/node2", "log_level": "INFO", "server": true, "node_name": "node2", "bind_addr": "127.0.0.1", "client_addr": "127.0.0.1", "advertise_addr": "127.0.0.1", "ports":{ "http": 8510, "dns": 8610, "server": 8310, "serf_lan": 8311, "serf_wan": 8312}} # 2、切换到 consul 根目录下:consul.exe agent -config-file=D:/Assembly/Consul/node2/basic.json -retry-join=127.0.0.1:8301
-
节点 3
# 1、新建配置文件,门路:文件地址:D:/Assembly/Consul/node3/basic.json {"datacenter": "dc1", "data_dir": "D:/Assembly/Consul/node3", "log_level": "INFO", "server": true, "node_name": "node3", "bind_addr": "127.0.0.1", "client_addr": "127.0.0.1", "advertise_addr": "127.0.0.1", "ports":{ "http": 8520, "dns": 8620, "server": 8320, "serf_lan": 8321, "serf_wan": 8322}} # 2、切换到 consul 根目录下:consul.exe agent -config-file=D:/Assembly/Consul/node3/basic.json -retry-join=127.0.0.1:8301
运行后果如图:
-
-
查看主节点
#切换到 consul 根目录下 consul.exe info
-
集群搭建命令
-bind:为该节点绑定一个地址 -enable-script-checks=true:设置查看服务为可用 -join:退出到已有的集群中 -server 示意以后应用的 server 模式 -node:指定以后节点在集群中的名称 -config-file - 要加载的配置文件 -config-dir:指定配置文件,定义服务的,默认所有以.json 结尾的文件都会读 -datacenter: 数据中心没名称,不设置的话默认为 dc -client: 客户端模式 -ui: 应用 consul 自带的 ui 界面 -data-dir consul 存储数据的目录 -bootstrap:用来管制一个 server 是否在 bootstrap 模式,在一个 datacenter 中只能有一个 server 处于 bootstrap 模式,当一个 server 处于 bootstrap 模式时,能够本人选举为 raft leader。-bootstrap-expect:在一个 datacenter 中冀望提供的 server 节点数目,当该值提供的时候,consul 始终等到达到指定 sever 数目的时候才会疏导整个集群,该标记不能和 bootstrap 专用 这两个参数非常重要,二选一,如果两个参数不应用的话,会呈现就算你应用 join 将 agent 退出了集群依然会报 2018/10/14 15:40:00 [ERR] agent: failed to sync remote state: No cluster leader
-
配置文件参数
ui: 相当于 -ui 命令行标记。acl_token:agent 会应用这个 token 和 consul server 进行申请 acl_ttl:管制 TTL 的 cache,默认是 30s addresses:一个嵌套对象,能够设置以下 key:dns、http、rpc advertise_addr:等同于 -advertise bootstrap:等同于 -bootstrap bootstrap_expect:等同于 -bootstrap-expect bind_addr:等同于 -bindca_file:提供 CA 文件门路,用来查看客户端或者服务端的链接 cert_file:必须和 key_file 一起 check_update_interval:client_addr:等同于 -client datacenter:等同于 -dc data_dir:等同于 -data-dir disable_anonymous_signature:在进行更新查看时禁止匿名签名 enable_debug:开启 debug 模式 enable_syslog:等同于 -syslog encrypt:等同于 -encrypt key_file:提供私钥的门路 leave_on_terminate:默认是 false,如果为 true,当 agent 收到一个 TERM 信号的时候,它会发送 leave 信息到集群中的其余节点上。log_level:等同于 -log-level node_name: 等同于 -node ports:这是一个嵌套对象,能够设置以下 key:dns(dns 地址:8600)、http(http api 地址:8500)、rpc(rpc:8400)、serf_lan(lan port:8301)、serf_wan(wan port:8302)、server(server rpc:8300) protocol:等同于 -protocol rejoin_after_leave:等同于 -rejoin retry_join:等同于 -retry-join retry_interval:等同于 -retry-interval server:等同于 -server syslog_facility:当 enable_syslog 被提供后,该参数管制哪个级别的信息被发送,默认 Local0 ui_dir:等同于 -ui-dir
-