前言

没看dotnet微服务之API网关Ocelot的请先看,这篇文章接上面文章

安装consul

#自定义网络,自定义网络可以指定容器IP,这样服务器重启consul集群也可以正常运行。
docker network create --driver bridge --subnet=172.21.0.0/16 --gateway=172.21.0.16 adnc_consul docker run -d -p 8500:8500 -p 8600:8600 -p 8301:8301 --restart=always --network=adnc_consul --ip 172.21.0.1 --privileged=true --name=consul_server_1 --name consul consul:1.15.4 agent -server -bootstrap -ui -node=consul_server_1 -client='0.0.0.0'

在GoodApi项目中修改Program.cs

先要添加Consul包

再添加Consul注册于注销等相关代码

using Consul;
using System.Linq;
using System.Net;
using System.Net.Sockets; // 创建Consul客户端
var consulAddress = "http://10.75.174.43:8500";// Environment.GetEnvironmentVariable("CONSUL_ADDRESS"); //10.75.174.43
var consulUri = new Uri(consulAddress);
var client = new ConsulClient(config =>
{
config.Address = consulUri;
}); // 配置服务的健康检查
var check = new AgentServiceCheck()
{
HTTP = $"http://{GetLocalIpAddress("InterNetwork").FirstOrDefault()}:8080/health", // 健康检查地址
Interval = TimeSpan.FromSeconds(10) // 检查间隔
};
var serviceId = "goodapi-1"; // 要注销的服务的ID
// 注册一个服务
var registration = new AgentServiceRegistration()
{
ID = serviceId,
Name = "goodapi",
Address = GetLocalIpAddress("InterNetwork").FirstOrDefault(),
Port = 8080,
Check = check
}; await client.Agent.ServiceDeregister(serviceId);
client.Agent.ServiceRegister(registration); var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} app.MapControllers(); app.MapGet("/health", async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("health");
}); app.Run(); // 注销服务 await client.Agent.ServiceDeregister(serviceId); List<string> GetLocalIpAddress(string netType)
{
string hostName = Dns.GetHostName();
IPAddress[] addresses = Dns.GetHostAddresses(hostName); var IPList = new List<string>();
if (netType == string.Empty)
{
for (int i = 0; i < addresses.Length; i++)
{
IPList.Add(addresses[i].ToString());
}
}
else
{
//AddressFamily.InterNetwork = IPv4,
//AddressFamily.InterNetworkV6= IPv6
for (int i = 0; i < addresses.Length; i++)
{
if (addresses[i].AddressFamily.ToString() == netType)
{
IPList.Add(addresses[i].ToString());
}
}
}
return IPList;
}

加Dockerfile文件

#使用asp.net 6作为基础镜像,起一个别名为base
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
#设置容器的工作目录为/app
WORKDIR /app
#COPY 文件
COPY . /app
ENV ASPNETCORE_ENVIRONMENT Production #设置时区为东八区
ENV TZ Asia/Shanghai
#启动服务
ENTRYPOINT ["dotnet", "GoodApi.dll"]
# 运行goodapi项目
docker stop goodapi
docker rm -f goodapi
docker build -t goodapi .
docker run --name=goodapi -d -p 8080:8080 --network=adnc_consul goodapi

在OcelotGA中加consul配置与代码

加包Consul,Ocelot.Provider.Consul

改ocelot.json配置

{
"Routes": [
{
"UseServiceDiscovery": true,
"UpstreamPathTemplate": "/good/{everything}",
"UpstreamHttpMethod": [ "Get" ],
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"ServiceName": "goodapi",
"LoadBalancerOptions": {
"Type": "LeastConnection"
}
},
{
"UseServiceDiscovery": true,
"UpstreamPathTemplate": "/order/{everything}",
"UpstreamHttpMethod": [ "Get" ],
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"ServiceName": "orderapi",
"LoadBalancerOptions": {
"Type": "LeastConnection"
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://gw.wxy.ink",
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "10.75.174.43", // 这里是您Consul的地址
"Port": 8500, // Consul的端口
"Type": "Consul"
}
}
}

修改Program.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using System;
using System.Collections.Generic;
using System.Net; using Consul;
using OcelotGA; // 创建Consul客户端
var consulAddress = "http://10.75.174.43:8500";// Environment.GetEnvironmentVariable("CONSUL_ADDRESS"); //10.75.174.43
var consulUri = new Uri(consulAddress);
var client = new ConsulClient(config =>
{
config.Address = consulUri;
}); // 配置服务的健康检查
var check = new AgentServiceCheck()
{
HTTP = $"http://{GetLocalIpAddress("InterNetwork").FirstOrDefault()}:8080/health", // 健康检查地址
Interval = TimeSpan.FromSeconds(10) // 检查间隔
};
var serviceId = "gw-1"; // 要注销的服务的ID
// 注册一个服务
var registration = new AgentServiceRegistration()
{
ID = serviceId,
Name = "gw",
Address = GetLocalIpAddress("InterNetwork").FirstOrDefault(),
Port = 8080,
//Check = check
}; await client.Agent.ServiceDeregister(serviceId);
client.Agent.ServiceRegister(registration); var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true); builder.Services.AddOcelot().AddConsul<MyConsulServiceBuilder>(); //这里要注意MyConsulServiceBuilder var app = builder.Build(); app.UseOcelot().Wait(); app.UseRouting(); app.MapGet("/Health", async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("Health");
}); app.Run(); // 注销服务 await client.Agent.ServiceDeregister(serviceId); List<string> GetLocalIpAddress(string netType)
{
string hostName = Dns.GetHostName();
IPAddress[] addresses = Dns.GetHostAddresses(hostName); var IPList = new List<string>();
if (netType == string.Empty)
{
for (int i = 0; i < addresses.Length; i++)
{
IPList.Add(addresses[i].ToString());
}
}
else
{
//AddressFamily.InterNetwork = IPv4,
//AddressFamily.InterNetworkV6= IPv6
for (int i = 0; i < addresses.Length; i++)
{
if (addresses[i].AddressFamily.ToString() == netType)
{
IPList.Add(addresses[i].ToString());
}
}
}
return IPList;
}

添加MyConsulServiceBuilder.cs

using Consul;
using Ocelot.Logging;
using Ocelot.Provider.Consul;
using Ocelot.Provider.Consul.Interfaces; namespace OcelotGA
{
public class MyConsulServiceBuilder : DefaultConsulServiceBuilder
{
public MyConsulServiceBuilder(IHttpContextAccessor contextAccessor, IConsulClientFactory clientFactory, IOcelotLoggerFactory loggerFactory)
: base(contextAccessor, clientFactory, loggerFactory) { } // I want to use the agent service IP address as the downstream hostname
protected override string GetDownstreamHost(ServiceEntry entry, Node node)
=> entry.Service.Address;
}
}

运行网关项目

我们访问gw.wxy.ink/good/health

爬坑记录

Program.cs中的

builder.Services.AddOcelot().AddConsul<MyConsulServiceBuilder>(); //这里要注意MyConsulServiceBuilder
若为
builder.Services.AddOcelot().AddConsul();

则会出现下面问题

服务解析出来是node的名称,而非服务的IP

解决方法:Service Discovery — Ocelot Gateway 23.4 documentation

就是说默认的DefaultConsulServiceBuilder会这样处理

protected virtual string GetDownstreamHost(ServiceEntry entry, Node node)
=> node != null ? node.Name : entry.Service.Address;

而我们需要的是

protected override string GetDownstreamHost(ServiceEntry entry, Node node)
=> entry.Service.Address;

作者

吴晓阳(手机:13736969112微信同号)

Ocelot集成Consul实现api网关与服务发现的更多相关文章

  1. SpringCloud之API网关与服务发现——Cloud核心组件实战入门及原理

    微服务发展历史 单体模式——>服务治理(服务拆分)——>微服务(细分服务)——>Segments(服务网格) 微服务 VS SOA 微服务:模块化.独立部署.异构化 SOA:共同的治 ...

  2. .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡

    大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...

  3. .Net Core微服务——网关(2):ocelot集成consul

    有consul基础的都知道,consul可以发现新增的服务,剔除掉无效的服务,赋予应用自动伸缩的能力.而ocelot如果集成了consul,那ocelot也能拥有这些能力,还可以自主选择负载均衡策略, ...

  4. 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡等方面

    Ocelot   路由  请求聚合  服务发现 认证  鉴权 限流熔断 内置负载均衡器 Consul   自动服务发现    健康检查 通过Ocelot搭建API网关   服务注册   负载均衡 1. ...

  5. Ocelot + Consul + Registrator 基于Docker 实现服务发现、服务自动注册

    目录 1. Consul集群搭建 1.1 F&Q Consul官方推荐的host网络模式运行 2. Registrator服务注册工具 2.1 F&Q Registrator悬挂服务 ...

  6. SpringCloud系列之API网关(Gateway)服务Zuul

    1.什么是API网关 API网关是所有请求的入口,承载了所有的流量,API Gateway是一个门户一样,也可以说是进入系统的唯一节点.这跟面向对象设计模式中的Facet模式很像.API Gatewa ...

  7. 基于consul构建golang系统分布式服务发现机制

    原文地址-石匠的Blog: http://www.bugclosed.com/post/5 在分布式架构中,服务治理是一个重要的问题.在没有服务治理的分布式集群中,各个服务之间通过手工或者配置的方式进 ...

  8. BeetleX服务网关之服务发现与泛域名路由

    在新版本的服务网关中提供了服务发现和泛域名路由解决功能,服务发现可以在无须配置的情况下实现服务自动注册到网关中解脱对服务配置的繁琐工作:而泛域名路由则可以针对不同的域名制定不同的负载规则. 使用con ...

  9. ocelot集成consul服务发现

    首先下载consul 点击这里下载 转到解压文件夹目录输入cmd命令  consul agent -dev (有时候会卡住按一下方向键上) 在浏览器中输入http://localhost:8500/u ...

  10. 微服务&#183;API网关

    阅文时长 | 3.52分钟 字数统计 | 1232字符 主要内容 | 1.什么是API网关 2.微服务中的API网关 3.几种部署策略 『微服务·API网关』 编写人 | SCscHero 编写时间 ...

随机推荐

  1. Coursera, Big Data 5, Graph Analytics for Big Data, Week 1/2

    Graph表示 1. adjacency matrix最简单的一种表示:行是From 列是To, 这种表示是稀疏矩阵 2. 另一种表示,如下图,很多graph数据库用这种,是的数据库操作更有效率 us ...

  2. wxpython开发gui界面基础

    wxpython 开发gui 基础知识 一 .前言 记录使用wxpython开发gui工具吧.gui界面主要就是先布局,每个模块都是一个对象. 二.基础知识 import wx class MyFra ...

  3. 使用 `Roslyn` 分析器和修复器 对异步方法规范化返回Async结尾

    之前写过一篇使用修复器帮助添加头部注释文本的功能,今天使用Roslyn的代码修复器对异步返回方法规范化的功能 实现分析器 首先需要实现分析器,使用RegisterSyntaxNodeAction,分析 ...

  4. RxJS 系列 – Observable to Subject (Hot, Cold, Warm, connectable, share)

    前言 前两篇介绍了 Observable 和 Subject.它们有一个重大区别当 multiple subscribe 的时候. Observable 每一次 subscribe 都会调用初始化方法 ...

  5. ASP.NET Core – View Component

    前言 以前写过 Asp.net core 学习笔记 ( ViewComponent 组件 ), 这篇作为翻新版. 参考 Docs – View components in ASP.NET Core D ...

  6. HTML – HTML Tags & Semantic HTML 语义化 HTML

    前言 HTML tag 有 100 多个, 有些是功能形的, 非用不可, 有些是为了语义化对 screen reader 友好 (给眼睛有残缺的人也可以获取清晰的网站信息). 语义化是很重要的, 有些 ...

  7. EF Core – Unit of Work, DbContext, Transaction 概念解释

    前言 踩了一个坑, 下面是 2 个 scope 的调用, 第 1 和 3 是一个 Audit log filter action, 第 2 个是 controller. // open tran // ...

  8. Brainstorm 了道题但是不会做

    题 因为没想出来暂时没定数据范围,不过应该会在 \(n^{2}\) 到 \(n^{3}\) 级别 我的一个思路是先对合法的方案连并查集,然后并查集内判重,但是不会算方案数,因为假如找到重的了不能直接看 ...

  9. AD域下,环境下办公机系统时间不准确

    事件起因: 某部门一同事电脑时间和AD域控时间相差3分钟,虽然说时间相差5分钟内问题不大,但是本着有问题就解决的原则,还是花了点时间去查资料解决. (小小吐槽一下,在我看来域控机是掌管下面所有的办公机 ...

  10. CSP-S 2023 游记

    CSP-S 2023 游记 Day 0 明天便是 CSP-S 第一轮了,考试前一天万万不能学什么太复杂,太深奥的东西,最好甚至不要过于强度的用脑,保持放空的轻松地状态,心中不要有压力才是最好的考前状态 ...