上一篇   负载均衡之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. ssh使用秘钥文件连接提示WARNING: UNPROTECTED PRIVATE KEY FILE!(转载)

    转自:http://www.01happy.com/ssh-unprotected-private-key-file/ 在centos 6.4下使用ssh连接远程主机时,用的是另外一个密钥,需要用-i ...

  2. bzoj 1800: [Ahoi2009]fly 飞行棋【枚举】

    在圆里所以没有平行四边形,n^4枚举点即可 #include<iostream> #include<cstdio> using namespace std; const int ...

  3. OAuth2.0最简向导

    无论你是否有技术背景,你都能看懂授权协议框架OAuth2.0 翻译来自:川崎高彦对自己投资人讲解自己的SaaS安全产品. Got it! https://medium.com/@darutk/the- ...

  4. python 操作数据库时遇到的错误

       pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; ch    之前的写法是从文件里 ...

  5. 396 Rotate Function 旋转函数

    给定一个长度为 n 的整数数组 A .假设 Bk 是数组 A 顺时针旋转 k 个位置后的数组,我们定义 A 的“旋转函数” F 为:F(k) = 0 * Bk[0] + 1 * Bk[1] + ... ...

  6. js jquery 获取服务器控件的三种方法

    由于ASP.NET网页运行后,服务器控件会随机生成客户端id,jquery获取时候不太好操作,google了下,总结有以下3种方法: 服务器控件代码:<asp:TextBox ID=" ...

  7. Java内存模型原理,你真的理解吗?

    [51CTO.com原创稿件]这篇文章主要介绍模型产生的问题背景,解决的问题,处理思路,相关实现规则,环环相扣,希望读者看完这篇文章后能对 Java 内存模型体系产生一个相对清晰的理解,知其然知其所以 ...

  8. Elasticsearch--更好的搜索_加权得分,脚本,同义词

    目录 Apache Lucene评分 Elasticsearch的脚本功能 脚本执行过程中可以使用的对象 使用自定义的脚本库 搜索不同语言的内容 使用加权影响得分 加权 function_score查 ...

  9. 百度地图API在vue-cli中路径错误的问题

    在使用百度地图的时候,需要使用自定义的icon图片,百度的案例中使用的是线上地址,但当替换为本地图片路径的时候,错误出现了 这是本地图片地址 ) // 设置覆盖物大小 ); 这里有一点需要注意,这里路 ...

  10. SQL server 上机练习题

    首先创建一个数据库,里面有 登录表 学生表   课程表   选课表 成绩表 1. 查询Student表中的所有记录的Sname.Ssex和Class列.2. 查询教师所有的单位即不重复的Depart列 ...