.net Core微服务架构之健康检查和自定义负载均衡策略

.net Core微服务架构之健康检查和自定义负载均衡策略 以下是框架结构图

Nuget下载Consul,服务注册核心代码(写了一个扩展方法) Nuget下载Consul,服务注册核心代码(写了一个扩展方法)
public static class ConsuHelper
{
    public static void ConsuRegist(this IConfiguration configuration)
    {
        try
        {
            //与Consul建立连接
            ConsulClient client = new ConsulClient(c =>
            {
                c.Address = new Uri("http://42.51.12.85:8500");//localhost
                c.Datacenter = "dc1";
            });

            string ip = configuration["ip"];//这个一定要命令行启动,不然获取不到会报错
            int port = int.Parse(configuration["port"]);
            //注册服务到Consul
            client.Agent.ServiceRegister(new AgentServiceRegistration()
            {
                ID = "Service" + Guid.NewGuid(),//维一ID
                Name = "lqwvje",//组名
                Address = ip,//"127.0.0.1",
                Port = port,
                Check = new AgentServiceCheck()
                {
                    Interval = TimeSpan.FromSeconds(5),//健康检查时间间隔,或者称为心跳间隔
                    HTTP = $"http://{ip}:{port}/api/HealthCheck",//健康检查地址
                    Timeout = TimeSpan.FromSeconds(5),
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5)//服务启动多久后注册
                }
            });
        }
        catch
        {
        }
    }
}
//下面是Startup类 Configure应用此扩展方法  这里我用的是.net core 3.0
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //TODO...
    this.Configuration.ConsuRegist();
}
服务端心跳Api接口
[Route("api/[controller]")]
[ApiController]
public class HealthCheckController : ControllerBase
{
    // GET: api/HealthCheck
    [HttpGet]
    public OkResult Get()
    {
        return Ok();
    }
}
下面是客户端发现服务端核心代码如下
private static int iSeed = 0;
public string GetAPIData()
{
    //与Consul建立连接
    ConsulClient client = new ConsulClient(c =>
    {
        c.Address = new Uri("http://localhost:8500");
        c.Datacenter = "dc1";
    });
    var dic = client.Agent.Services().Result.Response;//获取集群所有服务端信息
    string url = "http://lqwvje/weatherforecast";  //lqwvje为服务端注册的组名
    Uri uri = new Uri(url);
    string groupName = uri.Host;
    var list = dic.Where(k => k.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase));
    if (list == null || list.Count() < 1) { return "未发现服务端"; }
    if (iSeed > 100_000_000) { iSeed = 0; }
    var keyValuePair = list.ToArray()[iSeed % list.Count()];//轮询策略--多线程的话对++上锁


    //现在只用
    {
        //keyValuePair = list.ToArray()[new Random(iSeed++).Next(0, list.Count())];//均衡策略--平均呗
    }


    {
        //权重策略--原来也就这么简单
        //客户端必须知道服务实例的权重---注册consul时提供的--1/3/6
        //List<KeyValuePair<string, AgentService>> pairsList = new List<KeyValuePair<string, AgentService>>();
        //foreach (var pair in list)
        //{
        //    int count = int.Parse(pair.Value.Tags?[0]);
        //    for (int i = 0; i < count; i++)
        //    {
        //        pairsList.Add(pair);
        //    }
        //}
        //keyValuePair = pairsList.ToArray()[new Random(iSeed++).Next(0, pairsList.Count())];
    }


    iSeed++;
    string targetUrl = $"{uri.Scheme}://{keyValuePair.Value.Address}:{keyValuePair.Value.Port}/WeatherForecast";

    using (HttpClient httpClient = new HttpClient())//获取接口数据
    {
        HttpRequestMessage message = new HttpRequestMessage();
        message.Method = HttpMethod.Get;
        message.RequestUri = new Uri(targetUrl);
        HttpResponseMessage result2 = httpClient.SendAsync(message).Result;
        string rs = result2.Content.ReadAsStringAsync().Result;
        return targetUrl+"\r\n" + rs;
    }
}

转载请保留原创地址 http://www.luofenming.com/show.aspx?id=ART2019121800002

整套源码下载地址:https://pan.baidu.com/s/1Tjiii5R_cgwhqihTpvvpmg  提取码:74br


服务流程

启动 Consul服务
consul_1.6.2.exe agent -dev -http-port 8500 -ui -client 0.0.0.0
//查看Consul状态
http://localhost:8500 
//启动服务端  端口可以随意写  多启动几个
dotnet apiServerDemo.dll --urls="http://*:5004"  --ip="127.0.0.1" --port=5004
dotnet apiServerDemo.dll --urls="http://*:5005"  --ip="127.0.0.1" --port=5005
dotnet apiServerDemo.dll --urls="http://*:5006"  --ip="127.0.0.1" --port=5006

//客户端  启动就会根据  自定义负载均衡策略 在集群中某台服务器上执行业务
dotnet apiClient.dll
浏览器防问 http://localhost:5000/,每次刷新都会换成不同的服务端数据