SpringCloud-Eureka


整体的架构图如下
在这里插入图片描述
项目链接 (最新git光出问题)

链接:https://pan.baidu.com/s/13e2Q8_fSzrX2UoQn35m7Xg 
提取码:ko20 

1. 简单的Eureka消费者调用生产者

父项目依赖

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

Eureka服务

依赖

   <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- SpringBoot整合eureka客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

application.yml

###服务端口号
server:
  port: 8100
###eureka 基本信息配置
eureka:
  instance:
    ###注册到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://localhost:8100/eureka
    ###因为自己是为注册中心,不需要自己注册自己
    register-with-eureka: false
    ###因为自己是为注册中心,不需要检索服务
    fetch-registry: false

启动类

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

输入localhost:8100 启动即可看到Eureka的界面

生产者一号
依赖

 <!-- 管理依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--SpringCloud eureka-server -->
        <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>
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

配置文件

###服务启动端口号
server:
  port: 8200
###服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-member
###服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8100/eureka
    ###因为该应用为客户端,需要注册自己
    register-with-eureka: true
    ###是否需要从eureka上获取注册信息
    fetch-registry: true

Controller

@RestController
public class ProductController {
    @Value("${server.port}")
    private String port;
    /**
     *  eureka的生产和消费者的简单调用
     * @return
     */
    @GetMapping("getIndex")
    public String getIndex(){
        return "hello eurka"+port;
    }
}

启动类

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

消费者一号
依赖

<!-- 管理依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <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>
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

配置文件

###服务启动端口号
server:
  port: 8300
###服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-order
###服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8100/eureka
    ###因为该应用为注册中心,不会注册自己
    register-with-eureka: true
    ###是否需要从eureka上获取注册信息
    fetch-registry: true

配置类

@Configuration
public class RestConfig {

    @Bean
    // 默认开启rubbin 负载均衡的,所以必须添加这个注解
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

调用类

@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    /**
     * eureka使用别名调用消费者
     * @return
     */
    @GetMapping("/getIndexFromProduct")
    public String getIndexFromProduct(){
        return restTemplate.getForObject("http://app-member:8200/getIndex", String.class);
    }
}

先启动Eureka服务然后启动生产者,最后启动消费者,访问localhost:8300/getIndexFromProduct 既可以看到消费的结果

2.Eureka的集群高可用

  1. 我们需要同Eureka服务,在创建一个Eurak服务,即A,B两个Eurak服务
  2. 在进行注册时候,我们需要把A注册到B, B注册到A当中
  3. 作为客户端,我们需要把注册的地址,同时注册到两个Eureka服务当中

改动文件

  1. Erueka 服务端改动

8500Eurak服务注册到 8100 Eurak服务当中,同理 8100注册到8500,同时作为自己被注册需要设置配置文件为true

###服务端口号
server:
  port: 8500
###eureka 基本信息配置
eureka:
  instance:
    ###注册到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:8100/eureka/
    ###因为自己是为注册中心搭建集群,不需要自己注册自己
    register-with-eureka: true
    ###因为自己是为注册中心,不需要检索服务
    fetch-registry: true
  1. 客户端改动
    同时注册到两个服务端当中
###服务启动端口号
server:
  port: 8300
###服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-itmayiedu-order1
###服务注册到eureka地址
eureka:
  client:
    service-url:
    ## 同时注册到两个服务端当中
      defaultZone:  http://localhost:8100/eureka,http://localhost:8500/eureka
    ###因为该应用为注册中心,不会注册自己
    register-with-eureka: true
    ###是否需要从eureka上获取注册信息
    fetch-registry: true

3.Eureka的自我保护机制

当我们启动Eureka 的时候,我们会这个红字,翻译一下是这个意思

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 可能不正确地声称实例在不在的情况下出现。续订小于阈值,因此不会为了安全而过期实例。
在这里插入图片描述
1. Eureka自我保护的产生原因:

Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。
我们在单机测试的时候很容易满足心跳失败比例在 15 分钟之内低于 85%,这个时候就会触发 Eureka 的保护机制,一旦开启了保护机制
解决办法

2. 要注意什么时候剔除和什么时候不剔除搞清楚
在这里插入图片描述
3. 什么时候开启服务保护机制呢?

在本地开发环境中,建议禁止自我保护j值
在生产环境中,建议开启自我保护

4. 如何关闭自我保护
服务端

###服务端口号
server:
  port: 8100
###eureka 基本信息配置
eureka:
  instance:
    ###注册到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://localhost:8500/eureka
    ###因为自己是为注册中心,不需要自己注册自己
    register-with-eureka: true
    ###因为自己是为注册中心,不需要检索服务
    fetch-registry: true
    server:
      ### 设为false,关闭自我保护
      enable-self-preservation: false
      ### # 清理间隔(单位毫秒,默认是60*1000)
      eviction-interval-timer-in-ms: 60

客户端

###服务启动端口号
server:
  port: 8300
###服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-itmayiedu-order1
###服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8100/eureka,http://localhost:8500/eureka
    ###因为该应用为注册中心,不会注册自己
    register-with-eureka: true
    ###是否需要从eureka上获取注册信息
    fetch-registry: true
  instance:
    ###eureka客户端在收到最后一次心跳之后的等待上限,单位为秒(默认90秒)
    lease-expiration-duration-in-seconds: 30
    ###eureka客户端向服务端发送心跳时间间隔,单位为秒(默认30秒)
    lease-renewal-interval-in-seconds: 15

4.使用Zookeper代替Eureka

注意因为是Zookeper代替Eureka,所以以前咱们创建Eureka就不用启动

Zookeper链接:https://pan.baidu.com/s/16OhFXOAPgHL36N6Ghqaggg 
提取码:ojsb

(下面的改动为生产者,具体消费者的改动也和生产者一直,需要注意的就是别名的问题,需要变动)
改动文件
1.依赖
需要注意的是,Eureka的依赖不能和Zk的依赖共存,不然会报错的

   <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        SpringCloud eureka-server-->
<!--        <dependency>-->
<!--        <groupId>org.springframework.cloud</groupId>-->
<!--        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
<!--    </dependency>-->
        <!--SpringCloud Zookeper-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>
    </dependencies>
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

2.修改配置文件

###zk的配置信息
server:
  port: 8003
###服务别名----服务注册到注册中心名称
spring:
  application:
    name: zk-order
  cloud:
    zookeeper:
      connect-string: 127.0.0.1:2181

3.启动类

@SpringBootApplication
//zk,和consul 代替erueka使用的注解
@EnableDiscoveryClient
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}

5.使用Consul替换Eureka

Consul软件以及搭建  链接:https://pan.baidu.com/s/1U9Z5LKnPvPVtVAj3VVFKTg 
提取码:d41l 

文件改动
1.依赖

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
	</parent>
	<!-- 管理依赖 -->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.M7</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<!-- SpringBoot整合Web组件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--SpringCloud consul-server -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
	</dependencies>
	<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/libs-milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

2.配置文件

###eureka 服务端口号
server:
  port: 8502
spring:
  application:
    name: consul-order
####consul注册中心地址
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        hostname: 192.168.18.220

3.启动类

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

6.discoveryClient的具体用法

DiscoveryClient 他可以根据注册中心的别名信息,获取具体的实例

@RestController
public class OrderApiController {

	@Autowired
	private RestTemplate restTemplate;
	@Autowired
	private DiscoveryClient discoveryClient;

	public String getServiceUrl(String name) {
		List<ServiceInstance> list = discoveryClient.getInstances(name);
		if (list != null && !list.isEmpty()) {
			return list.get(0).getUri().toString();
		}
		return null;
	}
}

7.Zk和Eureka的区别在哪里

著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。

3.1 Zookeeper保证CP
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

3.2 Eureka保证AP
Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

  1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
  2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
  3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

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

8.Nging和Ribbon的区别

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值