Spring Cloud NetFlix

news2025/1/24 2:28:07

文章目录

  • 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:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端可滚动分类商品List列表 可用于电商分类列表

前端可滚动分类商品List列表 可用于电商分类列表 引言 在电商应用中&#xff0c;一个高效、用户友好的分类列表是提高用户体验和转化率的关键。本文将探讨如何使用xg-list-item、uni-grid和xg-tab等组件创建一个可滚动的分类商品列表&#xff0c;并处理相关的用户交互事件&…

Python容器——字典

Key——Value 键值对

canvas 轮廓路径提取效果

前言 微信公众号&#xff1a;前端不只是切图 轮廓 对内容做border效果&#xff0c;可以先看下代码运行的效果 内容是黑线构成的五角星&#xff0c;其轮廓就是红线的部分&#xff0c;本文主要介绍如何在canvas中实现这种效果 Marching Square 这里运用到的是marching square算法…

探索 Web API:SpeechSynthesis 与文本语言转换技术

一、引言 随着科技的不断发展&#xff0c;人机交互的方式也在不断演变。语音识别和合成技术在人工智能领域中具有重要地位&#xff0c;它们为残障人士和日常生活中的各种场景提供了便利。Web API 是 Web 应用程序接口的一种&#xff0c;允许开发者构建与浏览器和操作系统集成的…

Kubernetes(K8s)_16_CSI

Kubernetes&#xff08;K8s&#xff09;_16_CSI CSICSI实现CSI接口CSI插件 CSI CSI(Container Storage Interface): 实现容器存储的规范 本质: Dynamic Provisioning、Attach/Detach、Mount/Unmount等功能的抽象CSI功能通过3个gRPC暴露服务: IdentityServer、ControllerServe…

微信小程序组件与插件有啥区别?怎么用?

目录 一、微信小程序介绍 二、微信小程序组件 三、微信小程序插件 四、微信小程序组件与插件有啥区别 一、微信小程序介绍 微信小程序是一种基于微信平台的应用程序&#xff0c;它可以在微信客户端内直接运行&#xff0c;无需下载和安装。微信小程序具有轻量、便捷、跨平台…

RT-Thread ADC_DMA

看到这里&#xff0c;相信大家已经尝试过网上各类ADC_DMA传输的文章&#xff0c;且大多都并不能实现&#xff0c;因为在RT-Thread中并没有找到关于ADC的DMA接口&#xff0c;在官方例程中有关DMA的传输也只有一个串口接收的介绍&#xff0c;找遍全网怕也没能找到真正有用的消息。…

PyLMKit(5):基于网页知识库的检索增强生成RAG

基于网页知识库的检索增强生成RAG 0.项目信息 日期&#xff1a; 2023-12-2作者&#xff1a;小知课题: RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09;是一种利用知识库检索的方法&#xff0c;提供与用户查询相关的内容&#xff0c;从而…

1 NLP分类之:FastText

0 数据 https://download.csdn.net/download/qq_28611929/88580520?spm1001.2014.3001.5503 数据集合&#xff1a;0 NLP: 数据获取与EDA-CSDN博客 词嵌入向量文件&#xff1a; embedding_SougouNews.npz 词典文件&#xff1a;vocab.pkl 1 模型 基于fastText做词向量嵌入…

二、ZooKeeper集群搭建

目录 1、概述 2、安装 2.1 第一步&#xff1a;下载zookeeeper压缩包 2.2 第二步&#xff1a;解压 2.3 第三步&#xff1a;修改配置文件 2.4 第四步&#xff1a;添加myid配置 ​​​​​​​2.5 第五步&#xff1a;安装包分发并修改myid的值 ​​​​​​​2.6 第六步&a…

Ubuntu22.04无需命令行安装中文输入法

概要&#xff1a;Ubuntu22.04安装完成后&#xff0c;只需在设置中点点点即可完成中文输入法的安装&#xff0c;无需命令行。 一、安装中文语言包 1、点击屏幕右上角&#xff0c;如下图所示。 2、点击设置 3、选择地区与语言&#xff0c;点击管理已安装的语言 4、点击安装 5、输…

SSM SpringBoot vue社团事务管理系统

SSM SpringBoot vue社团事务管理系统 系统功能 登录 个人中心 人员信息管理 考勤信息管理 空闲时间管理 现金日记账管理 经费预算管理 物品租借管理 会议信息管理 活动信息管理 项目任务管理 公告通知管理 物资信息管理 开发环境和技术 开发语言&#xff1a;Java 使用框架:…

人工智能时代:AIGC的横空出世

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 什么是AIGC?二. AIGC的主要特征2.1 文本生成2.2 图像生成2.3 语音生成2.4 视…

微信支付/

微信支付准备工作 3.2.1 如何保证数据安全&#xff1f; 完成微信支付有两个关键的步骤&#xff1a; 第一个就是需要在商户系统当中调用微信后台的一个下单接口&#xff0c;就是生成预支付交易单。 第二个就是支付成功之后微信后台会给推送消息。 这两个接口数据的安全性&#x…

13.字符串处理函数——输入输出

文章目录 前言一、题目描述 二、解题 程序运行代码 三、总结 前言 本系列为字符串处理函数编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 二、解题 程序运行代码 #include<stdio.h> #include<string.h> int main() {char str[10];printf(&q…

思维导图应用程序:iThoughts 6.5 Crack

为什么选择 iThoughts&#xff1f; 有很多思维导图应用程序。他们中的许多人都非常好。那么您为什么要考虑 iThoughts&#xff1f; 免责声明&#xff1a;我创建了 iThoughts - 这是我过去 12 年的生活 - 我有点偏见&#xff01; 大多数思维导图应用程序都提供相同的基本功能级…

BUUCTF 间谍启示录 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 在城际公路的小道上&#xff0c;罪犯G正在被警方追赶。警官X眼看他正要逃脱&#xff0c;于是不得已开枪击中了罪犯G。罪犯G情急之下将一个物体抛到了前方湍急的河流中&#xff0c;便头一歪突然倒地。警官X接近一看&…

【算法刷题】Day11

文章目录 面试题 08.01. 三步问题题干&#xff1a;算法原理&#xff1a;1、状态表示2、状态转移方程3、初始化4、填表顺序5、返回值 代码&#xff1a; 209. 长度最小的子数组题干&#xff1a;算法原理&#xff1a;1、暴力枚举出所有的子数组的和2、利用单调性&#xff0c;使用“…

【Unity动画】状态机添加参数控制动画切换(Animator Controller)

Unity - 手册&#xff1a;动画参数 在Unity中&#xff0c;动画状态的切换是通过Animator Controller中的过渡&#xff08;Transition&#xff09;来实现的。过渡是状态之间的连接&#xff0c;控制过渡一般都是靠调用代码参数 我们来实现一个案例&#xff1a; 创建动画状态机&a…

Zabbix HA高可用集群搭建

Zabbix HA高可用集群搭建 Zabbix HA高可用集群搭建一、Zabbix 高可用集群&#xff08;Zabbix HA&#xff09;二、部署Zabbix高可用集群1、两个服务端配置1.1主节点 Zabbix Server 配置1.2 备节点 Zabbix Server 配置1.3 主备节点添加监控主机1.4 查看高可用集群状态 2、两个客户…