一、为什么要有网关Gateway?
1、做服务的管理,屏蔽外界对服务的访问,保护服务。
2、微服务那么多服务,而且每一个服务都是集群式的,调用方不想记住每一个服务的IP+端口号。
3、像授权每一个微服务都要授权,那么加到网关就可以了。
二、网关是做什么的?
做请求转发,转发策略的(如:随机调度,均匀调度,权重调度),映射的,就像一个代理一样。
三、Ocelot配置
1、nuget引入Ocelot
2、Ocelot配置文件configuration.json
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/{url}",//下游--被调用方--服务地址--url变量 "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 10010//服务的端口 }, //可以多个,自行负载均衡 { "Host": "localhost", "Port": 10020//服务的端口 } //可以多个,自行负载均衡 ], "LoadBalancerOptions": { "Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡 }, "UpstreamPathTemplate": "/DavidMeng123456abc/{url}",//上游--调用方--网关地址--url变量 //冲突的还可以加权重Priority "UpstreamHttpMethod": [ "Get", "Post" ] } ] }
3、Program.cs中替换配置文件configuration.json
namespace NetCore2._2_OcelotGateway { public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration(cfg => { cfg.AddJsonFile("configuration.json", optional: false, reloadOnChange: true); }) .UseStartup<Startup>(); } }
4、Startup.cs配置使用Ocelot中间件
namespace NetCore2._2_OcelotGateway { 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.AddOcelot(Configuration); //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 { // 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.UseOcelot().Wait(); //app.UseHttpsRedirection(); //app.UseMvc(); } } }
四、启动Ocelot Gateway
找到编译路径,地址栏输入cmd,通过命令行启动
dotnet NetCore2.2_OcelotGateway.dll --urls="http://*:9527" --ip="127.0.0.1" --port=9527
五、通过命令行启动WebApi
通过命令行启动2个不同端口的WebApi
dotnet ConsulServiceFind.dll --urls="http://*:10010" --ip="127.0.0.1" --port=10010 --weight=2
dotnet ConsulServiceFind.dll --urls="http://*:10020" --ip="127.0.0.1" --port=10020 --weight=8
六、运行效果
每刷新一次,端口变化一次,完成负载均衡。
七、Gateway缺陷
通过命令行启动个新的不同端口的WebApi,dotnet ConsulServiceFind.dll --urls="http://*:10010" --ip="127.0.0.1" --port=10030
配置文件得改下,网关得重启下,所以需要结合Consul主动服务发现
1、需要在nuget引入Ocelot.Provider.Consul
2、修改Ocelot配置文件configuration.json
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/{url}",//下游--被调用方--服务地址--url变量 "DownstreamScheme": "http", "UpstreamPathTemplate": "/MyConsul/{url}", //上游--调用方--网关地址--url变量 "UpstreamHttpMethod": [ "Get", "Post" ], "UseServiceDiscovery": true, //使用服务发现 "ServiceName": "david_webapi", //Consul中注册的服务名称 "LoadBalancerOptions": { "Type": "RoundRobin" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡 } } ], "GlobalConfiguration": { "BaseUrl": "http://127.0.0.1:9527", //网关对外地址 "ServiceDiscoveryProvider": {//Consul配置 "Host": "localhost", "Port": 8500, //由Consul提供服务发现 "Type": "Consul" } } }
3、修改添加中间件
public void ConfigureServices(IServiceCollection services) { services.AddOcelot(Configuration).AddConsul(); //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
4、再使用命令行启动一个WebAPi实例,端口号为10030
我们看到Consul后台就主动又发现一个端口号为10030的服务
我们发现第一次页面打开的时候,端口号为10010,刷新下页面,端口号变成了10020,再次刷新页面,端口号变成了10030,完成了负载均衡,均衡调度。
八、总结Ocelot和Consul区别
1、Ocelot需要维护服务的IP和端口。
2、增加个WebApi实例,configuration.json需要修改,增加配置节点。
3、是维护整个服务的,Consul是维护单个服务的。
4、Ocelot是做请求转发的,而Consul是做服务注册与发现的,健康检查的。
九、环境和解决方案截图
1、环境截图
启动了5个控制台,分别是1个Consul,3个不同端口号的WebApi实例,1个Ocelot Gateway
2、项目截图