net 6 使用 consul 做服务注册与服务发现(上)

1413人阅读 2023/8/27 20:08 总访问:679881 评论:0 收藏:0 手机
分类: .net core

前言

学无止境

今天来了解一下使用 cousul ,那什么是consul 呢

Consul是一种开源的、分布式的服务发现和配置管理工具。它由HashiCorp公司开发,用于帮助构建和维护现代化的分布式系统和微服务架构。


Consul提供了许多核心功能,包括:


服务发现:Consul充当了一个注册表,使得服务能够自动注册和发现其他服务。当新的服务启动或停止时,Consul能够自动更新服务注册表,并通知其他服务。


健康检查:Consul可以周期性地检查服务的健康状态,确保只有可用的服务被注册并参与负载均衡。


键值存储:Consul提供了一个分布式键值存储系统,允许应用程序存储和检索配置信息、特征标志或其他共享数据。


多数据中心支持:Consul支持多个数据中心之间的连接和复制,以确保服务在不同地理位置的高可用性。


安全性:Consul提供了身份验证和授权机制,以确保只有经过授权的服务可以访问和使用共享资源。

首先是安装counsul

 安装这块我主要用docker 做例子
 使用命令拉取consul (不知道为啥我的虚拟机中的docker 必须要让我填版本号)

$ docker pull consul # 默认拉取latest
$ docker pull consul:1.6.1 # 拉取指定版本

拉取完成后 运行

docker run -d -p 8500:8500 --restart=always --name=consul consul:latest agent -server -bootstrap -ui -node=1 -client='0.0.0.0'
  • agent: 表示启动 Agent 进程。

  • server:表示启动 Consul Server 模式

  • client:表示启动 Consul Cilent 模式。

  • bootstrap:表示这个节点是 Server-Leader ,每个数据中心只能运行一台服务器。技术角度上讲 Leader 是通过 Raft 算法选举的,但是集群第一次启动时需要一个引导 Leader,在引导群集后,建议不要使用此标志。

  • ui:表示启动 Web UI 管理器,默认开放端口 8500,所以上面使用 Docker 命令把 8500 端口对外开放。

  • node:节点的名称,集群中必须是唯一的,默认是该节点的主机名。

  • client:consul服务侦听地址,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1所以不对外提供服务,如果你要对外提供服务改成0.0.0.0

  • join:表示加入到某一个集群中去。 如:-json=192.168.0.11。

防火墙开启8500 端口

【查看防火墙是否开启】

$ systemctl status firewalld

【开启或关闭防火墙】

$ systemctl start firewalld
$ systemctl stop firewalld

【查看所有开启的端口】

$ firewall-cmd --list-ports

【开启8500端口】

$ firewall-cmd --zone=public --add-port=8500/tcp --permanent

【重启防火墙,使其生效】

$ firewall-cmd --reload


接下来就可以访问8500 端口了
成功后如下图



代码部分

先下载consul nuget 包


添加一个ConsulHelper,提供一个服务注册的方法

        /// <summary>
        /// 服务注册到consul
        /// </summary>
        /// <param name="app"></param>
        /// <param name="lifetime"></param>
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IConfiguration configuration, IHostApplicationLifetime lifetime)
        {
            var consulClient = new ConsulClient(c =>
            {
                //consul地址
                c.Address = new Uri(configuration["ConsulSetting:ConsulAddress"]);
            });

            var registration = new AgentServiceRegistration()
            {
                ID = Guid.NewGuid().ToString(),//服务实例唯一标识
                Name = configuration["ConsulSetting:ServiceName"],//服务名
                Address = configuration["ConsulSetting:ServiceIP"], //服务IP
                Port = int.Parse(configuration["ConsulSetting:ServicePort"]),//服务端口 因为要运行多个实例,端口不能在appsettings.json里配置,在docker容器运行时传入
                Check = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔
                    HTTP = $"http://{configuration["ConsulSetting:ServiceIP"]}:{configuration["ConsulSetting:ServicePort"]}{configuration["ConsulSetting:ServiceHealthCheck"]}",//健康检查地址
                    Timeout = TimeSpan.FromSeconds(5)//超时时间
                }
            };

            //服务注册
            consulClient.Agent.ServiceRegister(registration).Wait();

            //应用程序终止时,取消注册
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

            return app;
        }

appsettings.json 文件入下

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConsulSetting": {
    "ServiceName": "OrderService", //服务名
    "ServiceIP": "192.168.1.3", //服务IP
    "ServiceHealthCheck": "/healthcheck",//健康检查地址
    "ConsulAddress": "http://192.168.1.3:8500" //注意,docker容器内部无法使用localhost访问宿主机器,如果是控制台启动的话就用localhost
  }
}

在管道中注册consul


记得添加健康检查接口,与上方配置的路径一致即可


接下来就是程序的打包运行了
将程序打包到docker 中 

dockerfile 示例如下

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base 

WORKDIR /app/publish

EXPOSE 80
  
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY . .   

ENV ASPNETCORE_URLS=http://+:80

ENTRYPOINT ["dotnet", "Order.API.dll"]

然后在执行 docker 将项目运行 5 份 分别是这几个端口

docker build -t orderapi -f ./Dockerfile .

docker run -d -p 9051:80 --name orderservice1 orderapi --ConsulSetting:ServicePort="9051"
docker run -d -p 9052:80 --name orderservice2 orderapi --ConsulSetting:ServicePort="9052"
docker run -d -p 9053:80 --name orderservice3 orderapi --ConsulSetting:ServicePort="9053"
docker run -d -p 9054:80 --name orderservice4 orderapi --ConsulSetting:ServicePort="9054"
docker run -d -p 9055:80 --name orderservice5 orderapi --ConsulSetting:ServicePort="9055"


运行完成后,查看一下,已经成功启动


然后在consul 中查看服务是否已经注册成功


现在是五个,因为在上方注册服务的方法中方还写了,程序终止时取消注册

  //应用程序终止时,取消注册
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

现在来试一下,随便停止其中一个容器


这就是consul 的服务注册


 

评价
脚踏实地,一步一个脚印
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
欢迎加群交流技术