上一篇   负载均衡之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. 基于ELK的传感器数据分析练习

    目录 Sensor Data Analytics Application 数据构成 数据模型设计 Logstash配置 Kibana可视化 Sensor Data Analytics Applicat ...

  2. MogileFS介绍

    MogileFS介绍 MogileFS 是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发. Danga团队开发了包括 Memcached.Mog ...

  3. robotframework - selenium 分层思路

    前言: 对于每一条用例来说,调用“百度搜索”关键字,输入搜索内容,输入预期结果即可.不同关心用例是如何执行的.如果百度输入框的定位发生了变化,只用去修改“百度搜索”关键字即可,不用对每一条用例做任何修 ...

  4. 测试神器Swagger的相关使用

    1.Swagger简介 swagger官网地址: https://swagger.io/ swagger官网文档介绍地址: https://swagger.io/about/ ​ swagge是一个易 ...

  5. 经典矩阵dp寻找递增最大长度

    竖向寻找矩阵最大递增元素长度,因为要求至少一列为递增数列,那么每行求一下最大值就可以作为len[i]:到i行截止的最长的递增数列长度. C. Alyona and Spreadsheet time l ...

  6. 278 First Bad Version 第一个错误的版本

    你是产品经理,目前正在领导一个团队开发一个新产品.不幸的是,您的产品的最新版本没有通过质量检查.由于每个版本都是基于之前的版本开发的,所以错误版本之后的所有版本都是不好的.假设你有 n 个版本 [1, ...

  7. Canvas入门笔记-实现极简画笔

    今天学习了Html5 Canvas入门,已经有大神写得很详细了http://www.cnblogs.com/tim-li/archive/2012/08/06/2580252.html#8 在学习过后 ...

  8. js实现浮动框跟随页面滚动,最后停留在原来位置

    左边悬浮的二维码会跟随页面向上或者向下滚动,最后停留在原来的位置. <div style="background:red; width:1000px; height:7000px; m ...

  9. Scala-基础-函数(1)

    import junit.framework.TestCase //函数(1) class Demo5 extends TestCase { def testDemo(){ println(" ...

  10. (1)麻省理工:计算机科学和 Python 编程导论

    本门课用的语言是python2.7,我的主要学习语言是C++11,所以不是特殊说明,则认为和C++中的是一样的(不管是语法还是表达式),当然,也有我不懂而错认为与C++一样的东西~ Week1 第一讲 ...