2018-06-16-Spring cloud(2)-服务发现(Eureka,Consul)

在分布式系统领域有个著名的CAP定理C-数据一致性A-服务可用性P-服务对网络分区故障的容错性,这三个特性在任何分布式系统中不能同时满足,最多同时满足两个);
eureka是AP,zookeeper是CP。对于服务发现而言,可用性数据一致性更加重要——AP胜过CP

Consul zookeeper euerka etcd
服务健康检查 服务状态,内存,硬盘等 (弱)长连接,keepalive 可配支持 连接心跳
多数据中心 支持
kv存储服务 支持 支持 支持
一致性 raft paxos raft
CAP ca cp ap cp
使用接口(多语言能力) 支持http和dns 客户端 http(sidecar) http/grpc
watch支持(客户端观察到服务提供者变化) 全量/支持long polling 支持 支持long polling/大部分增量 支持long polling
自身监控 metrics metrics metrics
安全 acl /https acl https支持(弱)
spring cloud集成 已支持 已支持 已支持 已支持
  • raft:Raft强依赖 Leader 节点的可用性来确保集群数据的一致性。

    raft

  • paxos: 第一次由提交者Leader向所有其他服务器发出prepare消息请求准备,所有服务器中大多数如果回复诺言承诺就表示准备好了,可以接受写入;第二次提交者向所有服务器发出正式建议propose,所有服务器中大多数如果回复已经接收就表示成功了。

  • long polling:长轮询,客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

  • metrics:作为一款监控指标的度量类库,它提供了很多模块可以为第三方库或者应用提供辅助统计信息, 它还可以将度量数据发送给Ganglia和Graphite以提供图形化的监控

  • Eureka的自我保护模式
    Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否
    低于85%,如果出现低于的情况(实际在
    生产环境上通常是由于网
    络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提
    示警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分
    区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注
    册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。
    所以Eureka的哲学是,同时保留”好数据“”坏数据“总比丢掉任何”好数据“要更好,所以这种模式在实践中非常有效。,

为啥不使用zookeeper做发现服务呢?

  1. ZooKeeper是分布式协调服务,它的职责是保证数据(注:配置数据,状态数据)在其管辖下的所有服务之间保持同步、一致;(强一致性)
  2. 发现服务的核心应该是需要强调服务的高可用
  3. ZooKeeper使用单一主进程Leader用于处理客户端所有事务请求,采用ZAB协议将服务器数状态以事务形式广播到所有Follower上;如果三台服务挂了两台怎么选出leader1 不大于 (3/2)=1的
  4. 正确的设置与维护ZooKeeper服务就非常的困难
  5. 集群中出现了网络分割的故障(交换机故障导致交换机底下的子网间不能互访)ZooKeeper会将它们都从自己管理范围中剔除出去,外界就不能访问到这些节点了,本身这些节点是“健康”的,能提供服务的
  6. 发现服务就算是返回了包含不实的信息的结果也比什么都不返回要好(因为暂时的网络故障而找不到可用的服务器)

因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

Spring Cloud Eureka(服务注册)

  • 添加依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
  • 开启服务注册

通过 @EnableEurekaServer注解启动一个服务注册中心提供给其他应用进行对话,这个注解需要在springboot工程的启动application类上加

    package io.ymq.example.eureka.server;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    }

Spring Cloud Service Provider(服务提供者)

  • 服务提供方
  • 将自身服务注册到 Eureka 注册中心,从而使服务消费方能够找到
  • 添加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
  • 开启服务注册
    在应用主类中通过加上 @EnableEurekaClient,但只有Eureka 可用,你也可以使用@EnableDiscoveryClient。需要配置才能找到Eureka注册中心服务器
    discovery service有许多种实现(eureka、consul、zookeeper等)
    @EnableDiscoveryClient基于spring-cloud-commons,
    @EnableEurekaClient基于spring-cloud-netflix
    就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient
    如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient
@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }

    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class, args);
    }
}
  • 添加配置 application.yml
    添加配置找到Eureka服务器
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: eureka-provider
server:
  port: 8081

Spring Cloud Service Consumer(服务消费者)

Eureka注册服务,消费者使用Ribbon开启负载均衡

Ribbon是什么?

RibbonNetflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

Ribbon的核心组件

Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果。

  • ServerList:用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。
  • ServerListFilter:仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。
  • IRule:选择一个最终的服务地址作为LB结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。

Ribbon提供的主要负载均衡策略

  • 简单轮询负载均衡(RoundRobin) 以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
  • 随机负载均衡 (Random) 随机选择状态为UP的Server
  • 加权响应时间负载均衡 (WeightedResponseTime) 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
  • 区域感知轮询负载均衡(ZoneAvoidanceRule) :复合判断server所在区域的性能和server的可用性选择server

服务提供者(提供服务)

  • 开启服务注册
    注册三台
@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {
    @Value("${server.port}")
    String port;
    @RequestMapping("/")
    public String home() {
        return "Hello world ,port:" + port;
    }
    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class, args);
    }
}
  • 添加配置 application.yml
    端口依次为8081,8082,8083
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: eureka-provider

server:
  port: 8081

服务消费者(依赖于其它服务)

  • pom.xml添加依赖
<!-- 客户端负载均衡 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

<!-- eureka客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
  • 开启服务负载均衡
    通过@EnableDiscoveryClient向服务注册中心注册;并且向程序的ioc注入一个bean: restTemplate并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }
}
  • 消费提供者方法
/**
 * 描述:调用提供者的 `home` 方法
 **/
@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/hello")
    public String hello() {
        return restTemplate.getForEntity("http://eureka-provider/", String.class).getBody();
    }
}
  • 添加配置 application.yml
    指定服务的注册中心地址,配置自己的服务端口,服务名称
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: ribbon-consumer

server:
  port: 9000

依次启动服务(Eureka服务,三台service provider和service Consumer),查看ribbon是否开启负载均衡

Spring Cloud Consul(针对Consul的服务治理实现)

由于Consul自身提供了服务端,所以我们不需要像之前实现Eureka的时候创建服务注册中心,直接通过下载consul的服务端程序就可以使用。
Consul内置了服务注册发现框架(一站式)、具有以下性质(参考上面列表):

  • 分布一致性协议实现
  • 健康检查
  • Key/Value存储
  • 多数据中心方案

Consul的优势

  • 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接
  • 支持多数据中心,内外网的服务采用不同的端口进行监听
  • 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等
  • 支持健康检查
  • 支持 http 和 dns 协议接口
  • 官方提供web管理界面

Consul的角色

  • client:客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群,所有注册到当前节点的服务会被转发到server,本身是不持久化这些信息
  • server:服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯,功能和client都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.
  • server-leader:表明这个server是它们的老大,它和其它server不一样的一点是,它需要负责同步注册的信息给其它的server,同时也要负责各个节点的健康监测。
  • raft:server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是taft。
  • 服务发现协议:consul采用http和dns协议,etcd只支持http
  • 服务注册:支持两种方式实现服务注册,consul官方建议使用第二种方式。
  1. 一种是通过consul的服务注册http API,由服务自己调用API实现注册,
  2. 另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。
  • 服务发现:支持两种方式实现服务发现,
  1. 一种是通过http API来查询有哪些服务,
  2. 另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。
  • 服务间的通信协议:Consul使用gossip协议管理成员关系、广播消息到整个集群

结语

关于consul的环境搭建以及应用后续再补充吧~
github上有关于Spring Cloud完整的部署。
其它相关文章
Spring cloud(1)-简介以及选择
Spring cloud(2)-服务发现(Eureka,Consul)
Spring cloud(3)-负载均衡(Feign,Ribbon)
Spring cloud(4)-熔断(Hystrix)
Spring cloud(5)-路由网关(Zuul)
Spring cloud(6)-配置管理及刷新(Config,Bus)
最后,给个 star 吧~
个人博客~
简书~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容