.Net Core微服务入门——Ocelot API网关接入
上一章我们测试了一个简单的Client 端访问Consul实现服务注册与发现,但是现实生产环境我们直接通过Client自行连接Consul实现服务注册与发现,基本是不可行的,我们需要一个统一的入口来连接客户端与服务,统一管理,并做安全认证等。
所以,这里就需要用到Ocelot
Ocelot
官网:https://ocelot.readthedocs.io/
Ocelot正是为.Net微服务体系提供一个统一的入口点,称为:Gateway(网关)。
新建Ocelot项目
1、创建一个空的 core web项目。
2、引入Ocelot包:
3、新增ocelot.json,配置服务api信息:
{"Routes": [{"DownstreamPathTemplate": "/api/product/getall","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 5001},{"Host": "localhost","Port": 5002}],"UpstreamPathTemplate": "/api/product/getall","UpstreamHttpMethod": ["Get"],"LoadBalancerOptions": {"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions}}],"GlobalConfiguration": {"BaseUrl": "http://localhost:5010"}}
这里我们先忽略 Consul,采用直连API服务,因为Consul、Ocelot等组件都是可以独立存在的。
配置文件中的Routes节点用来配置路由:
Downstream代表下游,也就是服务实例,就是我们的服务api地址
如:http://192.168.8.61:5001/api/product/getall
Upstream代表上游,也就是提供给客户端调用的api地址
如:http://192.168.8.61:5010/api/product/getall,
如果这里改成 api1/product/getall,那么客户端访问的api地址就是 http://192.168.8.61:5010/api1/product/getall
上游的路径不一定要和下游一致,可自行配置
LoadBalancerOptions节点用来配置负载均衡:
Ocelot内置了 LeastConnection、RoundRobin、NoLoadBalancer、CookieStickySessions 4种负载均衡策略。
LeastConnection -最少连接,跟踪哪些服务正在处理请求,并把新请求发送到现有请求最少的服务上。该算法状态不在整个Ocelot集群中分布。
RoundRobin - 轮询可用的服务并发送请求。 该算法状态不在整个Ocelot集群中分布。
NoLoadBalancer - 不负载均衡,从配置或服务发现提供程序中取第一个可用的下游服务。
CookieStickySessions - 使用cookie关联所有相关的请求到制定的服务。
BaseUrl节点就是配置我们ocelot网关将要运行的地址。
4、修改Program.cs:
public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.AddJsonFile("ocelot.json");}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}
5、修改Startup.cs
public class Startup{// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit /fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){//添加ocelot服务services.AddOcelot();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){//设置Ocelot中间件app.UseOcelot().Wait();}}
6、运行Oeclot项目
我们先手动运行 ,直接进入bin目录下,执行控制台命令:`dotnet Ocelot.APIGateway.dll --urls=“http://*:5010”
浏览器访问 http://192.168.8.61:5010/api/product/getall
这里说明Ocelot网关正常运行了,下一步,我们client接入网关
7、修改Client
IGatewayServiceHelper. cs
public interface IGatewayServiceHelper{/// <summary>/// 获取产品数据/// </summary>/// <returns></returns>Task<string> GetProduct();/// <summary>/// 获取服务列表/// </summary>void GetServices();}
GatewayServiceHelper.cs
public class GatewayServiceHelper: IGatewayServiceHelper{public async Task<string> GetProduct(){var Client = new RestClient("http://localhost:5010");var request = new RestRequest("/api/product/getall", Method.GET);var response = await Client.ExecuteAsync(request);return response.Content;}public void GetServices(){throw new NotImplementedException();}}
Startup.cs
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>();//注入IServiceHelperservices.AddSingleton<IGatewayServiceHelper, GatewayServiceHelper>();注入IServiceHelper//services.AddSingleton<IServiceHelper, GatewayServiceHelper>();}// 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)public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});//程序启动时 获取服务列表//serviceHelper.GetServices();}}
ProductsController.cs
[Produces("application/json")][Route("product")]public class ProductsController{private readonly IGatewayServiceHelper _serviceHelper;public ProductsController(IGatewayServiceHelper 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;}}
调试启动Client,浏览器自动打开:https://localhost:44393/product/getall
Client顺利连上了网关层。
有人问,那我api有多个接口怎么办呢,总不能每个接口都配置一下吧。
多个接口的话,只需要修改ocelot.json即可,将具体api接口 改成 api/{url}
{"Routes": [{"DownstreamPathTemplate": "/api/{url}","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 5001},{"Host": "localhost","Port": 5002}],"UpstreamPathTemplate": "/api/{url}","UpstreamHttpMethod": ["Get"],"LoadBalancerOptions": {"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions}}],"GlobalConfiguration": {"BaseUrl": "http://localhost:5010"}}
那如果有多个Service呢
{"Routes": [{"DownstreamPathTemplate": "/api/{url}","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 5001},{"Host": "localhost","Port": 5002}],"UpstreamPathTemplate": "/api/{url}","UpstreamHttpMethod": ["Get"],"LoadBalancerOptions": {"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions}},{"DownstreamPathTemplate": "/api/{url}","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 5005},{"Host": "localhost","Port": 5006}],"UpstreamPathTemplate": "/api/{url}","UpstreamHttpMethod": ["Get"],"LoadBalancerOptions": {"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions}}],"GlobalConfiguration": {"BaseUrl": "http://localhost:5010"}}
下一章,我们将继续深入,探讨Ocelot 连接 Consul,服务治理等
/weixin_41003771/article/details/119177786