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

2018-10-24  本文已影响0人  ohcomeyes

在分布式系统领域有个著名的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集成 已支持 已支持 已支持 已支持

为啥不使用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(服务提供者)

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {

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

    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class, args);
    }
}
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选择出一台服务器作为最终结果。

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

服务提供者(提供服务)

@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);
    }
}
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: eureka-provider

server:
  port: 8081

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

<!-- 客户端负载均衡 -->
<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
@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();
    }
}
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内置了服务注册发现框架(一站式)、具有以下性质(参考上面列表):

Consul的优势

Consul的角色

  1. 一种是通过consul的服务注册http API,由服务自己调用API实现注册,
  2. 另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。
  1. 一种是通过http API来查询有哪些服务,
  2. 另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。

结语

关于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 吧~
个人博客~
简书~

上一篇 下一篇

猜你喜欢

热点阅读