SpringCloud nine, eureka self-protection mechanism of introduction, service discovery eureka, eureka cluster configuration, where eureka than the zookeeper good news.

①eureka self-protection mechanism introduced.

Symptom:

 

Currently:

 

 

Yml changes at the contents of the file:

Then yml files changed back. Note yml files all have a space after the colon! Did not write content, such as sping: behind must leave a space.

 

Bottom line: a certain time a service is not available the micro, eureka not clean up immediately, will still save the information service of the micro.

What is the eureka self-protection mode?

By default, if a heartbeat is not received EurekaServer a widget service instance within a certain time, the cancellation will EurekaServer instance (default 90 seconds). But when the network partition failure, between micro and EurekaServer service can not communicate, above behaviors may become very dangerous - because micro service itself is actually healthy, then this should not be written off this micro-services. Eureka to solve this problem through the "limp home mode" - when EurekaServer node losing too much in a short time a client (network partition failure may have occurred), then the node goes into self-preservation mode. Once in this mode, EurekaServer will protect the information service in the registry, delete data no longer service registry (which is not written off any micro-services). When the network fault recovery, the Eureka Server node will automatically exit the self-protection mode.
 

In the self-protection mode, Eureka Server service will protect the information in the registry, no cancellation of any service instance. When it receives the heart rate restored to above the threshold, the Eureka Server node will automatically exit the self-protection mode. Its design philosophy is rather reserved the wrong service registration information, do not blindly write off any possible health service instance. Sentence to explain: Live Is Better Than To Die
 

In summary, the self-protection mode is a security measure to respond to network anomalies. Its architecture is rather philosophy while retaining all micro-services (health services and unhealthy micro-micro services will be kept), nor blindly cancellation of any healthy micro-services. Use self-protection mode, allowing Eureka clusters more robust and stable.
 

 

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

在7001,eureka server端的yml文件中加eureka.server.enable-self-preservation = false,即可禁用自我保护机制,但是并不推荐使用。

自我保护机制的内容:

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

②eureka的服务发现。

microservicecloud-provider-dept-8001服务发现Discovery

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息

第一步:修改microservicecloud-provider-dept-8001工程的DeptController.java类。

增加的内容是:

 @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() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
         + element.getUri());
    }
    return this.client;
  }

DeptController.java最后更改后全部的内容是:

package com.lss.springcloud.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.lss.springcloud.entities.Dept;
import com.lss.springcloud.service.DeptService;

@RestController
public class DeptController {

	@Autowired
	private DeptService service;

	@Autowired
	private DiscoveryClient client;

	@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
	public boolean add(@RequestBody Dept dept) {
		return service.add(dept);
	}

	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	public Dept get(@PathVariable("id") Long id) {
		return service.get(id);
	}

	@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
	public List<Dept> list() {
		return service.list();
	}

	@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
	public Object discovery() {
		//盘点eureka里面的微服务有哪些。
		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() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
					+ element.getUri());
		}
		return this.client;
	}

}

第二步:修改DeptProvider8001_App主启动类。

增加新注释:@EnableDiscoveryClient 

DeptProvider8001_App.java的全部内容是:

 
@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient //服务发现
public class DeptProvider8001_App
{
  public static void main(String[] args)
  {
   SpringApplication.run(DeptProvider8001_App.class, args);
  }
}
 

第三步:自测:

先要启动Eureka  Server,即先启动7001

再启动服务提供者,DeptProvider8001_App主启动类,需要稍等一会儿,等的是让服务提供者入驻eureka注册中心。

浏览器输入:http://localhost:8001/dept/discovery

 

第四步:修改microservicecloud-consumer-dept-80工程的DeptController_Consumer.java的内容。

DeptController_Consumer.java增加的内容是:


	// 测试@EnableDiscoveryClient,消费端可以调用服务发现
	@RequestMapping(value = "/consumer/dept/discovery")
	public Object discovery() {
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
	}

DeptController_Consumer.java的全部内容是:

package com.lss.springcloud.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.lss.springcloud.entities.Dept;

@RestController
public class DeptController_Consumer {

	private static final String REST_URL_PREFIX = "http://localhost:8001";

	@Autowired
	private RestTemplate restTemplate;

	/*
	 * 使用: 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
	 * ResponseBean.class)这三个参数分别代表  REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
	 */
	@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);
	}

}

第五步:测试消费者。

先启动eureka server 微服务。即7001端口。

再启动服务提供者微服务,即8001端口。

最后启动服务消费者微服务,即80端口。

浏览器地址栏输入:http://localhost/consumer/dept/discovery

③eureka集群配置。

什么是集群:在不同的机器上(节点上)(服务器上)配置相同的服务,对外做一个超大运算的整体。

eureka集群的原理说明:

基本原理
上图是来自eureka的官方架构图,这是基于集群配置的eureka; 
- 处于不同节点的eureka通过Replicate进行数据同步 
- Application Service为服务提供者 
- Application Client为服务消费者 
- Make Remote Call完成一次服务调用
 

 

服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。

当服务注册中心Eureka Server检测到服务提供者因为宕机、网络原因不可用时,则在服务注册中心将服务置为DOWN状态,并把当前服务提供者状态向订阅者发布,订阅过的服务消费者更新本地缓存。

服务提供者在启动后,周期性(默认30秒)向Eureka Server发送心跳,以证明当前服务是可用状态。Eureka Server在一定的时间(默认90秒)未收到客户端的心跳,则认为服务宕机,注销该实例。

 

第一步:新建microservicecloud-eureka-7002/microservicecloud-eureka-7003两个eureka  server 的子工程(module工程)

 

 

 

第二步:按照7001为模板粘贴POM。

需要复制的pom内容是:

 <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>

 

microservicecloud-eureka-7002的pom完整内容是:

<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.lss.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>

microservicecloud-eureka-7003的pom完整内容是:

<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.lss.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>microservicecloud-eureka-7003</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>

 

然后分别update一下。

 

第三步:修改7002和7003的主启动类。

 

 

 

 

 

 

第四步:修改域名映射配置。

找到C:\Windows\System32\drivers\etc路径下的hosts文件。

修改映射配置添加进hosts文件。

127.0.0.1 eureka7001.com      中间只能有一个空格才有效。

127.0.0.1 eureka7002.com      中间只能有一个空格才有效。

127.0.0.1 eureka7003.com      中间只能有一个空格才有效。

127.0.0.1  eureka7003.com  像这样,有两个空格,则无效。

中间只能有一个空格才有效。

第五步:3台eureka服务器的yml配置

7001的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/
      

7002的yml的全部内容:

server: 
  port: 7002

eureka: 
  instance:
    hostname: eureka7002.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://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

7003的yml全部内容:

server: 
  port: 7003

eureka: 
  instance:
    hostname: eureka7003.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://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

 

第六步:microservicecloud-provider-dept-8001微服务发布到上面3台eureka集群配置中。

修改microservicecloud-provider-dept-8001微服务,服务提供者,的yml文件。

yml文件修改的内容:

eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

microservicecloud-provider-dept-8001微服务的yml文件修改后的全部内容是:

server:
  port: 8001
  
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件
    
spring:
   application:
    name: microservicecloud-dept 
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/clouddb01              # 数据库名称
    username: root
    password: lss19881218
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                  # 等待连接获取的最大超时时间

 
eureka:
  client:
    service-url: 
       defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: microservicecloud-dept8001
    prefer-ip-address: true 
   
info: 
  app.name: lss-microservicecloud
  company.name: www.lss.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

  

第七步:测试。

启动eureka server 7001  7002   7003

再启动8001 服务提供者

再启动80    服务消费者

 

然年分别看7002和7003,发现分别牵着另外两边。

7002牵着7001和7003

7003牵着7001和7002

 

 

 

④eureka比zookeeper好在哪里。

作为服务注册中心,Eureka比Zookeeper好在哪里?

Netflix在设计Eureka时遵守的就是AP原则。

RDBMS(Relational Database Management System)(传统的)关系型数据库管理系统。如:mysql、Oracle、sqlserver等。有一个最重要的概念ACID。事务管理(ACID)。

谈到事务一般都是以下四点

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
 

 

NOSQL,如:mongdb、redis等。有一个重要的概念:CAP。CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency((强)一致性)、 Availability((高)可用性)、Partition tolerance(分区容错性),三者不可得兼。任何一个分布式系统,按照目前的理论要求,只能三个里面进两个。最多只能较好的满足两个。

而且对于分布式的系统,P(Partition tolerance(分区容错性))是一定要占有的。所以对于分布式系统,较好情况下,只能选择CP或者AP其中一种。

CAP的3进2。

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。

而由于当前的网络硬件肯定会出现延迟丢包等问题,所以

分区容忍性是我们必须需要实现的。

所以我们只能在一致性和可用性之间进行权衡。没有NOSQL系统能同时保证这三点。

 

 

 

 

如果问:eureka和zookeeper的区别在哪里?第一个关键点是:

eureka遵守AP( Availability(高可用性)、Partition tolerance(分区容错性)),zookeeper遵守CP(Consistency(强一致性)、Partition tolerance(分区容错性))。

作为服务注册中心,Eureka比Zookeeper好在哪里
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。
因此
Zookeeper保证的是CP,
Eureka则是AP。
 
4.1 Zookeeper保证CP
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。
 
4.2 Eureka保证AP
Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况: 
1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务 
2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用) 
3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
 
因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪

发布了130 篇原创文章 · 获赞 1 · 访问量 6520

Guess you like

Origin blog.csdn.net/lbh19630726/article/details/104074946