侧边栏壁纸
博主头像
进击的码农博主等级

新年新气象,开搞开搞

  • 累计撰写 31 篇文章
  • 累计创建 11 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

.Net里Consul的使用

wosperry
2022-09-18 / 0 评论 / 0 点赞 / 4 阅读 / 5248 字

Consul

运行Consul

docker run -d -p 8500:8500 --restart=always --name=consul consul:latest agent -server -bootstrap -ui -node=1 -client='0.0.0.0'

API的代码



using Consul;
using Newtonsoft.Json;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); 

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

// 传参是为了告诉consul自己的 host 和 port
// 这里我是直接取执行的参数,可以自己换别的形式通知到应用自己的host和port。
if (!string.IsNullOrWhiteSpace(args[0]) && !string.IsNullOrWhiteSpace(args[1]) && !string.IsNullOrWhiteSpace(args[2]))
{
    var name = args[0];
    var host = args[1];
    var port = int.Parse(args[2]);


    var consulClient = new ConsulClient(options =>
    {
        options.Address = new Uri($"http://wosperry.com.cn:8500/");
        options.Datacenter = "dc1";
    });
    var httpCheck = new AgentServiceCheck()
    {
        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
        Interval = TimeSpan.FromSeconds(10),//健康监测
        HTTP = string.Format($"http://{host}:{port}/api/health"),//心跳检测地址
        Timeout = TimeSpan.FromSeconds(5)
    };

    Console.WriteLine(JsonConvert.SerializeObject(httpCheck));

    //注册
    var registrtion = new AgentServiceRegistration()
    {

        Checks = new[] { httpCheck },
        ID = "perry-" + Guid.NewGuid().ToString(),//服务编号不可重复
        Name = name,//服务名称
        Address = host,//ip地址
        Port = port//端口
    };
    //注册服务
    consulClient.Agent.ServiceRegister(registrtion);
}

app.MapGet("api/health", () => { });

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

 

Docker 拉代码、构建、运行 API


# docker镜像名字
IMAGE=perry20220918
# 服务名字(Consul用的)
NAME=perry-test
# API 应用自己的Host
HOST=http://wosperry.com.cn
# API 应用自己的端口,给docker,并传到ENTRYPOINT 给dotnet cli 用
# 这个$1是因为我不想手动一次次复制,就定义了一个update.sh文件,通过 ./update.sh 8001 把端口当成参数给到命令里。
# (如果Linux不能执行,可以 chmod 777 update.sh 给全部权限
PORT=$1  
# 这里的几个参数其实是我用代码写的 args[0] 这样获取的,可以换别的形式传

# 下面是真正的命令,就移除掉 容器、镜像,然后拉代码,重新构建镜像,然后运行到指定的端口
docker rm -f ${NAME}-${PORT}
docker rmi -f ${IMAGE}
git pull
docker build -t ${IMAGE} -f Perry20220918/Dockerfile .  
docker run -d -p ${PORT}:80 --name ${NAME}-${PORT} ${IMAGE} ${NAME} ${HOST} ${PORT}

Ocelot的配置

{
  "Routes": [
    {
      //转发到下游服务地址--url变量
      "DownstreamPathTemplate": "/{url}",
      //下游http协议
      "DownstreamScheme": "http",
      //负载方式,
      "LoadBalancerOptions": {
        "Type": "RoundRobin" // 轮询 RoundRobin  最少连接 LeastConnection
      },
      //上游地址
      "UpstreamPathTemplate": "/serviceA/{url}", //网关地址--url变量   //冲突的还可以加权重Priority
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "UseServiceDisConvery": true, //使用服务发现
      "ServiceName": "perry-test", //Consul服务名称
      //缓存设置
      "FileCacheOptions": {
        "TtlSeconds": 10, //缓存10s(同一个地址请求就返回缓存结果)
        "Region": "" //缓存region
      }
    },

    {
      //转发到下游服务地址--url变量
      "DownstreamPathTemplate": "/{url}",
      //下游http协议
      "DownstreamScheme": "http",
      //负载方式,
      "LoadBalancerOptions": {
        "Type": "RoundRobin" // 轮询
      },
      //上游地址
      "UpstreamPathTemplate": "/serviceB/{url}", //网关地址--url变量   //冲突的还可以加权重Priority
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "UseServiceDisConvery": true, //使用服务发现
      "ServiceName": "hahaha", //Consul服务名称
      //缓存设置
      "FileCacheOptions": {
        "TtlSeconds": 10, //缓存10s(同一个地址请求就返回缓存结果)
        "Region": "" //缓存region
      }
    },

    {
      //转发到下游服务地址--url变量
      "DownstreamPathTemplate": "/{url}",
      //下游http协议
      "DownstreamScheme": "http",
      //负载方式,
      "LoadBalancerOptions": {
        "Type": "RoundRobin" // 轮询
      },
      //上游地址
      "UpstreamPathTemplate": "/serviceC/{url}", //网关地址--url变量   //冲突的还可以加权重Priority
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "UseServiceDisConvery": true, //使用服务发现
      "ServiceName": "PTEST", //Consul服务名称
      //缓存设置
      "FileCacheOptions": {
        "TtlSeconds": 10, //缓存10s(同一个地址请求就返回缓存结果)
        "Region": "" //缓存region
      }
    }
  ],
  "GlobalConfiguration": {
    //Ocelot应用地址
    "BaseUrl": "http://localhost:5096",
    "ServiceDiscoveryProvider": {
      //Consul地址
      "Host": "wosperry.com.cn",
      //Consul端口
      "Port": 8500,
      "Type": "Consul" //由Consul提供服务发现,每次请求Consul
    }
  }
}

consul api读取服务列表: https://www.jianshu.com/p/d35cd527d5fb
官方文档: https://ocelot.readthedocs.io/en/latest/features/servicediscovery.html
腾讯云文档《.NET 5 中使用 Consul+Ocelot+Polly缓存、限流、熔断、降级》: https://cloud.tencent.com/developer/article/1899794

0

评论区