<develop>:(Web 端)<无> 增加 微服务 网关 Ocelot.ApiGateWay

parent 3f8edfb1
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ocelot" Version="24.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
</Project>
using Microsoft.AspNetCore.Mvc;
namespace ConsulAndOcelot.ApiGateWay.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

using Ocelot.DependencyInjection;
using Ocelot.Middleware;
namespace ConsulAndOcelot.ApiGateWay
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => { /* Configuration */ });
//添加 Ocelot 并添加配置文件
builder.Configuration.AddJsonFile("ocelot.json", optional: true, reloadOnChange: true);
//使用 Ocelot 接管代码
builder.Services.AddOcelot(builder.Configuration);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseOcelot();
app.Run();
}
}
}
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:15944",
"sslPort": 44370
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5198",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7171;http://localhost:5198",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
namespace ConsulAndOcelot.ApiGateWay
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
{
"Routes": [
{
//转发到下游服务地址--url变量
"DownstreamPathTemplate": "/api/{url}",
//下游http协议
"DownstreamScheme": "http",
//负载方式,
"LoadBalancerOptions": {
"Type": "RoundRobin" // 轮询
},
"DownstreamHostAndPorts": [
{
"Host": "192.168.8.248",
"Port": 5201 //服务端口
}, //可以多个,自行负载均衡
{
"Host": "192.168.8.248",
"Port": 5202 //服务端口
},
{
"Host": "192.168.8.248",
"Port": 5203 //服务端口
}
],
//上游地址
"UpstreamPathTemplate": "/T1/{url}", //网关地址--url变量 //冲突的还可以加权重Priority
"UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ]
}
]
}
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ocelot" Version="24.0.0" />
</ItemGroup>
</Project>
@ConsulAndOcelot.GateWay_HostAddress = http://localhost:5153
GET {{ConsulAndOcelot.GateWay_HostAddress}}/todos/
Accept: application/json
###
GET {{ConsulAndOcelot.GateWay_HostAddress}}/todos/1
Accept: application/json
###
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using System.Threading.Tasks;
namespace ConsulAndOcelot.GateWay
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
//添加 Ocelot 并添加配置文件
builder.Configuration.AddJsonFile("ocelot.json", optional: true, reloadOnChange: true);
builder.Services.AddOcelot(builder.Configuration);//使用 Ocelot 接管代码
var app = builder.Build();
//启用 Ocelot 中间件
await app.UseOcelot();
app.Run();
}
}
}
\ No newline at end of file
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "todos",
"applicationUrl": "http://localhost:5153",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
{
"Routes": [
{
//转发到下游服务地址--url变量
"DownstreamPathTemplate": "/api/{url}",
//下游http协议
"DownstreamScheme": "http",
//负载方式,
"LoadBalancerOptions": {
"Type": "RoundRobin" // 轮询
},
"DownstreamHostAndPorts": [
{
"Host": "192.168.8.248",
"Port": 5201 //服务端口
}, //可以多个,自行负载均衡
{
"Host": "192.168.8.248",
"Port": 5202 //服务端口
},
{
"Host": "192.168.8.248",
"Port": 5203 //服务端口
}
],
//上游地址
"UpstreamPathTemplate": "/T1/{url}", //网关地址--url变量 //冲突的还可以加权重Priority
"UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ]
}
]
}
0fc1819d58ab31eed6b40887ba13d8157f6c169c807440241c2623947fdcb23b
515be560c2b1cb046e38567d2ee007af5e00151ec7907753ca92e8aefca8672b
1a5cec2c18a94b87e91fd29df781ce5fbecc86700b5f24531ca20baaf29fb690
13dea82d2b65a33097a42e7e8ef6ce87162c2feb36a9c6ff0e44b7e4001fa8d1
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
262c6486c621daa2975b0f50f5a8b3415e99f4e3cc61f8086ffde768c852ba63
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Configuration.Internal;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace CoreCms.Net.Utility.Consul
{
/// <summary>
/// Consul 注册
/// </summary>
public static class ConsulRegister
{
#region 服务注册
/// <summary>
/// 服务注册
/// </summary>
/// <param name="app"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration)
{
//获取主机生命周期管理接口
var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();
ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri(configuration["Consul:consulAddress"]);
c.Datacenter = "orderService";
});
string ip = configuration["ip"];//优先接收变量的值
string port = configuration["port"];//优先接收变量的值
string currentIp = configuration["Consul:currentIP"];
string currentPort = configuration["Consul:currentPort"];
ip = string.IsNullOrEmpty(ip) ? currentIp : ip;//当前程序的 IP
port = string.IsNullOrEmpty(port) ? currentPort : port;//当前程序的端口
string serviceID = $"service:{ip}:{port}";
//服务注册
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = serviceID,//唯一的
Name = configuration["Consul:serviceName"],//组名称-Group
Address = ip,//IP 地址
Port = int.Parse(port),//端口
Tags = new string[] { "api 站点" },
//健康检查
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(10),//多久检查一次心跳
HTTP = $"http://{ip}:{port}/Health",//健康检查地址
Timeout = TimeSpan.FromSeconds(5), //超时时间
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5)//服务启动多久后注册
}
}).Wait();
//健康检查,不需要新建 Controller
app.MapWhen(context => context.Request.Path.Equals("/Health"), appBuilder =>
{
appBuilder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
await context.Response.WriteAsync("Success");
});
});
//应用程序终止时,取消注册
lifetime.ApplicationStopping.Register(() =>
{
client.Agent.ServiceDeregister(serviceID).Wait();
});
return app;
}
#endregion
}
}
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Consul" Version="1.7.14.7" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NPOI" Version="2.6.2" /> <PackageReference Include="NPOI" Version="2.6.2" />
<PackageReference Include="ToolGood.Words" Version="3.1.0" /> <PackageReference Include="ToolGood.Words" Version="3.1.0" />
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -21,11 +21,6 @@ ...@@ -21,11 +21,6 @@
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&libraries=place&key=225d6c323c15ed3391a890f834bc4533"></script> <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&libraries=place&key=225d6c323c15ed3391a890f834bc4533"></script>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script> <script>
/^http(s*):\/\//.test(location.href) || alert('请先部署到 localhost 下再访问'); /^http(s*):\/\//.test(location.href) || alert('请先部署到 localhost 下再访问');
</script> </script>
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
</div> </div>
</div> </div>
<style> <style>
body { font-family: 'Inter',sans-serif; line-height: 1.5; color: #4f5464; } /* body { font-family: 'Inter',sans-serif; line-height: 1.5; color: #4f5464; }*/
</style> </style>
<script> <script>
layui.use(['admin', 'form', 'coreHelper'], function () { layui.use(['admin', 'form', 'coreHelper'], function () {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -55,6 +55,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreCms.Net.RedisMQ", "Core ...@@ -55,6 +55,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreCms.Net.RedisMQ", "Core
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "8.MicroService", "8.MicroService", "{213FB1ED-B055-4E93-B735-70B3741EDB3F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "8.MicroService", "8.MicroService", "{213FB1ED-B055-4E93-B735-70B3741EDB3F}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.MicroService", "5.MicroService", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsulAndOcelot.ApiGateWay", "ConsulAndOcelot.ApiGateWay\ConsulAndOcelot.ApiGateWay.csproj", "{1262A559-1A8D-444D-B191-86A904770FCB}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -141,6 +145,10 @@ Global ...@@ -141,6 +145,10 @@ Global
{927E68B4-92D1-4F66-B137-87804055DE93}.Debug|Any CPU.Build.0 = Debug|Any CPU {927E68B4-92D1-4F66-B137-87804055DE93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{927E68B4-92D1-4F66-B137-87804055DE93}.Release|Any CPU.ActiveCfg = Release|Any CPU {927E68B4-92D1-4F66-B137-87804055DE93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{927E68B4-92D1-4F66-B137-87804055DE93}.Release|Any CPU.Build.0 = Release|Any CPU {927E68B4-92D1-4F66-B137-87804055DE93}.Release|Any CPU.Build.0 = Release|Any CPU
{1262A559-1A8D-444D-B191-86A904770FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1262A559-1A8D-444D-B191-86A904770FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1262A559-1A8D-444D-B191-86A904770FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1262A559-1A8D-444D-B191-86A904770FCB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
...@@ -166,6 +174,7 @@ Global ...@@ -166,6 +174,7 @@ Global
{0E024CA5-FCE6-48A7-8209-201FF2D9237E} = {82634406-6F43-4E90-B57D-5C7AC3DAFF11} {0E024CA5-FCE6-48A7-8209-201FF2D9237E} = {82634406-6F43-4E90-B57D-5C7AC3DAFF11}
{7043B7B2-6496-4FCB-A230-1EBC5E11B91C} = {B3F41F4C-3681-48F3-9BE3-809763AC1937} {7043B7B2-6496-4FCB-A230-1EBC5E11B91C} = {B3F41F4C-3681-48F3-9BE3-809763AC1937}
{927E68B4-92D1-4F66-B137-87804055DE93} = {B3F41F4C-3681-48F3-9BE3-809763AC1937} {927E68B4-92D1-4F66-B137-87804055DE93} = {B3F41F4C-3681-48F3-9BE3-809763AC1937}
{1262A559-1A8D-444D-B191-86A904770FCB} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A325D634-06E7-4F4E-BA15-AB3E14622FF1} SolutionGuid = {A325D634-06E7-4F4E-BA15-AB3E14622FF1}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment