创建一个 NetCore3.1的WebAPi项目与NetCore3.1的ServiceGateway网关WebAPI项目
1.服务注册
在WebAPI项目引用Consul这个包,同时新增ConsulHelper类扩展IConfiguration方法
public static class ConsulHelper
{
public static void ConsulRegist(this IConfiguration configuration)
{
try
{
ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri("http://localhost:8500/");
c.Datacenter = "dc1";
});
string ip = configuration["ip"];
int port = int.Parse(configuration["port"]);//命令行参数必须传入
//int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);//命令行参数必须传入
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = "UserService" + port.ToString(),//唯一的
Name = "UserService",//组名称-Group
Address = ip,//其实应该写ip地址
Port = port,//不同实例
//Tags = new string[] { weight.ToString() },//标签
Check = new AgentServiceCheck()//配置心跳检查的
{
Interval = TimeSpan.FromSeconds(12),
HTTP = $"http://{ip}:{port}/Api/Health/Index",
Timeout = TimeSpan.FromSeconds(5),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5)
}
});
Console.WriteLine($"http://{ip}:{port}完成注册");
}
catch (Exception ex)
{
Console.WriteLine($"ConsulRegist注册失败!----异常消息:{ex.Message}");
}
}
}
通过这个类可以提供服务注册的基本参数。
修改Startup启动项中的Configure方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime) {
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Console.WriteLine(this.Configuration["ip"]);
Console.WriteLine(this.Configuration["port"]);
//实例启动时执行,且只执行一次
this.Configuration.ConsulRegist();
}
2.服务发现
新建API项目ServiceGateway,通过NuGet引用Ocelot和Ocelot.Provider.Consul,Ocelot.Provider.Polly三个包,并修改启动项注册Ocelot和Consul:
public void ConfigureServices(IServiceCollection services) { services.AddOcelot().AddConsul().AddPolly(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseOcelot(); //app.UseMvc(); }
然后添加配置文件consul.json: 坑就在这里 ReRoutes 要改成Routes ,
Ocelot在6.X以后的版本根节点不在使用ReRoutes 更改为Routes
{
"DownstreamPathTemplate": "/api/{url}", //服务地址--url变量
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/consul/{url}", //网关地址--url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"ServiceName": "UserService", //consul服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
},
"UseServiceDiscovery": true,
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求
"DurationOfBreak": 10000, // 熔断的时间,单位为ms
"TimeoutValue": 10000 //如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90秒
}
//"RateLimitOptions": {
// "ClientWhitelist": [], //白名单
// "EnableRateLimiting": true,
// "Period": "5m", //1s, 5m, 1h, 1d jeffzhang
// "PeriodTimespan": 5, //多少秒之后客户端可以重试
// "Limit": 5 //统计时间段内允许的最大请求数量
//},
//"FileCacheOptions": {
// "TtlSeconds": 10
//} //"缓存"
}
],
"GlobalConfiguration": {
"BaseUrl": "http://127.0.0.1:6299", //网关对外地址
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 8500,
"Type": "Consul" //由Consul提供服务发现
}
//"RateLimitOptions": {
// "QuotaExceededMessage": "Too many requests, maybe later? 11", // 当请求过载被截断时返回的消息
// "HttpStatusCode": 666 // 当请求过载被截断时返回的http status
//}
}
}