asp.net core系列 61 Ocelot 构建服务发现简单示例

一.概述

Ocelot允许指定服务发现提供程序,如Consul或Eureka。 这二个中间件是用来实现:服务治理或秒服务发现,服务发现查找Ocelot正在转发请求的下游服务的主机和端口。目前Ocelot仅在GlobalConfiguration部分支持配置服务发现功能,这意味着相同的服务发现提供程序将用于为ReRoute级别指定ServiceName的所有ReRoutes。这里介绍下服务发现的二个中间件:Consul与Eureka。

1. Consul介绍

Consul服务发现是用GO语言的开源框架,是一个分布式, 高可用,数据中心感知的解决方案,用于跨任何运行时平台和公共云或私有云连接。Consul是服务发现和配置工具。主要功能包括:

(1) 服务发现 - Consul使用简单的服务来注册自己,并通过DNS或HTTP接口发现其他服务。还可以注册外部服务,比如SaaS提供者。

(2) 运行状况检查 -运行状况检查使Consul能够快速向操作员发出有关群集中任何问题的警报, 与服务发现的集成可防止将流量路由到不健康的主机,并启用服务级别的断路器。

(3) Key/Value存储 - 灵活的Key/Value存储可以存储动态配置,功能标记,协调,领导者选举等。简单的HTTP API使其易于在任何地方使用。

(4) 多数据中心 - Consul可以识别数据中心,并且可以支持任意数量的区域而无需复杂的配置。

(5) 服务分段 - Consul 连接通过自动TLS加密和基于身份的授权实现安全的服务到服务通信。
 2. Eureka介绍

Eureka服务发现是用java语言的开源框架,最新版本为19.9 (有报道后面2.0版本不开源)。是一种基于REST的服务,主要用于AWS云,用于定位服务,以实现中间层服务器的负载平衡和故障转移。

使用Eureka示例:Service Discovery Demo With Eureka

示例介绍:https://www.c-sharpcorner.com/article/building-api-gateway-using-ocelot-in-asp-net-core-service-discoveryeureka/

二.演示项目介绍

本篇重点了解Consul的使用,下面参考开源项目Github , 本篇在部署上 对比 参考示例 有些小改动,项目使用了Ocelot + IdentityServer4 + Consul中间件。

image

说明:

(1) 用到的软件包括:centos系统, iis, fiddler。其中centos系统用于做Consul服务注册,iis做webapi的宿主承载,fiddler用于客户端模拟测试。

(2) 演示中 IdentityServer4服务认证和ApiGateway网关项目由vs2017 来做宿主承载,但也可以用iis承载。

项目名称 Ip和端口 说明
ApiGateway http://localhost:38039 网关项目。统一访问入口点,在生产环境下ip要在广域网,供第三方客户端访问。做好网关路由配置,将自动转发。
IdentityServer4 http://127.0.0.1:8021 Is4令牌服务。ip是在局域网, 通过web api来调用令牌
Service A/B http://127.0.0.1:8010 (A) http://127.0.0.1:8011 (B) 服务项目。ip是在局域网,由网关转发进来访问。
Consul 搭建 http://172.168.18.201:8500 服务发现。在linux中启动Consul服务,默认是8500端口,用于监听服务的健康状态。在linux中需要拼通服务ip及port, 反之一样。可telnet命令。配置服务注册文件
fiddler客户端模拟 调用服务A获取IS4令牌,通过该令牌访问服务A受保护的接口

三. web api服务

参考开源项目,Service A和Service B服务项目相关配置都一样,以Service A为例:

1.项目中有三个api接口

(1) 一个必须要诊断接口api/Health

(1) 一个必须要的获取令牌接口api/Session

(3) 一个业务测试接口api/Values。 因为业务接口是受保护的,所以该接口加了[Authorize],需要令牌来访问

[Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new[] { "value1", "value2" };
        }
    }

2. 在启动时,加了授权中间件,采用JwtBearer方案。设置了受信任的is4服务基地址,以及Audience保护的资源。

services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "http://127.0.0.1:8021";
                    options.RequireHttpsMetadata = false;
                    options.Audience = "ServiceB";
                });

四. ApiGateway项目

  1. 在网关项目中,配置ocelot文件
{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      //客户端通过/ServiceA来访问ServiceA的服务
      "UpstreamPathTemplate": "/ServiceA/{everything}",
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      //服务发现Consul用到
      "ServiceName": "ServiceA",
      "LoadBalancerOptions": {
        "Type": "LeastConnection"
      }
    },
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ServiceB/{everything}",
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "ServiceName": "ServiceB",
      "LoadBalancerOptions": {
        "Type": "LeastConnection"
      }
    }
  ],
  "GlobalConfiguration": {
    //配置Consul的信息
    "ServiceDiscoveryProvider": {
      "Host": "172.168.18.201",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

2.启动时添加网关中间件

public static void Main(string[] args)
        {
            new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile("appsettings.json", true, true)
                        .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
                        .AddJsonFile("ocelot.json")
                        .AddEnvironmentVariables();
                })
                .ConfigureServices(services =>
                {
                    services.AddOcelot().AddConsul();
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    //add your logging
                })
                .UseIISIntegration()
                .Configure(app =>
                {
                    app.UseOcelot().Wait();
                })
                .Build()
                .Run();
        }

五. IdentityServer令牌服务

参考开源IdentityServer项目代码,在令牌服务中,使用AddDeveloperSigningCredential来添加临时证书,在生产环境下,可以使用AddSigningCredential来添加证书。客户端基于用户名和密码的方式来获取令牌GrantTypes.ResourceOwnerPassword。

六 Consul搭建

1. consul安装

--下载安装包
        [root@hsr opt]# wget https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
    --将conusl命令移到bin目录下,方便启动
        [root@hsr opt]# mv consul /usr/local/bin/
    --测试安装是否成功,ok
    [root@hsr ~]# consul
    Usage: consul [--version] [--help] <command> [<args>]

2.添加服务注册放到/usr/etc/



 3. 启动客户端agent 测试

 consul agent -dev -data-dir=/usr/etc  -config-dir=/usr/etc/consul.json -client 172.168.18.201

启动成功后,会每隔10秒检查一次服务的健康状态,如下所示:


image
       -dev开发模式,启动该参数配置下,不会有任何持久化操作,即不会有任何数据写入到磁盘

       -config-file 指定服务注册文件

       -client指定当前ip,默认是127.0.0.1

       -data-dir指定agent储存状态的数据目录

4.关闭201防火墙, 在win系统上访问服务发现管理界面如下:

systemctl stop firewalld.service

image

七.fiddler测试

  1. 测试开始步骤:

(1) 两个服务ServerA/ServerB发布到iis上。

(2) 在vs2017中启动ApiGateway网关项目和IS4项目。

(3) 在linux系统中启动consul(现只是监听服务是否健康)
  2.测试ServerA服务

(1)通过用户名和密码,获取要访问ServerA服务的令牌

image

 (2) 获取受保护的api接口,将拿到的令牌加到headers中去请求


image

(3) 请求http://localhost:38039/serviceA/values数据接口成功,如下所示:

image

参考文献

服务发现

参考项目示例

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容