chap03-Eureka-1-服务治理-环境搭建

《Spring Cloud 微服务实战》 学习笔记

服务治理

服务治理可以说是微服务架构中最核心和基础的模块,它主要来实现各个微服务实力的自动化注册与发现。
服务注册
在服务治理框架中,通常会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按照服务名分类组织服务清单。

比如: 有服务A和服务B,
服务A运行了两个节点,分别运行在server1:8000server2:8001
服务B运行了3个节点, 分别运行在server1:9000,server2:9001server3:9002
当这些服务均向注册中心注册后,注册中心会有如下的一个服务清单:

服务名位置
服务Aserver1:8000, server2:8001
服务Bserver1:9000,server2:9001,server3:9002

服务发现
由于在服务治理框架下,服务间的调用不再通过指定具体的实例地址来发现,而是通过服务名发起请求调用实现。
所以, 服务调用方在调用服务提供方的接口时,并不知道服务的具体地址。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。

比如,现有服务C希望调用服务A,服务C就需要向服务注册中心发起咨询服务,服务中心会将服务A的位置清单返回给服务C,C会获取上述配置的两个可用位置:server1:8000server2:8001,当服务C要发起调用的时候,便从该清单中以某种轮训策略去除一个位置来进行服务调用(这就是后续会分析 客户端负载均衡)。实际的框架为了性能等因素,不会采取每次请求都想注册中心获取服务的方式,而且不同的应用场景在缓存和服务剔除等机制上也有一些不同的实现策略。

Netflix Eureka

Spring Cloud Eureka使用 Netflix Eureka来实现服务注册与发现。
Eureka服务端
Eureka服务端,我们也称之为注册中心,它通其他服务注册中心一样,支持高可用配置。
它依托强一致性提供良好的服务实例可用性,可以应对多种不同的故障场景。
如果Eureka以集群模式部署,当集群中有分片出现故障时,那么Eureka就转入自我保护模式。它允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复运行时,集群中的其他分片会把他们的状态再次童虎回来。

Eureka客户端
Eureka客户端,主要处理服务的注册与发现。客户端服务通过注解和参数配置的方式,嵌入在客户端应用程序的代码中,在应用程序中,Eureka客户端向注册中心注册自身提供的服务并周期性的发送心跳来更新它的服务租约。 同时,它也能从服务端查询注册的服务信息并把它们缓存到本地并周期性地刷新服务状态

搭建服务注册中心

pom.xml

<parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.1.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
  </parent>
  
<dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
       </dependency>
   </dependencies>

   <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-dependencies</artifactId>
               <version>Greenwich.SR2</version>
               <type>pom</type>
               <scope>import</scope>
           </dependency>
       </dependencies>
   </dependencyManagement>

启动类
在启动类上添加@EnableEurekaServer注解启动一个服务注册中心。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

配置文件

server:
  port: 1111

eureka:
  instance:
    hostname: localhost
  client:
    #是否向注册中心注册自己
    register-with-eureka: false
    #是否从注册中心查询服务
    fetch-registry: false
    service-url:
      # 通过改地址注册、发现服务
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

配置文件中添加了几个属性:

  • eureka.client.register-with-eureka: 由于该应用时注册中心,所以设置为false,表示不向注册中心注册自己。
  • eureka.client.fetch-registry: 由于注册中心的职责是维护服务实例,它并不需要去检索调用服务,所以也设置为false.

访问
完成上述的配置后,通过http://localhost:1111/ 便可看到Eureka信息面板:
在这里插入图片描述
其中Instances currently registered with Eureka面板为空,表示当前注册中心没有任何注册服务。

注册服务

在完成注册中心的搭建之后,接下来我们尝试搭建一个spring-boot应用,并将它加入到Eureka的服务治理体系去。
pom.xml

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
  </dependencies>

启动类
添加注解@EnableDiscoveryClient用于向注册中心注册服务。

@SpringBootApplication
@EnableDiscoveryClient
public class Client1Application {
    public static void main(String[] args) {
        SpringApplication.run(Client1Application.class, args);
    }
}

配置文件

server:
  port: 8080
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka/
spring:
  application:
    #### 注册到注册中心的应用名。不能带有 下划线
    name: cloud-eureka-client

启动
启动client后,会在Eureka注册中心看到注册信息。
在这里插入图片描述
编写HelloController

@RestController
public class HelloController {

    //注意,引入的包不要搞错
    @Autowired
    private org.springframework.cloud.client.discovery.DiscoveryClient discoveryClient;

    @Value("${spring.application.name}")
    private String appName;

    @RequestMapping("/hello")
    public String index() {
        List<ServiceInstance> instanceInfos = discoveryClient.getInstances(appName);
        instanceInfos.forEach(instanceInfo -> {
            System.out.println(instanceInfo.getInstanceId() +":"+instanceInfo.getServiceId());
        });
        return "hello world";
    }
}

通过http://localhost:8080/hello访问接口,后台打印如下日志:
在这里插入图片描述

高可用注册中心

在微服务架构中,需要充分考虑发生故障的情况,所以生产环境中必须对各个组件进行高可用部署,对微服务如此,对服务注册中心也一样。
Eureka Server的设计以爱是就考虑了高可用问题。在前面Eureka Server单节点的配置中,我们设置过下面两个参数,让注册中心不注册自己:

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

Eureka Server高可用实际上就是讲自己作为服务向其他注册中心注册自己,这样就形成了一组互相注册的服务注册中心,达到高可用的效果。
如下:

  • application-peer1.yml: 作为peer1服务中心的配置,并将serverUrl指向peer2:
server:
  port: 1111

eureka:
  instance:
    hostname: peer1
  client:
    service-url:
      defaultZone: http://peer2:1112/eureka/

  • application-peer2.yml: 作为peer2服务中心的配置,并将serverUrl指向peer1:
server:
  port: 1112

eureka:
  instance:
    hostname: peer2
  client:
    service-url:
      defaultZone: http://peer1:1111/eureka/

修改hosts文件:

127.0.0.1 peer1
127.0.0.1 peer2

分别使用如下命令,启动应用:
java -jar chap03-eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=peer1 java -jar chap03-eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=peer2
访问peer1,显示如下:
在这里插入图片描述

访问peer2,显示如下:
在这里插入图片描述

客户端注册到集群
在服务注册中心集群化后,服务提供方(客户端)需要简单修改一下配置才能将服务注册到Eureka Server集群中:

eureka:
  client:
    service-url:
      ### 多个以逗号分隔开
      defaultZone: http://peer1:1111/eureka/,http://peer2:1112/eureka/

通过上面的操作,我们实现了服务注册中心(高可用模式)的搭建。
以及将服务注册到注册中心。

服务发现与消费

本文之前的内容,提供了 服务注册中心以及服务提供者(“cloud-eureka-client”),下面我们尝试构建一个服务消费者,它主要完成两个目标:发现服务以及消费服务.

  • 发现服务:由 Eureka的客户端完成
  • 消费服务: 由Ribbon完成。

Ribbon
Ribbon是一个基于HTTP和TCP的客户端负载均衡器.它可以通过客户端中配置的服务端列表(ribbonServerList)去轮训访问以达到负载均衡的效果。
当Ribbon和Eureka联合使用时,ribbonServerList会被扩展成从Eureka中心获取服务端列表。同时它也将职责委托给Eureka来确定服务端是否已经启动。后续会有专门的文章来介绍。

下面我们通过构建一个简单的实例,来看看Eureka的服务治理体系下,是如何实现服务的发现与消费的。

  • 首先将Eureka Server 启动,并将hello-service 启动两个实例:
java -jar chap03-eureka-client-1.0-SNAPSHOT.jar --server.port=8080	
java -jar chap03-eureka-client-1.0-SNAPSHOT.jar --server.port=8090	

此时注册中心信息如下:
在这里插入图片描述

服务消费端(ribbo)
pom.xml
同client配置,需额外添加依赖


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

配置文件

server:
  port: 9000
eureka:
  client:
    service-url:
      ### 多个以逗号分隔开
      defaultZone: http://peer1:1111/eureka/,http://peer2:1112/eureka/
  instance:
    prefer-ip-address: true
spring:
  application:
    #### name 不能带有 下划线
    name: ribbon-client

启动类
注册 RestTemplate,并使用@LoadBalance注解,标注使用负载均衡。

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonClient1Application {
    public static void main(String[] args) {
        SpringApplication.run(RibbonClient1Application.class, args);
    }


    @Bean    
    //负载均衡
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

ConsumerController

@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/ribbon-consumer")
    public String consumer() {
    	//CLOUD-EUREKA-CLIENT 为服务提供方在Eureka中注册的应用名称。
        return restTemplate.getForEntity("http://CLOUD-EUREKA-CLIENT/hello",String.class).getBody();
    }
}

应用
通过http://localhost:9000/ribbon-consumer请求接口,多次请求,并观察两个hello-service的后台日志,可以发现两个节点都接收到了部分请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值