preamble
didn't seedotnet microservices API gateway OcelotPlease read it first, this article follows on from the above article
Installing consul
#Customize the network, the custom network can specify the container IP so that the server reboot consul cluster can also run normally.
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'
Modify in the GoodApi project
First you need to add the Consul package
Add Consul registration and logout code.
using Consul;
using ;
using ;
using ;
// establishConsulclient (computing)
var consulAddress = "http://10.75.174.43:8500";// ("CONSUL_ADDRESS"); //10.75.174.43
var consulUri = new Uri(consulAddress);
var client = new ConsulClient(config =>
{
= consulUri;
});
// Configuring health checks for services
var check = new AgentServiceCheck()
{
HTTP = $"http://{GetLocalIpAddress("InterNetwork").FirstOrDefault()}:8080/health", // Health Screening Address
Interval = (10) // Inspection intervals
};
var serviceId = "goodapi-1"; // of services to be canceledID
// Register for a service
var registration = new AgentServiceRegistration()
{
ID = serviceId,
Name = "goodapi",
Address = GetLocalIpAddress("InterNetwork").FirstOrDefault(),
Port = 8080,
Check = check
};
await (serviceId);
(registration);
var builder = (args);
// Add services to the container.
();
// Learn more about configuring Swagger/OpenAPI at /aspnetcore/swashbuckle
();
();
var app = ();
// Configure the HTTP request pipeline.
//if (())
{
();
();
}
();
("/health", async context =>
{
= 200;
await ("health");
});
();
// Write-off services
await (serviceId);
List<string> GetLocalIpAddress(string netType)
{
string hostName = ();
IPAddress[] addresses = (hostName);
var IPList = new List<string>();
if (netType == )
{
for (int i = 0; i < ; i++)
{
(addresses[i].ToString());
}
}
else
{
// = IPv4,
//AddressFamily.InterNetworkV6= IPv6
for (int i = 0; i < ; i++)
{
if (addresses[i].() == netType)
{
(addresses[i].ToString());
}
}
}
return IPList;
}
Add the Dockerfile file
# Use 6 as the base image, with an alias of base
FROM /dotnet/aspnet:8.0 AS base
# Set the container's working directory to /app
WORKDIR /app
#COPY the file
COPY . /app
ENV ASPNETCORE_ENVIRONMENT Production
# Set the time zone to East 8
ENV TZ Asia/Shanghai
#Start the service
ENTRYPOINT ["dotnet", ""]
# (of a computer) rungoodapisports event
docker stop goodapi
docker rm -f goodapi
docker build -t goodapi .
docker run --name=goodapi -d -p 8080:8080 --network=adnc_consul goodapi
Adding consul configuration and code in OcelotGA
Add the package Consul.
reconfigure
{
"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": "",
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "10.75.174.43", // Here is yourConsuladdresses
"Port": 8500, // Consulports
"Type": "Consul"
}
}
}
modifications
using ;
using ;
using ;
using ;
using ;
using System;
using ;
using ;
using Consul;
using OcelotGA;
// establishConsulclient (computing)
var consulAddress = "http://10.75.174.43:8500";// ("CONSUL_ADDRESS"); //10.75.174.43
var consulUri = new Uri(consulAddress);
var client = new ConsulClient(config =>
{
= consulUri;
});
// Configuring health checks for services
var check = new AgentServiceCheck()
{
HTTP = $"http://{GetLocalIpAddress("InterNetwork").FirstOrDefault()}:8080/health", // Health Screening Address
Interval = (10) // Inspection intervals
};
var serviceId = "gw-1"; // of services to be canceledID
// Register for a service
var registration = new AgentServiceRegistration()
{
ID = serviceId,
Name = "gw",
Address = GetLocalIpAddress("InterNetwork").FirstOrDefault(),
Port = 8080,
//Check = check
};
await (serviceId);
(registration);
var builder = (args);
("", optional: false, reloadOnChange: true);
().AddConsul<MyConsulServiceBuilder>(); //Here's something to keep in mind.MyConsulServiceBuilder
var app = ();
().Wait();
();
("/Health", async context =>
{
= 200;
await ("Health");
});
();
// Write-off services
await (serviceId);
List<string> GetLocalIpAddress(string netType)
{
string hostName = ();
IPAddress[] addresses = (hostName);
var IPList = new List<string>();
if (netType == )
{
for (int i = 0; i < ; i++)
{
(addresses[i].ToString());
}
}
else
{
// = IPv4,
//AddressFamily.InterNetworkV6= IPv6
for (int i = 0; i < ; i++)
{
if (addresses[i].() == netType)
{
(addresses[i].ToString());
}
}
}
return IPList;
}
increase
using Consul;
using ;
using ;
using ;
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)
=> ;
}
}
Run the gateway project
We visit/good/health
Pit Climbing Record
hit the nail on the head
().AddConsul<MyConsulServiceBuilder>(); // Note here that MyConsulServiceBuilder
If it is
().AddConsul();
Then the following problem occurs
The service resolves out to the name of the node, not the IP of the service
Solution:Service Discovery — Ocelot Gateway 23.4 documentation
That is, the default DefaultConsulServiceBuilder will handle it like this
protected virtual string GetDownstreamHost(ServiceEntry entry, Node node)
=> node != null ? : ;
And what we need is
protected override string GetDownstreamHost(ServiceEntry entry, Node node)
=> ;
author
Wu Xiaoyang (cell phone: 13736969112 wechat the same number)