一、Consul服务注册发现
1.启动Consul :consul agent -dev
2.打开Consul地址,默认8500端口:8500
3.封装静态类,注册Consul服务的方法:
using Consul;
using Microsoft.Extensions.Configuration;
using System;
public static class ConsulHelper
{
/// <summary>
/// Consul注册
/// </summary>
/// <param name="configuration"></param>
public static void ConsulRegist(this IConfiguration configuration)
{
ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri("http://localhost:8500/");
c.Datacenter = "dc1";
});//找到consul
string ip = string.IsNullOrWhiteSpace(configuration["ip"]) ? "192.168.3.230" : configuration["ip"];
int port = int.Parse(configuration["port"]);//命令行参数必须传入
int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = "service" + Guid.NewGuid(),//注册的服务ID
Name = "TestService",//Group--分组
Address = ip,//
Port = port,//
Tags = new string[] { weight.ToString() },//标签 每个服务所占的权重
//设置健康检测,动态伸缩,当服务不可用时删掉该服务,服务可用增加
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(12),//间隔12s一次
HTTP = $"http://{ip}:{port}/Api/Health/Index",//控制器
Timeout = TimeSpan.FromSeconds(5),//检测等待时间
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(120)//失败后多久移除
}
});
//命令行参数获取
Console.WriteLine($"注册成功:{ip}:{port}--weight:{weight}");
}
}
4.在Startup.cs文件或者Program.cs文件总注册服务:
//初始化一次
app.Configuration.ConsulRegist();
5.设置健康检测的控制服务
app.MapWhen(context => context.Request.Path.Equals("/Api/Health/Index"),
applicationBuilder => applicationBuilder.Run(async context =>
{
Console.WriteLine($"This is Health Check");
context.Response.StatusCode = (int)HttpStatusCode.OK;
await context.Response.WriteAsync("OK");
}));
二、前端服务的发现与调用
private static int iIndex = 0;//暂不考虑线程安全
#region Consul服务注册发现
//consul获取服务--得知道Consul服务中的服务组名和API函数名
string url = null;
url = "http://ZhaoxiService/api/users/all";//Consul服务中的服务组名和API函数名
ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri("http://localhost:8500/");
c.Datacenter = "dc1";
});//找到consul--像DNS
var response = client.Agent.Services().Result.Response;//获取服务清单
Uri uri = new Uri(url);
string groupName = uri.Host;
AgentService agentService = null;
var dictionary = response.Where(s => s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();
////默认使用第一个注册的服务,无意义
{
//agentService = dictionary[0].Value;
}
////轮询策略 也是平均,但是太僵硬了
{
//agentService = dictionary[iIndex++ % dictionary.Length].Value;
}
////平均策略--随机获取索引--相对就平均
{
//agentService = dictionary[new Random(iIndex++).Next(0, dictionary.Length)].Value;
}
//权重:3个实例能力不同,承担的压力也要不同
{
List<KeyValuePair<string, AgentService>> pairsList = new List<KeyValuePair<string, AgentService>>();
foreach (var pair in dictionary)
{
int count = int.Parse(pair.Value.Tags?[0]);//1 5 10
for (int i = 0; i < count; i++)
{
pairsList.Add(pair);
}
}
//16个
agentService = pairsList.ToArray()[new Random(iIndex++).Next(0, pairsList.Count())].Value;
}
url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";
string content = InvokeApi(url);
base.ViewBag.Users = JsonConvert.DeserializeObject<IEnumerable<User>>(content);
Console.WriteLine($"This is {url} Invoke");
#endregion
标签:负载,服务,string,dictionary,int,Consul,new,搭建 From: https://www.cnblogs.com/jiangyuhu/p/17726402.html