• 微服务-基于Consul的服务注册与发现(1)


    本系列简单介绍自己搭建微服务架构的过程,如有问题,请多指正!

    1.集群部署
    微服务被调用后,如果意外停止服务,将会影响系统的部分功能运行,于是采用集群来解决这个问题。
    创建.Net Core的WebApi项目,编译后启动
    dotnet MicService.dll --urls="http://*:7002" --text="我是7002"
    dotnet MicService.dll --urls="http://*:7003" --text="我是7003"
    dotnet MicService.dll --urls="http://*:7004" --text="我是7004"
     
    2.Nginx负载均衡
    集群过多之后,需要做负载均衡,引入了Nginx。
    Nginx有4种经典方式:轮询方式权重方式ip_hash方式,第三方模块方式
    本次我们采用权重方式
    nginx.conf的配置如下:
     1 upstream myserver {
     2     server localhost:7002 weight=1;
     3     server localhost:7003 weight=3;
     4     server localhost:7004 weight=6;
     5 } 
     6 server {
     7     listen   82;
     8     server_name localhost;
     9     location / {
    10         proxy_pass   http://myserver;
    11     }
    12 }
    Nginx启动,双击即可。

     

    如果Nginx启动出错,可能安装路径含有中文,错误如下图所示:
    结果如下:监听82端口,根据分配权重,跳转到7002,7003,或7004端口下

     

    3.Consul服务发现与治理
    Nginx使用的过程中,需要手动配置对应的微服务地址,无法主动发现,通过Ocelot来处理解决服务治理的问题。服务通过再Consul注册,从而发现服务,统一管理。
    下载完成后启动: consul.exe agent -dev

     

    Consul的默认端口是8500,访问本地8500,localhost:8500

     

    (1)服务注册
    引入Consul的Nuget包
     1 public static async void ConsulRegist(this IConfiguration configuration)
     2     {
     3         string ip = configuration["ip"];
     4         int port = int.Parse(configuration["port"]);
     5         int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
     6         using (ConsulClient client = new ConsulClient(c =>
     7         {
     8             c.Address = new Uri("http://localhost:8500/");
     9             c.Datacenter = "dc1";
    10         }))
    11         {
    12             await client.Agent.ServiceRegister(new AgentServiceRegistration()
    13             {
    14                 ID = "service " + ip + ":" + port,// 服务唯一标识
    15                 Name = "MicServiceName",//分组
    16                 Address = ip,
    17                 Port = port,
    18                 Tags = new string[] { weight.ToString() }, //额外信息传递
    19                 //心跳检查
    20                 Check = new AgentServiceCheck()
    21                 {
    22                     Interval = TimeSpan.FromSeconds(12),  //12秒间隔一次
    23                     HTTP = $"http://{ip}:{port}/Api/Health/Index", //心跳检查地址
    24                     Timeout = TimeSpan.FromSeconds(5), //监测等待时间
    25                     DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20) //失败后20秒移除
    26                 }
    27             });
    28           
    29         }
    30     }

    在startup.cs文件的Configure添加注册

     this.Configuration.ConsulRegist();
    (2)服务发现之WebApi
    dotnet MicService.dll --urls="http://*:7002" --ip="127.0.0.1" --port=7002 --weight=1
    dotnet MicService.dll --urls="http://*:7003" --ip="127.0.0.1" --port=7003 --weight=1
    MicServiceName的Instance实例数变为2个
    点击“MicServiceName”详情,可以看到两个注册的服务在运行中
    (2)服务发现之GPRPC
    ====待补充===
     
    4.使用服务
    (1)创建客服端WebAPI项目
     
    引入Consul的Nuget包
     
    新建API控制器“ClienterController.cs”,注意其中的url,对应步骤3中的服务名称(MicServiceName),"http://MicServiceName/WeatherForecast"
     1 public class ClienterController : ControllerBase
     2 {
     3     private static int _iTotalCount = 0;
     4     private static int iTotalCount
     5     {
     6         get
     7         {
     8             return _iTotalCount;
     9         }
    10         set
    11         {
    12             _iTotalCount = value >= Int32.MaxValue ? 0 : value;
    13         }
    14     }
    15     /// <summary>
    16     /// GetConsulMic
    17     /// </summary>
    18     /// <returns></returns>
    19     [HttpPost("GetConsulMic")]
    20     public async  Task<string> GetConsulMic()
    21     {
    22         string url = null;
    23          
    24         #region Consul
    25         url = "http://MicServiceName/WeatherForecast";//客户端得知道调用啥服务,啥名字---consul就是个DNS
    26 
    27         ConsulClient client = new ConsulClient(c =>
    28         {
    29             c.Address = new Uri("http://localhost:8500/");
    30             c.Datacenter = "dc1";
    31         });
    32         var response = client.Agent.Services().Result.Response;
    33 
    34 
    35         Uri uri = new Uri(url);
    36         string groupName = uri.Host;
    37         AgentService agentService = null;
    38 
    39         //找到的全部服务
    40         var serviceDictionary = response.Where(s => s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();
    41         {
    42            
    43             //有多个服务 选择一个 用到负载均衡策略
    44             int index = iTotalCount++ % serviceDictionary.Length;
    45             agentService = serviceDictionary[index].Value;
    46         }
    47         url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";
    48         #endregion
    49          
    50         return InvokeApi(url);
    51     }
    52     public static string InvokeApi(string url)
    53     {
    54         using (HttpClient httpClient = new HttpClient())
    55         {
    56             HttpRequestMessage message = new HttpRequestMessage();
    57             message.Method = HttpMethod.Get;
    58             message.RequestUri = new Uri(url);
    59             var result = httpClient.SendAsync(message).Result;
    60             string content = result.Content.ReadAsStringAsync().Result;
    61             return content;
    62         }
    63     }
    64 }
    运行结果如下:
    (2)对字符串进行解析,返回实体数组
    1 return Newtonsoft.Json.Linq.JArray.Parse(content).ToObject<List<WeatherForecast>>();

    结果如下:

     
    以上,仅用于学习和总结!

  • 相关阅读:
    Flex 学习笔记------组件和视图
    Flex 学习笔记------基于LZMA的文件压缩与上传
    Flex 学习笔记------FLACC & Crossbridge
    Flex 学习笔记------全局事件
    Flex 学习笔记------对象的深层拷贝
    Flex 学习笔记------as 与 js 的通信
    Flex 学习笔记------Local Shared Object 和 Custom Class
    Flex 学习笔记------读取Jpeg图片的width,height和colorSpace
    翻译:eval() 不是魔鬼,只是易被误解
    翻译:javascript 内存管理
  • 原文地址:https://www.cnblogs.com/ywkcode/p/14186986.html
Copyright © 2020-2023  润新知