SpringCloud微服务学习之Eureka服务治理

本文介绍了微服务的优势和挑战,包括快速响应变更、独立扩展等优点,以及复杂的部署结构和分布式问题等缺点。接着探讨了CAP定理,解释了一致性、可用性和分区容错性的权衡。详细阐述了服务治理中的Eureka实现,包括服务注册、发现、心跳检测和服务剔除,并通过实例展示了如何创建Eureka服务器、服务提供者和消费者。最后讨论了服务心跳、注册中心高可用方案以及配置细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微服务学习
一、微服务的优点

  1. 快速响应变更:单一职责,独立部署
  2. 精粒度业务控制:降级熔断,局部限流
  3. 独立扩展:边界清晰,不过度受制于技术栈
  4. 面向业务/领域模型:不依赖数据模型,易于抽象

二、微服务的缺点

  1. 部署结构复杂:模块众多,一堆额外组件
  2. 依赖平台支撑:依赖微服务组件,研发成本
  3. 分布式问题:一致性,异常补偿
  4. 拆分水平:粒度过程/过细

三、分布式系统CAP定理

  1. C:一致性
    强一致性:一次更新终身有效
    弱一致性:更新过后,一部分或者全部请求都拿不到数据
    最终一致性:经过一定的时间以后,所有数据保持一直
  2. A:可用性
  3. P:分区容错性
  4. CAP大定理:分布式系统只能三选二,不能全占

服务治理
一、Eureka

  1. 服务治理的伟大目标:高可用性、分布式调用、生命周期管理、健康度检查
  2. 服务注册 - 服务提供方自报家门
    服务发现 - 服务消费者拉取注册数据
    心跳检测,服务续约
    服务剔除 一套由服务提供方和注册中心配合完成的去伪存真的过程
    服务下线 - 服务提供方发起主动下线
  3. 服务治理三大门派:Consul、Eureka、Nacos
    在这里插入图片描述
  4. 服务注册是为了解决Who are you这个问题,即获取所有服务节点的身份信息和服务名称,从注册中心的角度来说我们有以下两种比较直观的解决方案:
    三顾茅庐 由注册中心主动访问网络节点中所有机器
    等待戈多 注册中心坐等服务节点上门注册
  5. 注册中心的日常任务:当我期盼的戈多到来了以后,他会告诉关于他的三件事情
     他会的技能(所提供的微服务是什么,比如“洗剪吹”)
     他住在哪里(IP地址+端口)
     他的状态(通常注册完成时的服务状态就是UP)
    在等待戈多的过程中,其实这两位流浪汉也没有那么闲,他在空余时间还是干了两件微小的事:
     心跳检测和服务剔除 已经注册过的戈多们,会时不时来跟我打声招呼(心跳检测),如果隔段时间没见着他们了,我就只好从注册名单中把他们删除(服务剔除)。
     注册信息同步 我们两个流浪汉分别接待不同的戈多,有的戈多在我这里注册,没有在他那里注册。我抽空就会把我这里的戈多名单和他做分享。

创建服务注册中心

  1. 创建项目
    spring-clound-demo下的eureka文件中创建eureka-server
    在这里插入图片描述

  2. 修改spring-clound-demo的pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<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>

    <groupId>com.cmy</groupId>
    <artifactId>spring-clound-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-server</module>
    </modules>

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

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.1.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  1. 修改eurka-server项目的pom.xml
 <?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>spring-clound-demo</artifactId>
        <groupId>com.cmy</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <packaging>jar</packaging>

    <artifactId>eureka-server</artifactId>

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

</project>
  1. 创建启动类EurekaServerApplication
/**
 * @Auther: chenmy
 * @Date: 2021/05/17/23:10
 * @Description:
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaServerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}
我们在启动类上加了一个 @EnableEurekaServer 注解,Spring Cloud 中,包含 @EnableEurekaServer 注解的服务意味着就是一个 Eureka 服务器组件
  1. 创建配置文件application.properties
spring.application.name=eureka-server

server.port=20000

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

6.启动项目访问
在这里插入图片描述
成功了!!!

注册服务提供方

  1. 创建项目eureka-client
    在这里插入图片描述
  2. 修改pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>spring-clound-demo</artifactId>
        <groupId>com.cmy</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>eureka-client</artifactId>

    <name>eureka-client</name>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
  1. 创建启动类
 package com.cmy.springclound;


import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @Auther: chenmy
 * @Date: 2021/05/18/1:34
 * @Description:
 */
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaClientApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }

}
  1. 控制层
package com.cmy.springclound;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Auther: chenmy
 * @Date: 2021/05/18/1:37
 * @Description:
 */
@RestController
@Slf4j
public class Controller {

    @Value("${server.port}")
    private String port;

    @GetMapping("/sayHi")
    private String sayHi(){
        return "This is"+port;
    }

    @PostMapping("/sayHi")
    public Friend sayHiPost(@RequestBody Friend friend) {
        log.info("You are " + friend.getName());
        friend.setPort(port);
        return friend;
    }
}
  1. 其他类
package com.cmy.springclound;

import lombok.Data;

/**
 * @Auther: chenmy
 * @Date: 2021/05/18/1:39
 * @Description:
 */
@Data
public class Friend {

    private  String name;

    private String port;
}
  1. 配置文件
spring.application.name=eureka-client

server.port=3000

eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
  1. 启动访问即可
    在这里插入图片描述
    创建服务消费者

  2. 创建项目eureka-consumer 在这里插入图片描述

  3. 修改pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>spring-clound-demo</artifactId>
        <groupId>com.cmy</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-consumer</artifactId>
    <packaging>jar</packaging>
    <name>eureka-consumer</name>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 创建启动类
package com.cmy.springclound;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @Auther: chenmy
 * @Date: 2021/05/18/22:35
 * @Description:
 */
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaConsumerApplication {
    @Bean
    public RestTemplate register() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaConsumerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

  1. 控制层类
package com.cmy.springclound;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Auther: chenmy
 * @Date: 2021/05/18/22:35
 * @Description:
 */
@RestController
@Slf4j
public class Controller {

    @Autowired
    private LoadBalancerClient client;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/hello")
    public String hello() {
        ServiceInstance instance = client.choose("eureka-client");

        if (instance == null) {
            return "No available instances";
        }

        String target = String.format("http://%s:%s/sayHi",
                instance.getHost(),
                instance.getPort());
        log.info("url is {}", target);

        return restTemplate.getForObject(target, String.class);
    }

    @PostMapping("/hello")
    public Friend helloPost() {
        ServiceInstance instance = client.choose("eureka-client");

        if (instance == null) {
            return null;
        }

        String target = String.format("http://%s:%s/sayHi",
                instance.getHost(),
                instance.getPort());
        log.info("url is {}", target);

        Friend friend = new Friend();
        friend.setName("Eureka Consumer");

        return restTemplate.postForObject(target, friend, Friend.class);
    }
}

  1. 实体类
package com.cmy.springclound;

import lombok.Data;

@Data
public class Friend {

    private String name;

    private String port;

}
  1. 配置文件
spring.application.name=eureka-consumer

server.port=31000

eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
  1. 启动前面的三个项目访问如图
    在这里插入图片描述

服务心跳
在这里插入图片描述

启用心跳检测
1.在eureka-client的配置文件中添加以下配置

# 每隔5秒钟,向服务中心发送一条续约指令
 eureka.instance.lease-renewal-interval-in-seconds=5

# 如果30秒内,依然没有收到续约请求,判定服务过期(上西天)
 eureka.instance.lease-expiration-duration-in-seconds=30
  1. 在eureka-server的配置文件中添加以下配置
# 强制关闭服务自保(自动开关不起作用)
eureka.server.enable-self-preservation=false

# 每隔多久触发一次服务剔除
eureka.server.eviction-interval-timer-in-ms=10000
  1. 启动服务隔一会就会发现服务被剔除了

注册中心的高可用方案

  1. 搭建两个注册中心
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值