Agileconfig 1.6.0 release – support service registration and discovery

Time:2022-4-27

Hello, everyone. I haven’t output blog posts for a long time. One reason is that I’m busy. Another reason is that I’m mainly focused on adding a new function to agileconfig: service registration and discovery.
First, let’s talk about why this function is added. My own project uses consul to register and discover components for services. Since I launched agileconfig as the configuration center, I rarely go to consult to observe the online status of the service, because the agileconfig client list can represent the status of the service to a certain extent. In fact, the service registration, discovery and configuration center essentially solves a kind of problem, that is, the dynamic configuration. Therefore, you will see that many famous components in the industry realize these two functions at the same time, such as consul, Nacos, etc. So I’d like to add this function simply, which can save the need to deploy a component.
Of course, some students said that I didn’t do my job and didn’t go to the configuration center to find out what service registration was. But I did…
However, you can rest assured that the main business of agileconfig is still in the configuration center. It is found that the service registration is only a complimentary dish, which can be used or not. The decision is entirely up to you. In terms of implementation, I am also completely decoupled from the two functions. In other words, these two functions operate independently without affecting each other. The only intersection is that if the websocket channel of the client of the configuration center is successfully established, the heartbeat of the service will borrow this channel.
✨✨✨ GitHub address:https://github.com/dotnetcore/AgileConfigOpen source is not easy, welcome star ✨✨✨
✨✨✨ Gitee address:https://gitee.com/kklldog/AgileConfig ✨✨✨

What is service registration and discovery

First, let’s review the concept of service registration discovery.
After implementing microservices, our calls become calls between services. Inter service calls need to know IP, port and other information. Before there was no micro service, our call information was usually written in the caller’s configuration file (of course, this is not absolute. Some companies will write this information to public places such as databases for maintenance). Due to the complexity of the business, each service may depend on n other services. If the IP, port and other information of a service changes, the configuration files of all services that depend on the service have to be modified, which is obviously too troublesome. Some services have multiple instances for load, and the number of instances may be adjusted at any time. If you have to modify the configuration of other services and restart each time you adjust the number of instances, it’s too troublesome.
In order to solve this problem, the industry has a service registration and discovery component.
Suppose we have a service a that needs to call service B, and a service registration discovery component R. The whole process will become about three parts:
Service B starts registering its own information with service R
Service a pulls the information of service B from service R
Service a invokes service B
With the service registration and discovery component, you don’t have to modify other related services when modifying service a information.

Refer to my other article:. net core with microservices – consul registry

Using service registration and discovery

To use the service registration and discovery function, you need to update the server and client to version 1.6.0 and above.

Start the server

Update the server to the latest image or the image above v-1.6.0.
Run the server instance using docker:

sudo docker run \
--name agile_config \
-e TZ=Asia/Shanghai \
-e adminConsole=true \
-e db:provider=sqlite \
-e db:conn="Data Source=agile_config.db" \
-p 5000:5000 \
#-v /your_host_dir:/app/db \
-d kklldog/agile_config:latest

The basic usage has not changed much, but the relevant management interface of the service has been added to the interface, which will not be repeated here.
Related tutorials:. net core & agile config configuration center

Use client

The client needs to install the client package above version 1.6.0 from nuget.

Install-Package AgileConfig.Client -Version 1.6.0

The new version of client simplifies the use, as shown below Net6 as an example:
Call useagileconfig extension method to inject agileconfig client

var builder = WebApplication.CreateBuilder(args);

//use agileconfig client
builder.Host.UseAgileConfig();

...

At Appsettings JSON add configuration information:

"AgileConfig": {
    "appId": "test_app",
    "secret": "test_app",
    "nodes": "http://agileconfig_server.xbaby.xyz/",
    "name": "client123",
    "tag": "tag123",

    "Serviceregister": {// service registration information. If this node is not configured, no services related to service registration will be started
      "Serviceid": "net6", // service ID, globally unique, used to uniquely identify a service
      "Servicename": "net6mvc service test"
      "IP": "127.0.0.1"
      "Port": 5005, // optional port of service
  }

The appid, secret and other configurations are the same as the original configuration center.
serviceRegisterThe node describes the service registration information (if this node is deleted, the service registration function will not be started):

  • serviceId
    Service ID, globally unique, is used to uniquely identify a service
  • serviceName
    The service name can be repeated. When a service is deployed with multiple instances, the servicename can be repeated
  • ip
    Optional IP service
  • port
    The port of the service is optional
  • metaData
    A string array that can carry some service related information, such as version, etc
  • alarmUrl
    The alarm address is optional.
    If a service is abnormal, such as no heartbeat for a period of time, the server will post a request to this address and carry the service related information. The user can realize the reminder function by himself, such as sending text messages, e-mails, etc
{
    "serviceId":"0001",
    "serviceName":"xxxx",
    "time":"2022-01-01T12:00:000",
    "status":"Unhealty",
    "Message": "the service is unhealthy"
}
  • heartbeat:mode
    Specify the heartbeat mode, server / client. Server represents the active detection of the server, and client represents the active reporting of the client. The default client mode is optional
  • heartbeat:interval
    Heartbeat interval, default time 30s, optional
  • heartbeat:url
    When the heartbeat mode is server, you need to fill in the health detection address. If the httpstatus is 200 segments, it is determined to be alive, and others are regarded as failures

Registration of services

After configuring the client, start the corresponding application, and the service information will be automatically registered to the server and start the heartbeat. If the service is registered to the server correctly, the service management interface of the console can view:

Service discovery

Now that the service has been registered, how can we get all the services in the registration center? It’s also very simple. Just inject in the programIDiscoveryService Interface can get all registered services through it.

public interface IDiscoveryService
    {
        string DataVersion { get; }
        List UnHealthyServices { get; }
        List HealthyServices { get; }
        List Services { get; }
        Task RefreshAsync();
    }

In addition to the built-in methods of the interface, there are several extension methods for users to use, such as a random service:

public static class DiscoveryServiceExtension
    {
        public static IEnumerable GetByServiceName(this IDiscoveryService ds, string serviceName)
        {
            return ds.Services.GetByServiceName(serviceName);
        }

        public static ServiceInfo GetByServiceId(this IDiscoveryService ds, string serviceId)
        {
            return ds.Services.GetByServiceId(serviceId);
        }

        public static ServiceInfo RandomOne(this IDiscoveryService ds, string serviceName)
        {
            return ds.Services.RandomOne(serviceName);
        }
    }

At this point, the registration and discovery of the service have been completed.

Some important information

The above is the simple use of service registration discovery, but there are still some important information. I hope you can understand it before use, which is conducive to better use and positioning problems when they occur.

High availability

Like the configuration center function of agileconfig, the service is written to the database after registration. Agileconfig’s server can deploy multiple to prevent single point of failure and share the pressure at the same time. Therefore, the best practice of high availability is to deploy more than two server nodes, and then make a high availability scheme for the database. This is enough to cope with most scenes where the requirements are not particularly high.

Strong consistency

As above, agileconfig ensures the consistency of multiple nodes during deployment through the database.

Health testing of services

There are generally two schemes for health testing of services:

  1. The server asks actively
  2. Client active heartbeat
    Agileconfig supports both schemes. Agileconfig client implements active heartbeat by default. The active heartbeat of agileconfig client has two channels:
  • websocket
    Long connection. If the agileconfig client works normally as the configuration center client, the heartbeat will go through the websocket channel
  • http
    If websocket is unavailable, an HTTP request will be directly initiated as the heartbeat.
    However, for some applications, the active heartbeat does not mean that the service is really available, because the heartbeat starts when the service has been started, but some interfaces may not be really ready to be called. At this time, you can choose the server to actively ask (heartbeat: mode = server) the corresponding detection interface to determine whether the service is really available.
    Agileconfig actually implements the third method:
  1. Not detected
    If you are sure that a service will always be online or cannot integrate the SDK of agileconfig client, you can mark it as not detected, so that it will always be healthy.

How is service discovery updated on the fly

Our client will pull the full list of services once it is started. However, the service will go online and offline continuously, so the client needs to be notified of the update of service status, and then the client will pull the new service list. Agileconfig also has two policies to ensure that the service list is refreshed immediately:

  1. When the service state changes, the server will immediately notify all clients to actively refresh the configuration list through websocket
  2. If the active notification of the server fails due to network and other reasons, the client will compare the MD5 version of the local service list with the MD5 information of the server list at each heartbeat. If it is inconsistent, the client will actively pull a new service list.

Turn off service registration and discovery

deleteserviceRegisterConfigure the node or do not configure any information.

last

✨✨✨ GitHub address:https://github.com/dotnetcore/AgileConfigOpen source is not easy, welcome star ✨✨✨
✨✨✨ Gitee address:https://gitee.com/kklldog/AgileConfig ✨✨✨
Demo address:http://agileconfig_server.xbaby.xyz/Super administrator account: admin Password: 123456

Follow my official account and play with technology