一、为什么需要服务治理?
从之前的调用流程中可以看到,无论是业务端直接调用还是微服务网关调用,调用的前提都是需要知道服务的地址和端口才能调用。
那么如何才能知道服务的地址呢?能想到的比较简单的办法就是,当服务部署好后,将服务的地址和名称配置到业务端和微服务网关的配置文件中,这样只需要简单的读取配置文件即可知道某个服务的服务调用地址。
放到配置文件虽然简单,但也有问题:首先就是同一个地址需要配置多次,在每一个微服务网关实例的配置文件中都需要进行配置;其次就是当服务的地址变更(原来的服务实例有问题,停止后重新在启动的实例端口或ip可能会不同)或扩展(当流量太大,需要增加服务实例来响应处理时,这些新增的服务地址也需要让微服务网关知晓)的时候,也需要更改配置文件,然后重新启动服务网关;再次就是无法根据服务的实际运行情况来动态检测。服务治理要解决的就是这些问题。
二、服务治理的发现的作用
- 服务注册:服务启动的时候,将服务地址以服务名称和标记注册到注册中心
- 服务健康检测:注册中心按注册时指定的健康检测条件,定期的检测服务运行状态
- 服务发现:微服务网关或其他服务消费者,在需要调用某个服务的时候,从注册中心根据服务名称和标记获取到指定服务的健康的运行地址,如果有多个的话,还需要考虑某种调度算法(比较简单的就是随机算法)来选择一个服务实例进行调用
- 配置中心也可以放到服务治理组件中,也可以单独出来。
三、有服务治理后的调用流程
四、服务治理的作用
| 功能 | Consul | zookeeper | etcd | euerka |
|---|---|---|---|---|
| 服务健康检查 | 服务状态,内存,硬盘等 | (弱)长连接,keepalive | 连接心跳 | 可配支持 |
| 多数据中心 | 支持 | — | — | — |
| kv存储服务 | 支持 | 支持 | 支持 | — |
| 一致性 | raft | paxos | raft | — |
| cap | ca | cp | cp | ap |
| 使用接口 (多语言能力) |
支持http和dns | 客户端 | http/grpc | http |
| watch支持 | 全量/支持long polling | 支持 | 支持long polling | 支持long polling/大部分增量 |
| 自身监控 | metrics | — | metrics | metrics |
| 安全 | acl/https | acl | https支持(弱) | — |
| spring cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |
六、服务注册示例
//register serviceConsulClient client = new ConsulClient();var serviceInfo = new AgentServiceRegistration{ID = $"Service1_{ip}:{firstPort}",Name = $"Service1",Address = ip,Port = firstPort,Check = new AgentServiceCheck{Interval = TimeSpan.FromSeconds(5),Timeout = TimeSpan.FromSeconds(3),TCP = $"{ip}:{firstPort}"}};client.Agent.ServiceRegister(serviceInfo);
七、服务发现示例
//discover service
ConsulClient client = new ConsulClient();
var loginServiceDiscoverResponse = await client.Health.Service("Login");
var loginServiceAddresses = loginServiceDiscoverResponse.Response;
if(loginServiceAddresses.Length <= 0)
{
Console.WriteLine("没有找到Login登录服务,请先启动服务");
return;
}
var serviceEntry = loginServiceAddresses[0];
var serviceAddress = $"{serviceEntry.Service.Address}:{serviceEntry.Service.Port}";
