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-2026 CODEPRJ.COM