如果没看第一篇的可以看第一篇(小白)
前言
提示:Ocelot + Consul + Polly … + Ids4(后面再补充)
例如:随着后端的不断发展,服务治理这门技术也越来越重要,很多人都开启了学习服务治理,本文就介绍了一点点基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Ocelot Consul Polly 是什么?
上一篇是 Ocelot第一篇 没看的可以去看看点击左侧连接
consul 注册发现
是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)
Polly 熔断降级
.Net Core 中有一个被.Net基金会认可的k库,可以用来进行熔断降级,主要功能:1.重试(retry);2.断路器(circuit-breaker);3.超时检测(timeout);4.缓存(cache);5.降级(fallback)
官方:https://github.com/app-vnext/polly nuget: install-package Polly-Version 6.0.1
他们加一起就可以搞服务治理;
二、使用步骤
1.引入库
代码如下(示例):
using Consul;
using Microsoft.Extensions.Configuration; //是为了读取配置文件块;
2. 注册服务
Consul自行下载:
下载后启动:
consul agent -dev -bind=192.168.1.200 -client 0.0.0.0 -ui
这样就可以启动了
========================
服务端:
consul agent -server -bootstrap-expect 1 -config-dir /etc/consul.d/ -data-dir /var/opt/consul -bind=125.72.214.83 >> /var/opt/consul/consul.log 2>&1
客户端
consul agent -config-dir /etc/consul.d/ -data-dir /var/opt/consul -bind=121.42.204.73 -join=121.42.204.73 >consul.log 2>&1 &
服务端和客户端的启动命令 我是从这个地方抄的,尊重原作者我附上原文连接 :https://www.cnblogs.com/niejunlei/p/5982911.html
代码如下(示例):可以封装在基础框架里面 或者 Core 核心层 或者Common等代码类库李;
//注册的代码
public class consulwebhost
{
public string ip { get; set; }
public string port { get; set; }
public string name { get; set; }
public string schame { get; set; }
}
public static class ConsulExtend
{
public static void AddConsulRegister(this IConfiguration _configuration)
{
string ConsulHostPort = _configuration["consul:consulhost"];
ConsulClient clinet = new ConsulClient(c =>
{
c.Address = new Uri(ConsulHostPort); //consul 控制台的地址。
c.Datacenter = "dcl";
});
var list = _configuration.GetSection("consul:webhost").Get<List<consulwebhost>>();
foreach (var item in list)
{
string ip = item.ip;
int port = int.Parse(item.port);
string name = item.name;
clinet.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = name + "-" + port,
Name = name,
Address = ip,
Port = port,
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(1),//间隔*秒一次
HTTP = $"{item.schame}://{ip}:{port}/api/Health/Check", ///这是你要让他定期访问的地址 返回一个ok就行
Timeout = TimeSpan.FromSeconds(1),//检测等待时间
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10)//失败多久后移除
}
}).Wait();
}
}
}
//配置文件 (需要放到appsettings。json里)
"consul": {
"consulhost": "http://你的ip地址:端口",
"webhost": [
{
"schame": "http",
"ip": "IP",
"port": "端口",
"name": "FarmzaiV3",
"timeout": "1"
}
]
}
添加调用 configuration.AddConsulRegister();
网关代码
1.初始化管道配置
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot().AddConsul();//.AddPolly();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOcelot().Wait();
}
Program builder.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath).AddJsonFile(“ocelot.json”)
这句最重要
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, builder) => {
builder.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath).AddJsonFile("ocelot.json");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
2.配置文件配置
该处使用的url网络请求的数据。
{
"Routes": [
{
"DownstreamPathTemplate": "/{url}", //服务地址--url变量
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/v3/{url}", //网关地址--url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"UseServiceDiscovery": true,
"ServiceName": "ServiceA", //consul服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
}
}
],
"GlobalConfiguration": {
"BaseUrl": "IP:PORT", //网关对外地址
"ServiceDiscoveryProvider": {
"Host": "IP", /// 这个地方不要加http://之类的 --- 有坑 有坑 有坑!!!
"Port": 8500,
"Type": "Consul" //由Consul提供服务发现, 每次请求去consul
}
}
}
*****************************Consul+缓存Cache********************************
//{
// "Routes": [
// {
// "DownstreamPathTemplate": "/api/{url}", //服务地址--url变量
// "DownstreamScheme": "http",
// "UpstreamPathTemplate": "/T/{url}", //网关地址--url变量
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UseServiceDiscovery": true,
// "ServiceName": "ServiceA", //consul服务名称
// "LoadBalancerOptions": {
// "Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
// },
// "FileCacheOptions": {
// "TtlSeconds": 15, //Second
// "Region": "UserCache" //可以调用Api缓存清理
// }
// }
// ],
// "GlobalConfiguration": {
// "BaseUrl": "http://IP:PORT", //网关对外地址
// "ServiceDiscoveryProvider": {
// "Host": "localhost",
// "Port": 8500,
// "Type": "Consul" //由Consul提供服务发现, 每次请求去consul
// }
// //"ServiceDiscoveryProvider": {
// // "Host": "localhost",
// // "Port": 8500,
// // "Type": "PollConsul", //由Consul提供服务发现,
// // "PollingInterval": 1000 //轮询consul,频率毫秒--down掉是不知道的
// // //"Token": "footoken"//需要ACL的话
// //}
// }
//}
雪崩效应
如果有三台服务器ABC 那么突如其来的大流量 可能会冲垮其中一台服务器 如果A挂了 网关会把流量都转到B A 那么可能会导致B挂了 那么流量都会转发到A 。。。最后就成了单体架构了 大量的流量都转发到A那么A也会被冲挂了:
1.超时 熔断 限流 - 降级
using Ocelot.Provider.Polly;
*****************************超时+限流+熔断+降级+Consul+Polly********************************
//{
// "Routes": [
// {
// "DownstreamPathTemplate": "/api/{url}", //服务地址--url变量
// "DownstreamScheme": "http",
// "UpstreamPathTemplate": "/T/{url}", //网关地址--url变量
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UseServiceDiscovery": true,
// "ServiceName": "ServiceA", //consul服务名称
// "LoadBalancerOptions": {
// "Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
// },
// "RateLimitOptions": {
// "ClientWhitelist": [ "eleven", "seven" ], //白名单 ClientId 区分大小写
// "EnableRateLimiting": true,
// "Period": "5m", //1s, 5m, 1h, 1d
// "PeriodTimespan": 30, //多少秒之后客户端可以重试
// "Limit": 5 //统计时间段内允许的最大请求数量
// },
// //"AuthenticationOptions": {
// // "AuthenticationProviderKey": "UserGatewayKey",
// // "AllowedScopes": []
// //}
// //"QoSOptions": {
// // "ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求
// // "DurationOfBreak": 10000, // 熔断的时间,单位为ms
// // "TimeoutValue": 2000 //单位ms 如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90秒
// //}
// //"FileCacheOptions": {
// // "TtlSeconds": 15,
// // "Region": "UserCache" //可以调用Api清理
// //}
// }
// ],
// "GlobalConfiguration": {
// "BaseUrl": "http://IP:PORT", //网关对外地址
// "ServiceDiscoveryProvider": {
// "Host": "localhost",
// "Port": 8500,
// "Type": "Consul" //由Consul提供服务发现
// },
// "RateLimitOptions": {
// "QuotaExceededMessage": "Too many requests, maybe later? 11", // 当请求过载被截断时返回的消息
// "HttpStatusCode": 666, // 当请求过载被截断时返回的http status
// //"ClientIdHeader": "client_id" // 用来识别客户端的请求头,默认是 ClientId
// }
// }
//}
//*****************************请求聚合Aggregator********************************
{
"Routes": [
{
"DownstreamPathTemplate": "/api/users/all",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5726 //服务端口
} //可以多个,自行负载均衡
],
"UpstreamPathTemplate": "/T5/users/all",
"UpstreamHttpMethod": [ "Get", "Post" ],
"key": "T5"
},
{
"DownstreamPathTemplate": "/api/users/all",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5727 //服务端口
}
],
"UpstreamPathTemplate": "/T6/users/all",
"UpstreamHttpMethod": [ "Get", "Post" ],
"key": "T6"
},
{
"DownstreamPathTemplate": "/api/users/all",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5728 //服务端口
}
],
"UpstreamPathTemplate": "/T7/users/all",
"UpstreamHttpMethod": [ "Get", "Post" ],
"key": "T7"
}
],
"Aggregates": [
{
"RouteKeys": [
"T5",
"T6",
"T7"
],
"UpstreamPathTemplate": "/UserAggregator", //如果某个404 是不影响返回,当成null
"Aggregator": "CustomUserAggregator" //自定义聚合器
}
]
}
总结
提示:
这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了Ocelot+Consul的使用。
现在整再使用的配置文件:
{
“Routes”: [
{
“DownstreamPathTemplate”: “/{url}”, //服务地址–url变量
“DownstreamScheme”: “http”,
“UpstreamPathTemplate”: “/{url}”, //网关地址–url变量
“UpstreamHttpMethod”: [ “Get”, “Post” ],
“UseServiceDiscovery”: true,
“ServiceName”: “FarmzaiV3”, //consul服务名称
“LoadBalancerOptions”: {
“Type”: “RoundRobin” //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
},
“RateLimitOptions”: {
“ClientWhitelist”: [ “bin”, “charles” ], //白名单 ClientId 区分大小写
“EnableRateLimiting”: true,
“Period”: “5m”, //1s, 5m, 1h, 1d
“PeriodTimespan”: 10, //多少秒之后客户端可以重试
“Limit”: 100 //统计时间段内允许的最大请求数量
},
“QoSOptions”: { //超时 熔断
“ExceptionsAllowedBeforeBreaking”: 3, //允许多少个异常请求
“DurationOfBreak”: 10000, // 熔断的时间,单位为ms
“TimeoutValue”: 3000 //单位ms 如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90秒
}
// //“AuthenticationOptions”: {
// // “AuthenticationProviderKey”: “UserGatewayKey”,
// // “AllowedScopes”: []
// //}
// //"FileCacheOptions": {
// // "TtlSeconds": 15,
// // "Region": "UserCache" //可以调用Api清理
// //}
},
{
"DownstreamPathTemplate": "/{url}", //服务地址--url变量
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/t/{url}", //网关地址--url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"UseServiceDiscovery": true,
"ServiceName": "test", //consul服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
},
"RateLimitOptions": {
"ClientWhitelist": [ "bin", "charles" ], //白名单 ClientId 区分大小写
"EnableRateLimiting": true,
"Period": "5m", //1s, 5m, 1h, 1d
"PeriodTimespan": 10, //多少秒之后客户端可以重试
"Limit": 100 //统计时间段内允许的最大请求数量
},
"QoSOptions": { //超时 熔断
"ExceptionsAllowedBeforeBreaking": 10, //允许多少个异常请求
"DurationOfBreak": 10000, // 熔断的时间,单位为ms
"TimeoutValue": 3000 //单位ms 如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90秒
}
}
],
“GlobalConfiguration”: { //服务发现
“BaseUrl”: “http://localhost:44324”, //网关对外地址
“ServiceDiscoveryProvider”: {
“Host”: “192.168.1.200”,
“Port”: 8500,
“Type”: “Consul” //由Consul提供服务发现, 每次请求去consul
},
“RateLimitOptions”: { //限流
“QuotaExceededMessage”: "Too many requests, maybe later? ", // 当请求过载被截断时返回的消息
“HttpStatusCode”: 666, // 当请求过载被截断时返回的http status
“ClientIdHeader”: “client_id” // 用来识别客户端的请求头,默认是 ClientId
}
}
}