Consul服务注册与发现(三)
本章主要讲述Consul服务的调用
新建一个Client 端 .NET Core WebAPI(可以不用Docker支持)
2、引入Consul 和 RestSharp包
3、配置 Consul信息
在appsettings.json 添加 Consul地址
"ConsulSetting": {
"ConsulAddress": "http://localhost:8500/" //注意,docker容器内部无法使用localhost访问宿主机器,如果是控制台启动的话就用localhost
}
4、新增IServiceHelper 服务接口
public interface IServiceHelper
{
/// <summary>
/// 获取产品数据
/// </summary>
/// <returns></returns>
Task<string> GetProduct();
/// <summary>
/// 获取服务列表
/// </summary>
void GetServices();
}
5、新增ServiceHelper
public class ServiceHelper : IServiceHelper
{
private readonly IConfiguration _configuration;
private readonly ConsulClient _consulClient;
private ConcurrentBag<string> _myApiUrls;
public ServiceHelper(IConfiguration configuration)
{
_configuration = configuration;
_consulClient = new ConsulClient(c =>
{
//consul地址
c.Address = new Uri(_configuration["ConsulSetting:ConsulAddress"]);
//c.Datacenter = "dc1";
});
}
public async Task<string> GetProduct()
{
if (_myApiUrls == null)
return null; //Task.FromResult(""); //Task.FromResult("【产品服务】正在初始化服务列表...");
//每次随机访问一个服务实例
var client = new RestClient(_myApiUrls.ElementAt(new Random().Next(0, _myApiUrls.Count())));
var request = new RestRequest("/api/product/getall", Method.GET);
var response = await client.ExecuteAsync(request);
if (response.StatusCode == HttpStatusCode.OK)
{
return response.Content;
}
else
{
return null;
}
}
public void GetServices()
{
//var serviceNames = new string[] { "OrderService", "ProductService" };
var serviceNames = new string[] { "MyApi"};
Array.ForEach(serviceNames, p =>
{
Task.Run(() =>
{
//WaitTime默认为5分钟
var queryOptions = new QueryOptions { WaitTime = TimeSpan.FromMinutes(10) };
while (true)
{
GetServices(queryOptions, p);
}
});
});
}
private void GetServices(QueryOptions queryOptions, string serviceName)
{
var res = _consulClient.Health.Service(serviceName, null, true, queryOptions).Result;
Console.WriteLine($"{DateTime.Now}获取{serviceName}:queryOptions.WaitIndex:{queryOptions.WaitIndex} LastIndex:{res.LastIndex}");
//版本号不一致 说明服务列表发生了变化
if (queryOptions.WaitIndex != res.LastIndex)
{
queryOptions.WaitIndex = res.LastIndex;
//服务地址列表
var serviceUrls = res.Response.Select(p => $"http://{p.Service.Address + ":" + p.Service.Port}").ToArray();
if (serviceName == "MyApi")
_myApiUrls = new ConcurrentBag<string>(serviceUrls);
}
}
}
6、注入ServiceHelper
在Startup中注入 ServiceHelper
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.AddControllers();
//注入IServiceHelper
services.AddSingleton<IServiceHelper, ServiceHelper>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceHelper serviceHelper)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//程序启动时 获取服务列表
serviceHelper.GetServices();
}
}
7、新增api,调用Consul服务
[Produces("application/json")]
[Route("product")]
public class ProductsController
{
private readonly IServiceHelper _serviceHelper;
public ProductsController(IServiceHelper serviceHelper)
{
_serviceHelper = serviceHelper;
}
/// <summary>
/// 获取产品列表
/// </summary>
/// <returns>产品列表</returns>
[Route("GetAll")]
[HttpGet]
public List<Product> GetAllProducts()
{
var result = _serviceHelper.GetProduct();
if (!string.IsNullOrWhiteSpace(result.Result))
{
var json = result.Result;
//将Json转换回商品
var products = JsonConvert.DeserializeObject<List<Product>>(json);
return products;
}
return null;
}
}
8、设置api启动配置
9、运行,显示结果如下:
到这里,简单的Consul服务注册与发现基本就结束了
下一步,我们将接入Ocelot网关
https://blog.csdn.net/weixin_41003771/article/details/119175940