前言

上一篇【.Net Core微服务入门全纪录(三)——Consul-服务注册与发现(下)】已经使用Consul完成了服务的注册与发现,实际中光有服务注册与发现往往是不够的,我们需要一个统一的入口来连接客户端与服务。

Ocelot

官网:https://ocelot.readthedocs.io/

Ocelot正是为.Net微服务体系提供一个统一的入口点,称为:Gateway(网关)。

  • 上手Ocelot:

首先创建一个空的asp.net core web项目。



注意ocelot.json是我们添加的Ocelot的配置文件,记得设置生成时复制到输出目录。ocelot.json的文件名不是固定的,可以自己定义。

NuGet安装一下Ocelot:

只需简单的修改几处默认代码:

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>();
});
}

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 https://go.microsoft.com/fwlink/?LinkID=398940
public 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();
}
}

ocelot.json:

{
"Routes": [
{
"DownstreamPathTemplate": "/products",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 9050
},
{
"Host": "localhost",
"Port": 9051
},
{
"Host": "localhost",
"Port": 9052
}
],
"UpstreamPathTemplate": "/products",
"UpstreamHttpMethod": [
"Get"
],
"LoadBalancerOptions": {
"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions
}
},
{
"DownstreamPathTemplate": "/orders",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 9060
},
{
"Host": "localhost",
"Port": 9061
},
{
"Host": "localhost",
"Port": 9062
}
],
"UpstreamPathTemplate": "/orders",
"UpstreamHttpMethod": [
"Get"
],
"LoadBalancerOptions": {
"Type": "RoundRobin" //负载均衡,轮询机制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:9070"
}
}

我们先暂时忽略Consul,将服务实例的地址都写在配置文件中。要知道Consul、Ocelot等组件都是可以独立存在的。

配置文件中的Routes节点用来配置路由,Downstream代表下游,也就是服务实例,Upstream代表上游,也就是客户端。我们的路径比较简单,只有/products、/orders,路径中如果有不固定参数则使用{}匹配。我们这个配置的意思呢就是客户端访问网关的/orders、/products,网关会转发给服务实例的/orders、/products,注意这个上游的路径不一定要和下游一致,比如上游路径可以配置成/api/orders,/xxx都可以。

LoadBalancerOptions节点用来配置负载均衡,Ocelot内置了 LeastConnection、RoundRobin、NoLoadBalancer、CookieStickySessions 4种负载均衡策略。

BaseUrl节点就是配置我们ocelot网关将要运行的地址。

  • 运行gateway:

目前不考虑网关集群,就不放在docker里了。直接控制台执行:`dotnet Ocelot.APIGateway.dll --urls="http://*:9070"

用浏览器测试一下:





测试正常,我们通过网关可以正常的访问到服务实例。

  • 接下来继续改造客户端代码:



因为改动太多就直接新建一个GatewayServiceHelper来做。

GatewayServiceHelper:

    /// <summary>
/// 通过gateway调用服务
/// </summary>
public class GatewayServiceHelper : IServiceHelper
{
public async Task<string> GetOrder()
{
var Client = new RestClient("http://localhost:9070");
var request = new RestRequest("/orders", Method.GET); var response = await Client.ExecuteAsync(request);
return response.Content;
} public async Task<string> GetProduct()
{
var Client = new RestClient("http://localhost:9070");
var request = new RestRequest("/products", Method.GET); var response = await Client.ExecuteAsync(request);
return response.Content;
} public void GetServices()
{
throw new NotImplementedException();
}
}

然后在Startup中修改一下注入的类型,别的就不用改了,这就是依赖注入的好处之一。。。

Startup.ConfigureServices():

//注入IServiceHelper
//services.AddSingleton<IServiceHelper, ServiceHelper>(); //注入IServiceHelper
services.AddSingleton<IServiceHelper, GatewayServiceHelper>();

Startup.Configure():

//程序启动时 获取服务列表
//serviceHelper.GetServices();

运行客户端测试:

好了,现在客户端对服务的调用都通过网关进行中转,客户端再也不用去关心那一堆服务实例的地址,只需要知道网关地址就可以了。另外,服务端也避免了服务地址直接暴露给客户端。这样做对客户端,服务都非常友好。

至于我们的api网关呢,又要说到服务发现的问题了。目前我们的服务地址是写在ocelot.json配置文件里的,当然这种做法在服务实例不经常变化的情况下是没有问题的,一旦服务变化,需要人为的修改配置文件,这又显得不太合理了。

当然,强大的Ocelot为我们提供了服务发现的方案。

代码放在:https://github.com/xiajingren/NetCoreMicroserviceDemo

未完待续...

.Net Core微服务入门全纪录(四)——Ocelot-API网关(上)的更多相关文章

  1. .Net Core微服务入门全纪录(五)——Ocelot-API网关(下)

    前言 上一篇[.Net Core微服务入门全纪录(四)--Ocelot-API网关(上)]已经完成了Ocelot网关的基本搭建,实现了服务入口的统一.当然,这只是API网关的一个最基本功能,它的进阶功 ...

  2. .Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)

    前言 上一篇[.Net Core微服务入门全纪录(一)--项目搭建]讲到要做到服务的灵活伸缩,那么需要有一种机制来实现它,这个机制就是服务注册与发现.当然这也并不是必要的,如果你的服务实例很少,并且很 ...

  3. .Net Core微服务入门全纪录(三)——Consul-服务注册与发现(下)

    前言 上一篇[.Net Core微服务入门全纪录(二)--Consul-服务注册与发现(上)]已经成功将我们的服务注册到Consul中,接下来就该客户端通过Consul去做服务发现了. 服务发现 同样 ...

  4. .Net Core微服务入门全纪录(六)——EventBus-事件总线

    前言 上一篇[.Net Core微服务入门全纪录(五)--Ocelot-API网关(下)]中已经完成了Ocelot + Consul的搭建,这一篇简单说一下EventBus. EventBus-事件总 ...

  5. .Net Core微服务入门全纪录(七)——IdentityServer4-授权认证

    前言 上一篇[.Net Core微服务入门全纪录(六)--EventBus-事件总线]中使用CAP完成了一个简单的Eventbus,实现了服务之间的解耦和异步调用,并且做到数据的最终一致性.这一篇将使 ...

  6. .Net Core微服务入门全纪录(八)——Docker Compose与容器网络

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 前言 上一篇[.Net Core微服务入门全纪录(七)--IdentityServer4-授权认证]中使用IdentityServer4 ...

  7. .Net Core微服务入门全纪录(完结)——Ocelot与Swagger

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 前言 上一篇[.Net Core微服务入门全纪录(八)--Docker Compose与容器网络]完成了docker-compose.y ...

  8. .Net Core微服务入门全纪录(一)——项目搭建

    前言 写这篇博客主要目的是记录一下自己的学习过程,只能是简单入门级别的,因为水平有限就写到哪算哪吧,写的不对之处欢迎指正. 什么是微服务? 关于微服务的概念解释网上有很多... 个人理解,微服务是一种 ...

  9. NET Core微服务之路:基于Ocelot的API网关Relay实现--RPC篇

    前言 我们都知道,API网关是工作在应用层上网关程序,为何要这样设计呢,而不是将网关程序直接工作在传输层.或者网络层等等更底层的环境呢?让我们先来简单的了解一下TCP/IP的五层模型.     (图片 ...

随机推荐

  1. Oracle 中同义词使用

    一.数据库对象: 模式对象: 数据库对象是逻辑结构的集合,最基本的数据库对象是表; 其他对象包括:create增.drop删.改alter 同义词.序列.视图.索引 1.同义词: ①. 现有对象的一个 ...

  2. Msql 给结果拼接字符串

    SELECT CONCAT("内容:",info)AS info FROM 表名;

  3. Cypress系列(1)- Window下安装 Cypress 并打开

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 系统要求 Cypress 是一个被安装在 ...

  4. python的生成器和迭代器

    三.推倒式从时间上比较:集合 字典 元祖 列表 (从小到大)占用内存比较:字典 集合 列表 元祖 (从大到小) 字典是可进行hash操作,操作的是字典的key ,而对list进行hash操作的时候操作 ...

  5. C#网络编程入门之UDP

    目录: C#网络编程入门系列包括三篇文章: (一)C#网络编程入门之UDP (二)C#网络编程入门之TCP (三)C#网络编程入门之HTTP 一.概述 UDP和TCP是网络通讯常用的两个传输协议,C# ...

  6. 用非常硬核的JAVA序列化手段实现对象流的持久化保存

    目录 背景 对象流的概念 对象流实例 引入一张组织结构图 定义组织架构图的类 类的完整结构 用对象流保存组织架构的对象信息 核心代码 用对象流读取文件并输出 核心代码 总结 背景 在OOP(面向对象编 ...

  7. Python对象组合

    一个类的对象作为另一个类的对象的属性,称为类的组合. 即 class1.instance1.property = class2.instance 组合也是代码重用的重要方式之一. 先定义三个类:人.汽 ...

  8. 初步理解 MySQL数据库

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1. 索引是做什么的? 索引用于快速找出在某个列中有一特定值的行.不使用索引,MYSQL必须从第1条记录 ...

  9. Java实现蓝桥杯二项式的系数规律

    二项式的系数规律,我国数学家很早就发现了. 如[图1.png],我国南宋数学家杨辉1261年所著的<详解九章算法>一书里就出现了. 其排列规律: 1 1 1 2 1 3 3 1 4 6 4 ...

  10. Java实现 蓝桥杯 历届试题 翻硬币

    问题描述 小明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如 ...