上一篇   负载均衡之Ocelot+Consul(文件配置注册服务),介绍了如何通过json文件注册服务,本篇将学习如何通过web api 注册服务。

在展开学习过程之前,且先总结一下 consul服务发现的知识:

上篇的服务发现介绍,是基于单机单节点的,并没有跟其它机子进行联盟。Consul 是建议至少要有3台机子来做一个集群,并且从中先出一个leader,作为其他两个随从者的老大,由它来负责处理所有的查询和事务。如果leader挂掉了,集群会自动重新选举一个leader,这样也就保证了集群高可用性。

具体可看:张善友 https://www.cnblogs.com/shanyou/p/6286207.html

尽管如此,本学习过程依然是单机来做试验,原因还是没有准备好虚拟机,另外也还没进一步地学习docker,最优的做法应该是创建几个docker容器来做这个试验。

前话说完,下面开始试验如何在节点API上面注册服务:

主要一步 就是在webapi 请求管道中 加入 一个 consul 中间件,关于.net core web api 中间件的知识,我认为所有学习.net core编程的码友都要去了解。具体可以看一下这里: https://www.cnblogs.com/whuanle/p/10095209.html

consul 中间件:

 public static class ConsulBuilderExtensions

    {

        // 服务注册

        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, HealthService healthService, ConsulService consulService)

        {

            var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{consulService.IP}:{consulService.Port}"));//请求注册的 Consul 地址

            var httpCheck = new AgentServiceCheck()

            {

                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(),//服务启动多久后注册

                Interval = TimeSpan.FromSeconds(),//健康检查时间间隔,或者称为心跳间隔

                HTTP = $"http://{healthService.IP}:{healthService.Port}/master/health",//健康检查地址

                Timeout = TimeSpan.FromSeconds()

            };

            // Register service with consul

            var registration = new AgentServiceRegistration()

            {

                Checks = new[] { httpCheck },

                ID = healthService.Name + "_" + healthService.Port,

                Name = healthService.Name,

                Address = healthService.IP,

                Port = healthService.Port,

                Tags = new[] { $"urlprefix-/{healthService.Name}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别

            };

            consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)

            lifetime.ApplicationStopping.Register(() =>

            {

                consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册

            });

            return app;

        }

    }

public class ConsulService

    {

        public string IP { get; set; }

        public int Port { get; set; }

    }

    public class HealthService

    {

        public string Name { get; set; }

        public string IP { get; set; }

        public int Port { get; set; }
}

相应的配置:

  "Service": {
"Name": "MasterService",
"IP": "192.168.1.232",
"Port": ""
}, "Consul": {
"IP": "192.168.1.23",
"Port": ""
}

这个就非常像上篇,文件方式注册服务的注册:

services": [
{
"id": "api1",
"name": "MasterService",
"tags": [ "ApiService" ],
"address": "192.168.1.232",
"port": ,
"checks": [
{
"id": "ApiServiceA_Check",
"name": "ApiServiceA_Check",
"http": "http://192.168.1.232:5011/health",
"interval": "10s",
"tls_skip_verify": false,
"method": "GET",
"timeout": "1s"
}
]
}

主要提供了服务名,标签,地址,端口,健康检查入口,等等

中间件准备好之后,在startup中使用中间件:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseSwagger(); app.UseSwagger(c =>
{
c.RouteTemplate = "{documentName}/swagger.json";
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/master/swagger.json", "api1 doc");
c.ShowExtensions();
}); app.UseMvc(); ConsulService consulService = new ConsulService() { IP = Configuration["Consul:IP"], Port = Convert.ToInt32(Configuration["Consul:Port"]) }; HealthService healthService = new HealthService() { IP = Configuration["Service:IP"], Port = Convert.ToInt32(Configuration["Service:Port"]), Name = Configuration["Service:Name"], }; app.RegisterConsul(lifetime, healthService, consulService);
}

以此,将当前webapi 注册到了 consul。

另外一个子节点webapi要做一样的处理;下面进行检验结果

1. 开启 consul 服务

consul agent -server -ui -bootstrap-expect= -data-dir=/tmp/consul -node=consul- -client=0.0.0.0 -bind=0.0.0.0 -datacenter=dc1 &

报错, No cluster leader

服务没有选举出新的leader,这里正常情况下,是会选举出新leader consul-1, 因为单机,所以只能选惟一那个(空头司令)

查到原因说是, consul 服务没有被优雅的关闭掉,导致的。

进到  https://learn.hashicorp.com/consul/day-2-operations/advanced-operations/outage

To recover from this, go to the -data-dir of the failing Consul server. Inside the data directory there will be a raft/ sub-directory. Create a raft/peers.json file in the raft/ directory.

For Raft protocol version 3 and later, this should be formatted as a JSON array containing the node ID, address:port, and suffrage information of the Consul server, like this:

[{ "id": "<node-id>", "address": "<node-ip>:8300", "non_voter": false }]

node-id,和node-ip也换了,照做了,没用。

于是我暴力地把 -data-dir 下面的文件全干掉了。

再次启动 consul 服务,是可以正常开启了

成功选举了当前节点为leader

将API全部开启,可以看到两个服务都能成功注册进去。从上面的实验得出一个结论,单机模式是真的很有风险的,因为些不可知的原因导致consul服务停掉了。

下面跟上一篇一样,最关键的一步,让其中一个节点挂掉,看看服务还能不能继续,我把 api2,关掉,后面再访问,一直都是

试验完毕。

至此,单机环境下,以 ocelot为网关做负载均衡,并使用consul来做服务发现的学习到此分享完。

负载均衡之Ocelot+Consul(WebAPI注册服务)的更多相关文章

  1. 负载均衡之Ocelot+Consul(配置文件注册服务)

    继上篇 Ocellot 做负载均衡之后,本篇将记录 Ocelot + Consul 试验如何做服务发现和服务注册. 服务发现和服务注册的背景知识,一搜满街都是. 在此,我还是写下自己对这个术语的理解吧 ...

  2. 负载均衡之nginx+consul(自动更新路由)

    前几篇先是记载了如何通过nginx配置服务负载均衡,后面记载了如何通过 ocelot 配置 服务负载均衡,分别介绍了用webapi注册服务以及配置文件注册服务,通过ocelot webapi + co ...

  3. 动态负载均衡(Nginx+Consul+UpSync)环境搭建

    首先 安装好 Consul upsync 然后: 1.配置安装Nginx 需要做配置,包括分组之类的,创建目录,有些插件是需要存放在这些目录的 groupadd nginx useradd -g ng ...

  4. 动态负载均衡(Nginx+Consul+UpSync)

    Http动态负载均衡 什么是动态负载均衡 传统的负载均衡,如果Upstream参数发生变化,每次都需要重新加载nginx.conf文件, 因此扩展性不是很高,所以我们可以采用动态负载均衡,实现Upst ...

  5. 【3分钟就会系列】使用Ocelot+Consul搭建微服务吧!

    一.什么Ocelot? API网关是一个服务器,是系统的唯一入口.API 网关一般放到微服务的最前端,并且要让API 网关变成由应用所发起的每个请求的入口.这样就可以明显的简化客户端实现和微服务应用程 ...

  6. Ocelot+Consul实现微服务架构

    API网关 API 网关一般放到微服务的最前端,并且要让API 网关变成由应用所发起的每个请求的入口.这样就可以明显的简化客户端实现和微服务应用程序之间的沟通方式.以前的话,客户端不得不去请求微服务A ...

  7. 负载均衡之Ocelot

    Ocelot 负载均衡:   背景知识,ocelot是基于 webapi 的网关框架,要使用ocelot来做路由转发和负载均衡,需要创建一个webapi,然后以这个webapi来做gateway.   ...

  8. 客户端负载均衡Feign之一:申明式服务调用Feign入门示例

    Spring Cloud提供了Ribbon和Feign作为客户端的负载均衡. 前面使用了Ribbon做客户端负载均衡,使用Hystrix做容错保护,这两者被作为基础工具类框架被广泛地应用在各个微服务的 ...

  9. 网关/负载均衡下的consul集群代理

    之前有做过使用单机版的consul实现Prometheus服务注册,以为使用集群版的consul只是将consul服务地址从节点IP变为了网关IP.但比较坑的就是,当使用consul注册一个servi ...

随机推荐

  1. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  2. Linux学习笔记之Linux相关知识

    [想成为某一方面的大神,没有捷径可走,只能不断的记录.练习.总结.coding……] notes:主要从网上摘录了一些关于Linux的历史以及一些相关内容,以便对Linux系统有一定的了解.这不但可以 ...

  3. 2017杭电多校第五场Rikka with Subset

    Rikka with Subset Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  4. Tomcat6和7版本对web.xml中taglib标签的配置差异

    原来部署在Tomcat6中的应用在Tomcat7中运行时报错如下错误: java.lang.IllegalArgumentException: taglib definition not consis ...

  5. nodejs安装node-rsa遇到的问题及解决

    nodejs第一次使用,故碰到一些小白问题: 1.使用 npm install node-rsa -S 2.封装rsa import NodeRSA from 'node-rsa'; const rs ...

  6. CircuitBreaker design pattern---reference

    It's common for software systems to make remote calls to software running in different processes, pr ...

  7. Hibernate+Spring整合开发步骤

    Hibernate是一款ORM关系映射框架+Spring是结合第三方插件的大杂烩,Hibernate+Spring整合开发效率大大提升. 整合开发步骤如下: 第一步:导入架包: 1.Hibernate ...

  8. WinRT ListView间隔变色(一)

    我们知道,在WPF里,MSDN提供了三种方法 1.使用转换器Converter 2.继承ListView类,自己处理 3.使用StyleSelctor 到了WinRT的世界了 1. Winrt中Set ...

  9. CAD制作简单动画

    主要用到函数说明: IMxDrawEntity::Rotate 旋转一个对象.详细说明如下: 参数 说明 [in] IMxDrawPoint* basePoint 旋转基点 [in] DOUBLE d ...

  10. 13Microsoft SQL Server SQL 高级事务,锁,游标,分区

    Microsoft SQL Server SQL高级事务,锁,游标,分区 通过采用事务和锁机制,解决了数据库系统的并发性问题. 9.1数据库事务 (1)BEGIN TRANSACTION语句定义事务的 ...