前言

一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目。正好由于最近刚好辞职,有了时间可以写写自己感兴趣的东西,所以在此想把自己了解的微服务相关的概念和技术框架使用实现记录在一个完整的工程中,由于本人技术有限,所以错误的地方希望大家指出。\

项目地址:https://github.com/yingpanwang/fordotnet/tree/dev

什么是Api网关

  由于微服务把具体的业务分割成单独的服务,所以如果直接将每个服务都与调用者直接,那么维护起来将相当麻烦与头疼,Api网关担任的角色就是整合请求并按照路由规则转发至服务的实例,并且由于所有所有请求都经过网关,那么网关还可以承担一系列宏观的拦截功能,例如安全认证,日志,熔断

为什么需要Api网关

 因为Api网关可以提供安全认证,日志,熔断相关的宏观拦截的功能,也可以屏蔽多个下游服务的内部细节

有哪些有名的Api网关项目

  • Zuul Spring Cloud 集成
  • Kong 一款lua轻量级网关项目
  • Ocelot .NETCore网关项目

Ocelot使用

1.通过Nuget安装Ocelot

2.准备并编辑Ocelot配置信息

Ocelot.json

{
"ReRoutes": [
// Auth
{
"UpstreamPathTemplate": "/auth/{action}", // 上游请求路径模板
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ], // 上游请求方法
"ServiceName": "Auth", // 服务名称
"UseServiceDiscovery": true, // 是否使用服务发现
"DownstreamPathTemplate": "/connect/{action}", // 下游匹配路径模板
"DownstreamScheme": "http", // 下游请求
"LoadBalancerOptions": { // 负载均衡配置
"Type": "RoundRobin"
}
//,
// 如果不采用服务发现需要指定下游host
//"DownstreamHostAndPorts": [
// {
// "Host": "10.0.1.10",
// "Port": 5000
// },
// {
// "Host": "10.0.1.11",
// "Port": 5000
// }
//]
}
],
"GlobalConfiguration": { // 全局配置信息
"BaseUrl": "http://localhost:5000", // 请求 baseurl
"ServiceDiscoveryProvider": { //服务发现提供者
"Host": "106.53.199.185",
"Port": 8500,
"Type": "Consul" // 使用Consul
}
}
}

3.添加Ocelot json文件到项目中

将Config目录下的ocelot.json添加到项目中

4.在网关项目中 StartUp ConfigService中添加Ocelot的服务,在Configure中添加Ocelot的中间件(由于我这里使用了Consul作为服务发现,所以需要添加Consul的依赖的服务AddConsul,如果不需要服务发现的话可以不用添加)

5.将需要发现的服务通过代码在启动时注册到Consul中

我这里自己封装了一个注册服务的扩展(写的比较随意没有在意细节)

appsettings.json 中添加注册服务配置信息

"ServiceOptions": {
"ServiceIP": "localhost",
"ServiceName": "Auth",
"Port": 5800,
"HealthCheckUrl": "/api/health",
"ConsulOptions": {
"Scheme": "http",
"ConsulIP": "localhost",
"Port": 8500
}
}

扩展代码 ConsulExtensions(注意:3.1中 IApplicationLifetime已废弃 所以使用的是IHostApplicationLifetime 作为程序生命周期注入的方式)


using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System; namespace ForDotNet.Common.Consul.Extensions
{
/// <summary>
/// 服务配置信息
/// </summary>
public class ServiceOptions
{
/// <summary>
/// 服务ip
/// </summary>
public string ServiceIP { get; set; } /// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; } /// <summary>
/// 协议类型http or https
/// </summary>
public string Scheme { get; set; } = "http"; /// <summary>
/// 端口
/// </summary>
public int Port { get; set; } /// <summary>
/// 健康检查接口
/// </summary>
public string HealthCheckUrl { get; set; } = "/api/values"; /// <summary>
/// 健康检查间隔时间
/// </summary>
public int HealthCheckIntervalSecond { get; set; } = 10; /// <summary>
/// consul配置信息
/// </summary>
public ConsulOptions ConsulOptions { get; set; }
} /// <summary>
/// consul配置信息
/// </summary>
public class ConsulOptions
{
/// <summary>
/// consul ip
/// </summary>
public string ConsulIP { get; set; } /// <summary>
/// consul 端口
/// </summary>
public int Port { get; set; } /// <summary>
/// 协议类型http or https
/// </summary>
public string Scheme { get; set; } = "http";
} /// <summary>
/// consul注册客户端信息
/// </summary>
public class ConsulClientInfo
{
/// <summary>
/// 注册信息
/// </summary>
public AgentServiceRegistration RegisterInfo { get; set; } /// <summary>
/// consul客户端
/// </summary>
public ConsulClient Client { get; set; }
} /// <summary>
/// consul扩展(通过配置文件配置)
/// </summary>
public static class ConsulExtensions
{
private static readonly ServiceOptions serviceOptions = new ServiceOptions(); /// <summary>
/// 添加consul
/// </summary>
public static void AddConsulServiceDiscovery(this IServiceCollection services)
{
var config = services.BuildServiceProvider().GetService<IConfiguration>();
config.GetSection("ServiceOptions").Bind(serviceOptions);
//config.Bind(serviceOptions); if (serviceOptions == null)
{
throw new Exception("获取服务注册信息失败!请检查配置信息是否正确!");
}
Register(services);
} /// <summary>
/// 添加consul(通过配置opt对象配置)
/// </summary>
/// <param name="app"></param>
/// <param name="life">引用生命周期</param>
/// <param name="options">配置参数</param>
public static void AddConsulServiceDiscovery(this IServiceCollection services, Action<ServiceOptions> options)
{
options.Invoke(serviceOptions);
Register(services);
} /// <summary>
/// 注册consul服务发现
/// </summary>
/// <param name="app"></param>
/// <param name="life"></param>
public static void UseConsulServiceDiscovery(this IApplicationBuilder app, IHostApplicationLifetime life)
{
var consulClientInfo = app.ApplicationServices.GetRequiredService<ConsulClientInfo>();
if (consulClientInfo != null)
{
life.ApplicationStarted.Register( () =>
{
consulClientInfo.Client.Agent.ServiceRegister(consulClientInfo.RegisterInfo).Wait();
}); life.ApplicationStopping.Register( () =>
{
consulClientInfo.Client.Agent.ServiceDeregister(consulClientInfo.RegisterInfo.ID).Wait();
});
}
else
{
throw new NullReferenceException("未找到相关consul客户端信息!");
}
} private static void Register(this IServiceCollection services)
{
if (serviceOptions == null)
{
throw new Exception("获取服务注册信息失败!请检查配置信息是否正确!");
}
if (serviceOptions.ConsulOptions == null)
{
throw new ArgumentNullException("请检查是否配置Consul信息!");
} string consulAddress = $"{serviceOptions.ConsulOptions.Scheme}://{serviceOptions.ConsulOptions.ConsulIP}:{serviceOptions.ConsulOptions.Port}"; var consulClient = new ConsulClient(opt =>
{
opt.Address = new Uri(consulAddress);
}); var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10), // 服务启动多久后注册
Interval = TimeSpan.FromSeconds(serviceOptions.HealthCheckIntervalSecond), // 间隔
HTTP = $"{serviceOptions.Scheme}://{serviceOptions.ServiceIP}:{serviceOptions.Port}{serviceOptions.HealthCheckUrl}",
Timeout = TimeSpan.FromSeconds(10)
}; var registration = new AgentServiceRegistration()
{
Checks = new[] { httpCheck },
ID = Guid.NewGuid().ToString(),
Name = serviceOptions.ServiceName,
Address = serviceOptions.ServiceIP,
Port = serviceOptions.Port,
}; services.AddSingleton(new ConsulClientInfo()
{
Client = consulClient,
RegisterInfo = registration
});
}
}
}

6.启动运行

  • 启动consul
  • 启动 Auth,Gateway项目
  • 通过网关项目访问Auth

启动Consul

为了方便演示这里是以开发者启动的consul

在consul.exe的目录下执行

consul agent -dev -ui // 开发者模式运行带ui

启动 Auth,Gateway项目

启动项目和可以发现我的们Auth服务已经注册进来了

通过网关访问Auth

我们这里访问 http://localhost:5000/auth/token 获取token

我们可以看到网关项目接收到了请求并在控制台中打印出以下信息



然后在Auth项目中的控制台中可以看到已经成功接收到了请求并响应

.NETCore微服务探寻(一) - 网关的更多相关文章

  1. .NETCore微服务探寻(三) - 分布式日志

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  2. .NETCore微服务探寻(二) - 认证与授权

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  3. .NETCore微服务探寻(三) - 远程过程调用(RPC)

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  4. AspNetCore微服务下的网关-Kong(一)

    Kong是Mashape开源的高性能高可用API网关和API服务管理层.它基于OpenResty,进行API管理,并提供了插件实现API的AOP.Kong在Mashape 管理了超过15,000 个A ...

  5. (1)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 什么是微服务架构,.netCore微服务选型

    开发工具:VS2017 .Net Core 2.1 什么是微服务?单体结构: 缺点: 1)只能采用同一种技术,很难用不同的语言或者语言不同版本开发不同模块: 2)系统耦合性强,一旦其中一个模块有问题, ...

  6. (1).NET CORE微服务 Micro-Service ---- 什么是微服务架构,.netCore微服务选型

    开发工具:VS2017 .Net Core 2.1 什么是微服务?单体结构: 缺点:1)只能采用同一种技术,很难用不同的语言或者语言不同版本开发不同模块:2)系统耦合性强,一旦其中一个模块有问题,整个 ...

  7. 什么是微服务架构,.netCore微服务选型

    什么是微服务架构,.netCore微服务选型 https://www.cnblogs.com/uglyman/p/9182485.html 开发工具:VS2017 .Net Core 2.1 什么是微 ...

  8. .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一)

    原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一) 写下此文章只为了记录Surging微服务学习过程,并且分享给广大想学习surging的基友,方便广大 ...

  9. .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二)

    原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二) 先上项目解决方案图: 以上可以看出项目结构可以划分为4大块,1是surging的核心底层,2,3,4都可以 ...

随机推荐

  1. Java内存虚拟机理解

        对于Java程序员,在虚拟机自动内存管理机制的帮助下,不需要再为每一个操作写配对的释放资源操作,不容易出现内存泄露和内存溢出问题.加深对Java虚拟机的理解,有助于在发现问题时精准定位问题,排 ...

  2. DQN(Deep Q-learning)入门教程(一)之强化学习介绍

    什么是强化学习? 强化学习(Reinforcement learning,简称RL)是和监督学习,非监督学习并列的第三种机器学习方法,如下图示: 首先让我们举一个小时候的例子: 你现在在家,有两个动作 ...

  3. nginx四种均衡策略

    1.基于轮询的均衡策略: 轮询嘛,就是说对进到nginx的request按照遍历的方式进行分发,如果request 1 分发到 Server A,那么request 2将被分发到 Server B,. ...

  4. 关于Tensorflow基于Windows安装那些事儿

    声明:代码及博客小白一枚,如有错误,感谢指正~~ 众所周知,摘抄来温习一遍: Tensorflow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库.节点(Nodes) ...

  5. MySQL 5.7.30 的安装/升级(所有可能的坑都在这里)

    楔子 由于之前电脑上安装的MySQL版本是比较老的了,大概是5.1的版本,不支持JSON字段功能.而最新开发部门开发的的编辑器产品,使用到了JSON字段的功能. 因此需要升级MySQL版本,升级的目标 ...

  6. 关于自己配置有关webpack.config.js和vue项目搭建相关步骤

    ## Webpack的配置和使用 ### 安装 1. 全局安装 ``` npm install webpack -g ``` 2. 本地安装 ``` npm install webpack -D `` ...

  7. Rocket - tilelink - Xbar

    https://mp.weixin.qq.com/s/UXFHYEQaYotWNEhshro68Q   简单介绍Xbar的实现.   ​​   1. 基本介绍   用于为Xbar的输入和输出连接生成内 ...

  8. rewrite和return的简单需求

    Rewrite 需求作业 背景:现在我有一个网站,www.linux.com www.linux.com访问主页面 friend.linux.com访问交友页面 blog.linux.com访问博客页 ...

  9. Java实现基础练习十进制转十六进制

    基础练习 十进制转十六进制 时间限制:1.0s 内存限制:512.0MB 提交此题 锦囊1 锦囊2 问题描述 十六进制数是在程序设计时经常要使用到的一种整数的表示方式.它有0,1,2,3,4,5,6, ...

  10. Java实现 蓝桥杯 算法训练 递归求二项式系数

    算法训练 6-1 递归求二项式系数值 时间限制:10.0s 内存限制:256.0MB 问题描述 样例输入 一个满足题目要求的输入范例. 3 10 样例输出 与上面的样例输入对应的输出. 数据规模和约定 ...