Consul--客户端访问Consul服务


          根据上一篇Consul服务的注册和发现,那么客户端如何去访问我们的Consul服务?其实客户端访问Consul实际上是访问Consul的服务实例。客户端自己可以实现对Consul服务实例的轮训,每次刷新端口都会发生改变,由于客户端访问Consul采用的轮训策略,所以每次刷新Consul的服务实例都会发生改变。

       下面就直接上客户端访问Consul服务实例的代码:

      

using System;
using System.Collections.Generic;
using System.Text;

namespace Demo
{
    /// <summary>
    /// 用户服务的接口定义。
    /// </summary>
    public interface IUserService
    {
        /// <summary>
        /// 查找指定主键的用户实例对象。
        /// </summary>
        /// <param name="id">用户的主键。</param>
        /// <returns>返回查找到的用户实例对象。</returns>
        User FindUser(int id);

        /// <summary>
        /// 获取所有用户的实例集合。
        /// </summary>
        /// <returns>返回所有的用户实例。</returns>
        IEnumerable<User> UserAll();
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Demo
{
    /// <summary>
    /// 用户模型。
    /// </summary>
    public class User
    {
        /// <summary>
        /// 获取或者设置用户主键。
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// 获取或者设置用户姓名。
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 获取或者设置用户账号名称。
        /// </summary>
        public string Account { get; set; }

        /// <summary>
        /// 获取或者设置用户密码。
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// 获取或者设置用户的电子邮箱地址。
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// 获取或者设置用户角色。
        /// </summary>
        public string Role { get; set; }

        /// <summary>
        /// 获取或者设置用户的登录时间。
        /// </summary>
        public DateTime LoginTime { get; set; }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo
{
    /// <summary>
    /// 实现用户服务接口的实现类型。
    /// </summary>
    public class UserService : IUserService
    {
        private IList<User> dataList;

        /// <summary>
        /// 初始化类型的实例
        /// </summary>
        public UserService()
        {
            dataList = new List<User>()
             {
             new User {ID=1,Name="张三",Account="5435435345",Password="4535435435",Email="4535345345", Role="Admin", LoginTime=DateTime.Now},
             new User {ID=2,Name="李四",Account="5435435345",Password="5435345345",Email="543534535", Role="Admin", LoginTime=DateTime.Now.AddDays(-5) },
             new User { ID = 3, Name = "王二", Account = "45354", Password = "3245345", Email = "54353455", Role = "Admin", LoginTime = DateTime.Now.AddDays(-30) },
             new User { ID = 4, Name = "麻子", Account = "45354", Password = "4534535", Email = "453534534", Role = "Admin", LoginTime = DateTime.Now.AddDays(-90) },
             new User { ID = 5, Name = "陈五", Account = "54353", Password = "5435345", Email = "5435345345", Role = "Admin", LoginTime = DateTime.Now.AddMinutes(-50) }
             };
        }

        /// <summary>
        /// 查找指定主键的用户实例对象。
        /// </summary>
        /// <param name="id">用户的主键。</param>
        /// <returns>返回查找到的用户实例对象。</returns>
        public User FindUser(int id)
        {
            return dataList.FirstOrDefault(user => user.ID == id);
        }

        /// <summary>
        /// 获取所有用户的实例集合。
        /// </summary>
        /// <returns>返回所有的用户实例。</returns>
        public IEnumerable<User> UserAll()
        {
            return dataList;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ConsulDemo.Models;
using Microsoft.Extensions.Logging;
using Demo;
using Consul;
using System.Net.Http;

namespace ConsulDemo.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
          private readonly IUserService _userService;
          private static int index;
 
          /// <summary>
          /// 初始化该类型的新实例。
        /// </summary>
          /// <param name="logger">注入日志对象。</param>
         /// <param name="userService">注入用户服务对象。</param>
         public HomeController(ILogger<HomeController> logger, IUserService userService)
          {
             _logger = logger;
              _userService = userService;
        }
  
         /// <summary>
         /// 首页。
          /// </summary>
          /// <returns></returns>
         public IActionResult Index()
          {
             #region 分布式架构           
 
             #region  通过 Consul 服务发现来执行服务实例。
  
            //发现服务
              string url = "http://PatrickLiuService/api/users/all";
  
              ConsulClient client = new ConsulClient(config =>
             {
                  config.Address = new Uri("http://localhost:8500/");
                 config.Datacenter = "dc1";
             });
             var response = client.Agent.Services().Result.Response;
             foreach (var item in response)
               {
                     Console.WriteLine("*************************************************************");
                   Console.WriteLine(item.Key);
                    var service = item.Value;
                   Console.WriteLine($"{service.Address}--{service.Port}--{service.Service}");
                    Console.WriteLine("*************************************************************");
               }
             Uri uri = new Uri(url);
            string groupName = uri.Host;
            AgentService agentService = null;

            var serviceDirectory = response.Where(s => s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();
            //{//1、 写死的
            //    agentService = serviceDirectory[0].Value;
             //}
            {
                    //2、轮询
                if (index >= 10000)
                       {
                            index = 0;
                       }
                    agentService = serviceDirectory[index++ % serviceDirectory.Length].Value;
              }
            // {//3、随机
           //     var indexResult = new Random(index++).Next(0, serviceDirectory.Length);
            //     agentService = serviceDirectory[indexResult].Value;
           //}
             url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";

 
#endregion

             string content = InvokeAPI(url);
             this.ViewBag.Users = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<User>>(content);
             Console.WriteLine($"This is {url} Invoke.");

 
#endregion
 
             return View();
         }
 
          /// <summary>
         /// 封装 HttpClient 实例,提供 Http 调用。
          /// </summary>
          /// <param name="url">http url 的地址。</param>
          /// <returns>返回结束数据,格式:JSON。</returns>
          public static string InvokeAPI(string url)
         {
                using (HttpClient client = new HttpClient())
                   {
                        HttpRequestMessage message = new HttpRequestMessage();
                        message.Method = HttpMethod.Get;
                       message.RequestUri = new Uri(url);
                       var result = client.SendAsync(message).Result;
                         string conent = result.Content.ReadAsStringAsync().Result;
                        return conent;
                     }
           }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Demo;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace ConsulDemo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSingleton<IUserService, UserService>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

 

启动Consul:

   Consul启动命令:Consul agent –dev

 

 启动5个服务实例端口分别为:1000,2000,3000,4000,5000

 

Consul实例:

 

 

 

 

 然后启动客户端,访问Consul服务实例:

第一次启动:端口1000

 

 第一次刷新端口为:2000

 

 第二次刷新端口为:3000

 

       目前为止 虽然可以自由的发现新服务,也可以发现失败的服务,实现了服务的自动注册和发现,但是Consul另外一个问题就是,客户端使用太麻烦,我们需要自己去决定调用服务策略,是轮训、随机、权重,还是其他策略,如果项目很小不是问题,如果项目很大,需求变化很快,我们都需要手动去做这些事,就太浪费时间和精力了。
         

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM