文章目录
- 微服务架构
- Spring Cloud
- 微服务或Spring Cloud的工作流程:
- 常见注册中心技术
- 常见的负载均衡技术
- 常见的熔断器技术
- 常见的配置管理技术
- 常见的网关技术
- 常见的消息追踪技术
- 常见的消息总线技术
- 示例:服务注册发现eureka的使用
- Eureka服务器
- 服务消费者(Consumer)
- 服务提供者(Provider)
- 运行
- 示例:负载均衡ribbon的使用
- 服务消费方接入ribbon
- 如何确认使用了负载均衡
- ribbon的负载均衡算法
- 示例:熔断器Hystrix的使用
- 服务雪崩问题
- 服务消费方接入hystrix:服务降级
- 服务消费方接入hystrix:熔断断开
- 示例:HTTP 客户端Feign的使用
- 服务消费方集成Feign
- feign开启熔断
- 示例:网关Spring Cloud Gateway的使用
- 路由的使用
- 过滤器的使用
微服务架构
微服务是一种软件架构风格,将一个大型的应用程序拆分成一组小而独立的服务。每个服务都运行在自己的进程中,拥有自己的数据库,并通过API与其他服务通信。这种方式的好处包括:
- 可伸缩性: 可以独立扩展每个微服务,而不是整个应用程序。
- 独立部署: 可以独立开发、部署和维护每个微服务。
- 松散耦合: 每个微服务都是独立的,可以使用不同的技术栈。
Spring Cloud
Spring Cloud是Spring生态系统的一部分,它提供了一组工具和框架,简化了微服务架构的开发和部署。以下是Spring Cloud的一些关键特性:
- 服务注册与发现: Spring Cloud提供了服务注册中心,如Netflix Eureka,用于注册和发现各个微服务。
- 负载均衡: 集成了负载均衡器,如Netflix Ribbon,以确保请求被均匀地分布到多个服务实例。
- 断路器(熔断器): 通过Hystrix实现断路器模式,提高系统的容错性和稳定性。
- 配置管理: 使用Spring Cloud Config,可以集中管理和配置微服务的配置信息。
- API网关: Spring Cloud Zuul充当API网关,用于处理请求路由、过滤和负载均衡。
- 分布式追踪: 集成了Spring Cloud Sleuth和Zipkin,用于跟踪和监控微服务之间的调用关系。
- 消息总线: 使用Spring Cloud Bus实现消息总线,用于在微服务之间传播状态变化。
微服务或Spring Cloud的工作流程:
- 服务注册: 微服务在启动时向服务注册中心注册自己的信息。
- 服务发现: 其他微服务可以通过服务注册中心查询并发现可用的服务。
- 负载均衡: 负载均衡器确保请求通过多个服务实例进行均匀分布。
- 断路器: 断路器用于防止故障扩散,并提供降级机制。
- API网关: API网关处理外部请求,路由请求到相应的微服务,并执行过滤和负载均衡。
- 分布式追踪: 追踪工具用于监控微服务之间的调用关系,以便进行性能分析和故障排除。
- 配置管理: 集中管理微服务的配置信息,确保配置的一致性和可维护性。
总的来说,Java微服务和Spring Cloud为构建可伸缩、灵活、可维护的分布式系统提供了强大的工具和框架。它们的结合使得开发者能够更容易地设计、构建和管理复杂的微服务架构。
常见注册中心技术
类似:月嫂中心、滴滴打车平台等等。服务提供方和消费方都注册到注册中心,之后就可以使用服务了
-
Eureka(Netflix OSS): Eureka 是 Netflix 开源的服务注册与发现工具,用于构建弹性、可伸缩的微服务架构。Spring Cloud 提供了对 Eureka 的集成,使得开发者可以轻松地实现服务注册与发现。
-
Consul: Consul 是一个开源的服务发现和配置管理工具,由 HashiCorp 开发。Consul 提供了服务注册、健康检查、故障恢复等功能,并支持多数据中心的部署。Spring Cloud 也对 Consul 提供了支持。
-
Zookeeper: Apache ZooKeeper 是一个分布式协调服务,也可以用于服务注册与发现。ZooKeeper 提供了分布式锁、选主、配置管理等功能,广泛应用于分布式系统。
-
Nacos: Nacos 是阿里巴巴开源的服务注册与发现工具,支持服务注册、健康检查、动态配置等功能。Nacos 是一个全功能的动态服务发现、配置管理和服务管理平台。
-
etcd: etcd 是一个高可靠的分布式键值存储系统,也可以用于服务注册与发现。它由 CoreOS 开发,支持分布式锁、租约机制等特性。
-
Kubernetes Service Discovery: 如果微服务应用运行在 Kubernetes 等容器编排平台上,可以利用 Kubernetes 的内置服务发现机制,通过服务名和 DNS 来实现服务的注册与发现。
选择合适的服务注册与发现技术通常取决于项目需求、技术栈和部署环境。Spring Cloud 提供了对多种服务注册与发现技术的集成支持,因此可以根据项目的实际情况选择适合的实现。
常见的负载均衡技术
微服务的负载均衡是确保在微服务架构中各个服务实例能够分担负载,提高系统的可用性和性能的关键组成部分。一般来说,有多种负载均衡技术和工具可供选择。以下是一些常见的微服务负载均衡技术:
-
Ribbon: Ribbon是Netflix开发的一个基于HTTP和TCP的客户端负载均衡器。它集成在Spring Cloud中,可以与Eureka等服务发现工具一起使用。Ribbon提供了多种负载均衡策略,包括轮询、随机、权重等。
-
Eureka: Eureka本身是一个服务发现工具,但它也包含了基本的负载均衡功能。通过与Ribbon结合使用,Eureka可以自动从可用的服务实例中选择一个来处理请求。
-
Nginx: Nginx是一个高性能的反向代理服务器,也可以用作负载均衡器。它支持多种负载均衡算法,如轮询、IP哈希、加权轮询等。Nginx在静态资源服务和反向代理方面表现优异,经常被用于负载均衡微服务。
-
HAProxy: HAProxy是一款开源的负载均衡器和反向代理工具。它支持TCP和HTTP应用,并提供了强大的负载均衡算法。HAProxy广泛应用于高流量和高可用性的场景。
-
Envoy: Envoy是由Lyft开发的高性能、开源的代理和通信总线。它专注于支持微服务架构,提供了负载均衡、服务发现、故障恢复等功能。Envoy适用于容器化环境,并能与Kubernetes等平台集成。
-
Consul: Consul是一款由HashiCorp开发的服务发现和配置管理工具。它集成了负载均衡功能,可以自动分配流量到可用的服务实例。
这些负载均衡技术可以根据具体的需求和环境进行选择。在一些场景中,组合使用多个负载均衡策略可以提供更好的性能和可用性。例如,可以在服务发现工具(如Eureka)与客户端负载均衡器(如Ribbon)之间结合使用,以实现更灵活的负载均衡策略。
常见的熔断器技术
微服务熔断器(Circuit Breaker)是一种用于处理分布式系统中故障的模式。它的目标是在服务发生故障时,防止故障在整个系统中传播,通过打开断路器来阻止请求。以下是一些常见的微服务熔断器技术:
-
Hystrix: Hystrix是Netflix开发的熔断器库,它专门设计用于处理分布式系统中的故障。Hystrix提供了线程隔离、超时设置、熔断器状态监控和回退机制等功能。它可以与Spring Cloud等微服务框架无缝集成。
-
Resilience4j: Resilience4j是一款轻量级的熔断器库,具有与Hystrix相似的功能。它采用了函数式编程的风格,并支持Java 8的新特性。Resilience4j提供了丰富的配置选项,可灵活地适应不同的应用场景。
-
Sentinel: Sentinel是阿里巴巴开源的一款面向分布式系统的流量控制和熔断降级的库。它提供了实时的监控和控制台,可以快速响应系统的状态变化。
-
Envoy: Envoy是由Lyft开发的开源代理工具,也可以用作熔断器。Envoy支持流量控制、重试策略和故障注入等特性,适用于容器化环境,并与Kubernetes等平台集成。
-
Spring Cloud Circuit Breaker: Spring Cloud提供了对不同熔断器实现的抽象,包括对Hystrix和Resilience4j的支持。通过Spring Cloud Circuit Breaker,你可以在不修改代码的情况下更换熔断器实现。
-
Istio: Istio是一个开源的服务网格框架,具有熔断、流量管理、故障注入等功能。它提供了强大的控制平面,用于管理服务之间的通信,并支持多种熔断器策略。
选择合适的熔断器技术取决于项目需求、团队经验和技术栈。通常来说,Hystrix和Resilience4j是常见的选择,而Sentinel和Envoy等新兴技术也受到了关注。在进行选择时,建议考虑熔断器的性能、灵活性、集成性和社区支持等因素。
常见的配置管理技术
微服务的配置管理是确保微服务应用程序能够在不同环境中灵活运行的关键部分。以下是一些常见的微服务配置管理技术:
-
Spring Cloud Config: Spring Cloud Config 是一个基于Git的配置管理工具,可以集中管理配置文件,并提供 REST 接口供微服务应用程序读取配置。它与 Spring Cloud 生态系统集成紧密,支持动态刷新配置。
-
Consul: Consul 是一个开源的服务发现和配置管理工具。它提供了键值存储,可用于存储和检索配置信息。Consul还与微服务框架(如Spring Cloud和HashiCorp的服务网格)一起使用。
-
etcd: etcd 是一个分布式键值存储系统,常用于配置管理和服务发现。它是 Kubernetes 中的一部分,也可以用于其他微服务架构。
-
Apache ZooKeeper: ZooKeeper 是一个分布式协调服务,可以用于配置管理和分布式应用程序的同步。它支持分布式配置的存储和更新。
-
HashiCorp Vault: Vault 是一个用于管理秘密和保护敏感数据的工具,同时也提供了配置管理的功能。它可以集中存储和分发应用程序的机密信息和配置。
-
Git: 将配置文件存储在 Git 仓库中,可以方便地进行版本控制和历史记录。微服务应用程序可以从 Git 仓库中拉取配置文件,并在运行时读取配置信息。
-
ConfigMap 和 Secrets(Kubernetes): 如果你的微服务运行在 Kubernetes 中,你可以使用 Kubernetes 的 ConfigMap 和 Secrets 对象来管理配置信息。它们可以动态地注入到容器中。
-
Spring Cloud Vault: Spring Cloud Vault 是 Spring Cloud 生态系统的一部分,用于与 HashiCorp Vault 集成。它使得微服务可以方便地从 Vault 中读取配置信息。
选择适合项目需求和团队经验的配置管理技术是重要的。很多时候,选择与已有的技术栈和服务治理方案集成良好的工具是一个不错的选择。
常见的网关技术
微服务网关是微服务架构中的关键组件,用于处理对微服务的所有请求和流量管理。以下是一些常见的微服务网关技术:
-
Spring Cloud Gateway: Spring Cloud Gateway 是 Spring Cloud 生态系统的一部分,它提供了一种基于反应式编程的方式来构建微服务网关。它集成了 Spring WebFlux,并支持动态路由、请求过滤、限流等功能。
-
Netflix Zuul: Zuul 是 Netflix 提供的微服务网关,支持动态路由、负载均衡、过滤器等功能。然而,Netflix 已经宣布不再积极维护 Zuul 项目,建议用户迁移到 Spring Cloud Gateway。
-
Nginx: Nginx 是一款高性能的反向代理服务器,也可用作微服务网关。它支持负载均衡、SSL 终结、缓存和请求转发等功能。Nginx在处理静态资源和反向代理方面表现优异。
-
Kong: Kong 是一个开源的微服务和 API 管理网关,它构建在 Nginx 之上。Kong 提供了灵活的插件系统,支持认证、限流、日志记录等功能。
-
Envoy: Envoy 是由 Lyft 开源的高性能代理和通信总线,也可用作微服务网关。它支持负载均衡、路由、故障恢复等功能,并广泛应用于服务网格场景。
-
Traefik: Traefik 是一款现代化的反向代理和负载均衡工具,特别适用于微服务架构。它与容器化平台(如Docker和Kubernetes)紧密集成,并支持自动发现服务。
-
API Gateway(AWS、Azure、Google Cloud): 云服务提供商(如AWS、Azure、Google Cloud)通常都提供了自己的 API 网关服务,用于管理和路由 API 请求。这些服务通常与云平台的其他功能集成,提供了全球分发、认证、授权等功能。
选择微服务网关技术时,需要考虑项目需求、团队熟悉度、性能要求和与其他微服务组件的集成。当前,Spring Cloud Gateway 和 Envoy 在微服务社区中受到广泛关注。
常见的消息追踪技术
微服务的分布式追踪是一项关键的技术,用于监测和诊断分布式系统中的请求流。以下是一些常见的微服务分布式追踪技术:
-
Spring Cloud Sleuth:是 Spring Cloud 生态系统中用于分布式追踪的一个组件。它提供了在微服务架构中跟踪请求的功能,使开发人员能够了解请求在多个微服务之间的传递情况。
Spring Cloud Sleuth 主要通过为请求生成唯一的跟踪标识(Trace ID)和跟踪片段标识(Span ID),以及将这些标识传递给微服务之间的请求,从而形成一条完整的请求链路。这使得在分布式系统中,开发人员可以追踪请求在微服务之间的传递路径,查看性能指标,以便更好地理解系统的运行状况和进行调优。
Sleuth通常与其他分布式追踪工具(如Zipkin、Jaeger等)结合使用,以提供更丰富的追踪数据可视化和分析功能。这种集成使得开发人员可以通过图形化的界面查看请求的时序图,诊断性能问题,并在需要时进行深入的分析。 -
Zipkin: Zipkin 是一款开源的分布式追踪系统,由 Twitter 开发。它提供了一个简单的 UI,可用于可视化请求的传播路径,并显示每个微服务的性能指标。Zipkin支持多种后端存储,包括内存、MySQL、Cassandra等。
-
Jaeger: Jaeger 是一个由 Uber Technologies 开发的开源分布式追踪系统。它支持多种编程语言和多种后端存储,如Elasticsearch、Cassandra、Kafka等。Jaeger提供了直观的UI,用于查看请求的时序图和性能指标。
-
OpenTelemetry: OpenTelemetry 是一个由云原生计算基金会(CNCF)支持的开源项目,它提供了跨语言和跨平台的 API,用于收集分布式追踪和度量数据。OpenTelemetry 已经整合了以前的 OpenTracing 和 OpenCensus 项目。
-
AppDynamics: AppDynamics 是一款应用性能管理(APM)工具,它提供了对微服务架构的实时监测和诊断功能。AppDynamics 支持跟踪请求的流经路径,并提供性能指标和错误报告。
-
New Relic: New Relic 是一款云端的应用性能监控工具,它提供了对微服务的分布式追踪和实时监控。New Relic 的分布式追踪功能可以帮助识别性能问题并优化微服务架构。
-
Dynatrace: Dynatrace 是一款全栈的监控工具,包括应用性能监控、基础设施监控和用户体验监控。它提供了对微服务的分布式追踪功能,帮助诊断性能问题和优化应用程序。
选择分布式追踪技术时,需要考虑对应用程序的语言支持、集成容易程度、性能开销以及对不同存储后端的支持。这些工具通常与现代的微服务架构非常兼容,可以帮助开发人员理解系统的运行状况并快速诊断潜在问题。
常见的消息总线技术
微服务架构中的消息总线用于实现微服务之间的异步通信,以支持解耦、灵活性和可伸缩性。以下是一些常见的微服务消息总线技术:
-
Spring Cloud Bus :Spring Cloud Bus 是 Spring Cloud 生态系统中用于微服务之间消息传递和事件广播的组件。它建立在分布式消息代理之上,通过消息总线将不同微服务实例连接在一起,以便它们可以共享配置信息、触发事件、更新状态等。Spring Cloud Bus 可以与多种消息代理集成,包括 RabbitMQ、Kafka 等。这样,你可以选择适合你架构的消息代理,并根据需要进行扩展。
-
Apache Kafka: Apache Kafka 是一个高吞吐量的分布式消息系统,特别适用于构建实时数据流应用程序。Kafka 提供了持久性、可靠性和水平扩展性,被广泛用于微服务架构中的事件驱动架构。
-
RabbitMQ: RabbitMQ 是一个开源的消息代理,实现了 AMQP(高级消息队列协议)标准。它提供了可靠的消息传递机制,支持多种消息模式,包括点对点、发布-订阅等,适用于微服务之间的通信。
-
ActiveMQ: Apache ActiveMQ 是一个开源的消息代理,实现了 JMS(Java Message Service)规范。它支持多种消息模式,并能够在 Java 环境中轻松集成。
-
NATS: NATS 是一个轻量级、高性能的消息代理系统,具有低延迟和简单的设计。NATS 提供了基于主题的发布-订阅和请求-响应模式,适用于微服务之间的通信。
-
Kubernetes Event-driven Autoscaling (KEDA): KEDA 是一个用于 Kubernetes 的开源项目,它使得微服务能够根据事件驱动的方式自动扩展。KEDA可以与多种消息代理集成,包括 Kafka、Azure Event Hubs 等。
-
Amazon Simple Notification Service (SNS) 和 Simple Queue Service (SQS): 这是亚马逊云服务中的两个托管的消息服务。SNS 支持发布-订阅模型,而 SQS 提供了队列服务,可以用于微服务之间的异步通信。
-
Google Cloud Pub/Sub: 这是 Google Cloud Platform 提供的消息服务,支持多种消息模式,包括发布-订阅和点对点。
选择消息总线技术时,需要考虑性能要求、可靠性、部署环境以及与其他微服务组件的集成。不同的场景可能适合不同的消息总线解决方案。
示例:服务注册发现eureka的使用
下面是一个简单的Java项目,演示如何集成Spring Cloud,并使用Spring Cloud的一些关键组件,包括Eureka作为注册中心、Feign用于服务间的HTTP通信、以及Config用于配置管理。这个示例包含两个微服务:一个是服务提供者(provider),另一个是服务消费者(consumer)。
Eureka服务器
<dependencies>
<!-- Spring Cloud Eureka Server 用于构建 Eureka 服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
服务消费者(Consumer)
<dependencies>
<!-- Spring Boot Starter Web 用于构建Web应用程序 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Eureka Client 用于注册到 Eureka 服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Spring Cloud OpenFeign 用于声明式REST客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
spring.application.name=consumer
server.port=8082
# Eureka配置
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
// 服务消费者主类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
// Feign客户端接口
@FeignClient(name = "provider")
public interface HelloClient {
@GetMapping("/hello")
String hello(@RequestParam String name);
}
// 服务消费者Controller
@RestController
public class HelloController {
@Autowired
private HelloClient helloClient;
@GetMapping("/consumeHello")
public String consumeHello(@RequestParam String name) {
return helloClient.hello(name);
}
}
服务提供者(Provider)
<dependencies>
<!-- Spring Boot Starter Web 用于构建Web应用程序 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Eureka Client 用于注册到 Eureka 服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
spring.application.name=provider
server.port=8081
# Eureka配置
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
// 服务提供者主类
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
// 服务提供者Controller
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello, " + name + "! (from port " + port + ")";
}
}
运行
启动Eureka服务器(EurekaServerApplication)。
启动服务提供者(ProviderApplication)。
启动服务消费者(ConsumerApplication)。
访问 http://localhost:8761/ 可以看到Eureka的管理界面,显示服务提供者和服务消费者已经成功注册。
然后,通过访问 http://localhost:8082/consumeHello?name=YourName ,可以看到服务消费者调用了服务提供者的接口并返回结果。
示例:负载均衡ribbon的使用
在微服务中引入 Ribbon 主要是为了实现客户端负载均衡。Ribbon 是 Netflix 开源的负载均衡器,它可以在微服务架构中自动分发负载到多个服务实例,提高系统的可用性和性能。下面是一个简单的示例,演示如何在 Spring Cloud 中引入 Ribbon。
既然是负载,那肯定作用在服务的消费方,服务提供方就不需要了。
服务消费方接入ribbon
接下来我们改造服务消费方的代码
<!-- Spring Cloud Starter Ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
# 如果需要自定义 Ribbon 的配置,可以添加以下配置(可选)
ribbon:
eureka:
enabled: true
// ConsumerServiceApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
@RequestMapping("/api")
class ApiController {
private final RestTemplate restTemplate;
public ApiController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/consume")
public String consume() {
// 使用 Ribbon 负载均衡调用服务提供者,这里直接使用spring.application.name,不用localhost了
String providerResponse = restTemplate.getForObject("http://provider-service/api/greet", String.class);
return "Consumer Service: " + providerResponse;
}
}
通过 @LoadBalanced 注解启用 Ribbon 的负载均衡。
服务消费者的 /api/consume 接口使用 RestTemplate 发起对服务提供者的调用,由 Ribbon 实现负载均衡。确保在服务提供者和服务消费者的配置文件中配置了 Eureka 相关的配置,以便服务的注册与发现。
这是一个简单的示例,实际项目中需要更多的配置和管理。同时,Spring Cloud 提供了更高级的工具,如 Feign 和 OpenFeign,以简化微服务之间的通信。
如何确认使用了负载均衡
确保你的微服务应用正确使用了负载均衡是很重要的。以下是一些方法,可以帮助你确认负载均衡是否生效:
1、查看 Ribbon 日志: Ribbon 在 DEBUG 或 TRACE 日志级别下会输出详细的日志信息。你可以将日志级别设置为 DEBUG,然后查看应用启动日志,以确认 Ribbon 是否成功地执行了负载均衡。在 Spring Boot 项目中,可以在 application.yml 或 application.properties 中添加如下配置:
logging:
level:
org.springframework.cloud.netflix.ribbon: DEBUG
或者使用 application.properties 文件:
logging.level.org.springframework.cloud.netflix.ribbon=DEBUG
2、观察服务调用结果: 在你的服务消费者中,发起对服务提供者的多次请求,观察请求是否轮询到不同的服务实例。你可以在服务提供者的日志中看到接收到请求的服务实例的标识。
3、使用 Ribbon 提供的 REST 接口: Ribbon 提供了一组 REST 接口,用于查看当前的服务实例列表和负载均衡状态。默认情况下,这些接口路径是 /actuator/ribbon。你可以使用以下命令调用这些接口:
curl http://your-consumer-service/actuator/ribbon
这将返回包含当前服务实例列表和选定实例的信息。确保服务实例在不同的主机或端口上。
4、使用 Spring Boot Admin: 如果你使用了 Spring Boot Admin 来监控微服务,该工具提供了对 Ribbon 状态的可视化支持。你可以在 Spring Boot Admin 的 Web 界面中查看服务实例和负载均衡的相关信息。
5、在代码中验证: 如果你愿意,你还可以在服务消费者的代码中加入一些打印或日志语句,以输出请求所选择的服务实例的标识。
通过结合上述方法,你应该能够确认是否成功使用了 Ribbon 负载均衡。确保你的服务消费者配置了 @LoadBalanced 注解或者使用了 RestTemplate 的负载均衡功能。同时,服务提供者应该正确注册到服务注册中心(如 Eureka)。
ribbon的负载均衡算法
Ribbon 提供了多种负载均衡算法,可以根据实际需求进行配置。以下是一些常见的负载均衡算法和在 Ribbon 中的配置方法:
- 轮询(Round Robin)
轮询算法按顺序选择下一个服务实例,循环遍历所有实例。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
- 随机(Random)
随机算法随机选择一个可用的服务实例。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
- 权重轮询(Weighted Round Robin)
权重轮询算法根据服务实例的权重进行轮询选择。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
- 权重随机(Weighted Random)
权重随机算法根据服务实例的权重进行随机选择。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedRandomRule
- 最佳可用(Best Available)
最佳可用算法选择可用服务实例中响应时间最短的一个。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule
- 最小并发(Zone Avoidance)
最小并发算法尽量避免选择正在处理大量并发请求的服务实例。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule
- 客户端IP哈希(Client IP Hash)
客户端IP哈希算法使用客户端的IP地址进行哈希计算,选择一个固定的服务实例。
配置方法:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ClientIpHashRule
以上配置中的 NFLoadBalancerRuleClassName 属性指定了使用的负载均衡规则类。注意是配置在服务消费方
示例:熔断器Hystrix的使用
服务雪崩问题
服务雪崩问题是指在分布式系统中,当某个服务出现故障或不可用时,该服务的请求流量被无法处理的错误或超时请求淹没,导致整个系统的性能急剧下降,最终导致更多的服务出现故障,形成类似雪崩般的连锁反应。服务雪崩问题是分布式系统中一种严重的故障,可能导致整个系统瘫痪。
服务雪崩问题通常由以下几个原因引起:
-
大规模故障: 当一个重要的服务出现故障或者被下线维护时,所有依赖于该服务的其他服务无法正常工作,导致大量请求失败。
-
不恰当的重试策略: 当某个服务不可用时,有些客户端会采用重试策略,即不断地重复发送请求,增加了故障服务的负载,可能加剧雪崩效应。
-
服务依赖链: 如果系统中的服务依赖形成了长链条,而其中某个服务出现问题,可能会导致整个链条上的服务全部不可用。
-
缓存失效: 当缓存失效时,所有的请求都会直接打到底层服务,增加了底层服务的负载,可能触发雪崩。
为了减轻服务雪崩问题,可以采取以下一些措施:
-
服务降级: 当某个服务不可用时,可以提供一个备用的降级服务,返回一个默认的响应,避免向下游服务传递错误。
-
限流: 通过限制请求的数量,确保系统的承载能力不会超过其正常处理能力,避免系统过载。
-
熔断器: 使用熔断器模式,当某个服务出现故障时,熔断器会直接拦截请求,不再发起新的请求,避免向下游服务传递错误,减轻负载。
-
合理的重试策略: 对于因为故障而导致的请求,采用合理的重试策略,防止因频繁重试而加剧雪崩效应。
-
服务拆分和隔离: 将系统拆分成更小的微服务,通过隔离和限制依赖关系,降低整个系统受单个服务故障影响的可能性。
服务雪崩问题的预防需要在设计和架构层面上进行,通过采取合理的容错和恢复策略,提高系统的抗干扰能力。
服务消费方接入hystrix:服务降级
1、添加依赖
<!-- 添加 Hystrix 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、在主应用程序类上添加 @EnableHystrix 注解,以启用 Hystrix:
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableHystrix
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
3、在需要添加熔断器的方法上,使用 @HystrixCommand 注解定义一个熔断器命令。该注解会创建一个熔断器,以监控和控制该方法的执行。
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Service
public class YourService {
private final RestTemplate restTemplate;
public YourService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@HystrixCommand(fallbackMethod = "fallbackMethod")
public String yourMethod() {
// 调用其他服务的代码
return restTemplate.getForObject("http://other-service/api/endpoint", String.class);
}
// 备用方法,用于处理熔断时的逻辑
public String fallbackMethod() {
return "Fallback Response";
}
}
4、配置熔断器属性(可选)
hystrix:
command:
default:
execution.isolation.thread.timeoutInMilliseconds: 5000
上述配置将设置 Hystrix 默认命令的超时时间为 5000 毫秒。
注意事项:
Hystrix 默认使用线程池来隔离服务调用,可以通过 @HystrixCommand 的 commandProperties 属性进行配置。
使用 Hystrix Dashboard 和 Turbine 可以实现对 Hystrix 熔断器的监控和聚合。
服务消费方接入hystrix:熔断断开
代码还是不用变,按需修改配置部分
熔断器在面对故障时的状态和行为有三种:
Closed(关闭状态):
- 逻辑: 在关闭状态时,熔断器允许请求通过,并监控这些请求的成功和失败。
- 行为: 如果错误率(失败请求的百分比)超过预定的阈值,熔断器会进入打开状态,阻止进一步的请求通过。
Open(打开状态):
- 逻辑: 在打开状态时,熔断器会拒绝所有的请求,而不会将请求传递到实际的服务。
- 行为: 在打开状态下,熔断器会定期(定时器触发)尝试将自己切换到半开状态,以检查服务是否已经恢复。
Half Open(半开状态):
- 逻辑: 在半开状态时,熔断器允许一部分请求通过,同时监控这些请求的成功和失败。
- 行为: 如果请求成功,则熔断器会转回到关闭状态,继续监控;如果请求失败,则熔断器会回到打开状态,继续拒绝请求。
熔断器通过在打开状态拒绝请求,可以避免不断发送请求到已经故障的服务,从而减轻系统的负载并保护系统免受进一步的损害。半开状态允许系统在一段时间后重新尝试请求,以便检测服务是否已经恢复,从而逐渐恢复正常的请求流量。这种状态机的设计可以有效地防止连锁故障,并提高系统的可用性和稳定性。
示例:HTTP 客户端Feign的使用
Feign 是一个声明式的、基于注解的 HTTP 客户端,由 Spring Cloud 提供支持。开发者可以像调用本地方法一样调用远程服务。
- 集成 Spring Cloud: Feign 是 Spring Cloud 中的一部分,天然集成了服务注册与发现、负载均衡等特性。
- 集成 Ribbon: 默认情况下,Feign 使用 Ribbon 作为负载均衡器,可以通过配置切换到其他负载均衡器。
- 集成 Hystrix: Feign 可以集成 Hystrix,实现对服务调用的熔断和降级。
服务消费方集成Feign
1、引入依赖
<!-- 添加 Spring Cloud Feign 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、启用 Feign:
在主应用程序类上添加 @EnableFeignClients 注解,以启用 Feign:
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableFeignClients
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
3、定义 Feign 接口:
使用 @FeignClient 注解定义 Feign 接口,通过 @RequestMapping 注解定义接口的请求路径和参数:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
// 也就是服务提供者的名字
@FeignClient(name = "your-service-name")
public interface YourFeignClient {
@GetMapping("/api/endpoint")
String getEndpointData();
}
4、注入并使用 Feign 接口:
在需要调用远程服务的地方注入 Feign 接口并使用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class YourService {
private final YourFeignClient feignClient;
@Autowired
public YourService(YourFeignClient feignClient) {
this.feignClient = feignClient;
}
public String fetchDataFromRemoteService() {
return feignClient.getEndpointData();
}
}
通过上述配置和代码,Feign 将自动处理服务的注册与发现、负载均衡等工作,开发者只需关注声明式的接口定义和注解配置。这样,Feign 提供了一种简洁而强大的方式来实现微服务之间的通信。
feign开启熔断
1、在 Feign 接口上使用 @FeignClient 注解时,通过 fallback 属性指定一个熔断时的备用实现类。该实现类需实现 Feign 接口,并处理熔断时的逻辑。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "your-service-name", fallback = YourFeignClientFallback.class)
public interface YourFeignClient {
@GetMapping("/api/endpoint")
String getEndpointData();
}
2、创建熔断时的备用实现类
创建一个实现了 Feign 接口的备用实现类,处理熔断时的逻辑:
import org.springframework.stereotype.Component;
@Component
public class YourFeignClientFallback implements YourFeignClient {
@Override
public String getEndpointData() {
return "Fallback Response"; // 备用逻辑
}
}
在上述实例中,如果 Feign 接口调用失败或超时,将会触发熔断器,调用 YourFeignClientFallback 中的备用逻辑。
示例:网关Spring Cloud Gateway的使用
Spring Cloud Gateway 比 Netflix Zuul 更强大
-
基于 Reactor: Spring Cloud Gateway 基于 Reactor 编写,使用 Reactor 的非阻塞、响应式编程模型,能够处理大量并发请求。
-
更灵活的路由配置: Spring Cloud Gateway 提供了更灵活的路由配置方式,支持 Groovy 脚本,同时也支持 Java 配置。
-
全面的过滤器: Spring Cloud Gateway 提供了丰富的过滤器,可以用于修改请求、响应,实现身份验证、日志记录等功能。
-
支持动态路由: 可以通过 Spring Cloud Config 实现动态路由的更新。
-
Spring 生态系统集成: 与 Spring Boot 和 Spring Cloud 生态系统更紧密集成,可以更容易地利用 Spring 生态系统的其他功能。
路由的使用
网关需要新创建一个 module
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
spring:
cloud:
gateway:
routes:
- id: backend-route
uri: http://example.com # 实际后端服务的地址
predicates:
- Path=/api/**
上述配置表示,将以 /api/** 开头的请求路由到 http://example.com。
过滤器的使用
Spring Cloud Gateway 提供了强大的过滤器(Filter)功能,允许你在请求进入网关或者响应离开网关的时候执行一些特定的逻辑。过滤器可以用于修改请求、修改响应、添加头信息、记录日志等。
1、创建一个过滤器:
创建一个实现 GatewayFilter 接口的自定义过滤器类。这个示例中,我们创建一个简单的过滤器,用于在请求到达网关时记录请求的时间。
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import java.util.logging.Logger;
@Component
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
final Logger logger = Logger.getLogger(CustomFilter.class.getName());
public CustomFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
logger.info("Custom Filter Pre: " + System.currentTimeMillis());
// 在这里可以添加一些自定义的逻辑
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
logger.info("Custom Filter Post: " + System.currentTimeMillis());
}));
};
}
public static class Config {
// 可以在这里添加一些配置参数
}
}
2、配置过滤器:
在配置文件中,配置 Spring Cloud Gateway 使用自定义的过滤器。
spring:
cloud:
gateway:
routes:
- id: backend-route
uri: http://example.com
predicates:
- Path=/api/**
filters:
- CustomFilter= # 可以在这里传入配置参数
在上述配置中,我们将 CustomFilter 添加到了路由的过滤器列表中。
3、启动应用:
启动应用并访问相应的路由,你将看到日志中有关于过滤器的记录。