Ocelot\Consul\.NetCore的微服务应用案例

案例资料链接:https://download.csdn.net/download/ly1h1/90733765

1.效果

实现两个微服务ServerAPI1和ServerAPI2的负载均衡以及高可用。具体原理,看以下示意图。

2.部署条件

 1、腾讯云的轻量化服务器

 2、WindowServer2016 

 3、.NETCore7.0

 4、Negut 包:Consul1.7.14.7、Ocelot16.0.1、Ocelot.Provider.Conusl16.0.1

 5、.NET捆绑托管 dotnet-hosting-9.0.4-win.exe

3.开放端口

 2.1 云服务安全组端口开放

  端口:5000,是服务1

  端口:5001,是服务2

  端口:5010,是Ocelot网关

  端口:8050/8030/8031/8032,是Consul的端口

  • 8500 是核心 API 端口,必知;

  • 8030/31/32 需结合具体配置,可能是用户自定义的服务或工具端口。

2.2 服务器配置入栈站规则

3.Consul配置(部署可参考链接Consul安装部署(Windows环境)-CSDN博客)

{"datacenter": "dc1","data_dir": "C:\\consul\\data","node_name": "node-10-4-0-7","bind_addr": "0.0.0.0","advertise_addr": "10.0.4.7",(云服务内网的IP)"client_addr": "0.0.0.0","ports": {"http": 8500,"dns": 8600,"grpc": -1},"ui_config": {"enabled": true},"server": true,"bootstrap": true,"log_level": "ERROR","disable_update_check": true,"performance": {"raft_multiplier": 3,"leave_drain_time": "5s"}
}

4.Ocelot代码

4.1 Progrm.CS

using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul; // 引入 Consul 支持var builder = WebApplication.CreateBuilder(args);// 1. 配置 Kestrel 只监听 5010 端口(不绑定特定 IP)
builder.WebHost.UseUrls("http://*:5010"); // 监听所有网络接口
// 或者用 ConfigureKestrel(更灵活):
// builder.WebHost.ConfigureKestrel(serverOptions => serverOptions.ListenAnyIP(5010));// 2. 加载 Ocelot 配置
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);// 3. 添加 Ocelot 和 Consul 支持
builder.Services.AddOcelot(builder.Configuration).AddConsul(); // 关键:注入 Consul 提供程序var app = builder.Build();// 4. 使用 Ocelot 中间件
await app.UseOcelot();
app.Run();

4.2 Ocelot.JSON

{"Routes": [{"DownstreamPathTemplate": "/api/values/{action}","UpstreamPathTemplate": "/api/values/{action}","ServiceName": "ServerAPI","LoadBalancerOptions": {"Type": "RoundRobin"},"ServiceDiscoveryProvider": {"Type": "Consul","Host": "43.162.118.209","Port": 8500,"PollingInterval": 2000, // 每2秒从Consul拉取最新健康实例"SkipItemsWithUnhealthyStatus": true}}]
}

5.服务1代码

5.1 Program.CS

using Consul;
using Microsoft.OpenApi.Models;var builder = WebApplication.CreateBuilder(args);// 添加控制器和Swagger
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{c.SwaggerDoc("v1", new OpenApiInfo { Title = "ServerAPI1", Version = "v1" });
});// 注册Consul客户端
builder.Services.AddSingleton<IConsulClient>(new ConsulClient(c =>
{c.Address = new Uri("http://192.168.0.102:8500");
}));// 配置Kestrel(可选,根据实际需求)
builder.WebHost.UseUrls("http://*:5000");var app = builder.Build();// 健康检查端点
//app.MapGet("/health", () => Results.Ok("Healthy"));// 健康检查端点(模拟5000端口故障)
//app.MapGet("/health", (HttpContext context) =>
//{
//    var port = context.Request.Host.Port;
//    return port == 5000 ? Results.StatusCode(503) : Results.Ok("Healthy (Port: " + port + ")");
//});
//app.MapGet("/health", () => Results.Ok("Healthy (Port: 5000)"));
app.MapGet("/health", () =>
{// 基础存活检查(不依赖任何业务逻辑)return Results.Ok("Alive");
});// 注册到Consul
var consulClient = app.Services.GetRequiredService<IConsulClient>();
var registration = new AgentServiceRegistration
{ID = "ServerAPI-5000",Name = "ServerAPI",Address = "192.168.0.102",Port = 5000,Check = new AgentServiceCheck{HTTP = "http://192.168.0.102:5000/health",Interval = TimeSpan.FromSeconds(3),  // 每3秒检查一次Timeout = TimeSpan.FromSeconds(1),  // 1秒无响应视为失败DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10) // 10秒后自动移除}
};
consulClient.Agent.ServiceRegister(registration).Wait();// 其他中间件
app.UseRouting();
app.MapControllers();// 配置Swagger(开发环境)
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ServerAPI1 v1"));
}// 路由和控制器
app.UseRouting();
app.MapControllers();// 应用停止时注销服务
app.Lifetime.ApplicationStopping.Register(() =>
{consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});app.Run();

5.2 接口

    using Microsoft.AspNetCore.Mvc;using ServerAPI1.Models;namespace ServerAPI1.Controllers{[ApiController][Route("api/[controller]")][Produces("application/json")]public class ValuesController : ControllerBase{/// <summary>/// 获取服务基本信息/// </summary>[HttpGet("info")][ProducesResponseType(200)]public IActionResult GetInfo(){return Ok(new { Service = "ServerAPI1", Port = 5000 });}/// <summary>/// 计算服务 (A+B)/// </summary>/// <param name="model">输入参数</param>[HttpPost("calculate")][ProducesResponseType(200)][ProducesResponseType(400)]public IActionResult Calculate([FromBody] TestModel model){if (!ModelState.IsValid) return BadRequest(ModelState);return Ok(new { Result = 123 + 321, Input = model });}[HttpGet("getail")] // 实现 /api/values/getailpublic IActionResult Get(){return Ok("This is /api/values/getail from ServerAPI1");}[HttpGet("setail")]public IActionResult Gett(){return Ok("This is /api/values/setail from " + GetType().Assembly.GetName().Name);}}}

5.3 数据模型

using System.ComponentModel.DataAnnotations;namespace ServerAPI1.Models
{public class TestModel{[Required][StringLength(100)]public string AAA { get; set; }[StringLength(200)]public string BBB { get; set; }}
}

6.服务2代码

6.1 Program.CS

using Consul;
using Microsoft.OpenApi.Models;var builder = WebApplication.CreateBuilder(args);// 添加控制器和Swagger
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{c.SwaggerDoc("v1", new OpenApiInfo { Title = "ServerAPI2", Version = "v1" });
});// 注册Consul客户端
builder.Services.AddSingleton<IConsulClient>(new ConsulClient(c =>
{c.Address = new Uri("http://192.168.0.102:8500");
}));// 配置Kestrel(可选,根据实际需求)
builder.WebHost.UseUrls("http://*:5001");var app = builder.Build();// 健康检查端点
//app.MapGet("/health", () => Results.Ok("Healthy"));// 健康检查端点(模拟5000端口故障)
//app.MapGet("/health", (HttpContext context) =>
//{
//    var port = context.Request.Host.Port;
//    return port == 5000 ? Results.StatusCode(503) : Results.Ok("Healthy (Port: " + port + ")");
//});
//app.MapGet("/health", () => Results.Ok("Healthy (Port: 5001)"));
app.MapGet("/health", () =>
{// 基础存活检查(不依赖任何业务逻辑)return Results.Ok("Alive");
});// 注册到Consul
var consulClient = app.Services.GetRequiredService<IConsulClient>();
var registration = new AgentServiceRegistration
{ID = "ServerAPI-5001",Name = "ServerAPI",Address = "192.168.0.102",Port = 5001,Check = new AgentServiceCheck{HTTP = "http://192.168.0.102:5001/health",Interval = TimeSpan.FromSeconds(3),  // 每3秒检查一次Timeout = TimeSpan.FromSeconds(1),  // 1秒无响应视为失败DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10) // 10秒后自动移除}
};
consulClient.Agent.ServiceRegister(registration).Wait();
// 其他中间件
app.UseRouting();
app.MapControllers();// 配置Swagger(开发环境)
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ServerAPI2 v1"));
}健康检查端点
//app.MapGet("/health", () => Results.Ok("Healthy"));// 路由和控制器
app.UseRouting();
app.MapControllers();// 应用停止时注销服务
app.Lifetime.ApplicationStopping.Register(() =>
{consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});app.Run();

6.2 接口

using Microsoft.AspNetCore.Mvc;
using ServerAPI2.Models;namespace ServerAPI2.Controllers
{[ApiController][Route("api/[controller]")][Produces("application/json")]public class ValuesController : ControllerBase{/// <summary>/// 获取服务元数据/// </summary>[HttpGet("info")][ProducesResponseType(200)]public IActionResult GetInfo(){return Ok(new { Service = "ServerAPI2", Port = 8016 });}/// <summary>/// 字符串转换服务/// </summary>/// <param name="model">输入参数</param>[HttpPost("calculate")][ProducesResponseType(200)][ProducesResponseType(400)]public IActionResult Transform([FromBody] TestModel model){if (!ModelState.IsValid) return BadRequest(ModelState);return Ok(new { Result = $"{model.AAA}-{model.BBB}".ToUpper() });}[HttpGet("getail")] // 实现 /api/values/getailpublic IActionResult Get(){return Ok("This is /api/values/getail from ServerAPI2");}[HttpGet("setail")]public IActionResult Gett(){return Ok("This is /api/values/setail from " + GetType().Assembly.GetName().Name);}}
}

6.3 数据模型

    using System.ComponentModel.DataAnnotations;namespace ServerAPI2.Models{public class TestModel{[Required][StringLength(100)]public string AAA { get; set; }[StringLength(200)]public string BBB { get; set; }}}

7.发布形成Publish文件包

7.发布文件效果

8.运行Consul

8.1 显示双击文件夹内的Consul.exe

8.2 cmd进入Consul文件夹,运行指令:consul agent --config-file=C:\consul\config.json

9.运行服务

8.Publish文件夹内的Server1.exe\Server2.exe\OcelotDemo.exe,运行2个业务服务和网关服务

10.效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79472.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中小企业MES系统需求文档

适用对象&#xff1a;中小型离散制造企业&#xff08;年产值1-5亿&#xff0c;员工200-800人&#xff09; 版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、业务背景与目标 1.1 现状痛点 生产黑箱化&#xff1a;车间进度依赖人工汇报&#xff0c;异常响应延迟>2小…

OpenAI最新发布的GPT-4.1系列模型,性能体验如何?

简单来说,这次GPT-4.1的核心思路就是:更实用、更懂开发者、更便宜!OpenAI这次没搞太多花里胡哨的概念,而是实实在在地提升了大家最关心的几个点:写代码、听指令、处理超长文本,而且知识库也更新到了2024年6月。 写代码。要说这次GPT-4.1最亮眼的地方,可能就是写代码这块…

【基础算法】二分查找的多种写法

前言 在算法竞赛中&#xff0c;二分查找使用的频率是非常高的&#xff0c;对于C选手而言&#xff0c;有STL中自带的lower_bound和upper_bound二分查找&#xff0c;可以很方便的进行二分查找。但是非C选手、或者需要自定义多条件查找的情况需要自己写一个二分&#xff0c;本文对…

兰亭妙微:火箭发射界面案例分享

北京蓝蓝设计团队来自清华美院&#xff0c;工作多年&#xff0c;行业经验丰富&#xff0c;专业性很强。我们是热爱设计&#xff0c;设计不仅是我们的专业&#xff0c;我们的职业&#xff0c;还是我们的爱好。每一个蓝蓝设计的设计师都希望自己的设计越来越好&#xff0c;以高标…

完美解决.NET Framework 4.0 中 System.Drawing 库不支持 WebP 格式的图像处理

如果你想在 .NET Framework 4.0 中使用 ImageMagick 处理图片&#xff0c;可以通过 Magick.NET 库来实现。Magick.NET 是 ImageMagick 的 .NET 封装&#xff0c;可以用来读取、写入、编辑图像。 以下是如何使用 Magick.NET 来处理图像并提取图像的宽度和高度。 步骤&#xff…

string--OJ1

链接: 例一 链接: 例er class Solution { public:int myAtoi(string str) {int sign 1;int ret0;int i0;while(str[i] ){i;}if(str[i]||str[i]-){if(str[i]-)sign*-1;i;}while(str[i]>0&&str[i]<9){int rstr[i] - 0;if(ret>INT_MAX/10||(retINT_MAX/10&…

Go 写一个简单的Get和Post请求服务

Go 写一个简单的Get和Post请求服务 ✅ 一、准备工作 安装 Go 官网下载地址 安装后执行&#xff1a; go version安装 VS Code 插件 在 VS Code 插件市场搜索并安装插件&#xff1a;Go&#xff08;由 Go 团队提供&#xff09; 配置环境变量&#xff08;可选&#xff09; 设置 …

哪些因素会影响远程视频监控的质量?浅述EasyCVR视频智能诊断技术

在安防领域&#xff0c;无线监控系统凭借其灵活部署、便捷扩展的特性得到广泛应用。然而&#xff0c;实时监控图像清晰度不足、回放调查受限等问题&#xff0c;严重制约了其应用效果。经分析&#xff0c;摄像机性能、线缆质量、无线网桥性能、交换机配置及供电电压等是影响图像…

Java大师成长计划之第10天:锁与原子操作

&#x1f4e2; 友情提示&#xff1a; 本文由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;平台gpt-4o-mini模型辅助创作完成&#xff0c;旨在提供灵感参考与技术分享&#xff0c;文中关键数据、代码与结论建议通过官方渠道验证。 在多线程编程中&#xff0c;锁与原子…

线性代数——行列式⭐

目录 一、行列式的定义⭐ 1-1、三阶行列式练习 1-2、下面介绍下三角行列式、上三角行列式、对角行列式 ​编辑 二、行列式的性质 2-1、性质1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6 ​编辑 2-2、性质7 2- 3、拉普拉斯定理、克莱姆法则 三…

微软推出数款Phi 4“开放式”人工智能模型

微软周三推出了几款新的“开放式”人工智能模型&#xff0c;其中功能最强大的模型至少在一个基准测试上可与 OpenAI 的 o3-mini 相媲美。所有新的授权模型——Phi 4 mini reasoning、Phi 4 reasoning 和 Phi 4 reasoning plus——都是“推理”模型&#xff0c;这意味着它们能够…

VPN访问SAP组服务器报登陆负载均衡错误88:无法连接到消息服务器(RC=9)

用户反馈用SAPGUI接入SAP时报错&#xff1a;登陆负载均衡错误88&#xff1a;无法连接到消息服务器(RC9) 经了解是通过VPN访问&#xff0c;但VPN没有放行ICMP访问&#xff0c;导致不能PING通&#xff0c;不能确认是网络问题还是什么问题。 解决方案&#xff1a; 1、VPN由原&am…

使用AI-01开发板和开源后端服务搭建整套小智服务系统

使用AI-01开发板和开源后端服务搭建整套小智服务系统 四博智联的AI-01开发板&#xff0c;基于乐鑫ESP32-C2 专属定制的离线语音模组&#xff0c;能够完美的接入小智AI服务平台&#xff0c;再使用开源后端服务&#xff0c;就能够搭建一个完整的小智AI服务系统了。 下面是具体…

字节跳动在GitHub上有哪些开源项目

字节跳动&#xff08;ByteDance&#xff09;在GitHub上开源了许多项目&#xff0c;涵盖前端、后端、云原生、AI、数据库等多个领域。以下是一些典型项目及其简介&#xff1a; 1. 前端 & 跨平台开发 Hippy 仓库: Tencent/Hippy&#xff08;注&#xff1a;Hippy 最初由腾讯开…

超长8分钟Suno V4.5 – 支持一首歌多风格转换啦~~~

f历史文章 Suno AI API接入 - 将AI音乐接入到自己的产品中&#xff0c;支持120并发任务 AI音乐支持中文&#xff0c;实测效果&#xff0c;大家自己听听看喽 2025年新年快乐&#xff0c;Viggle AI打开新年快乐 让照片舞动起来&#xff0c;只要3分钟就可以搞定了&#xff0c;…

vue3+ts项目 配置vue-router

安装vue-router pnpm install vue-router配置 1.src/router/index.ts文件下的内容 import type { App } from vue import type { RouteRecordRaw } from vue-router import { createRouter, createWebHistory } from vue-router import remainingRouter from ./modules/remai…

如何利用dify 生成Fine‑tune 需要的Alpaca 格式数据

如果你选择llamafactory 格式进行微调&#xff0c;它只是格式是Alpaca格式&#xff0c;dify 的agent dsl 如下&#xff0c;你可以导入本地的dify 或者导入cloud 版本的&#xff1b;测试版本是0.1.5 app:description: 上传文件&#xff0c;基于文件内容&#xff0c;使用 Silico…

C++开发指南

一、C++ 是什么? C++ 是一种强大、灵活、高性能的系统级编程语言,由 Bjarne Stroustrup 在 20 世纪 80 年代初开发,是 C 语言的超集。它既支持面向过程编程,也支持面向对象、泛型、函数式等现代范式。 C++ 被广泛应用于: 系统软件(如操作系统、编译器)游戏开发(如 Un…

重测序关系矩阵构建方式汇总

样本间亲缘关系矩阵&#xff08;kinship matrix&#xff09;和同源性矩阵&#xff08;IBS matrix&#xff09;构建的方式 1. 可以使用plink的–make-rel计算个体之间的亲缘关系&#xff08;强调个体之间的遗传相似性&#xff09; /opt/software/plink --bfile vcf_bfile--mak…

docker 部署前、后端分离项目详细步骤(从打包到部署)

在平常的开发工作中&#xff0c;一个项目经历需求、开发、测试、上线等步骤。在开发测试完成后&#xff0c;我们需要部署测试环境、生产环境等&#xff0c;那么我们用 docker 方式应该怎么部署呢&#xff1f;前后端分离的项目又该如何部署呢&#xff1f;那么&#xff0c;今天我…