一、ConSul和Ocelot
Consul:是一个服务网格解决方案,提供了一个功能齐全的控制平面,具有服务发现、配置和分段功能。这些功能中的每一项都可以根据需要单独使用,也可以一起使用来构建一个完整的服务网格。Consul需要一个数据平面,并支持代理和原生集成模型。Consul提供了一个简单的内置代理,因此一切都可以开箱即用,具有注册中心、配置中心、健康检查等很好用的功能。
Ocelot:Ocelot首先通过配置将HttpRequest对象保存到一个指定的状态直到它到达用来创建HttpRequestMessage对象并将创建的HttpRequestMessage对象发送到下游服务中的请求构造中间件。通过中间件来发出请求是Ocelot管道中做的最后一件事。它不会再调用下一个中间件。下游服务的响应会存储在每个请求 scoped repository中,并作为一个请求返回到Ocelot管道中。有一个中间件将HttpResponseMessage映射到HttpResponse对象并返回给客户端。
接下来是你使用Ocelot是可能会使用的配置。
二、环境和版本
Demo框架:.Net6
Docker:20.10.18
Consul:1.6.10.8
Ocelot:18.0.0
三、Docker里面安装Consul
Docker安装可参考:https://www.cnblogs.com/chj929555796/p/16779240.html
执行拉取镜像命令:
docker pull consul
创建Consul容器:
docker run -d --name consul -p 8500:8500 consul:latest
四、Demo事例
一、Demo结构说明
Client-WebService:网关项目端口5001
Order-OrderApi:订单服务,端口5002、5004、5006
Product-ProductApi:产品服务,端口5003、5005
二、Consul扩展类
ConsulRegisterOptions:Consul注册服务节点类
namespace OrderApi.ConsulExtends { public class ConsulRegisterOptions { public string ConsulAddress { get; set; } public string Healthcheck { get; set; } public string ServiceName { get; set; } public string Ip { get; set; } public int Port { get; set; } } }
ConsulExend:Consul注入服务延伸类
namespace OrderApi.ConsulExtends { public static class ConsulExend { public static void AddConsulRegister(this IServiceCollection services) { services.AddTransient<IConsulRegister, ConsulRegister>(); } } }
IConsulRegister:注册服务接口类
namespace OrderApi.ConsulExtends { public interface IConsulRegister { Task ConsulRegisterAsync(); } }
ConsulRegister:注册服务实现类
using Consul; using Microsoft.Extensions.Options; namespace OrderApi.ConsulExtends { public class ConsulRegister : IConsulRegister { private readonly ConsulRegisterOptions _consulRegisterOptions; public ConsulRegister(IOptionsMonitor<ConsulRegisterOptions> consulRegisterOptions) { _consulRegisterOptions = consulRegisterOptions.CurrentValue; } public async Task ConsulRegisterAsync() { var client = new ConsulClient(options => { options.Address = new Uri(_consulRegisterOptions.ConsulAddress);// Consul客户端地址 }); var registration = new AgentServiceRegistration { ID = Guid.NewGuid().ToString(),//唯一ID Name = _consulRegisterOptions.ServiceName,//服务名 Address = _consulRegisterOptions.Ip,//服务绑定IP Port = _consulRegisterOptions.Port,//服务绑定端口 Check = new AgentServiceCheck { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(1),//服务启动后多久注册 Interval = TimeSpan.FromSeconds(5),//健康检查时间 HTTP = $"http://{_consulRegisterOptions.Ip}:{_consulRegisterOptions.Port}{_consulRegisterOptions.Healthcheck}",//检查地址 Timeout = TimeSpan.FromSeconds(10),//超时时间 } }; await client.Agent.ServiceRegister(registration); } } }
HealthCheckMiddleware:Consul检测服务中间件类
using System.Net; namespace OrderApi.ConsulExtends { public static class HealthCheckMiddleware { public static void UseHealthCheckMiddleware(this IApplicationBuilder app, string checkPath = "/healthcheck") { int code = 0; app.Map(checkPath, applicationBuilder => applicationBuilder.Run(async context => { Console.WriteLine("this is health check"); code = context.Response.StatusCode; context.Response.StatusCode = (int)HttpStatusCode.OK; await context.Response.WriteAsync("OK"); })); } } }
以上几个类OrderApi和ProductApi都一样,用于在服务启动时注册服务到Consul中。
三、appsettings.json和Program.cs配置
1、OrderApi服务
"ConsulRegister": { "ConsulAddress": "http://consul-IP:8500", //consul客户端地址 "Healthcheck": "/healthcheck", //consul健康检查地址 "ServiceName": "OrderService",//服务名称,服务启动时会注册到Consul中的Service "Ip": "consul-IP", "Port": "服务端口号"//定义一个就行,后期容器启动时可以通过命令映射更改 },
using OrderApi.ConsulExtends; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //注册consul服务 builder.Services.Configure<ConsulRegisterOptions>(builder.Configuration.GetSection("ConsulRegister")); builder.Services.AddConsulRegister(); builder.WebHost.UseUrls("http://*:5002"); var app = builder.Build(); //注册consul服务 app.Services.GetService<IConsulRegister>()!.ConsulRegisterAsync(); // Configure the HTTP request pipeline. //if (app.Environment.IsDevelopment()) //{ //app.UseExceptionHandler("/Home/Error"); app.UseSwagger(); app.UseSwaggerUI(); //} app.UseAuthorization(); app.MapControllers(); //注册consul健康检查中间件 app.UseHealthCheckMiddleware(); app.Run();
2、ProductApi服务
"ConsulRegister": { "ConsulAddress": "http://consul-IP:8500", //consul客户端地址 "Healthcheck": "/healthcheck", //consul健康检查地址 "ServiceName": "ProductService",//服务名称,服务启动时会注册到consul中的Service "Ip": "consul-IP", "Port": "服务端口号"//定义一个就行,后期容器启动时可以通过命令映射更改 },
using ProductApi.ConsulExtends; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //注册consul服务 builder.Services.Configure<ConsulRegisterOptions>(builder.Configuration.GetSection("ConsulRegister")); builder.Services.AddConsulRegister(); builder.WebHost.UseUrls("http://*:5003"); var app = builder.Build(); //注册consul服务 app.Services.GetService<IConsulRegister>()!.ConsulRegisterAsync(); // Configure the HTTP request pipeline. //if (app.Environment.IsDevelopment()) //{ app.UseSwagger(); app.UseSwaggerUI(); //} app.UseAuthorization(); app.MapControllers(); app.UseHealthCheckMiddleware(); app.Run();
截止为止,两个服务注册Consul相关已完成,启动服务时会自动把服务注册到Consul
查看详细服务
3、WebService网关项目
需要安装Nuget包:Consul、Ocelot、Ocelot.Provider.Consul
新增文件:ocelot.json
{ "Routes": [ { "UseServiceDiscovery": true, // 使用服务发现 "DownstreamPathTemplate": "/orderapi/{url}", //下游的路由模板,即真实处理请求的路径模板 "UpstreamPathTemplate": "/orderapi/{url}", //上游请求的模板,即用户真实请求的链接 "DownstreamScheme": "http", //"DownstreamHostAndPorts": [ // { // "Host": "consul-ip", // "Port": 5002 // }, // { // "Host": "consul-ip", // "Port": 5004 // }, // { // "Host": "consul-ip", // "Port": 5006 // } //], "ServiceName": "OrderService", // 服务名称-这个要跟应用注册时写的名字一致,否则无效 //配置负载均衡 "LoadBalancerOptions": { "Type": "RoundRobin" //负载均衡 RoundRobin(轮询)/LeastConnection(最少连接数) }, "UpstreamHttpMethod": [ "Options", "Get", "Post", "Put", "Delete" ], "ReRoutesCaseSensitive": false, // 路由大小写敏感设置 "key": "orderapi" }, { "UseServiceDiscovery": true, // 使用服务发现 "DownstreamPathTemplate": "/productapi/{url}", //下游的路由模板,即真实处理请求的路径模板 "UpstreamPathTemplate": "/productapi/{url}", //上游请求的模板,即用户真实请求的链接 "DownstreamScheme": "http", //"DownstreamHostAndPorts": [ // { // "Host": "consul-ip", // "Port": 5003 // }, // { // "Host": "consul-ip", // "Port": 5005 // } //], "ServiceName": "ProductService", // 服务名称-这个要跟应用注册时写的名字一致,否则无效 //配置负载均衡 "LoadBalancerOptions": { "Type": "RoundRobin" //负载均衡方式 }, "UpstreamHttpMethod": [ "Options", "Get", "Post", "Put", "Delete" ], "ReRoutesCaseSensitive": false, // 路由大小写敏感设置 "key": "productapi" } ], "GlobalConfiguration": { // 网关全局配置 "BaseUrl": "http://consul-ip:5001", //当前网关项目的地址 "ServiceDiscoveryProvider": { // 服务发现的配置 "Scheme": "http", "Host": "consul-ip", //Consul 服务的访问ip "Port": 8500, //Consul 服务的访问端口 "Type": "Consul" } } }
WebService-Program.cs
using Ocelot.DependencyInjection; using Ocelot.Middleware; using Ocelot.Provider.Consul; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Configuration.AddJsonFile("appsettings.json", true, true); //支持在更改时重新加载 json 配置文件 builder.Configuration.AddJsonFile("ocelot.json",false,true).AddEnvironmentVariables(); builder.Services.AddOcelot().AddConsul(); builder.WebHost.UseUrls("http://*:5001"); var app = builder.Build(); // Configure the HTTP request pipeline. //if (!app.Environment.IsDevelopment()) //{ // app.UseExceptionHandler("/Error"); //} app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.UseOcelot().Wait(); app.Run();
五、Docker构建
一、上传项目文件夹到云服务器
二、切换到每个目录下依次执行构建镜像及创建容器
1、OrderApi
切换目录:cd /Order 构建镜像:sudo docker build -t microservicesorder . 创建容器: docker run -d -p 5002:5002 --name orderapitest microservicesorder --ConsulRegister:Port="5002" docker run -d -p 5004:5002 --name orderapitest1 microservicesorder --ConsulRegister:Port="5004" docker run -d -p 5006:5002 --name orderapitest2 microservicesorder --ConsulRegister:Port="5006" 这里需要注意ConsulRegister:Port的地方,以往我们构建容器方式是 docker run --name orderapitest -p 5002:5002 microservicesorder 但是此处多了--ConsulRegister:Port="5006",此段代码就是在访问时去替换当前服务appsettings.json文件ConsulRegister节点的Port
2、ProductApi
切换目录:cd /Product 构建镜像:sudo docker build -t microservicesproduct . 创建容器: docker run -d -p 5003:5003 --name productapitest microservicesproduct --ConsulRegister:Port="5003" docker run -d -p 5005:5003 --name productapitest1 microservicesproduct --ConsulRegister:Port="5005"
3、Client网关
切换目录:cd /Client 构建镜像:sudo docker build -t microservicesclient . 创建容器:docker run --name clienttest -p 5001:5001 microservicesclient
服务健康监测运行情况
访问Order服务
访问Product服务
参考文献:https://blog.xiaobaicai.fun/share/7386.html
标签:builder,服务,app,Port,consul,Ocelot,NET,Consul From: https://www.cnblogs.com/chj929555796/p/17252783.html