基于Docker的Consul 集群+.netcore微服务部署

网上一大堆Consul集群的文章,但是就是没有一篇完整的从Consul集群到微服务集群的文章,那么今天,我经过踩了无数个坑,终于写了这个“从头到尾”的文章,详细介绍,如果从Consul集群到和微服务集群搭建起来并且能运行的整个过程。

1.创建网络

docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 kafkanet

2.Consul 集群部署的docker-compose.yml的文件内容

version: '3.6'
networks:
  kafkanet:
    external: true

services:
  consul1:
    image: consul:latest
    container_name: consul1
    restart: always
    ports:
      - 8501:8500
    command: agent -server -bind=172.19.0.3 -client=0.0.0.0 -bootstrap-expect=3 -node=consul1
    volumes:
      - /root/consulGroup/consul1/data:/consul/data
      - /root/consulGroup/consul1/config:/consul/config
    networks:
      kafkanet:
  consul2:
    image: consul:latest
    container_name: consul2
    restart: always
    ports:
      - 8502:8500
    command: agent -server -bind=172.19.0.4 -client=0.0.0.0 -retry-join=consul1 -node=consul2
    volumes:
      - /root/consulGroup/consul2/data:/consul/data
      - /root/consulGroup/consul2/config:/consul/config
    networks:
      kafkanet:
  consul3:
    image: consul:latest
    container_name: consul3
    restart: always
    ports:
      - 8503:8500
    command: agent -server -bind=172.19.0.5 -client=0.0.0.0 -retry-join=consul1 -node=consul3
    volumes:
      - /root/consulGroup/consul3/data:/consul/data
      - /root/consulGroup/consul3/config:/consul/config
    networks:
      kafkanet:
  consul4:
    image: consul:latest
    container_name: consul4
    restart: always
    ports:
      - 8500:8500
    command: agent -bind=172.19.0.2 -client=0.0.0.0 -retry-join=consul1 -ui -node=client1
    volumes:
      - /root/consulGroup/consul4/data:/consul/data
      - /root/consulGroup/consul4/config:/consul/config
    networks:
      kafkanet:

3.使用docker文件制作镜像

命令:docker build -t webappconsuljiqunimg

VS生成的Docker文件内容简化如下面这样,注意,这个是自己发布的,不是把整个项目拷贝过去

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "WebAppConsulJiQun.dll"]

4.微服务的docker-compose.yml文件内容(注意这里使用的是基于3创建的镜像):

version: '3.3'
networks:
  kafkanet:
    external: true
services:
  service1:
    image: webappconsuljiqunimg
    networks:
      kafkanet:
        ipv4_address: 172.19.0.67
    ports:
      - 1501:80/tcp
    command: ["dotnet", "/app/WebAppConsulJiQun"]
    volumes:
      - /root/webUseConsul/appsettings1501.json:/app/appsettings.json
  service2:
    image: webappconsuljiqunimg
    networks:
      kafkanet:
        ipv4_address: 172.19.0.68
    ports:
      - 1502:80/tcp
    command: ["dotnet", "/app/WebAppConsulJiQun"]
    volumes:
      - /root/webUseConsul/appsettings1502.json:/app/appsettings.json
  service3:
    image: webappconsuljiqunimg
    networks:
      kafkanet:
        ipv4_address: 172.19.0.69
    ports:
      - 1503:80/tcp
    command: ["dotnet", "/app/WebAppConsulJiQun"]
    volumes:
      - /root/webUseConsul/appsettings1503.json:/app/appsettings.json

5.基于4创建的3个微服务挂载的文件内容(微服务和Consul的注册配置就在这,一定要注意这里的IP配置和Consul地址的配置)(特别注意:ConsulAddress节点,可以是其他的Consul节点的IP,但,一定要记住,端口必须是8500

另外:ip和port,要写成外网地址,因为后面服务发现时,要拿 的就是这个地址,如果你写成内网的,那么 你的服务怎么调用 ?

第一个文件appsettings1501.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ip": "172.19.0.67",
  "port": 80,

  "weight": 1,
  "ConsulAddress": "http://172.19.0.2:8500/",
  "ConsulCenter": "dc1"

}
第二个文件appsettings1502.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ip": "172.19.0.68",
  "port": 80,
  "weight": 2,
  "ConsulAddress": "http://172.19.0.2:8500/",
  "ConsulCenter": "dc1"

}
第三个文件appsettings1503.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ip": "172.19.0.69",
  "port": 80,
  "weight": 3,
  "ConsulAddress": "http://172.19.0.2:8500/",
  "ConsulCenter": "dc1"

}

 

6.注册服务的代码:

自己声名一个类:

public static class RegistService
    {
        public static void RegistMicService(this IConfiguration configuration)
        {
            try
            {
                string ip = configuration["ip"];
                int port = int.Parse(configuration["port"]);
                int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
                using (ConsulClient client = new ConsulClient(c =>
                {
                    c.Address = new Uri(configuration["ConsulAddress"]);
                    c.Datacenter = configuration["ConsulCenter"];
                }))
                {
                    try
                    {
                        client.Agent.ServiceRegister(new AgentServiceRegistration()
                        {
                            ID = "service " + ip + ":" + port,//Eleven  独一无二
                            Name = "consul",//分组---朝夕教育的老师
                            Address = ip,
                            Port = port,
                            Tags = new string[] { weight.ToString() },
                            Check = new AgentServiceCheck()
                            {
                                Interval = TimeSpan.FromSeconds(12),
                                HTTP = $"http://{ip}:{port}/home/helth",
                                Timeout = TimeSpan.FromSeconds(5),
                                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)
                            }
                        }).Wait();
                    }
                    catch (Exception ex22)
                    {
                        Console.WriteLine(ex22.Message);
                    }
                    //命令行参数获取
                    Console.WriteLine($"服务地址:{ip}:{port}--weight:{weight},注册到的Consul服务器是{configuration["ConsulAddress"]}");

                    //client.KV.del
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

在Startup文件里的Configure调用 这个扩展方法

this.Configuration.RegistMicService();

最终 完成。。注意,看到这篇文章的小伙伴们,第一执行我上面的代码 的时候,千万不要修改里面的任何一个文字,否则,有可能会失败,要千万注意!!!

 

7.获取节点

/// <summary>
        /// 获取Consul配置的真正的服务地址
        /// </summary>
        /// <returns></returns>
        public string Index()
        {

            string serviceName = GetService();

            string url = serviceName + "/home/datas";

            return url;
        }

        /// <summary>
        /// 根据Consul随机获取地址
        /// </summary>
        /// <returns></returns>
        private string GetService()
        {
            var config = new ConsulClientConfiguration()
            {
                Address = new Uri("http://47.95.221.215:8500/"),
                Datacenter = "dc1",
            };
            string url = "";
            using (ConsulClient client = new ConsulClient(config))
            {
                var dic = client.Agent.Services().Result.Response;//这里也只能拿到 在 上面的 new Uri("http://47.95.221.215:8500/") 注册的节点,当然这里也在在一个问题,如果节点都注册到这个端上,那么如果这个端挂了,和这个端相关的微服务就全部找不到了

//所以,其实这块可以扩展从多个Consul端去获取服务地址,这个代码很简单,基本上就是把现在的代码复制几份改一下就行了
                Random num = new Random();
                var index = num.Next(0, dic.Keys.Count);

                var keys = dic.Keys.Select(k => k).ToList();


                var agent = dic[keys[index]];
                url = "http://" + agent.Address + ":" + agent.Port;
            }
            return url;
        }

7.1 从多个端获取服务地址

/// <summary>
        /// 根据Consul随机获取地址
        /// </summary>
        /// <returns></returns>
        private string GetService()
        {
            Dictionary<string, AgentService> dic = new Dictionary<string, AgentService>();

            {
                var config = new ConsulClientConfiguration()
                {
                    Address = new Uri("http://47.95.221.215:8500/"),
                    Datacenter = "dc1",
                };
                using (ConsulClient client = new ConsulClient(config))
                {
                    dic = client.Agent.Services().Result.Response;//这里也只能拿到 在 上面的 new Uri("http://47.95.221.215:8500/") 注册的节点
                }
            }
            {
                var config = new ConsulClientConfiguration()
                {
                    Address = new Uri("http://47.95.221.215:8501/"),
                    Datacenter = "dc1",
                };
                using (ConsulClient client = new ConsulClient(config))
                {
                    var dic1 = client.Agent.Services().Result.Response;//这里也只能拿到 在 上面的 new Uri("http://47.95.221.215:8500/") 注册的节点
                    foreach (var item in dic1)
                    {
                        dic.Add(item.Key, item.Value);
                    }
                }
            }

            {
                var config = new ConsulClientConfiguration()
                {
                    Address = new Uri("http://47.95.221.215:8502/"),
                    Datacenter = "dc1",
                };
                using (ConsulClient client = new ConsulClient(config))
                {
                    var dic1 = client.Agent.Services().Result.Response;//这里也只能拿到 在 上面的 new Uri("http://47.95.221.215:8500/") 注册的节点
                    foreach (var item in dic1)
                    {
                        dic.Add(item.Key, item.Value);
                    }
                }
            }

            {
                var config = new ConsulClientConfiguration()
                {
                    Address = new Uri("http://47.95.221.215:8503/"),
                    Datacenter = "dc1",
                };
                using (ConsulClient client = new ConsulClient(config))
                {
                    var dic1 = client.Agent.Services().Result.Response;//这里也只能拿到 在 上面的 new Uri("http://47.95.221.215:8500/") 注册的节点
                    foreach (var item in dic1)
                    {
                        dic.Add(item.Key, item.Value);
                    }
                }
            }

            string url = "";

            Random num = new Random();
            var index = num.Next(0, dic.Keys.Count);

            var keys = dic.Keys.Select(k => k).ToList();


            var agent = dic[keys[index]];
            url = "http://" + agent.Address + ":" + agent.Port;

            return url;
        }

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值