Spring Cloud NetFlix

文章目录

  • Spring Cloud
  • 1 介绍
  • 2 Eureka(服务注册与发现)
    • 2.1 介绍
    • 2.2 服务注册与发现示例
      • 2.2.1 Eureka Server:springcloud-eureka
      • 2.2.2 Eureka Client:springcloud-provider
      • 2.2.3 Eureka Client:springcloud-consumer
    • 2.3 Eureka主从
  • 3 Ribbon(负载均衡)
    • 3.1 介绍
    • 3.2 负载均衡策略
    • 3.3 负载均衡示例
      • 3.3.1 Eureka Server:springcloud-eureka
      • 3.3.2 Eureka Client:springcloud-provider1
      • 3.3.3 Eureka Client:springcloud-provider2
      • 3.3.4 Eureka Client:springcloud-consumer
  • 4 Hystrix(熔断器)
    • 4.1 介绍
    • 4.2 熔断示例
      • 4.2.1 Eureka Server:springcloud-eureka
      • 4.2.2 Eureka Client:springcloud-provider
      • 4.2.3 Eureka Client:springcloud-consumer
      • 4.2.2 Eureka Client:springcloud-dashboard
  • 5 Feign(声明式服务调用)
    • 5.1 介绍
    • 5.2 示例
      • 5.2.1 Eureka Server:springcloud-eureka
      • 5.2.2 Eureka Client:springcloud-feign-provider
      • 5.2.3 Eureka Client:springcloud-feign-consumer
  • 6 Zuul(API网关)
    • 6.1 介绍
    • 6.2 示例
      • 6.2.1 Eureka Server:springcloud-eureka
      • 6.2.2 Eureka Client:springcloud-zuul-provider
      • 6.2.3 Eureka Client:springcloud-zuul-gateway
      • 6.2.4 Eureka Client:springcloud-zuul-consumer

Spring Cloud

1 介绍

Spring Cloud是一套用于构建分布式系统的框架,它基于Spring Boot提供了一系列工具和库,用于快速开发具有弹性、可伸缩、分布式特性的微服务应用。Spring Cloud提供了众多功能,包括服务注册与发现、配置中心、负载均衡、断路器、网关等,帮助开发者轻松构建和管理微服务架构。

以下是一些Spring Cloud的核心组件和功能:

  1. Eureka(服务注册与发现): Eureka是Spring Cloud的服务注册与发现组件,允许服务注册和发现。服务提供者在启动时向Eureka注册自己,而服务消费者可以从Eureka中获取注册的服务列表,从而实现服务的动态发现。

  2. Ribbon(负载均衡): Ribbon是一个客户端负载均衡器,可以与Eureka等服务注册中心集成,实现对微服务的负载均衡。

  3. Feign(声明式服务调用): Feign是一个声明式的Web服务客户端,可以更轻松地实现服务之间的调用。通过使用注解,开发者可以定义接口,并在接口中使用注解来描述服务的调用方式,而Feign会根据这些注解自动生成具体的实现。

  4. Hystrix(熔断器): Hystrix是一个用于处理延迟和容错的库,它提供了熔断、隔离、Fallback等功能,保护分布式系统在高负载和故障情况下的稳定性。

  5. Zuul(API网关): Zuul是一个API网关服务,用于提供统一的入口和出口,实现路由、负载均衡、认证、监控等功能。

  6. Config(配置中心): Config组件用于实现分布式系统中的外部化配置,可以将配置信息存储在远程仓库中,实现配置的集中管理。

  7. Bus(消息总线): Spring Cloud Bus通过消息代理将分布式系统的节点连接在一起,支持动态刷新配置、传播状态变化等功能。

  8. Spring Cloud Stream(消息驱动): Spring Cloud Stream是一个用于构建消息驱动的微服务的框架,提供了简化消息通信的抽象。

这些组件和功能使得开发者能够更方便地构建和管理微服务架构,提供了一系列解决方案,用于应对分布式系统中的常见问题。Spring Cloud的设计理念是构建弹性、可伸缩、分布式的微服务架构,使得开发者能够更专注于业务逻辑的实现而不用过多关注底层的分布式系统细节。

2 Eureka(服务注册与发现)

2.1 介绍

Eureka是Spring Cloud中的一个服务注册与发现组件,它的主要功能是帮助微服务架构中的服务实现自动注册与发现。通过Eureka,服务提供者可以向注册中心注册自己的服务,并且服务消费者可以从注册中心获取服务提供者的信息,实现动态的服务发现。

以下是Eureka的一些主要特点和概念:

  1. 服务注册: 微服务在启动时会向Eureka Server注册自己的信息,包括服务名、IP地址、端口等。

  2. 服务发现: 微服务在运行时可以通过向Eureka Server发送请求来获取已注册的服务列表。服务消费者可以从注册中心中获取服务提供者的信息,从而实现动态的服务发现。

  3. 服务治理: Eureka通过定期发送心跳检测服务的可用性,并在一段时间内没有收到心跳时将服务标记为不可用。这有助于实现服务的自动下线和服务的高可用性。

  4. 区域和可用性区分: Eureka支持将服务注册到不同的区域(Region)和可用性区域(Availability Zone)。这对于构建分布式系统的多区域部署提供了支持。

  5. 自我保护机制: Eureka具有自我保护机制,当Eureka Server节点在一段时间内没有收到某个服务的心跳时,它会保护该服务,不会立即剔除,防止因为网络等原因造成的误剔除。

  6. Eureka Client: Eureka提供了Eureka Client库,使得微服务能够方便地与Eureka Server交互,实现服务注册和发现。

在Spring Cloud中使用Eureka通常涉及以下几个关键配置:

Eureka Server 配置:

server:
  port: 8761

spring:
  application:
    name: service-name

eureka:
  client:
    register-with-eureka: false	#告知注册中心 你不能向你自己注册
    fetch-registry: false	#主要作用是维护服务,不是检索服务
    service-url:
      defaultZone: http://localhost:8761/eureka/

Eureka Client 配置:

server:
  port: 8762

spring:
  application:
    name: service-name
    
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/	#注册中心的地址

2.2 服务注册与发现示例

2.2.1 Eureka Server:springcloud-eureka

添加依赖

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

配置 application.properties

server.port=9100
spring.application.name=eureka-server
#设置注册中心
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#注册中心的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

@SpringBootApplication
@EnableEurekaServer //启动eureka
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

启动应用,访问http://localhost:9100,将看到Eureka Server的控制台页面:
在这里插入图片描述

2.2.2 Eureka Client:springcloud-provider

添加依赖

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

配置 application.properties

server.port=8083
spring.application.name=server-provider
eureka.client.service-url.defaultZone=http://localhost:9100/eureka

启动类

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

编写TestController

@RestController
public class TestController {
    @RequestMapping("/test")
    public String test(){
        return "使用了Eureka注册中心的服务提供者!";
    }
}

启动应用,刷新http://localhost:9100,可以看到Eureka Server的控制台页面:
在这里插入图片描述
此时,已经将服务注册到注册中心。

2.2.3 Eureka Client:springcloud-consumer

添加依赖

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

配置 application.properties

server.port=8084
spring.application.name=server-consumer
eureka.client.service-url.defaultZone=http://localhost:9100/eureka

启动类

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

编写 RestTemplateConfig

@Configuration
public class RestTemplateConfig {
    /**
     *     LoadBalanced  标记 restTemplate使用 ribbon 的  负载均衡策略访问服务的提供者
     *      使用了 Eureka注册中心后   restTemplate 对象上方必须添加该注解
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

编写 TestController

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test(){
        ResponseEntity<String> result = restTemplate.getForEntity("http://SERVER-PROVIDER/test", String.class);
        return result.getBody();
    }
}

启动应用,刷新http://localhost:9100,可以看到Eureka Server的控制台页面:
在这里插入图片描述
再访问 http://localhost:8084/test,得到结果:
在这里插入图片描述
这说明,consumer 通过注册中心获取服务提供者的信息。

2.3 Eureka主从

在Eureka中,没有官方定义的“主从”概念,因为Eureka本身是为了构建高可用的服务注册和发现系统而设计的。Eureka Server之间通过互相注册为对方的客户端来实现高可用性。每个Eureka Server都包含了完整的服务实例信息,因此可以独立运行。

如果想要搭建一个具备高可用性的Eureka集群,可以简单地在多个地点启动Eureka Server实例,并将它们互相注册为对方的客户端。这样,每个Eureka Server都包含了完整的服务实例信息,客户端在向任何一个Eureka Server注册服务时,这个信息会被同步到集群中的其他Eureka Server。

以下是一个简单的示例,演示了如何在两个Eureka Server之间实现互相注册:

在 C:\Windows\System32\drivers\etc\hosts 文件中进行ip地址映射,修改内容如下 :

127.0.0.1 eureka9100
127.0.0.1 eureka9200

  1. Eureka Server1配置:

    server.port=9100
    
    spring.application.name=eureka9100
    
    eureka.instance.hostname=localhost
    
    eureka.client.register-with-eureka=false
    
    eureka.client.fetch-registry=false
    
    eureka.client.service-url.defaultZone=http://eureka9200:9200/eureka
    
  2. Eureka Server2配置:

    server.port=9200
    
    spring.application.name=eureka9200
    
    eureka.instance.hostname=localhost
    
    eureka.client.register-with-eureka=false
    
    eureka.client.fetch-registry=false
    
    eureka.client.service-url.defaultZone=http://eureka9100:9100/eureka
    

在这个示例中,两个Eureka Server相互注册,形成一个简单的高可用集群。可以进一步扩展集群规模,添加更多的Eureka Server实例,以提高系统的可用性。

注意:Eureka本身并没有“主从”之分,所有的Eureka Server都是对等的,它们之间通过相互注册来实现高可用性。

3 Ribbon(负载均衡)

3.1 介绍

Ribbon是Netflix开源的一个基于HTTP和TCP客户端的负载均衡器,它主要用于在微服务架构中进行客户端的负载均衡。在Spring Cloud中,Ribbon通常被集成为一个客户端负载均衡器,用于在服务调用时选择合适的目标服务实例。以下是Ribbon的一些关键特点和介绍:

  1. 负载均衡算法: Ribbon支持多种负载均衡算法,包括常见的轮询(Round Robin)、随机(Random)、加权轮询、加权随机等。这些算法可以根据实际需求进行配置。

  2. 服务实例选择: Ribbon通过与服务注册中心(如Eureka)集成,动态地获取可用的服务实例列表,并根据负载均衡算法选择目标服务实例。这样,即使服务实例的数量发生变化,Ribbon也能够自动适应。

  3. 超时和重试: Ribbon具备超时和重试机制,可以在调用服务时设置超时时间,并在发生错误时进行重试。这有助于提高系统的可靠性和容错能力。

  4. 自定义规则: 用户可以通过自定义的方式指定服务实例的选择规则,以满足特定的业务需求。例如,可以根据服务实例的元数据、性能指标等进行智能的服务选择。

  5. 集成Spring Cloud: 在Spring Cloud中,Ribbon与Eureka、Feign等组件无缝集成,使得微服务架构中的服务间调用更加方便。通过在Feign客户端中使用@LoadBalanced注解,可以让Feign利用Ribbon进行负载均衡。

  6. 动态属性配置: Ribbon支持动态属性配置,可以通过配置中心(如Spring Cloud Config)实时更新负载均衡的相关配置,而不需要重新启动服务。

  7. 可扩展性: Ribbon是一个可扩展的负载均衡框架,可以通过实现特定的接口来定制负载均衡策略,以适应不同场景下的需求。

3.2 负载均衡策略

在Spring Cloud中使用Ribbon作为客户端负载均衡器时,可以通过配置来指定负载均衡的策略。Ribbon支持多种负载均衡策略,常见的包括:

  1. RoundRobin(默认): 轮询策略,依次将请求分发到各个服务实例上。

  2. RandomRule: 随机策略,随机选择一个可用的服务实例进行请求。

  3. WeightedResponseTimeRule: 响应时间加权策略,根据服务实例的响应时间进行加权,响应时间越短的服务实例被选择的概率越大。

  4. RetryRule: 具备重试机制的策略,当请求失败时,会进行重试。

  5. BestAvailableRule: 选择一个并发请求最小的实例,适用于请求量比较大的场景。

  6. ZoneAvoidanceRule: 综合判断服务节点所在的区域的性能和服务节点的可用性,来选择哪个服务 。

  7. AvailabilityFilteringRule: 先过滤掉由于多次访问故障的服务,以及并发访问超过阈值的服务,然后对剩下的服务进行轮询访问策略。

3.3 负载均衡示例

3.3.1 Eureka Server:springcloud-eureka

添加依赖

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

配置 application.properties

server.port=9100
spring.application.name=eureka-server
#设置注册中心
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#注册中心的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

@SpringBootApplication
@EnableEurekaServer //启动eureka
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.3.2 Eureka Client:springcloud-provider1

添加依赖

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

配置 application.properties

server.port=8084
spring.application.name=04-springcloud-provider
eureka.client.service-url.defaultZone=http://localhost:9100/eureka

启动类

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

编写TestController

@RestController
public class TestController {
    @RequestMapping("/test")
    public String test(){
        return "使用了Eureka注册中心的8084服务提供者!";
    }
}

3.3.3 Eureka Client:springcloud-provider2

添加依赖

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

配置 application.properties

server.port=8085
spring.application.name=04-springcloud-provider
eureka.client.service-url.defaultZone=http://localhost:9100/eureka

启动类

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

编写TestController

@RestController
public class TestController {
    @RequestMapping("/test")
    public String test(){
        return "使用了Eureka注册中心的8085服务提供者!";
    }
}

3.3.4 Eureka Client:springcloud-consumer

添加依赖

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

配置 application.properties

server.port=8086
spring.application.name=server-consumer
eureka.client.service-url.defaultZone=http://localhost:9100/eureka

启动类

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

编写 RestTemplateConfig

@Configuration
public class RestTemplateConfig {
    /**
     *     LoadBalanced  标记 restTemplate使用 ribbon 的  负载均衡策略访问服务的提供者
     *      使用了 Eureka注册中心后   restTemplate 对象上方必须添加该注解
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

	 /*负载均衡策略*/
    @Bean
    public IRule iRule(){
        return new RoundRobinRule();//轮询访问
//        return new RandomRule();//随机访问
    }
}

编写 TestController

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test(){
        ResponseEntity<String> result = restTemplate.getForEntity("http://04-springcloud-provider/test", String.class);
        return result.getBody();
    }
}

启动4个应用,网址栏输入http://localhost:9100,可以看到Eureka Server的控制台页面:
在这里插入图片描述
由于使用的是RoundRobin轮询策略,依次将请求分发到各个服务实例上。

访问http://localhost:8086/test,得到结果:
在这里插入图片描述
刷新http://localhost:8086/test,得到结果:
在这里插入图片描述

4 Hystrix(熔断器)

4.1 介绍

Hystrix是Netflix开源的一个用于处理分布式系统的容错组件,它主要用于防止服务雪崩,提高系统的稳定性。在微服务架构中,服务之间的依赖关系复杂,一个服务的不可用可能会导致整个系统的不可用。Hystrix通过引入熔断器模式、隔离、Fallback等机制,提供了一种弹性和容错的解决方案。

以下是Hystrix的一些关键特点和概念:

  1. 熔断器模式: Hystrix通过引入熔断器模式,可以在服务调用失败时快速返回一个Fallback响应,而不是等待调用超时。当服务连续失败达到一定阈值时,Hystrix会启动熔断器,暂时阻断对失败服务的调用,避免对系统的进一步影响。

  2. 服务隔离: Hystrix通过线程池隔离和信号量隔离等方式,将不同的服务调用隔离开来,防止一个服务的问题影响到其他服务。这提高了系统的可用性,防止服务之间的故障传播。

  3. 超时和降级: Hystrix支持设置服务调用的超时时间,当调用超时时可以立即返回Fallback响应。同时,可以定义Fallback逻辑,即在主逻辑失败时执行备用逻辑,保障系统在某个服务不可用时仍能提供有限的功能。

  4. 请求缓存: Hystrix支持对相同请求的结果进行缓存,避免重复执行相同的操作,提高系统的性能。

  5. 实时监控和熔断器状态: Hystrix提供了实时的监控面板,可以查看熔断器的状态、请求的成功与失败情况、延迟分布等信息。通过这些监控数据,可以及时发现和解决系统中的问题。

  6. Fallback策略: Hystrix允许为每个服务定义特定的Fallback策略,以应对不同服务的故障情况。Fallback逻辑通常是一些简化的、无依赖的操作,确保即使主逻辑失败,系统仍能提供基本的服务。

在Spring Cloud中,Hystrix通常与Feign、Ribbon等组件一起使用,以提供更可靠的微服务调用。通过在Feign客户端中添加@HystrixCommand注解,可以将熔断逻辑嵌入到服务调用中。

4.2 熔断示例

4.2.1 Eureka Server:springcloud-eureka

添加依赖

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

配置 application.properties

server.port=8761

spring.application.name=eureka-server

#设置注册中心
eureka.instance.hostname=localhost
#告知注册中心 你不能向你自己注册
eureka.client.register-with-eureka=false
#你的主要作用是维护服务 ,不是检索服务
eureka.client.fetch-registry=false
#注册中心的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

@SpringBootApplication
@EnableEurekaServer //启动eureka
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4.2.2 Eureka Client:springcloud-provider

添加依赖

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

配置 application.properties

server.port=8083

spring.application.name=provider

eureka.client.service-url.defaultZone=http://localhost:8761/eureka

启动类

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

编写TestController

@RestController
public class TestController {

    @RequestMapping("/test")
    public String test(){
        int i = 1/0;
        return "使用了断路器的...";
    }

    @RequestMapping("/test02")
    public String test02(){
        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "使用了熔断机制的...";
    }
}

4.2.3 Eureka Client:springcloud-consumer

添加依赖

<!--豪猪依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

<!--仪表盘-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

<!-- 开启健康检查-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

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

配置 application.properties

server.port=8084

spring.application.name=consumer

eureka.client.service-url.defaultZone=http://localhost:8761/eureka

management.endpoints.web.exposure.include=hystrix.stream

启动类

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker  //启动熔断机制
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

编写 RestTemplateConfig

@Configuration
public class RestTemplateConfig {
    /**
     *     LoadBalanced  标记 restTemplate使用 ribbon 的  负载均衡策略访问服务的提供者
     *      使用了 Eureka注册中心后   restTemplate 对象上方必须添加该注解
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

编写 MyHystrixCommand

public class MyHystrixCommand  extends HystrixCommand<String> {

    private RestTemplate restTemplate;

    private String url;

    public MyHystrixCommand(Setter setter, RestTemplate restTemplate, String url) {
        super(setter);
        this.restTemplate = restTemplate;
        this.url = url;
    }

    @Override
    protected String run() throws Exception {
        return restTemplate.getForObject(url,String.class);
    }

    @Override
    protected String getFallback() {
        //需要在控制器中定义一个叫error的方法
       return "error";
    }
}

编写 TestController

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "error")
    @RequestMapping("/test")
    public String test(){
        ResponseEntity<String> result = restTemplate.getForEntity("http://provider/test", String.class);
        String body = result.getBody();
        return "使用了Hystrix的服务消费者:" + body;
    }


    public String error(Throwable throwable){
        System.out.println(throwable.getMessage());
        System.out.println(throwable.getClass());
        return "服务熔断了......";
    }
	
	//标识一个方法需要由Hystrix进行保护,指定了一个回调方法 error ,设置了超时时间为2000毫秒
    @HystrixCommand(fallbackMethod = "error",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")
    })
    @RequestMapping("/test02")
    public String test02(){
        ResponseEntity<String> result = restTemplate.getForEntity("http://provider/test02", String.class);
        String body = result.getBody();
        return "使用了Hystrix的服务消费者:" + body;
    }
}

4.2.2 Eureka Client:springcloud-dashboard

添加依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
</dependency>

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

配置 application.properties

server.port=2001

#用于配置 Hystrix Dashboard 允许代理的流(stream)的地址列表。
hystrix.dashboard.proxy-stream-allow-list=localhost

#默认注册中心端口号就是8761

启动类

@SpringBootApplication
@EnableHystrixDashboard	//启用Hystrix dashboard豪猪可视化监控中心
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

启动4个应用,网址栏输入http://localhost:8761,可以看到Eureka Server的控制台页面:
在这里插入图片描述
浏览器输入http://localhost:8084/actuator/hystrix.stream,可以看到页面:
在这里插入图片描述
浏览器输入http://localhost:2001/hystrix,可以看到页面:
在这里插入图片描述
新建页面后输入http://localhost:8084/test,由于java.lang.ArithmeticException: / by zero异常,发生熔断:
在这里插入图片描述
此时,http://localhost:8084/actuator/hystrix.stream页面发生变化
在这里插入图片描述
在豪猪页面输入http://localhost:8084/actuator/hystrix.stream:
在这里插入图片描述
点击按钮后可以看到仪表盘:
在这里插入图片描述
新建页面后输入http://localhost:8084/test02,由于线程睡眠超过2秒,发生熔断:
在这里插入图片描述
查看仪表盘:
在这里插入图片描述

5 Feign(声明式服务调用)

5.1 介绍

Feign 是一个声明式的、模板化的 HTTP 客户端,它是 Spring Cloud 生态系统中的一部分,用于简化服务间的 HTTP 调用。Feign 的设计目标是使 HTTP 客户端的编写变得更加简单和直观。下面是 Feign 的一些主要特点和用法:

  1. 声明式 API 定义: Feign 允许你使用注解方式定义 HTTP 客户端的接口。通过简单的注解,你可以指定服务端的 URL、HTTP 方法、请求参数等信息,而不需要手动构建 HTTP 请求。

    @FeignClient(name = "example", url = "http://example.com")
    public interface MyFeignClient {
        @RequestMapping("/api/resource")
        String getResource();
    }
    
  2. 集成 Ribbon: Feign 集成了 Ribbon 负载均衡器,因此它可以与服务发现(如 Eureka)一起使用,实现对多个服务实例的负载均衡。

  3. 支持多种编码器和解码器: Feign 支持多种编码器和解码器,包括 JSON、XML 等,可以根据需求选择合适的序列化方式。

  4. 集成 Hystrix: Feign 可以集成 Hystrix,实现对服务调用的容错和熔断功能。通过 @HystrixCommand 注解,可以定义服务调用失败时的降级逻辑。

    @FeignClient(name = "example", url = "http://example.com", fallback = MyFallback.class)
    public interface MyFeignClient {
        @RequestMapping("/api/resource")
        @HystrixCommand(fallbackMethod = "fallbackMethod")
        String getResource();
    }
    

Feign 的目标是简化服务调用的过程,让开发者可以更专注于业务逻辑而不是底层的 HTTP 请求。在 Spring Cloud 中,Feign通常与服务发现、负载均衡、断路器等组件一起使用,为微服务架构提供了便捷的服务间通信方式。

5.2 示例

5.2.1 Eureka Server:springcloud-eureka

添加依赖

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

配置 application.properties

server.port=8761

spring.application.name=eureka-server

#设置注册中心
eureka.instance.hostname=localhost
#告知注册中心 你不能向你自己注册
eureka.client.register-with-eureka=false
#你的主要作用是维护服务 ,不是检索服务
eureka.client.fetch-registry=false
#注册中心的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

@SpringBootApplication
@EnableEurekaServer //启动eureka
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

5.2.2 Eureka Client:springcloud-feign-provider

添加依赖

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

配置 application.properties

server.port=8083

spring.application.name=provider

eureka.client.service-url.defaultZone=http://localhost:8761/eureka

启动类

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

编写TestController

@RestController
public class TestController {

    @RequestMapping("/test")
    public String test(){
        System.out.println(1/0);
        return "使用了feign的服务提供者";
    }
}

5.2.3 Eureka Client:springcloud-feign-consumer

添加依赖

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

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

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

配置 application.properties

# 应用服务 WEB 访问端口
server.port=8084
spring.application.name=05-springcloud-feign-consumer
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

# 启用 Feign 的 Hystrix 支持
feign.hystrix.enabled=true

启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients  //激活 feign远程调用
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

编写User实体类

public class User {

    private String name;
    private Integer age;

    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

编写MyCallBackFactory

@Component
public class MyCallBackFactory implements FallbackFactory<TestService> {

    @Override
    public TestService create(Throwable throwable) {
        return new TestService() {
            @Override
            public String test() {
                return "使用了熔断器的 feign "+throwable.getMessage();
            }

            @Override
            public String test01(String name, Integer age) {
                return name+age;
            }

            @Override
            public User testUser() {
                return null;
            }
        };
    }
}

编写TestService

@FeignClient(name = "05-springcloud-feign-provider",fallbackFactory = MyCallBackFactory.class)
public interface TestService {

    @RequestMapping("/test")
    public String test();

    @RequestMapping("/test01")
    public String test01(@RequestParam("name") String name,@RequestParam("age") Integer age);

    @RequestMapping("/testUser")
    public User testUser();
}

编写TestController

@RestController
public class TestController {

    @Autowired
    private TestService testService;

    @RequestMapping("/test")
    public String test(){
        /*RestTemplate restTemplate = new RestTemplate();
        restTemplate.getForEntity("http://provider/test",String.class);*/
        String body = testService.test01("kong",18);//
        return "使用feign的消费者的...["+body+"]";
    }
}

启动三个服务,访问http://localhost:8084/test01,远程调用了提供者的服务:
在这里插入图片描述
访问http://localhost:8084/test,由于by zero出现异常,发生熔断:
在这里插入图片描述

6 Zuul(API网关)

6.1 介绍

Zuul 是 Netflix 提供的一个基于 JVM 的边缘服务网关,它在微服务架构中扮演着 API 网关的角色,用于处理请求的路由、负载均衡、过滤、认证等一系列边缘服务功能。以下是 Zuul 的一些主要特点和功能:

  1. 路由(Routing): Zuul 可以根据请求的路径和规则将请求路由到不同的后端服务。这使得微服务架构中的多个服务可以通过一个统一的入口点提供服务。

  2. 负载均衡(Load Balancing): Zuul 集成了 Ribbon 负载均衡器,可以将请求平均分发到多个相同的后端服务实例上,以提高系统的可伸缩性和可用性。

  3. 过滤器(Filter): Zuul 使用过滤器来执行各种任务,例如身份验证、授权、日志记录等。开发者可以自定义过滤器来处理请求和响应,实现定制化的功能。

  4. 服务发现与注册: Zuul 可以与服务注册与发现中心(如 Eureka、Consul)集成,自动发现可用的服务实例,并将请求路由到它们之间。

  5. 动态路由: Zuul 支持动态路由配置,可以根据需要实时更新路由规则,而无需重启 Zuul 服务。

  6. 错误处理: Zuul 提供了对错误的处理机制,包括定制错误页面、错误重试等,以提高系统的稳定性。

  7. 监控与度量: Zuul 支持集成监控和度量工具,例如 Netflix 的 Hystrix、Spring Cloud Sleuth 等,以便对路由和服务调用进行监控和追踪。

  8. 安全性: Zuul 可以通过集成安全性解决方案来保护服务,例如 OAuth2、JWT 等。

6.2 示例

6.2.1 Eureka Server:springcloud-eureka

添加依赖

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

配置 application.properties

server.port=8761

spring.application.name=eureka-server

#设置注册中心
eureka.instance.hostname=localhost
#告知注册中心 你不能向你自己注册
eureka.client.register-with-eureka=false
#你的主要作用是维护服务 ,不是检索服务
eureka.client.fetch-registry=false
#注册中心的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

@SpringBootApplication
@EnableEurekaServer //启动eureka
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

6.2.2 Eureka Client:springcloud-zuul-provider

添加依赖

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

配置 application.properties

server.port=8083
spring.application.name=06-springcloud-zuul-provider
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

启动类

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

编写TestController

@RestController
public class TestController {

    @RequestMapping("/test")
    public String test(){
        return "使用了zuul网关的控制器...服务提供者test";
    }

    @RequestMapping("/test02")
    public String test02(){
        return "使用了zuul网关的控制器...服务提供者test02";
    }
}

6.2.3 Eureka Client:springcloud-zuul-gateway

添加依赖

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

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

配置 application.properties

server.port=9000

spring.application.name=06-springcloud-zuul-gateway

eureka.client.service-url.defaultZone=http://localhost:8761/eureka

# 配置路由规则
zuul.routes.api-zuul.path=/api-zuul/**
zuul.routes.api-zuul.service-id=06-springcloud-zuul-provider
#或者 zuul.routes.api-zuul.serviceId

启动类

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy //激活zuul的支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

编写AuthFilter

@Component
public class AuthFilter extends ZuulFilter {

    //过滤器类型
    @Override
    public String filterType() {
        //前置过滤器
        return "pre";
    }

    //执行顺序,数字越小,越优先执行
    @Override
    public int filterOrder() {
        return 0;
    }

    // 是否启用过滤器
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //过滤器具体的操作
    @Override
    public Object run() throws ZuulException {

        //获取请求的上下文
        RequestContext context = RequestContext.getCurrentContext();

        HttpServletRequest request = context.getRequest();

        String token = request.getParameter("token");

        if(token == null || !"123456".equals(token)){
            //不转发给服务器
            context.setSendZuulResponse(false);
            //权限不足
            context.setResponseStatusCode(401);
            //设置响应编码
            context.addZuulResponseHeader("Content-Type","text/html;charset=GB2312");
            //设置响应内容
            context.setResponseBody("非法请求!");
        }else {
            System.out.println("执行下一个过滤器");
        }

        return null;
    }
}

6.2.4 Eureka Client:springcloud-zuul-consumer

添加依赖

<!--豪猪依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

<!--仪表盘-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

<!-- 开启健康检查-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

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

配置 application.properties

server.port=8084
spring.application.name=06-springcloud-zuul-consumer
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

启动类

@SpringBootApplication
@EnableEurekaClient
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

编写 RestTemplateConfig

@Configuration
public class RestTemplateConfig {
    /**
     *     LoadBalanced  标记 restTemplate使用 ribbon 的  负载均衡策略访问服务的提供者
     *      使用了 Eureka注册中心后   restTemplate 对象上方必须添加该注解
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

编写TestController

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test(){
        ResponseEntity<String> result = restTemplate.getForEntity("http://06-springcloud-zuul-provider/test",String.class);
        return "没有经过网关的...["+result+"]";
    }

    @RequestMapping("/test02")
    public String test02(String token){
        ResponseEntity<String> result = restTemplate.getForEntity("http://06-springcloud-zuul-provider/test02?token="+token,String.class);
        return "经过网关的 token...["+result+"]";
    }
}

启动四个服务,访问http://localhost:9000/api-zuul/test,由于没有传入token:
在这里插入图片描述
访问http://localhost:9000/api-zuul/test02?token=123456:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/211589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

木马病毒是怎么进入服务器的,要如何防范

木马病毒通常是基于计算机网络&#xff0c;基于客户端和服务端的通信、监控程序。名称来源于公元前十二世纪希腊和特洛伊之间的一场战争。能够在计算机管理员未发觉的情况下开放系统权限、泄漏用户信息、甚至窃取整个计算机管理使用权限&#xff0c;隐匿性高。 木马病毒的入侵方…

开关电源的电感选择和布局布线

开关电源&#xff08;SMPS&#xff0c; Switched-Mode Power Supply&#xff09;是一种非常高效的电源变换器&#xff0c;其理论值更是接近100%&#xff0c;种类繁多。按拓扑结构分&#xff0c;有Boost、Buck、Boost-Buck、Charge-pump等&#xff1b;按开关控制方式分&#xff…

c语言:整数与浮点数在内存中的存储方式

整数在内存中的存储&#xff1a; 在计算机内存中&#xff0c;整数通常以二进制形式存储。计算机使用一定数量的比特&#xff08;bit&#xff09;来表示整数&#xff0c;比如32位或64位。在存储整数时&#xff0c;计算机使用补码形式来表示负数&#xff0c;而使用原码形式来表示…

如何创建一个vue工程

1.打开vue安装网址&#xff1a;安装 | Vue CLI (vuejs.org) 2.创建一个项目文件夹 3.复制地址 4.打开cmd&#xff0c;进入这个地址 5.复制粘贴vue网页的安装命令 npm install -g vue/cli 6.创建vue工程 vue create vue这里可以通过上下键来进行选择。选最后一个选项按回车。 …

企业网盘在医疗行业资料管理中的应用与优势

随着企业网盘的广泛应用&#xff0c;医疗行业正逐渐实现资料安全存储和智能化管理。海量应用的推动下&#xff0c;医院管理正朝着线上化、智能化发展迈进。然而&#xff0c;医疗行业仍面临着诸多挑战。 医疗行业的痛点在于病例、档案、药品资料繁多且保存周期长。这些资料的整理…

L1-009:N个数求和

目录 ⭐题目描述⭐ ⭐分析 ⭐程序代码 运行结果 ⭐文案分享⭐ ⭐题目描述⭐ 本题的要求很简单&#xff0c;就是求N个数字的和。麻烦的是&#xff0c;这些数字是以有理数分子/分母的形式给出的&#xff0c;你输出的和也必须是有理数的形式。 输入格式&#xff1a; 输入第一行给出…

XIAO ESP32S3之SenseCraft 模型助手部署

sipeed教程&#xff1a;SenseCraft 模型助手部署 | Seeed Studio Wiki 一、安装ESP-IDF 鉴于我的电脑之前安装过esp-idf v4.3版本&#xff0c;而ESP32-S3需要v4.4及以上版本才支持&#xff0c;所以将esp-idf更新到最新5.1版本。 1、启动mingw32.exe应用 2、进入esp-idf目录 …

前端小记--2.element-ui中级联选择器cascader如何默认展开下拉框

最近做项目时&#xff0c;遇到一个需求&#xff1a;在一个排班表中&#xff0c;展示人员的值班情况&#xff0c;点击单元格&#xff0c;弹出下拉框&#xff0c;修改人员排班信息。 由于下拉框选择内容是树状结构&#xff0c;这里使用了element-ui中级联组件cascader&#xff0c…

ganache部署智能合约报错VM Exception while processing transaction: invalid opcode

这是因为编译的字节码不正确&#xff0c;ganache和remix编译时需要选择相同的evm version 如下图所示&#xff1a; remix: ganache: 确保两者都选择london或者其他evm&#xff0c;只要确保EVM一致就可以正确编译并部署&#xff0c; 不会再出现VM Exception while processing…

Wireshark使用详解

wireshark简介 wireshark是捕获机器上的某一块网卡的网络包&#xff0c;当你的机器上有多块网卡的时候&#xff0c;你需要选择一个网卡。   wireshark能获取HTTP&#xff0c;也能获取HTTPS&#xff0c;但是不能解密HTTPS&#xff0c;所以wireshark看不懂HTTPS中的内容&#…

【C++】类和对象——初始化列表和static修饰成员

首先我们来谈一下初始化列表&#xff0c;它其实是对于我们前边构造函数体内初始化的一种补充&#xff0c;换一种说法&#xff0c;它以后才是我们构造函数的主体部分。 我们先考虑一个问题&#xff0c;就是一个类里面有用引用或const初始化的成员变量&#xff0c;比如说&#xf…

【【FPGA 之 MicroBlaze 自定义IP核 之 呼吸灯实验】】

FPGA 之 MicroBlaze 自定义IP核 之 呼吸灯实验 通过创建和封装 IP 向导的方式来自定义 IP 核&#xff0c;支持将当前工程、工程中的模块或者指定文件目录封装成 IP 核&#xff0c;当然也可以创建一个带有 AXI4 接口的 IP 核&#xff0c;用于 MicroBlaze 软核处理器和可编程逻辑…

kubernetes中YAML介绍;API资源对象Pod;Pod原理和生命周期;Pod资源限制

YAML介绍&#xff1b;API资源对象Pod&#xff1b;Pod原理和生命周期&#xff1b;Pod资源限制 1&#xff09;认识YAML 官网&#xff08;https://yaml.org/&#xff09; YAML 语言创建于 2001 年&#xff0c;比 XML 晚了三年。YAML虽然在名字上模仿了XML&#xff0c;但实质上与…

Spring之RestTemplate详解

Spring之RestTemplate详解 1 RestTemplate1.1 引言1.2 环境配置1.2.1 非Spring环境下使用RestTemplate1.2.2 Spring环境下使用 RestTemplate1.2.3 Spring环境下增加线程号 1.3 API 实践1.3.1 GET请求1.3.1.1 不带参请求1.3.1.2 带参的get请求(使用占位符号传参)1.3.1.3 带参的g…

西南科技大学模拟电子技术实验四(集成运算放大器的线性应用)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) 反相比例运算电路(1)实验…

VMware Workstation Pro 17及 Windows 11 虚拟机的安装与激活

六点钟&#xff1a; 吃晚饭吗 不吃&#xff0c;胖胖 十点钟&#xff1a; 阿昊要吃夜宵对不对 ——CSDN&#xff0c;记录牛马生活 本文是在学习 Linux 期间&#xff0c;使用 VMware 时顺带学习 Windows 11 虚拟机的安装与激活 VMware Workstation Pro 17及 Windows 11 虚拟机…

MacDroid Pro for Mac – 安卓设备文件传输助手,实现无缝连接与传输!

想要在Mac电脑上轻松管理和传输您的安卓设备文件吗&#xff1f;MacDroid Pro for Mac 是您的最佳选择&#xff01;这款强大的文件传输助手可以让您在Mac上与安卓设备之间实现快速、方便的文件传输。 MacDroid Pro for Mac 提供了简单易用的界面&#xff0c;让您能够直接在Mac上…

基于Springboot + vue的汽车资讯网站

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

Vue学习记录

Vue学习记录 一、搭建Vue开发环境 到官网下载安装Vue&#xff1a;安装 — Vue.js (vuejs.org) ----->点击开发版下载 怎么解决&#xff1f; 到官网&#xff1a;安装 — Vue.js 点击&#xff1a; 下滑找到&#xff1a; 下载相应的版本的就行&#xff1a; 下载拓展后刷新…

Collection的其他相关知识

前置知识&#xff1a;可变参数 就是一种特殊参数&#xff0c;定义在方法 构造器的形参列表里&#xff0c;格式是&#xff1a;数据类型...参数名称&#xff1b; 可变参数的特点和好处 特点&#xff1a;可以不传数据给它&#xff1b;可以传一个或者同时传多个数据给它&#xff…