Location>code7788 >text

Ocelot integrates with Consul for api gateway and service discovery

Popularity:330 ℃/2024-11-20 17:18:50

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)