关于 consul
的介绍就不写了百度就行,我们直接开干。
拉取consul的镜像
docker pull consul
然后部署consul容器
docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:latest agent -server -bootstrap-expect 2 -ui -bind='0.0.0.0' -client='0.0.0.0'
8500 http
端口,用于 http
接口和 web ui
8300 server rpc
端口,同一数据中心 consul server
之间通过该端口通信8301 serf lan
端口,同一数据中心 consul client
通过该端口通信8302 serf wan
端口,不同数据中心 consul server
通过该端口通信8600 dns
端口,用于服务发现
-bbostrap-expect 2
: 集群至少两台服务器,才能选举集群 leader
-ui
:运行 web
控制台-bind
: 监听网口, 0.0.0.0
表示所有网口,如果不指定默认为 127.0.0.1
,则无法和容器通信-client
: 限制某些网口可以访问
-server
:表示该节点是 server
节点,不声明的话默认为 client
节点,它们的不同是 server
节点持久化信息,但是 client
不持久化会转发给 server
节点,并且 server
节点会有 leader
节点进行健康检测和同步信息到其他 server
节点
然后我们获取该 consul1
容器的 ip
,使用如下语句
docker inspect --format '{{ .NetworkSettings.IPAddress }}' consul1
获取到了 172.17.0.5
然后我们再新建另一个 consul
容器,使用 join
来加入第一个 consul1
容器的集群
docker run --name consul2 -d -p 18500:8500 -p 18300:8300 -p 18301:8301 -p 18302:8302 -p 18600:8600 consul:latest agent -server -ui -bind='0.0.0.0' -client='0.0.0.0' -join 172.17.0.5
我就建两个节点能运行即可, server
一般建 3-5
个, client
没有上限,所以根据上面的语句自己建立即可。
然后我们访问地址 http://localhost:8500/
可以进到控制界面。
为测试方便我们使用 -dev
参数允许启动一个 Consul
服务。
docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:latest agent -server -ui -bind='0.0.0.0' -client='0.0.0.0' -dev
我们新建一个项目,然后下载Consul包
Install-Package Consul
然后我们添加一个健康检查的接口
[Route("[controller]/[action]")]
[ApiController]
public class HealthController : Controller
{
[HttpGet("/healthCheck")]
public IActionResult Check() => Ok("ok");
}
之后我们在 appsetting.json
中配置我们的 Consul
参数,这些参数我们用来注册服务的一些信息,参数解释如下:
ServiceName
:是服务的名称,同一个服务名的服务将会注册到同一个服务下的实例
ServiceIP
:服务请求的主机地址
ServicePort
:服务请求的端口
ServiceHealthCheck
:服务健康检测接口地址,此处是 host.docker.internal
是因为 Consul
在容器内需要访问宿主主机运行的服务
Address
: Consul
服务的请求地址
"Consul": {
"ServiceName": "service-a",
"ServiceIP": "127.0.0.1",
"ServicePort": 5001,
"ServiceHealthCheck": "http://host.docker.internal:5001/healthCheck",
"Address": "http://127.0.0.1:8500"}
之后我们创建一个类名叫 ConsulOption
,用于使用过 Option
模式加载 appsetting.json
中我们配置的参数,用于注册
public classConsulOption
{
/// <summary>
///服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
///服务IP
/// </summary>
public string ServiceIP { get; set; }
/// <summary>
///服务端口
/// </summary>
public int ServicePort { get; set; }
/// <summary>
///服务健康检查地址
/// </summary>
public string ServiceHealthCheck { get; set; }
/// <summary>
///Consul 地址
/// </summary>
public string Address { get; set; }
}
View Code
然后创建一个 Consul
服务注册类 ConsulBuilderExtensions
,对将本服务推送到 Consul
中去,具体的参数解释在代码注释中了
public static classConsulBuilderExtensions
{
public static IApplicationBuilder RegisterConsul(thisIApplicationBuilder app, IHostApplicationLifetime lifetime, ConsulOption consulOption)
{
var consulClient = new ConsulClient(x =>{
x.Address = newUri(consulOption.Address);
});
var registration = newAgentServiceRegistration()
{
ID =Guid.NewGuid().ToString(),
Name = consulOption.ServiceName,//服务名
Address = consulOption.ServiceIP, //服务绑定IP
Port = consulOption.ServicePort, //服务绑定端口
Check = newAgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔
HTTP = consulOption.ServiceHealthCheck,//健康检查地址
Timeout = TimeSpan.FromSeconds(5)
}
};
//服务注册
consulClient.Agent.ServiceRegister(registration).Wait();
//应用程序终止时,服务取消注册
lifetime.ApplicationStopping.Register(() =>{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});
returnapp;
}
}
最后我们注入本服务
builder.Services.AddSingleton(builder.Configuration.GetSection("Consul").Get<ConsulOption>());
//....
app.RegisterConsul(app.Lifetime, app.Services.GetRequiredService<ConsulOption>());
启动项目就能看到服务已经注册
Consul提供了http api可以让我们进行查询、注册、接触注册等操作
http://127.0.0.1:8500/v1/health/service/service-a?passing
我们新建一个项目然后安装包
Install-Package Ocelot.Provider.Consul
然后注册服务
builder.Services.AddOcelot().AddPolly().AddConsul();
之后在配置文件中的 GlobalConfiguration
节点下添加如下参数,这是必须的如果没有指定主机 Host
和端口 Port
将会使用 Consul
默认的, Scheme
默认为 http
, Type
说明此服务发现由 Consul
提供
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"}
然后我们设置路由,添加我们刚注册的服务,最好是配合负载均衡参数咯,我这里没写
"Routes": [
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"ServiceName": "service-a",
"UpstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": [ "Get", "Post"]
}]
然后运行就可以看到结果了,需要注意的是请求是 http
还是 https
这些需要注意,我就卡在了这里很久,请求路径需要注意噢
最后, Ocelot
是每次请求都去 Consul
获取最新的服务,如果需要设置间隔多久去获取 Consul
的最新服务(可能会有微小的性能改进,但是不知道原有服务是否可用,可能会有错误的返回噢)可以如下设置:
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 8500,
"Type": "PollConsul",
"PollingInterval": 100}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.cnblogs.com/xwc1996/p/17233311.html
内容来源于网络,如有侵权,请联系作者删除!