ASP. NET core combined with consul cluster &docker to realize service governance

Source: Internet
Author: User
Tags cpu usage docker run

First, preface

Before writing this article, I read a lot about Consul's service governance, but found that basically all directly in PowerShell or in the form of command tools on the server directly input Consul agent .... To build a startup consul cluster, once the command tool is switched off, consul can no longer boot in the background, especially in Linux.

If the Windows system, the use of the bat file can be turned on, or in Linux, the command into a service file to boot can be implemented in the background run.

Therefore, in order for the community to better develop technology, and can apply consul in the production environment, I carefully review the application in the company project, I hereby develop and summarize the sharing to everyone, this article uses the Docker engine, and only involves the consul cluster deployment and the combination of ASP. Core Micro Service registration.

Of course, if the content of security risks involved, we can actively comment, common progress.

Note: The following involves the deployment process all through the landlord I repeatedly verified, summed up. Everyone in the application process if there is a problem, you can leave a message to consult.

Second. deployment of consul clusters

1, introduce consul

Consul Key Features

Service discovery: Support for service discovery. You can obtain service information via DNS or HTTP.
Health checks: Supports health checks. You can provide any number of health checks (such as Web status codes or CPU usage) that are associated with a given service.
K/V Storage: Key/value pair storage. You can store related information, such as dynamic configuration, through consul.
Multi-Datacenter: Supports multi-datacenter, out-of-the-box.
Web UI: Supports Web UI. With a little bit, you'll be able to see how your service is running, at a glance, and very friendly to devops.


In the consul scenario, the client Agent for Consul is deployed and run on each node that provides the service, and the collection of all running consul Agent nodes constitutes consul Cluster.

The Consul agent has two modes of operation: Server and client. the server and client here are only consul cluster-level distinctions, regardless of the application service built on top of cluster. The consul agent node running in server mode is used to maintain the state of the consul cluster, and the official recommendation is that each consul cluster at least 3 or more agent,client nodes running in server mode.

Consul supports multi-data centers, and consul cluster in each data center selects a leader node in the agent node running in server mode, which is ensured by Consul protocol, The consul data information on the server node is strongly consistent. The Consul Agent node in client mode is relatively simple and stateless, only responsible for forwarding requests to the Server Agent node.

Well, the introduction has been introduced, the next is the formal deployment of it

2, Docker running Consul first step: Security configuration, applicable authorization and data encryption transmission (production environment is necessary)

For consul security, gossip encryption is required and RPC encryption is combined with TLS.
gossip encryption: mainly used for receiving and sending cluster information security between nodes.
RPC encryption: used primarily for security of RPC authorization calls between agents.

Here you can refer to the official website or information:

Step Two: Consul cluster deployment

Prepare the server (can be deployed with virtual machines)

Name Ip
Centos7-1 Server1
Centos7-2 Server2
Centos7-3 Server3
Centos7-4 Client1
VS 2017 Project is deployed on Docker

Deploying Server1

Docker run-d--net=host-v $PWD/data:/consul/data-v $PWD/config:/consul/config--restart always--name consulServer1 con Sul Agent-server-bind= 3-data-dir=/consul/data-config-file=/consul/ Config-client

Deploying Server2

Docker run-d--net=host-v $PWD/data:/consul/data-v $PWD/config:/consul/config--restart always--name CS2 Consul agent -server-bind= 3-data-dir=/consul/data-config-file=/consul/config- Client

Deploying Server3

Docker run-d--net=host-v $PWD/data:/consul/data-v $PWD/config:/consul/config--restart always--name cs3 consul agent -server-bind= 3-data-dir=/consul/data-config-file=/consul/config- Client

Deploying client-Connection Server

Docker run-d--net=host-v $PWD/data:/consul/data-v $PWD/config:/consul/config--restart always--name cc1 Consul agent -bind=

Note: (for the above parameters and configuration explanation)

1. The data mount here is to mount the contents of the container to the external address,$PWD represents the current directory that you run the Docker command when the directory, of course $pwd can be replaced with a specific path .
2.-data-dir=/consul/consul-config-file=/consul/config: These two local representatives will put the data and configuration files into the specified directory after consul startup, which is especially important for agents running in server mode. Because they must be able to keep the cluster state.
3, summary, the above two points of the combination is to explain the consul generated data and then mount the external address for persistent storage.
4, the server side of the-client parameter can not be used, the official recommendation is to register the service to the client side, the client side and then the data submitted to the server side.

Parameter description

-client: represents the option to bind to all interfaces, and if this option is not available, ASP. NET core cannot be used for service registration

-bind: This address is used to communicate within the cluster, all nodes in the cluster must be accessible to the address.

--net=host allows Docker containers to bypass net namespace isolation, eliminating the step of manually specifying port mappings

-retry-join allows you to try after the first failure, adding an IP address for an agent that has already started

Number of server nodes provided by-bootstrap-expect

-ui start your own host interface

-data-dir: Provide a directory to hold the status of the agent, all the agents allow the directory, the directory must be stable, the system will continue to exist after the restart

consul_local_config={"Skip_leave_on_interrupt": true}: The default is true after version 0.7, so it is not required.

consul_local_config={"Leave_on_terminate": true}: The default is true after version 0.7, so it is not required. If enabled, when the agent receives a term signal, it sends a message to the rest of the leave cluster and normally leaves

Open the browser to view Consul:

See all Consul node conditions

Docker Exec-t CS1 Consul members

View the status of the server and which node is leader

Docker Exec-t CS1 Consul operator Raft List-peers


If one or more servers are hung off, the consul cluster will re-elect the new leader,
But once the number of nodes that have been hung is more than half, the consul cluster will not work.

Third. asp. NET core MicroServices Service registration

1. Create a new project, ASP. NET Core WEBAPI Project

Introducing Consul, NuGet package

2. Create a new controller in the controller health, on behalf of the medical examination

    public class HealthController : Controller
        public IActionResult Get() => Ok("ok");

3. Then add the configuration file in the Appsetting.json

You need to configure the address and port number manually.


   "Logging": {
     "IncludeScopes": false,
     "Debug": {
       "LogLevel": {
         "Default": "Warning"
     "Console": {
       "LogLevel": {
         "Default": "Warning"
   "ServiceRegister": { //Service registration
     "IsActive": true,
     "ServiceName": "testconsul6",
     "ServiceHost": "",
     "ServicePort": 5006,
     "Register": {
       "HttpEndpoint": ""

4, this step is the service registration class


Public class ServiceRegisterOptions
         /// <summary>
         /// Whether to enable
         /// </summary>
         Public bool IsActive { get; set; }
         /// <summary>
         /// service name
         /// </summary>
         Public string ServiceName { get; set; }
         /// <summary>
         /// Service IP or domain name
         /// </summary>
         Public string ServiceHost { get; set; }
         /// <summary>
         /// Service port number
         /// </summary>
         Public int ServicePort { get; set; }
         /// <summary>
         /// consul registered address
         /// </summary>
         Public RegisterOptions Register { get; set; }


 Public class registeroptions

5. Service Registration in Startup.cs

Public void ConfigureServices(IServiceCollection services)
             #region Service registration basic information configuration
             services.AddSingleton<IConsulClient>(p => new ConsulClient(cfg =>
                 Var serviceConfiguration = p.GetRequiredService<IOptions<ServiceRegisterOptions>>().Value;
                 If (!string.IsNullOrEmpty(serviceConfiguration.Register.HttpEndpoint))
                     cfg.Address = new Uri(serviceConfiguration.Register.HttpEndpoint);


Configuring code in the Configure method

Private static void RegisterService(IApplicationBuilder app,
            IOptions<ServiceRegisterOptions> serviceRegisterOptions,
            IConsulClient consul,
            IApplicationLifetime appLife)
            Var serviceId = $"{serviceRegisterOptions.Value.ServiceName}_{serviceRegisterOptions.Value.ServiceHost}:{serviceRegisterOptions.Value.ServicePort}";

            Var httpCheck = new AgentServiceCheck()
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//How long does the service start to register?
                Interval = TimeSpan.FromSeconds(30), // health check interval, or heartbeat interval
                HTTP = $"http://{serviceRegisterOptions.Value.ServiceHost}:{serviceRegisterOptions.Value.ServicePort}/api/health", // Health Check Address

            Var registration = new AgentServiceRegistration()
                Checks = new[] { httpCheck },
                Address = serviceRegisterOptions.Value.ServiceHost,
                ID = serviceId,
                Name = serviceRegisterOptions.Value.ServiceName,
                Port = serviceRegisterOptions.Value.ServicePort
                //Tags = new[] { $"urlprefix-/{serviceRegisterOptions.Value.ServiceName}" }//Add the tag tag in urlprefix-/servicename format for Fabio to recognize

            appLife.ApplicationStopping.Register(() =>
                consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();//Unregister when the service is stopped

Since then, we can deploy our project to Docker on the 163 server.

We took a look at the effect and successfully registered to

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.