ASP.NET Core combine Nacos to complete configuration management and service discovery

Foreword

In April of this year, and the group of colleagues platform with a little research Nacos, also wrote a .net core version of the unofficial version at that time SDK .

Although the house for some reason does not really last with them, but many people are still quite promising. After much communication and tidal town, I decided to write a blog a brief introduction.

The following chart is the focus of this paper.

Nacos Introduction

Nacos is an easy to build cloud native application of dynamic service discovery, configuration management and service management platform, which provides a set of simple-to-use set of features that help us quickly achieve dynamic service discovery, service configuration, service metadata and traffic management.

It has the following key features

  • Service discovery and health monitoring services
  • Dynamic configuration services
  • Dynamic DNS Service
  • Service and metadata management
  • ...

Or with a lot of properties, but also a place with a lot of the value of mining. For more information about Nacos can visit the following address:

Here began the topic, the first step must be to first Nacos run up.

Start Nacos

Because it is the presentation, so the direct use of docker start the Standalone Mysqlpattern.

git clone --depth 1 https://github.com/nacos-group/nacos-docker.git
cd nacos-docker
docker-compose -f example/standalone-mysql.yaml up

After running docker-compose, will first pull back a few mirror, and then you see the following output, the basic is properly started.

Open a browser to access http://localhost:8848/nacoscan see Nacos console login screen.

The initial user name and password are nacos , after logging in something like this.

Nacos can see up and running, version 1.1.3, there is clearly visible a few large menu, these are easy to manage us.

Then we first look at Nacos configuration management of it.

Configuration Management

In the above characteristics of the big picture, it has been very clear to tell us a few important functions of configuration management.

There are several more important concepts you need to look in the configuration.

  • tenant tenant information, the corresponding field Nacos namespace.
  • dataId configuration ID.
  • group configuration packet.

First add the following nuget package, and then look at how this configuration to play.

dotnet add package nacos-sdk-csharp-unofficial

There is essential in Startupconfiguring inside.

public void ConfigureServices(IServiceCollection services)
{
    // configuration
    services.AddNacos(configure =>
    {
        // default timeout
        configure.DefaultTimeOut = 8;
        // nacos's endpoint
        configure.ServerAddresses = new System.Collections.Generic.List<string> { "localhost:8848" };
        // namespace
        configure.Namespace = "";
        // listen interval
        configure.ListenInterval = 1000;
    });
    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

This is also a relatively common configuration, and is not to say, you can also load the configuration via the configuration file.

These configurations which, in fact, the most important is the address of Nacos.

Let's look at the simplest configuration information.

SDK provides a named INacosConfigClientClient interface, this interface all the contents inside are configuration-related operations.

[Route("api/[controller]")]
[ApiController]
public class ConfigController : ControllerBase
{
    private readonly INacosConfigClient _configClient;

    public ConfigController(INacosConfigClient configClient)
    {
        _configClient = configClient;
    }

    // GET api/config?key=demo1
    [HttpGet("")]
    public async Task<string> Get([FromQuery]string key)
    {
        var res = await _configClient.GetConfigAsync(new GetConfigRequest
        {
            DataId = key,
            Group = "DEFAULT_GROUP",
            //Tenant = "tenant"
        }) ;

        return string.IsNullOrWhiteSpace(res) ? "Not Found" : res;
    }
}

Obtaining the configuration above method of acquiring this configuration, the effect is to read default namespace (public) The following DEFAULT_GROUPvalues of the following configuration packet, called the key configuration Id.

If we enter key, in Nacos above does not, that this method will return Not Foundto the caller, if there is, it will return to a specific configuration values.

Since we are just running into action, nothing to operate, so certainly there is no configuration information.

Then we add a first, see how it works.

The same method of adding the following release configuration in the above controller, is also through INacosConfigClientto add configuration.

// GET api/config/add?key=demo1&value=123
[HttpGet("add")]
public async Task<string> Add([FromQuery]string key, [FromQuery]string value)
{
    var res = await _configClient.PublishConfigAsync(new PublishConfigRequest
    {
        DataId = key,
        Group = "DEFAULT_GROUP",
        //Tenant = "tenant"
        Content = value
    });

    return res.ToString();
}

This time we've added a success.

\ Go back to the console, you can also see just add configuration has been out.

Once again get access interface configuration information, you can already get a configuration corresponding to the content.

The following console to modify the contents of the configuration.

When point release the button, there will be a comparison page, let us compare the before and after modifying those contents.

By this time we INacosConfigClientwent to visit, it was found that we just can not get content updates.

This is because, after reading the configuration successfully from Nacos, configuration information is written to the local cache, then later visit will give priority to read the contents of the cache.

So how to do after someone modified the configuration of content, it can take effect in real time? Actually very simple, just add it to listen to configure it.

This allows us to benefit from Nacos monitor configuration to configuration changes in real-time perception. If the configuration changes, you get an interface to obtain the latest by the configured value, dynamic refresh the local cache.

The following is a simple example, here it is BackgroundServicehandled.

public class ListenConfigurationBgTask : BackgroundService
{
    private readonly ILogger _logger;

    private readonly INacosConfigClient _configClient;

    public ListenConfigurationBgTask(ILoggerFactory loggerFactory, INacosConfigClient configClient)
    {
        _logger = loggerFactory.CreateLogger<ListenConfigurationBgTask>();

        _configClient = configClient;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // Add listener
        await _configClient.AddListenerAsync(new AddListenerRequest
        {
            DataId = "demo1",
            //Group = "DEFAULT_GROUP",
            //Tenant = "tenant",
            Callbacks = new List<Action<string>>
            {
                x =>
                {
                    _logger.LogInformation($" We found something changed!!! {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}  [{x}]");
                },
            }
        });
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        // Remove listener
        await _configClient.RemoveListenerAsync(new RemoveListenerRequest
        {
            DataId = "demo1",
            Callbacks = new List<Action>
            {
                () =>
                {                        
                     _logger.LogInformation($" Removed listerner  ");
                },
            }
        });

        await base.StopAsync(cancellationToken);
    }
}

In fact, there is no content, it is to add the listener when the program starts, and then when the program exits, also quit listening.

Do not forget to add the following code in Startup, so that the configuration of the listener to take effect!

services.AddHostedService<ListenConfigurationBgTask>();

When we add a listener, to modify the contents of the configuration file, it can dynamically update loaded.

Also, the console monitor which also has a record, you can listen for queries found inside.

The following are specific log output

Each configuration changes, there will be history, you can find a version of history from the inside.

In addition to the historical record to see, you can also roll back to a specific version, which is a very useful function.

In the database, configuration information is stored so

There is a method to remove the configuration, not presented here, it is similar usage, but under normal circumstances should not delete the configuration, unless it is superfluous.

About this Nacos configuration management on a first come here, friends who are interested can continue to go to get to the bottom.

Here we take a look at Nacos service discovery.

Service Discovery

About service registration and discovery, listening is probably more, consul, eureka, etcd, k8s and so on.

In fact, almost thinking at the time the service starts, the information about the current registration services go up, and then to invoke a service when the service would get the list below, then select one of the available access. The final step is when the service stops, we have to log off the current service.

The SDK is currently available in two forms, one is the original API, one is the original API is encapsulated, directly downstream of the respective registration and discovery service.

The original API called in INacosNamingClientto provide Client interface, all the contents of this interface which are related to service discovery.

But here only introduced after the encapsulation method, of course, be processed in accordance with their original encapsulated API.

You must first add the following nuget package.

dotnet add package nacos-sdk-csharp-unofficial.AspNetCore

First up a service.

First in the configuration file appsettings.jsonand add the following content

{
  "nacos": {
    "ServerAddresses": [ "localhost:8848" ],
    "DefaultTimeOut": 15,
    "Namespace": "",
    "ListenInterval": 1000,
    "ServiceName": "BaseService",
    "Weight": 10
  }
}

This configuration is mainly expressed, this example is that the service name BaseService, weight is 10, Nacos the address localhost:8848.

Then Startup in the current instance is registered to Nacos.

namespace BaseService
{
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Nacos.AspNetCore;

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            // important step
            services.AddNacosAspNetCore(Configuration);
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            
            // important step
            app.UseNacosAspNetCore();
        }
    }
}

Here it requires only a simple configuration two places to complete the registration function of the service! !

Here's start this program.

You can see when you start the program, the current instance will send a heartbeat to Nacos, a heartbeat which contains information such as IP and port.

Back to the console, we can see this service now have an instance of.

Start a second instance of the same service name, here only the contents of the returned interface do a little adjustment, other are the same!

This time the details of which point into the service, you can see more specific information.

Service is already registered come up now, here we come again to call a service above the registered good service.

Startup of the contents are similar, except that, if the service is not called inside other applications to determine, you can not register to Nacos above.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        services.AddNacosAspNetCore(Configuration);
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();

        //app.UseNacosAspNetCore();
    }
}

Then it is to find a service.

INacosServerManagerWhich provides an example of just to get health services under the name of address information. Shortage of places is to overlook the namespace and clustering of these parameters will consider adding in a later version of it.

To obtain address information is randomly selected out of here, the simplest algorithm in rotation. . After obtaining the address information of all instances primary caches 10 seconds, it will take 10 seconds inside a direct address from the information in the cache.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly INacosServerManager _serverManager;
    private readonly IHttpClientFactory _clientFactory;

    public ValuesController(INacosServerManager serverManager, IHttpClientFactory clientFactory)
    {
        _serverManager = serverManager;
        _clientFactory = clientFactory;
    }

    // GET api/values
    [HttpGet]
    public async Task<string> GetAsync()
    {
        var result = await GetResultAsync();

        if (string.IsNullOrWhiteSpace(result))
        {
            result = "ERROR!!!";
        }

        return result;
    }

    private async Task<string> GetResultAsync()
    {
        var baseUrl = await _serverManager.GetServerAsync("BaseService");

        if (string.IsNullOrWhiteSpace(baseUrl))
        {
            return "";
        }

        var url = $"{baseUrl}/api/values";

        var client = _clientFactory.CreateClient();

        var result = await client.GetAsync(url);

        return await result.Content.ReadAsStringAsync();
    }
}

FIG effect will move the view.

In two instances when health status is true, it will call a random example.

When the stopped one of the instances, the health status of this example will be identified as false, this time will not be called to this instance of false.

After the re-run this instance, has returned to the random calls.

Nacos addition to service discovery described above, as well as system switch, indicator data, clustering information and other functions, to be to dig.

Written in the last

Nacos is not complicated to use, it is relatively easy to use, with a lot of companies.

There is a combination of the steeltoe and Nacos project skynet-cloud can also take a look.

Sample Code Here stamp paper may NacosDemo

SDK address nacos-sdk-csharp

Gangster hope interested to stars, but also very much hope that there are big brothers to maintain with this project, and to make recommendations.

Because it is the first time to write something SDK classes, reference is made to the other platform .NET SDK, and then combined with Nacos's Open API to write, there may be omissions and many bug, but please bear with me chiefs.

Guess you like

Origin www.cnblogs.com/catcher1994/p/11489052.html
Recommended