Ocelot集成Consul实现api网关与服务发现
前言
没看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;
}
}
运行网关项目


爬坑记录
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网关与服务发现的更多相关文章
- SpringCloud之API网关与服务发现——Cloud核心组件实战入门及原理
微服务发展历史 单体模式——>服务治理(服务拆分)——>微服务(细分服务)——>Segments(服务网格) 微服务 VS SOA 微服务:模块化.独立部署.异构化 SOA:共同的治 ...
- .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡
大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...
- .Net Core微服务——网关(2):ocelot集成consul
有consul基础的都知道,consul可以发现新增的服务,剔除掉无效的服务,赋予应用自动伸缩的能力.而ocelot如果集成了consul,那ocelot也能拥有这些能力,还可以自主选择负载均衡策略, ...
- 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡等方面
Ocelot 路由 请求聚合 服务发现 认证 鉴权 限流熔断 内置负载均衡器 Consul 自动服务发现 健康检查 通过Ocelot搭建API网关 服务注册 负载均衡 1. ...
- Ocelot + Consul + Registrator 基于Docker 实现服务发现、服务自动注册
目录 1. Consul集群搭建 1.1 F&Q Consul官方推荐的host网络模式运行 2. Registrator服务注册工具 2.1 F&Q Registrator悬挂服务 ...
- SpringCloud系列之API网关(Gateway)服务Zuul
1.什么是API网关 API网关是所有请求的入口,承载了所有的流量,API Gateway是一个门户一样,也可以说是进入系统的唯一节点.这跟面向对象设计模式中的Facet模式很像.API Gatewa ...
- 基于consul构建golang系统分布式服务发现机制
原文地址-石匠的Blog: http://www.bugclosed.com/post/5 在分布式架构中,服务治理是一个重要的问题.在没有服务治理的分布式集群中,各个服务之间通过手工或者配置的方式进 ...
- BeetleX服务网关之服务发现与泛域名路由
在新版本的服务网关中提供了服务发现和泛域名路由解决功能,服务发现可以在无须配置的情况下实现服务自动注册到网关中解脱对服务配置的繁琐工作:而泛域名路由则可以针对不同的域名制定不同的负载规则. 使用con ...
- ocelot集成consul服务发现
首先下载consul 点击这里下载 转到解压文件夹目录输入cmd命令 consul agent -dev (有时候会卡住按一下方向键上) 在浏览器中输入http://localhost:8500/u ...
- 微服务·API网关
阅文时长 | 3.52分钟 字数统计 | 1232字符 主要内容 | 1.什么是API网关 2.微服务中的API网关 3.几种部署策略 『微服务·API网关』 编写人 | SCscHero 编写时间 ...
随机推荐
- Mysql table 调整table的字符集和校对规则
ALTER TABLE `xxxx`.`xxx` CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_0900_ai_ci ;
- c程序设计语言 by K&R(五)UNIX系统接口
一.文件描述符 在unix操作系统中,所有的外围设备(包括键盘和显示器)都被看作是文件系统的文件,因此,所有的输入.输出都要通过读/写文件来完成.也就是说,通过一个单一的接口就可以处理外围设备和程序之 ...
- Goby漏洞发布 | CVE-2024-4879 ServiceNowUI /login.do Jelly模板注入漏洞【已复现】
漏洞名称:ServiceNowUI /login.do Jelly模板注入漏洞(CVE-2024-4879) English Name:ServiceNowUI /login.do Input Val ...
- 【合合TextIn】深度解析智能文档处理技术与应用
一.智能文档处理介绍 智能文档处理(Intelligent Document Processing, IDP)是利用人工智能(AI).机器学习(ML).计算机视觉(CV).自然语言处理(NLP)等技术 ...
- BOM – Navigator SendBeacon
介绍 游览器专门做给 tracking 用的接口. 从前我们想 tracking 用户点击 anchor 是比较麻烦的. 因为 click 事件触发后, 想发 ajxax 去做 tracking re ...
- CSS & JS Effect – 脉冲 Pulse Play Button
效果 参考 Youtube – Create a pulsing animation with CSS 重点 在背后做一个一样大的 div border 然后 animation scale up. ...
- PTA甲级—图
1.图的遍历 1013 Battle Over Cities (25 分) 一种方法使用dfs求连通块的个数 #include <cstdio> #include <cstring& ...
- vscode单行注释失效解决办法
第一种情况: bug:在使用快捷键注释的时候,只有style和script标签里的内容注释有问题,无法使用快捷键注释. 解决方法:禁用vscode的插件Jinja. 第二种情况 方法一 1.Ctrl+ ...
- Java以封装对象的方式读取CSV文件存储数据库
依赖 <!-- https://mvnrepository.com/artifact/net.sourceforge.javacsv/javacsv --> <dependency& ...
- C++的并发编程历史
多线程环境 并非所有的语言都提供了多线程的环境.即便是C++语言,直到C++11标准之前,也是没有多线程支持的. 在这种情况下,Linux/Unix平台下的开发者通常会使用POSIX Threads, ...