zoukankan      html  css  js  c++  java
  • springcloud Eureka 服务注册与发现

    1、Eureka是什么

    Eureka是Netflix的一个子模块,也是核心模块之一。
    Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
    服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。
    功能类似于dubbo的注册中心,比如Zookeeper。

    2、Eureka基本架构

    Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。

    Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。

    而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。
    这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
    SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。



    3、构建步骤

    3.1 服务注册中心


    pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
     
      <parent>
       <groupId>com.atguigu.springcloud</groupId>
       <artifactId>microservicecloud</artifactId>
       <version>0.0.1-SNAPSHOT</version>
      </parent>
     
      <artifactId>microservicecloud-eureka-7001</artifactId>
     
      <dependencies>
       <!--eureka-server服务端 -->
       <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-eureka-server</artifactId>
       </dependency>
       <!-- 修改后立即生效,热部署 -->
       <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>springloaded</artifactId>
       </dependency>
       <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
       </dependency>
      </dependencies>
     
    </project>
    
    
    application.yml
     
    server: 
      port: 7001
     
    eureka:
      instance:
        hostname: localhost #eureka服务端的实例名称
      client:
        register-with-eureka: false #false表示不向注册中心注册自己。
        fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/        #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
    
    App主启动类
    package com.atguigu.springcloud;
     
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
     
    @SpringBootApplication
    @EnableEurekaServer//EurekaServer服务器端启动类,接受其它微服务注册进来
    public class EurekaServer7001_App
    {
      public static void main(String[] args)
      {
       SpringApplication.run(EurekaServer7001_App.class, args);
      }
    }
     
     
    
    

    启动

    3.2、将已有的部门服务注册进Eureka服务中心

    修改部门服务8001pom.xml


    修改application.yml

    修改主启动类
    @EnableEurekaClient //本服务启动后会自动注册进eureka服务中


    3.3、actuator与注册微服务完善、主机映射名称修改

    修改application.yml
    instance:
        instance-id: microservicecloud-dept8001
    
    

    更改IP显示
     instance:
        instance-id: microservicecloud-dept8001   #自定义服务名称信息
        prefer-ip-address: true     #访问路径可以显示IP地址
    
    微服务Info内容详解


    8001pom.xml

    <!-- actuator监控信息完善 -->
    
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    总的父工程pom.xml修改

    <build>
       <finalName>microservicecloud</finalName>
       <resources>
         <resource>
           <directory>src/main/resources</directory>
           <filtering>true</filtering>
         </resource>
       </resources>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
           <configuration>
             <delimiters>
              <delimit>$</delimit>
             </delimiters>
           </configuration>
         </plugin>
       </plugins>
      </build>
    
    

    修改8001application.yml

    info:
      app.name: atguigu-microservicecloud
      company.name: www.atguigu.com
      build.artifactId: $project.artifactId$
      build.version: $project.version$
    
    

    3.4、Eureka的自我保护机制


    什么是自我保护模式?

    默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

    在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着

    综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

    在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保护模式。

    3.5、服务发现

    8001controller修改
    @Autowired
    private DiscoveryClient client;
    ......
    //	@Autowired
    //	private DiscoveryClient client;
    	@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
    	public Object discovery()
    	{
    		List<String> list = client.getServices();
    		System.out.println("**********" + list);
    
    		List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
    		for (ServiceInstance element : srvList) {
    			System.out.println(element.getServiceId() + "	" + element.getHost() + "	" + element.getPort() + "	"
    					+ element.getUri());
    		}
    		return this.client;
    	}
    
    8001主启动类
    @SpringBootApplication
    @EnableEurekaClient //本服务启动后会自动注册进eureka服务中
    @EnableDiscoveryClient //服务发现
    public class DeptProvider8001_App
    {
    	public static void main(String[] args)
    	{
    		SpringApplication.run(DeptProvider8001_App.class, args);
    	}
    }
    
    

    消费者80Controller修改
    	//private static final String REST_URL_PREFIX = "http://localhost:8001";
    	private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
    
    	/**
    	 * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
    	 * ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
    	 */
    ......
    // 测试@EnableDiscoveryClient,消费端可以调用服务发现
    	@RequestMapping(value = "/consumer/dept/discovery")
    	public Object discovery()
    	{
    		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
    	}
    
    

    完整代码

    @RestController
    public class DeptController_Consumer
    {
    
    	//private static final String REST_URL_PREFIX = "http://localhost:8001";
    	private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
    
    	/**
    	 * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
    	 * ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
    	 */
    	@Autowired
    	private RestTemplate restTemplate;
    
    	@RequestMapping(value = "/consumer/dept/add")
    	public boolean add(Dept dept)
    	{
    		return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
    	}
    
    	@RequestMapping(value = "/consumer/dept/get/{id}")
    	public Dept get(@PathVariable("id") Long id)
    	{
    		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
    	}
    
    	@SuppressWarnings("unchecked")
    	@RequestMapping(value = "/consumer/dept/list")
    	public List<Dept> list()
    	{
    		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
    	}
    
    	// 测试@EnableDiscoveryClient,消费端可以调用服务发现
    	@RequestMapping(value = "/consumer/dept/discovery")
    	public Object discovery()
    	{
    		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
    	}
    
    }
    
    


    3.6、Eureka集群配置

    新建工程7002,7003


    修改7002,7003pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>com.atguigu.springcloud</groupId>
    		<artifactId>microservicecloud</artifactId>
    		<version>0.0.1-SNAPSHOT</version>
    	</parent>
    	<artifactId>microservicecloud-eureka-7002</artifactId>
    
    
    	<dependencies>
    		<!--eureka-server服务端 -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-eureka-server</artifactId>
    		</dependency>
    		<!-- 修改后立即生效,热部署 -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>springloaded</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-devtools</artifactId>
    		</dependency>
    	</dependencies>
    
    </project>
      
    
    修改7002,7003 主启动类
    @SpringBootApplication
    @EnableEurekaServer // EurekaServer服务器端启动类,接受其它微服务注册进来
    public class EurekaServer7002_App
    {
    	public static void main(String[] args)
    	{
    		SpringApplication.run(EurekaServer7002_App.class, args);
    	}
    }
    
    修改host文件

    3台Eureka的yml文件配置
    server: 
      port: 7001
     
    eureka: 
      instance:
        hostname: eureka7001.com #eureka服务端的实例名称
      client: 
        register-with-eureka: false     #false表示不向注册中心注册自己。
        fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        service-url: 
          #单机 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/       #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    

    8001修改yml配置

    eureka:
      client: #客户端注册进eureka服务列表内
        service-url: 
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      instance:
        instance-id: microservicecloud-dept8002   #自定义服务名称信息
        prefer-ip-address: true     #访问路径可以显示IP地址
    




    3.7、Eureka比Zookeeper好在哪里







  • 相关阅读:
    KVC的取值和赋值
    OC中属性的内存管理
    mysql的通信协议
    Proactor模式&Reactor模式详解
    Linux异步IO学习
    Redis 分布式锁的实现原理
    redis过期键
    智能指针
    std::unique_lock与std::lock_guard
    手撕代码
  • 原文地址:https://www.cnblogs.com/xidianzxm/p/12410610.html
Copyright © 2011-2022 走看看