首页 > 其他分享 >Net8微服务之Consul、Ocelot、IdentityServer4

Net8微服务之Consul、Ocelot、IdentityServer4

时间:2024-04-24 23:44:44浏览次数:26  
标签:服务 -- Consul Ocelot http ServiceA IdentityServer4 客户端

前言

情绪的尽头是沉默

1.微服务概念

1.1微服务发展

分布式解决性能问题,微服务解决维护性、扩展性、灵活性。

image-20240422000607835

1.2微服务概念

微服务(或称微服务架构),是一种现代化的软件架构方法,它将一个应用程序分解为多个小型、独立的服务单元,每个服务都负责特定的业务功能,并且可以独立开发、测试、部署和扩展。

这些服务通常是松散耦合的,使用不同的技术栈和开发语言,并通过轻量级通信机制(如Rest API、消息传递 进行交互。微服务架构的核心在于提高应用程序的可维护性、可扩展性和灵活性,同时允许团队成员使用最适合其需求的技术和开发语言。与传统的大型单体应用架构相比,微服务架构能够更好地应对复杂系统和高速变化的技术环境。

特点:

  • 一组小的服务
  • 独立的进程
  • 轻量级的通信
  • 基于业务能力(DDD)
  • 独立部署:迭代速度快
  • 无集中式管理:无须统一技术栈,可以根据不同的服务或者团队进行灵活选择。

1.3微服务架构

微服务架构实施需要从业务领域、服务拆分、服务通信、数据管理、服务治理、自动化部署、监控与日志、测试策略等多个方面进行规划和设计。

image-20240422000831431

1.4微服务技术栈

微服务架构实施需要从业务领域、服务拆分、服务通信、数据管理、服务治理、自动化部署、监控与日志、测试策略等多个方面进行规划和设计。

2.Nginx负载均衡

基于Net8创建一个WebApi服务:Peng.Microservice.ServiceA

image-20240422001745868

在Peng.Microservice.ServiceA下cmd运行服务

dotnet run --urls=http://*:5000 --port=5000
dotnet run --urls=http://*:5001 --port=5001

image-20240422002902110

配置Nginx

同一个服务可以启动多个进程进行访问。

image-20240422002802901

3.Consul服务注册

基本使用概念之前写过:https://www.cnblogs.com/pengboke/p/16118746.html

3.1安装

补充到之前的博客了

https://www.cnblogs.com/pengboke/p/18156610

3.2服务注册

引入包

<PackageReference Include="Consul" Version="1.7.14.3" />

使用

 // Consul
builder.Services.ConsulRegister(option => { 
     var consulConfig = configuration.GetSection("ConsulConfig").Get<ConsulConfig>();
     option.Config(consulConfig);
 });

app.UseConsul(builder.Services.BuildServiceProvider(), app.Lifetime, configuration);

image-20240422215541291

启动

dotnet run --urls=http://*:5001 --port=5001
dotnet run --urls=http://*:5002 --port=5002

Peng.Microservice.ServiceA启动2个实例

image-20240422215305474

查看Consul

image-20240422215456230

3.3服务发现

创建控制台客户端获取ConsulClient注册实例并调用

image-20240422221403557

3.4服务权重

添加权重命令

dotnet run --urls=http://*:5001 --port=5001 --weight=1
dotnet run --urls=http://*:5002 --port=5002 --weight=2

image-20240422221858229

根据权重获取服务实例

因为5002权重大些,调用的几率会高

image-20240422222131625

3.5健康检测

添加健康检测接口,并配置AgentServiceRegistration

image-20240422222334633

Consul显示正常

image-20240422222728829

4.Ocelot网关

4.1概念

常用网关:Kong、Spring Cloud Gateway、Bumblebee、Ocelot

基本概念之前写过,这里不过多赘述:https://www.cnblogs.com/pengboke/p/16118726.html

安装包

  <ItemGroup>
    <PackageReference Include="Ocelot" Version="23.2.2" />
    <PackageReference Include="Ocelot.Provider.Consul" Version="23.2.2" />
    <PackageReference Include="Ocelot.Provider.Polly" Version="23.2.2" />
  </ItemGroup>

4.2Ocelot直连服务

注入服务

image-20240422233947308

配置路由ocelot.json

"Type": "RoundRobin"意思时轮询,每个服务实例都访问一次

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "5001"
        },
        {
          "Host": "localhost",
          "Port": "5002"
        }
      ],
      "UpstreamHttpMethod": [
        "GET",
        "POST",
        "DELETE",
        "PUT",
        "OPTIONS"
      ],
      "UpstreamPathTemplate": "/ServiceA/{url}", //httn://localhost:端口号/ServiceA/Home/Get
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "LeastConnection": "RoundRobin" //"LeastComnection" //少连接数的服务器 "NoLoadBalance”//不负载均衡 /"CookieStickySessions” //会话粘滞 //
      }
    }  
  ]
}

运行

dotnet run --urls=http://*:9000 --port=9000

image-20240422233919488

循环10次,每1s一次,每个服务轮流调用

image-20240423000854510

4.3Ocelot连接Consul

如果Ocelot直连服务实例,当某一个服务实例故障后,程序会无法连接。

所以需要连接Consul,故障后直接下机。

注入AddConsul

image-20240422235705344

修改配置文件

//consul+ocelot
{
  //服务中心信息
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  },
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ServiceA/{url}", //httn://localhost:端口号/ServiceA/Home/Get
      "UpstreamHttpMethod": [
        "GET",
        "POST",
        "DELETE",
        "PUT",
        "OPTIONS"
      ],
      "UseServiceDiscovery": true, //使用服务发现
      "ServiceName": "Peng.Microservice.ServiceA", //服务名称
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "LeastConnection": "RoundRobin" //"LeastComnection" //少连接数的服务器 "NoLoadBalance”//不负载均衡 /"CookieStickySessions” //会话粘滞 //
      }
    }
  ]
}

当断掉5001,使5001故障,Ocelot不会在来连接5001,一直使用可用的5002。

image-20240422235751946

4.4Ocelot缓存

修改配置,增加FileCacheOptions节点

//consul+ocelot(缓存)
{
  //服务中心信息
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  },
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ServiceA/{url}", //httn://localhost:端口号/ServiceA/Home/Get
      "UpstreamHttpMethod": [
        "GET",
        "POST",
        "DELETE",
        "PUT",
        "OPTIONS"
      ],
      "UseServiceDiscovery": true, //使用服务发现
      "ServiceName": "Peng.Microservice.ServiceA", //服务名称
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "LeastConnection": "RoundRobin" //"LeastComnection" //少连接数的服务器 "NoLoadBalance”//不负载均衡 /"CookieStickySessions” //会话粘滞 //
      },
      //缓存
      "FileCacheOptions": {
        "TtlSeconds": 10, //缓存时间
        "Region": "ServiceA" //缓存区
      }
    }
  ]
}

循环20次,每2s一次,10s过期会重新请求。

image-20240423001126548

4.5Ocelot自定义缓存

实现 IOcelotCache

image-20240423011245127

注入IOcelotCache服务

image-20240423011306915

改小过期时间,方便测试

image-20240423011337611

测试调用,输出自定义缓存日志

image-20240423011704505

4.6故障场景

1、重试策略(Retry):当服务调用失败时,Polly可以自动进行重试,这有助于 处理那些可能因为暂时性问题导致的服务不可用情况。

2、断路器(Circuit Breaker):当检测到服务连续不可用时,断路器策略会介入,快速返回错误响应,避免对下游服务的持续请求,从而预防服务雪崩现象。

3、超时策略(Timeout):为服务调用设置一个最大执行时间,超过这个时间的服务调用将被认为失败,可以采取预设的应对措施。

4、舱壁隔离(Bulkhead Isolation):通过限制对服务的并发调用数量,防止因某个服务的问题影响到整个系统的稳定性。

5、缓存策略(Cache):提供一种机制,可以在服务调用的结果不变的情况下直接使用缓存结果,减少不必要的服务调用。

6、降级策略(Fallback):当服务调用失败时,可以提供一个备用的逻辑或者数据作为响应,提高用户体验。

7、策略组合(PolicyWrap) : Polly针对不同的故障有不同的策略,我们可以灵活的组合策略,上述的六种策略可以灵活组合使用。

4.7Ocelot限流

配置限流,这里的策略为了方便测试配置策略5分钟最多访问3次。

image-20240423012354884

{
  //服务中心信息
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "QuotaExceededMessage": "Too many requests!Please wait a moment!", // 当请求过载被截断时返回的消息,中文会出现乱码
      "HttpStatusCode": 503 // 当请求过载被截断时返回的http status
    }
  },
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ServiceA/{url}", //httn://localhost:端口号/ServiceA/Home/Get
      "UpstreamHttpMethod": [
        "GET",
        "POST",
        "DELETE",
        "PUT",
        "OPTIONS"
      ],
      "UseServiceDiscovery": true, //使用服务发现
      "ServiceName": "Peng.Microservice.ServiceA", //服务名称
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "LeastConnection": "RoundRobin" //"LeastComnection" //少连接数的服务器 "NoLoadBalance”//不负载均衡 /"CookieStickySessions” //会话粘滞 //
      },
      //缓存
      "FileCacheOptions": {
        "TtlSeconds": 5, //缓存时间
        "Region": "ServiceA" //缓存区
      },
      //限流
      "RateLimitOptions": { //限流,限制了单位时间内的访问量
        "ClientWhitelist": [], //白名单
        "EnableRateLimiting": true,
        "Period": "5m", //1s, 5m, 1h, 1d  
        "PeriodTimespan": 5, //多少秒之后客户端可以重试
        "Limit": 3 //统计时间段内允许的最大请求数量
      }
    }
  ]
}

5分钟最多访问3次,第4次的时候直接返回503,然后5s之后可以再重新请求。

image-20240423012600438

4.8Ocelot+Polly熔断

修改配置文件,需要配置网关IP端口

熔断策略:5s内允许三次错误,5s后可重新请求

image-20240423015032060

//consul+ocelot+polly熔断
{
  //服务中心信息
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9000",
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "QuotaExceededMessage": "Too many requests!Please wait a moment!", // 当请求过载被截断时返回的消息,中文会出现乱码
      "HttpStatusCode": 503 // 当请求过载被截断时返回的http status
    }
  },
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ServiceA/{url}", //httn://localhost:端口号/ServiceA/Home/Get
      "UpstreamHttpMethod": [
        "GET",
        "POST",
        "DELETE",
        "PUT",
        "OPTIONS"
      ],
      "UseServiceDiscovery": true, //使用服务发现
      "ServiceName": "Peng.Microservice.ServiceA", //服务名称
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "LeastConnection": "RoundRobin" //"LeastComnection" //少连接数的服务器 "NoLoadBalance”//不负载均衡 /"CookieStickySessions” //会话粘滞 //
      },
      ////缓存
      //"FileCacheOptions": {
      //  "TtlSeconds": 5, //缓存时间
      //  "Region": "ServiceA" //缓存区
      //},
      //限流
      "RateLimitOptions": { //限流,限制了单位时间内的访问量
        "ClientWhitelist": [], //白名单
        "EnableRateLimiting": true,
        "Period": "1s", //1s, 5m, 1h, 1d  
        "PeriodTimespan": 5, //多少秒之后客户端可以重试
        "Limit": 1000 //统计时间段内允许的最大请求数量
      },
      //熔断设置
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求
        "DurationOfBreak": 5000, // 熔断的时间5s,单位为ms
        "TimeoutValue": 5000 //单位ms,如果下游请求的处理时间超过多少则自动将请求设置为超时 默认90秒
      }
    }
  ]
}

Peng.Microservice.ServiceA添加一个主动抛出异常的接口

image-20240423015144290

注入Polly

image-20240423015233742

5s内出现3次异常,第4次503,5s内都是503,然后5s过后可以重新请求。

image-20240423015322301

4.9Polly服务降级

安装包

  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

\Peng.Microservice.ServiceA添加接口GetExceptionByPolly,使用Policy进行降级,模拟当调用别的服务异常时返回Server Error

image-20240423173017430

客户端调用

image-20240423173219543

5.认证授权

5.1概念

以前简单的写过一些IdentityServer4:

https://www.cnblogs.com/pengboke/p/15738842.html

客户端模式:客户端模式只对客户端进行授权,不涉及到用户信息。如果你的api需要提供到第三方应用,第三方应用自己做用户授权,不需要用到你的用户资源,就可以用客户端模式,只对客户端进行授权访问api资源。

密码模式:需要客户端提供用户名和密码,密码模式相较于客户端凭证模式。通过User的用户名和密码向Identity Server申请访问令牌。

**(简化 没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

授权码模式:授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token。这比隐藏模式更为安全。从应用场景上来区分的话,隐藏模式适应于全前端的应用,授权码模式适用于有后端的应用,因为客户端根据授权码去请求token时是需要把客户端密码转进来的,为了避免客户端密码被暴露,所以请求token这个过程需要放在后台。

5.2授权服务

创建授权服务,并安装IdentityServer4

<PackageReference Include="IdentityServer4" Version="4.1.2" />

image-20240423203009624

配置ids4

 /// <summary>
 /// 授权配置
 /// </summary>
 public class AuthConfig
 {
     /// <summary>
     /// 定义ApiResource
     /// 这里的资源(Resources)指的就是管理的API
     /// </summary>
     /// <returns>多个ApiResource</returns>
     public static IEnumerable<ApiResource> GetApiResources()
     {
         return new[]
         {
             new ApiResource("ServiceA", "服务A")
             {
                 Scopes={ "scope1" }//4.x必须写的
             }
         };
     }

     /// <summary>
     /// 作用范围
     /// </summary>
     public static IEnumerable<ApiScope> GetApiScopes()
     {
         return new ApiScope[]
           {
             new ApiScope("scope1"),
             new ApiScope("scope2"),
           };
     }

     /// <summary>
     /// 定义验证条件的Client
     /// </summary>
     /// <returns></returns>
     public static IEnumerable<Client> GetClients()
     {
         return new[]
         {
             new Client
             {
                 ClientId = "AuthCenter",//客户端唯一标识
                 ClientName="AuthenticationCenter",//客户端名称
                 ClientSecrets = new [] { new Secret("123456".Sha256()) },//客户端密码,进行了加密
                 AllowedGrantTypes = GrantTypes.ClientCredentials,
                 //授权方式,客户端认证,只要ClientId+ClientSecrets
                 AllowedScopes = new [] { "scope1" },//允许访问的资源

                 Claims=new List<ClientClaim>(){
                     new ClientClaim(IdentityModel.JwtClaimTypes.Role,"Admin"),
                     new ClientClaim(IdentityModel.JwtClaimTypes.NickName,"Admin"),
                 }
             }
         };
     }
 }

注入id4服务

image-20240423203156629

运行授权服务

dotnet run --urls=http://*:9100 --port=9100

image-20240423203707474

访问获取jwt

image-20240423205347672

5.3JWT

JWT全称Json Web Token

把请求的Token放到https://jwt.io/

首先可以看到Token由Header(头部)、Payload(载荷)、Signature(签名)组成

然后看Payload发现获取的资源就是我们AuthConfig配置的

image-20240423205641485

5.4.Ocelot配置id4

Peng.Microservice.GateWay网关服务Ocelot给API服务配置id4认证

image-20240423214444407

Authority:认证服务地址

image-20240423214551535

Ocelot配置id4路由

image-20240423214802505

{
  "DownstreamPathTemplate": "/connect/token",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 9100
    }
  ],
  "UpstreamPathTemplate": "/connect/token",
  "UpstreamHttpMethod": [ "Post" ]
},
{
  "DownstreamPathTemplate": "/connect/authorize",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 9100
    }
  ],
  "UpstreamPathTemplate": "/connect/authorize",
  "UpstreamHttpMethod": [ "Get" ]
},
{
  "DownstreamPathTemplate": "/connect/logout",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 9100
    }
  ],
  "UpstreamPathTemplate": "/connect/logout",
  "UpstreamHttpMethod": [ "Get" ]
}

运行3个服务

# 网关服务
dotnet run --urls=http://*:9000 --port=9000
# 授权服务
dotnet run --urls=http://*:9100 --port=9100
# 服务A
dotnet run --urls=http://*:5001 --port=5001

image-20240423211309284

直接访问Api资源401

image-20240423215113250

通过Ocelot网关请求Token,带上Token再访问Api
image-20240423215430862

5.5授权角色

ocelot.json配置角色,只有Admin角色才可以访问

AuthConfig配置了客户端角色为Admin

image-20240424230825153

所以请求到Token可以正常访问接口

image-20240424231053638

修改配置的角色,id4客户端没有配置该角色权限,所以返回Forbidden(403)

image-20240424231231200

标签:服务,--,Consul,Ocelot,http,ServiceA,IdentityServer4,客户端
From: https://www.cnblogs.com/pengboke/p/18156627

相关文章

  • Window下运行Nginx、Redis、ES、RabbitMQ、Consul
    前言有时候需要在Windows下快速安装运行环境,比如Redis、Elasticsearch等,想通过bat命令快速启动。1.Nginx下载地址:https://nginx.org/en/download.html解压2.Redis下载地址:https://github.com/tporadowski/redis/releases解压3.Elasticsearch下载地址:https://www.elas......
  • 通过Java修改consul配置(保留注释、保留缩进)
         直接上代码了,找了很久也没找到保留注释的三方包,snakeyaml的缩进一直也有问题,就自己写了个正则方式的consul也没有相关接口,只接受整个的传key和value,替换相应value值,大佬有更好的方法希望能告诉我<dependency><groupId>com.orbitz.consu......
  • 07_NET中Ocelot结合Consult使用
    Consul主机:http://localhost:8500新建子服务:Consul.ServiceA【http://localhost:5011】,Consul.ServiceB【http://localhost:5012】配置内容(06_NET中使用Consul(服务发现)-野码-博客园(cnblogs.com))Consul.ServiceA:[Route("[controller]/[action]")][ApiControlle......
  • 06_NET中使用Consul(服务发现)
    官网:ConsulbyHashiCorp 中文文档:Consul中文文档|Consul中文文档(gitbook.io)安装Consulwindow安装:Install|Consul|HashiCorpDeveloper1.选择windowsx64版本(64bit)2.进入下载好的文件夹中,打开powershell,执行命令,启动服务端代理consul.exeagent-dev3.......
  • 05_NET中使用Ocelot网关(负载均衡、限流、认证)
    Ocelot是一个用.NETCore实现并且开源的API网关,它功能强大,包括了:路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与ServiceFabric、ButterflyTracing集成。而且这些功能都只需要简单的配置即可完成。官网:GitHub-ThreeMammals/Ocelot:.NETAPIGateway......
  • Vault high availability with Consul
    VaulthighavailabilitywithConsulhttps://developer.hashicorp.com/vaultWhatisVault?Secure,store,andtightlycontrolaccesstotokens,passwords,certificates,encryptionkeysforprotectingsecrets,andothersensitivedatausingaUI,CLI,orH......
  • .NET服务发现(Microsoft.Extensions.ServiceDiscovery)集成Consul
    随着Aspire发布preview5的发布,Microsoft.Extensions.ServiceDiscovery随之更新,服务注册发现这个属于老掉牙的话题解决什么问题就不赘述了,这里主要讲讲Microsoft.Extensions.ServiceDiscovery(preview5)以及如何扩展其他的中间件的发现集成.Microsoft.Extensions.ServiceDisc......
  • consul:啥?我被优化没了?AgileConfig+Yarp替代Ocelot+Consul实现服务发现和自动网关配置
    现在软件就业环境不景气,各行各业都忙着裁员优化。作为一个小开发,咱也不能光等着别人来优化咱,也得想办法优化下自己。就拿手头上的工作来说吧,我发现我的微服务应用里,既有AgileConfig这个配置中心组件,又有一个Consul服务发现组件。本来吧他俩也没啥事,各干个的。但是,我在操作AgileCo......
  • consul:啥?我被优化没了?AgileConfig+Yarp替代Ocelot+Consul实现服务发现和自动网关配置
    现在软件就业环境不景气,各行各业都忙着裁员优化。作为一个小开发,咱也不能光等着别人来优化咱,也得想办法优化下自己。就拿手头上的工作来说吧,我发现我的微服务应用里,既有AgileConfig这个日志组件,又有一个Consul服务发现组件。本来吧他俩也没啥事,各干个的。但是,我在操作AgileConfig......
  • feign.net 使用consul服务发现 配置
    所有依赖 <ProjectSdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net8.0</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><In......