断路器-网关-链路追踪

为什么需要断路器

微服务架构中的断路器是一种重要的组件,用于增加系统的弹性和可靠性。它的存在是为了处理服务之间的故障和不稳定性,以防止故障扩散和影响整个系统的可用性。

断路器的作用类似于电路中的保险丝,当一个服务出现故障或响应时间过长时,断路器会中断对该服务的请求,而不是持续发送请求导致更多的故障或延迟。

以下是为什么微服务需要断路器的几个关键原因:

  1. 故障隔离:当一个微服务出现故障时,断路器可以快速地将该服务从系统中隔离,防止故障扩散到其他服务。这种隔离可以提高系统的可用性和稳定性。
  2. 容错机制:断路器能够检测到服务的故障或慢响应,并在达到一定的阈值后自动打开。一旦断路器打开,后续的请求将被快速失败,而不会占用系统资源。这可以防止系统出现雪崩效应,即多个故障的服务相互影响导致整个系统不可用。
  3. 快速恢复:当断路器打开时,通常会有一段时间进行休眠以防止继续发送请求。断路器还会定期尝试发送测试请求以检测服务是否已经恢复正常。一旦服务恢复,断路器会关闭,并重新允许请求通过。
  4. 实时监控和指标收集:断路器可以提供实时监控和指标收集,以便进行故障排除和性能优化。它可以记录服务的错误率、响应时间等指标,帮助开发人员了解服务的健康状况并采取适当的措施。

综上所述,断路器是微服务架构中的一项重要机制,它能够增加系统的弹性、可靠性和容错能力,确保整个系统在面对服务故障时仍然能够正常运行。

服务雪崩效应

bill-service > user-service

在这里插入图片描述

此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。

此时,如果Service C因为抗不住请求,变得不可用。

那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。

紧接着,Service A也会不可用,这一过程如下图所示

image-20230517170538389

如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩(面试装13必备)。 那么,服务熔断和服务降级就可以视为解决服务雪崩的手段之一。

断路器处理雪崩

雪崩效应(Avalanche Effect)是指在分布式系统中,当一个服务或组件发生故障或不可用时,其影响会逐渐扩散到其他依赖于该服务或组件的系统,导致整个系统出现级联故障,最终导致系统不可用的现象。

雪崩效应的发生通常是由于系统中的相互依赖关系和负载均衡策略。当一个服务或组件不可用时,其他服务会继续发送请求,可能会导致请求积压和超时。这会进一步增加其他服务的负载,可能会导致它们也出现故障或响应变慢。这种连锁反应会不断扩大,最终导致系统范围内的大规模故障。

雪崩效应的结果是系统整体性能急剧下降甚至完全失效,影响用户体验和业务连续性。为了减轻雪崩效应的影响,可以采取以下几种策略:

  1. 断路器模式:使用断路器来隔离故障的服务或组件,防止故障的扩散,并提供快速失败的响应,避免资源浪费。
  2. 限流策略:通过限制请求的速率或并发量,控制对故障服务的压力,避免过载。
  3. 超时设置:对请求设置适当的超时时间,避免请求一直等待响应而占用资源。
  4. 优雅降级:当某个服务不可用时,可以使用备用方案或默认值来代替,确保系统的基本功能可用。
  5. 异步处理:通过使用消息队列等异步方式处理请求,减少对实时响应的依赖,降低系统耦合性。

综上所述,雪崩效应是指在分布式系统中一个服务或组件的故障扩散导致整个系统出现级联故障的现象。为了应对雪崩效应,需要采取合适的策略和机制来保护系统的稳定性和可用性。

因此,需要实现一种机制,可以做到自动监控服务状态并根据调用情况进行自动处理。

断路器模式

  1. 记录时间周期内服务调用失败次数:在断路器模式中,会统计一定时间周期内服务调用的失败次数。这样可以用来评估服务的可用性和稳定性,当失败次数达到一定阈值时,断路器将会打开,停止对该服务的请求转发。
  2. 维护断路器的打开、关闭、半开三种状态:断路器有三种状态,即打开、关闭和半开。
    • 打开状态:当服务的失败次数达到预设的阈值时,断路器会打开。在打开状态下,所有对该服务的请求将被快速失败,不再转发到服务。
    • 关闭状态:当服务的失败次数低于阈值时,断路器会关闭。在关闭状态下,请求将正常转发到服务,允许服务正常处理。
    • 半开状态:在一段时间后,断路器可能会进入半开状态。在半开状态下,断路器会允许一部分请求通过到服务。如果这些请求成功响应,断路器将会关闭;如果有请求失败,断路器将重新打开。这个半开状态可以用来测试服务是否已经恢复正常,如果恢复了,则允许继续提供服务;否则,断路器会继续保持打开状态。
  3. 提供fallback机制:fallback机制是断路器模式中的一种补偿机制,用于在服务不可用或失败时提供备选方案。当断路器打开时,可以定义一个fallback方法或返回一个预定义的默认值作为替代响应。这样可以确保即使服务出现故障,系统依然可以提供一些有限的功能或响应,而不会完全失败。

这些概念在断路器模式中被广泛使用,可以提高系统的容错性、稳定性和可用性,减少故障的传播范围,并提供备选方案以保持基本的系统功能。

image-20230517170821159

代码加入netflix-hystrix

Kubernetes(K8s)本身并不提供内置的断路器功能,但可以与断路器模式和断路器库集成,以处理微服务中的断路器。

在Kubernetes中,以下是一些常见的方式来处理断路器:

  1. 使用断路器库:可以在Kubernetes部署的微服务中使用流行的断路器库,例如Netflix的Hystrix或Istio的Envoy等。这些库提供了断路器模式的实现,可以与Kubernetes集成,并通过配置和注解来定义断路器的行为。
  2. 服务网格(Service Mesh):Kubernetes上的服务网格解决方案(如Istio、Linkerd)提供了对微服务通信的细粒度控制,包括断路器功能。通过在服务网格中配置断路器规则,可以控制请求的路由和故障隔离,以实现断路器的行为。
  3. 自定义实现:在Kubernetes中,可以自己编写代码来实现断路器模式。这可以通过在微服务中集成断路器库或编写自定义代码来实现断路器的逻辑和状态管理。然后,可以使用Kubernetes的自动伸缩机制或配置管理来动态调整断路器的配置。

无论使用哪种方法,重要的是将断路器的概念和实现与Kubernetes中的微服务架构相结合。这样可以实现故障隔离、容错和可靠性,防止故障在系统中扩散,并提供备选方案来处理故障情况。

修改bill-service源码

pom.xml

image-20230517171557247

# 加入2个插件
        <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.yml

FeignNetflix开发的声明式、模块化的HTTP客户端。Feign可帮助我们更好更快的便捷、优雅地调用HTTP API

Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解。

server:
  port: 7001
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:bill-service}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除
    lease-expiration-duration-in-seconds: 2
spring:
  application:
    name: bill-service
feign:
  hystrix:
    enabled: true

BillController.java

package cn.yuchaoit.billservice.controller;


import cn.yuchaoit.billservice.entity.User;
import cn.yuchaoit.billservice.interfaces.UserServiceCli;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BillController {

    @Autowired
    private UserServiceCli userServiceCli;


    @GetMapping("/bill/user")
    public String getUserInfo(){
        return userServiceCli.getUserService();
    }

    @GetMapping("/bill/user/{id}")
    public User getUserInfo(@PathVariable("id") int id){
        return userServiceCli.getUserInfo(id);
        //return restTemplate.getForObject("http://USER-SERVICE/user/" + id, String.class);
    }
}

BillServiceApplication.java

package cn.yuchaoit.billservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class BillServiceApplication {

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

}

声明式服务Feign

从上一章节,我们知道,当我们要调用一个服务时,需要知道服务名和api地址,这样才能进行服务调用,服务少时,这样写觉得没有什么问题,但当服务一多,接口参数很多时,上面的写法就显得不够优雅了。

所以,接下来,来说说一种更好更优雅的调用服务的方式:Feign

FeignNetflix开发的声明式、模块化的HTTP客户端。Feign可帮助我们更好更快的便捷、优雅地调用HTTP API

Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解。Feign支持多种注释,例如Feign自带的注解或者JAX-RS注解等 Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和 Eureka,从而让Feign 的使用更加方便。只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。

UserServiceCli.java

package cn.yuchaoit.billservice.interfaces;

import cn.yuchaoit.billservice.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name="user-service", fallback = UserServiceFallbackImpl.class)
public interface UserServiceCli {

    @GetMapping("/user")
    public String getUserService();

    @GetMapping("/user/{id}")
    public User getUserInfo(@PathVariable("id") int id);
}

User.java

package cn.yuchaoit.billservice.entity;


public class User {
    private int id;
    private String name;
    private int age;
    private String sex;

    public int getAge() {
        return age;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

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

    public void setId(int id) {
        this.id = id;
    }

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

    public void setSex(String sex) {
        this.sex = sex;
    }
}

UserServiceFallbackImpl.java

package cn.yuchaoit.billservice.interfaces;

import cn.yuchaoit.billservice.entity.User;
import org.springframework.stereotype.Component;

@Component("fallback")
public class UserServiceFallbackImpl implements UserServiceCli{

    @Override
    public String getUserService() {
        return "fallback user service";
    }

    @Override
    public User getUserInfo(int id) {
        User user = new User();
        user.setId(1);
        user.setName("feign-fallback");
        return user;
    }
}

代码结构目录

image-20230517173746883

修改服务故障时间差

当注册中心后面维护的服务实例出现故障后,注册中心会存在时间差来感知到服务故障,这个时间差主要通过如下方面来调节。

Eureka Server

server:
  port: ${EUREKA_PORT:8761}
eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_SERVER:http://${spring.security.user.name}:${spring.security.user.password}@localhost:8761/eureka/}
    fetch-registry: true
    register-with-eureka: true
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    hostname: ${EUREKA_INSTANCE_HOSTNAME:localhost}
    prefer-ip-address: true
  server:
    # 间隔5秒执行一次检测任务
    eviction-interval-timer-in-ms: 5000
spring:
  security:
    user:
      name: ${EUREKA_USER:admin}
      password: ${EUREKA_PASS:admin}
  application:
    name: eureka-cluster

Eureka client

user-service

server:
  port: 7000
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:user-service}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除
    lease-expiration-duration-in-seconds: 2
spring:
  application:
    name: user-service

bill-service

server:
  port: 7001
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
    registry-fetch-interval-seconds: 5
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:bill-service}
spring:
  application:
    name: bill-service
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
feign:
  hystrix:
    enabled: true

重启所有服务

  • Eureka
  • user-service
  • bill-service

image-20230517174252475

此时服务调用正常

image-20230517174335598

以及

image-20230517175525641

停止user-service

user-service服务被剔除

image-20230517174400398

查看fallback页面

image-20230517175549940


阻断Bill服务调用user服务故障的影响。

image-20230517175722673

因此程序调用,就已知user-service接口故障,看到fallback数据,而不是系统崩溃。

如何理解fallback

Fallback(降级)指的是在系统出现故障、异常或负载过高等情况下,为了保证系统的可用性,提供备用方案或默认值,而不是完全失败。

在分布式系统中,当某个服务不可用或响应时间过长时,可以使用Fallback机制来提供一种替代方案。当请求发生故障时,系统将自动切换到预定义的Fallback逻辑,而不会中断整个流程。

Fallback可以是以下几种形式之一:

  1. 返回默认值:如果服务不可用,可以返回一个预先定义的默认值,以确保请求的响应能够继续进行。
  2. 执行备选逻辑:在服务不可用时,可以执行备选逻辑或方法来代替原始的请求处理。这可以是一些基本的功能或应急处理的逻辑。
  3. 返回缓存数据:如果服务无法响应时,可以返回之前缓存的数据作为响应,以提供最近可用的数据。

Fallback的目的是在面对故障或异常时保证系统的可用性,并提供一种替代方案。它可以减少用户的不良体验,避免整个请求链路的中断,并为系统提供一个应急的处理手段。

在实际实现中,可以通过编程方式定义Fallback逻辑,也可以使用断路器模式、服务网格或其他相关技术来自动处理Fallback。具体实现方式根据系统架构和需求的不同而有所差异。

例如云原生网关的应用

https://help.aliyun.com/document_detail/452214.html

微服务为什么需要网关

微服务通常需要网关来解决以下问题:

  1. 路由和负载均衡:微服务架构中存在多个独立部署的服务,每个服务都有自己的API或服务地址。通过引入网关,可以根据请求的URL将流量路由到相应的微服务上,并进行负载均衡,确保请求被合理地分发和处理。
  2. 协议转换和适配:不同的微服务可能使用不同的通信协议或技术栈,如HTTP、RPC或WebSocket。网关可以提供协议转换和适配的功能,使得客户端无需关注底层微服务的实现细节,只需与网关进行通信。
  3. 安全和身份验证:通过网关,可以集中处理安全性和身份验证的问题。网关可以进行统一的身份验证、访问控制和权限管理,确保只有经过授权的请求能够访问相应的微服务。
  4. 监控和日志记录:网关可以对请求和响应进行监控和记录,收集有关服务调用的指标和日志数据。这有助于故障排查、性能优化和系统监控。
  5. 缓存和性能优化:网关可以实现对一些常用请求的缓存,提高响应速度和系统性能。
  6. 服务聚合和分解:网关可以对多个微服务的请求进行聚合或分解,将多个请求合并为一个或将一个请求拆分为多个,以满足特定的业务需求。

综上所述,网关在微服务架构中起到了统一入口、路由分发、安全控制、性能优化等重要作用,简化了客户端的调用过程,并提供了集中化的管理和控制手段。

Nginx

Nginx是一个高性能的开源反向代理服务器,可以用于处理客户端请求并将它们转发到相应的后端服务。在微服务架构中,Nginx常被用作API网关,具有以下特点和功能:

  1. 反向代理:Nginx可以作为反向代理,接收客户端请求并将其转发到后端微服务。客户端只需要与Nginx进行通信,而无需直接与后端微服务进行交互。
  2. 负载均衡:Nginx可以通过配置多个后端服务的上游服务器,并根据负载均衡算法将请求分发到不同的服务实例,以提高系统的性能和可扩展性。
  3. 路由和请求转发:Nginx可以根据请求的URL、头部信息或其他规则进行路由和请求转发,将请求发送到相应的微服务实例。
  4. 缓存和静态文件服务:Nginx具有内置的缓存和静态文件服务功能,可以缓存经常请求的数据或直接提供静态资源,以减轻后端微服务的负载和提高系统响应速度。
  5. 安全性:Nginx可以提供SSL/TLS终端加密、客户端身份验证、IP白名单等安全功能,保护微服务免受恶意访问和攻击。

总而言之,Nginx在微服务架构中常被用作网关,通过反向代理、负载均衡、路由和请求转发等功能,提供统一的入口和访问控制,简化客户端与后端微服务之间的交互,并提供额外的性能优化和安全性保障。

Nginx和kong

Nginx和Kong都可以用作网关,具体使用哪个作为网关取决于需求和场景。

  1. Nginx作为网关:Nginx本身是一个强大的开源反向代理服务器,具有高性能、灵活性和可扩展性。它可以通过配置实现负载均衡、路由转发、缓存、安全性等功能,因此可以被用作简单的API网关。如果你只需要基本的请求转发和负载均衡功能,并且不需要额外的高级API管理功能,那么Nginx作为网关可能是一个简单且有效的选择。
  2. Kong作为网关:Kong是基于Nginx开发的一个开源API网关和微服务管理平台,它在Nginx的基础上扩展了许多高级功能,如API管理、认证授权、流量控制、监控日志等。Kong提供了丰富的插件和管理接口,使得构建和管理复杂的微服务架构更加方便和可靠。如果你需要更多的高级API管理功能,并且希望有一个集中化的管理平台来管理和配置网关,那么Kong可能是一个更合适的选择。

综上所述,Nginx和Kong都可以作为网关使用,但根据具体的需求和场景,选择哪个作为网关取决于所需的功能和管理需求。对于简单的需求,Nginx作为网关可能足够;而对于复杂的微服务架构和高级API管理需求,Kong可能提供更好的解决方案。

什么是网关

在微服务架构中,每个微服务都是独立部署的,它们有各自的API或服务地址。对于内部微服务之间的通信,可以通过注册中心进行自动发现和连接。然而,当这些服务需要向外部系统提供服务时,无法使用同一个注册中心,并且这些微服务通常位于内网,无法直接与外界通信。

此外,对于外部调用者来说,调用不同服务的地址和参数也是不尽相同的,这给客户端带来了复杂性。此外,微服务可能采用不同的技术栈,如HTTP、RPC或WebSocket,进一步增加了客户端的调用难度。

因此,为了解决这些问题,通常会引入一个API网关。API网关作为统一的入口,根据请求的URL将流量路由到不同的后端微服务上。同时,API网关还提供统一的身份验证、日志记录、流量控制等功能,以简化客户端的调用过程,并提供额外的操作和保护措施。

image-20230518144147407

每一个Service应用,都需要记录日志,反向代理等,因此做一个统一的网关做转发。

网关的功能

  • 减少api请求次数
  • 限流
  • 缓存
  • 统一认证
  • 降低微服务的复杂度
  • 支持混合通信协议(前端只和api通信,其他的由网关调用)

image-20230518144425318

zuul网关

Zuul和Nginx都是常用的网关技术,用于构建和管理微服务架构中的API网关。它们在功能和特性上有一些区别,但目标都是为了简化微服务的访问和管理。

  1. Zuul:Zuul是Netflix开源的一个基于Java的API网关服务,它提供了路由、负载均衡、请求过滤、认证授权等功能。Zuul旨在为微服务架构提供动态路由和过滤的能力,可以根据请求的URL、头部信息等进行路由和过滤,以便实现许多高级功能。Zuul通常与Spring Cloud等微服务框架一起使用。
  2. Nginx:Nginx是一个高性能的开源反向代理服务器,也可以用作API网关。Nginx具有强大的负载均衡和请求转发能力,可以根据配置将请求路由到不同的后端服务,并提供缓存、安全性和静态文件服务等功能。Nginx通常通过配置文件来管理路由和转发规则,支持自定义插件扩展。

虽然Zuul和Nginx都可以用作API网关,但它们在实现和生态系统上有一些不同。Zuul是一个专门为微服务架构设计的网关,提供了更多与微服务相关的功能,如服务发现、动态路由和过滤等。而Nginx是一个通用的反向代理服务器,可以用于各种场景,包括作为API网关。它可以通过配置文件进行路由和转发,并提供强大的性能和扩展性。

最终选择Zuul还是Nginx作为API网关,取决于具体的需求、技术栈和生态系统。如果你正在使用Spring Cloud等Java微服务框架,Zuul可能更容易集成和使用。如果你更喜欢灵活的配置和更广泛的用例,Nginx可能更适合你的需求。

新建zuul项目

zuul本身需要注册到Eureka、以及引入springcloud的依赖包。

image-20230518144721413

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.yuchaoit</groupId>
    <artifactId>gateway-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-zuul</name>
    <description>gateway-zuul</description>


    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>${project.artifactId}</finalName><!--打jar包去掉版本号-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

务必maven reload

application.yml

server:
  port: 10000

spring:
  application:
    name: gateway-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:gateway-zuul}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实力删除
    lease-expiration-duration-in-seconds: 2

GatewayZuulApplication.java

package cn.yuchaoit.gatewayzuul;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class GatewayZuulApplication {

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

}

启动项目

image-20230518161910943

Spring Cloud Actuator

https://www.baeldung.com/spring-boot-actuators

Spring Cloud的Actuator是一个用于管理和监控Spring Cloud应用程序的模块。Actuator提供了一组RESTful端点,可以通过这些端点来获取有关应用程序的健康状况、度量指标、日志和其他运行时信息。它是基于Spring Boot Actuator构建的,为Spring Cloud应用程序增加了一些特定的功能。

Actuator的端点可以提供以下信息:

  1. 健康状况:检查应用程序是否正常运行,并提供详细的健康状态报告。
  2. 度量指标:暴露应用程序的性能指标,例如内存使用情况、CPU使用情况、请求数量等。
  3. 环境信息:获取有关应用程序配置的详细信息,包括属性值和配置文件。
  4. 日志文件:访问应用程序的日志文件,可以查看应用程序的日志输出。
  5. 线程转储:提供有关应用程序中运行的线程的信息,可用于故障排查和性能调优。
  6. 远程Shell:通过远程Shell与应用程序进行交互,执行一些管理操作。

Actuator为开发人员和运维人员提供了方便的监控和管理接口,帮助他们更好地了解和控制Spring Cloud应用程序的运行状况。

http://127.0.0.1:10000/actuator/
http://127.0.0.1:8761/actuator/

修改zuul代理配置

暴露更多API

server:
  port: 10000

spring:
  application:
    name: gateway-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:gateway-zuul}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实力删除
    lease-expiration-duration-in-seconds: 2

management:
  endpoints:
    web:
      exposure:
        include: "*"

http://127.0.0.1:10000/actuator/

image-20230518162055275

routes接口

image-20230518162116009

走网关访问服务

http://127.0.0.1:10000/user-service/user

http://127.0.0.1:10000/user-service/user/6

image-20230518162317484

http://127.0.0.1:10000/bill-service/bill/user/1

image-20230518162416480

修改代理配置

这段配置是 Zuul 的路由规则配置,用于将传入的请求转发到相应的后端服务。具体解释如下:

  • user-service 是一个服务名称或 ID,表示后端的用户服务。
  • /users/** 是一个匹配规则,它会将所有以 /users/ 开头的请求转发到 user-service 服务。
  • bill-service 是另一个服务名称或 ID,表示后端的账单服务。
  • /bill/** 是另一个匹配规则,它会将所有以 /bill/ 开头的请求转发到 bill-service 服务。

简而言之,这段配置告诉 Zuul 当收到以 /users/ 开头的请求时,将其转发到名为 user-service 的后端服务;而对于以 /bill/ 开头的请求,将其转发到名为 bill-service 的后端服务。

这样,Zuul 可以作为一个 API 网关,根据配置将请求导向不同的后端服务,实现请求路由和负载均衡的功能。

server:
  port: 10000

spring:
  application:
    name: gateway-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:gateway-zuul}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实力删除
    lease-expiration-duration-in-seconds: 2

management:
  endpoints:
    web:
      exposure:
        include: "*"
zuul:
  routes:
    user-service: /users/**
    bill-service:
      path: /bill/**
      service-id: bill-service

重启查看新路由

image-20230518162849791

http://127.0.0.1:10000/users/user/1

image-20230518163108514

自定义prefix

server:
  port: 10000

spring:
  application:
    name: gateway-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:gateway-zuul}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实力删除
    lease-expiration-duration-in-seconds: 2

management:
  endpoints:
    web:
      exposure:
        include: "*"
zuul:
  routes:
    user-service: /users/**
    bill-service:
      path: /bill/**
      service-id: bill-service
  prefix: /apis

http://127.0.0.1:10000/apis/users/user/1

以此实现统一的URL前缀

image-20230519121242512

查看可访问的API

image-20230519121405460

http://127.0.0.1:10000/apis/users/user/1

微服务为什么需要链路追踪系统

微服务架构中的每个服务都是相互独立的,处理一部分特定的业务逻辑。当一个请求在微服务之间传递时,它可能会经过多个不同的服务,每个服务都可能会产生一些日志和监控数据。这样的分布式系统中,出现了一些传统的监控和调试方法无法满足的挑战。

以下是微服务中为什么需要链路追踪系统的几个主要原因:

  1. 故障排查和问题定位:当一个请求在多个微服务之间传递时,如果出现了故障或错误,追踪请求的完整路径可以帮助我们快速定位问题所在。链路追踪系统可以提供请求的完整调用链信息,从而缩小故障排查范围,减少排查时间。
  2. 性能优化和瓶颈分析:链路追踪系统可以收集每个微服务的请求处理时间和资源消耗等指标。通过分析这些指标,我们可以找到性能瓶颈,了解每个服务的性能情况,并进行优化。同时,链路追踪系统也可以提供整体系统的性能指标,以便我们监控系统的健康状况。
  3. 服务依赖管理和版本控制:在微服务架构中,服务之间的依赖关系可能非常复杂。链路追踪系统可以帮助我们了解每个微服务的依赖情况,并监控服务之间的调用关系。这对于服务的版本控制、升级和变更管理非常重要,可以帮助我们避免出现意外的服务不兼容性问题。
  4. 总体系统可观测性:微服务架构中的每个微服务都是一个相对独立的部分,但是整个系统的行为是由这些微服务相互交互产生的。链路追踪系统可以提供整体系统的可观测性,帮助我们了解系统的整体健康状况,及时发现和解决潜在问题。

综上所述,链路追踪系统在微服务架构中起着重要的作用,可以帮助我们快速定位问题、优化性能、管理依赖关系,并提供整体系统的可观测性,从而提高系统的稳定性和可靠性。

链路追踪可选系统

img

全链路追踪工具一览:

  • Drapper(google--未开源):最早的APM;
  • 鹰眼(阿里--未开源):
  • CAT(大众点评--开源):跨服务的跟踪功能与点评内部的RPC框架集成,这部分未开源且项目在2014.1已经停止维护。服务粒度的监控,通过代码埋点的方式来实现监控,比如: 拦截器,注解,过滤器等,对代码的侵入性较大,集成成本较高;
  • Hydra(京东):与dubbo框架集成,对于服务级别的跟踪统计,现有业务可以无缝接入。对于细粒度的兴趣点,需要业务人员手动添加.开源项目已于2013年6月停止维护;
  • PinPoint(naver--开源):字节码探针技术,代码无侵入,体系完善不易修改,支持java,技术栈支持dubbo.其他语言社区支援中;
  • Zipkin(Twitter--开源):方便集成于spring cloud sleuth,社区支持的插件也包括dubbo,rabbit,mysql,httpclient等,同时支持php,go,js等语言客户端,界面功能较为简单,本身无告警功能,可能需要二次开发。代码入侵度小;
  • Uber-jaeger:Jaeger支持java/c++/go/node/php,在界面上较为完善(对比zipkin),但是也无告警功能。代码入侵度小。dubbo目前无插件支持,可二次开发;
  • Skywalking(华为--开源):类似于PinPoint,目前还在apache孵化中,网上吞吐量对比中强于pinpoint,实际未验证。本身支持dubbo;

全链路追踪的核心思想:

  • 为每条请求都单独分配一个唯一的 traceId 用来标识一条请求链路,该 traceId 会贯穿整个请求处理过程的所有服务。
  • 每个服务/线程都拥有自己的 spanId 标识,代表请求的其中一段处理步骤。
  • 一个请求包含一个 traceId 和一个或多个 spanId。

image-20230519151439122

Spring Cloud Sleuth

Spring Cloud Sleuth是一个用于分布式系统中追踪请求链路的开源框架。它是Spring Cloud生态系统的一部分,用于解决微服务架构中的分布式追踪问题。

Spring Cloud Sleuth可以自动为请求生成唯一的跟踪ID,并将其传递给所有涉及的微服务。它使用了OpenTracing和Zipkin等开放标准,通过在请求的各个服务之间添加跟踪信息,帮助开发人员在分布式系统中追踪和调试请求的流向和性能。

通过Spring Cloud Sleuth,开发人员可以快速了解请求在不同微服务之间的流动情况,包括请求的起点、终点以及经过的中间服务。它还提供了可视化的跟踪数据和性能指标,帮助开发人员进行故障排除和性能优化。

总之,Spring Cloud Sleuth是一个用于分布式系统中请求链路追踪的工具,可以帮助开发人员识别和解决分布式系统中的问题。

zipkin系统

Spring Cloud 中使用 Zipkin 是为了实现分布式系统的跟踪和监控功能。在分布式系统中,请求往往会经过多个服务的处理,每个服务都可能产生一些日志和监控数据。通过集成 Zipkin,可以将每个服务的请求链路信息收集起来,形成完整的跟踪信息。

使用 Zipkin 可以实现以下功能:

  1. 请求链路追踪:通过在每个服务中埋点,收集请求的调用信息和时间戳,形成请求链路图,可以查看请求从起始到终止的完整路径,方便排查问题和优化性能。
  2. 性能监控:收集每个服务的请求处理时间和资源消耗等指标,可以对系统的性能进行监控和分析,发现潜在的性能瓶颈和问题。
  3. 故障排查:当系统出现故障或异常时,可以通过查看请求链路信息,快速定位出问题的服务和具体的调用过程,方便进行故障排查和修复。

因此,Spring Cloud 中使用 Zipkin 是为了实现分布式系统的可观测性和故障排查能力,以提高系统的稳定性和性能。

image-20230519142423865


img

链路追踪名词

服务追踪的追踪单元是从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为止的过程,称为一个 trace。

每个 trace 中会调用若干个服务,为了记录调用了哪些服务,以及每次调用的消耗时间等信息,在每次调用服务时,埋入一个调用记录,称为一个 span。

这样,若干个有序的 span 就组成了一个 trace。

在系统向外界提供服务的过程中,会不断地有请求和响应发生,也就会不断生成 trace,把这些带有 span 的 trace 记录下来,就可以描绘出一幅系统的服务拓扑图。

附带上 span 中的响应时间,以及请求成功与否等信息,就可以在发生问题的时候,找到异常的服务;根据历史数据,还可以从系统整体层面分析出哪里性能差,定位性能优化的目标。

image-20230519143937080

Spring Cloud Sleuth 为服务之间调用提供链路追踪。

通过 Sleuth 可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而让我们可以很方便的理清各微服务间的调用关系。

此外 Sleuth 可以帮助我们:

  • 耗时分析: 通过 Sleuth 可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;

  • 链路优化: 对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。

  • 可视化错误: 对于程序未捕捉的异常,可以通过集成 Zipkin 服务界面上看到;
  • Spring Cloud Sleuth 可以结合 Zipkin,将信息发送到 Zipkin,利用 Zipkin 的存储来存储信息,利用 Zipkin UI 来展示数据。

安装zipkin

https://zipkin.io/pages/quickstart

apiVersion: apps/v1
kind: Deployment
metadata:
  name: zipkin
  namespace: yuchao
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zipkin
  template:
    metadata:
      labels:
        app: zipkin
    spec:
      containers:
        - name: zipkin
          image: openzipkin/zipkin:2.22
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9411
          resources:
            requests:
              memory: 400Mi
              cpu: 50m
            limits:
              memory: 2Gi
              cpu: 2000m
---
apiVersion: v1
kind: Service
metadata:
  name: zipkin
  namespace: yuchao
spec:
  ports:
    - port: 9411
      protocol: TCP
      targetPort: 9411
  selector:
    app: zipkin
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: zipkin
  namespace: yuchao
spec:
  ingressClassName: nginx
  rules:
  - host: zipkin.yuchaoit.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: zipkin
            port:
              number: 9411

创建启动

[root@k8s-master ~/springcloud]#kubectl apply -f zipkin.yml 
deployment.apps/zipkin created
service/zipkin created
ingress.networking.k8s.io/zipkin created
[root@k8s-master ~/springcloud]#

[root@k8s-master ~/springcloud]#kubectl -n yuchao get po
NAME                            READY   STATUS    RESTARTS         AGE
eladmin-api-7496b69c-dr9jk      1/1     Running   11 (3d23h ago)   7d22h
eladmin-web-7458474b64-jvcfg    1/1     Running   0                19h
eureka-cluster-0                1/1     Running   0                42m
eureka-cluster-1                1/1     Running   0                42m
eureka-cluster-2                1/1     Running   0                2d20h
mysql-559d5fcc8b-r7vnd          1/1     Running   0                19h
redis-7957d49f44-v6gjc          1/1     Running   0                19h
user-service-5997c9d59f-b2b57   1/1     Running   0                19h
user-service-5997c9d59f-ftc2c   1/1     Running   0                46h
user-service-5997c9d59f-vdw9n   1/1     Running   0                19h
user-service-5997c9d59f-z885f   1/1     Running   0                19h
zipkin-6cc5cbdd5d-sgcwd         1/1     Running   0                27s
[root@k8s-master ~/springcloud]#


[root@k8s-master ~/springcloud]#kubectl -n yuchao logs zipkin-6cc5cbdd5d-sgcwd 
2023-05-19 06:37:54,968 main ERROR Incorrect number of options on style. Expected at least 1, received 0
2023-05-19 06:37:54,975 main WARN Class org.springframework.boot.logging.log4j2.ColorConverter does not extend PatternConverter.
2023-05-19 06:37:54,976 main ERROR Unrecognized conversion specifier [clr] starting at position 4 in conversion pattern.
2023-05-19 06:37:54,976 main ERROR Incorrect number of options on style. Expected at least 1, received 0
2023-05-19 06:37:54,976 main WARN Class org.springframework.boot.logging.log4j2.ColorConverter does not extend PatternConverter.
2023-05-19 06:37:54,977 main ERROR Unrecognized conversion specifier [clr] starting at position 14 in conversion pattern.

                  oo
                 oooo
                oooooo
               oooooooo
              oooooooooo
             oooooooooooo
           ooooooo  ooooooo
          oooooo     ooooooo
         oooooo       ooooooo
        oooooo   o  o   oooooo
       oooooo   oo  oo   oooooo
     ooooooo  oooo  oooo  ooooooo
    oooooo   ooooo  ooooo  ooooooo
   oooooo   oooooo  oooooo  ooooooo
  oooooooo      oo  oo      oooooooo
  ooooooooooooo oo  oo ooooooooooooo
      oooooooooooo  oooooooooooo
          oooooooo  oooooooo
              oooo  oooo

     ________ ____  _  _____ _   _
    |__  /_ _|  _ \| |/ /_ _| \ | |
      / / | || |_) | ' / | ||  \| |
     / /_ | ||  __/| . \ | || |\  |
    |____|___|_|   |_|\_\___|_| \_|

:: version 2.22.2 :: commit 0b246dd ::

2023-05-19 06:37:56.296 %clr( INFO) %clr([/]){yellow} 1 --- [oss-http-*:9411] c.l.a.s.Server                           : Serving HTTP at /[0:0:0:0:0:0:0:0%0]:9411 - http://127.0.0.1:9411/
[root@k8s-master ~/springcloud]#

访问zipkin仪表板

image-20230519144144163

微服务改造

代码中引入zipkin插件

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

user-service

image-20230519144349169

bill-service

pom.xml

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

application.yml修改

A>B>C,请求打锚点

spring:
  zipkin:
    base-url: http://zipkin.yuchaoit.cn  # zipkin服务器的地址
    sender:
      type: web  # 设置使用http的方式传输数据
  sleuth:
    sampler:
      probability: 1  # 设置抽样采集为100%,默认为0.1,即10%
logging:
  level:
    org.springframework.cloud: debug

User-service.yml

server:
  port: 7000
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:user-service}
    #eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
    lease-renewal-interval-in-seconds: 2
    #eureka服务器在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除
    lease-expiration-duration-in-seconds: 2
spring:
  application:
    name: user-service
  zipkin:
    base-url: http://zipkin.yuchaoit.cn  # zipkin服务器的地址
    sender:
      type: web  # 设置使用http的方式传输数据
  sleuth:
    sampler:
      probability: 1  # 设置抽样采集为100%,默认为0.1,即10%
logging:
  level:
    org.springframework.cloud: debug

bill-service.yml

server:
  port: 7001
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://admin:admin@localhost:8761/eureka/}
    registry-fetch-interval-seconds: 5
  instance:
    instance-id: ${eureka.instance.hostname}:${server.port}
    prefer-ip-address: true
    hostname: ${INSTANCE_HOSTNAME:bill-service}
spring:
  application:
    name: bill-service
  zipkin:
    base-url: http://zipkin.yuchaoit.cn  # zipkin服务器的地址
    sender:
      type: web  # 设置使用http的方式传输数据
  sleuth:
    sampler:
      probability: 1  # 设置抽样采集为100%,默认为0.1,即10%
logging:
  level:
    org.springframework.cloud: debug
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
feign:
  hystrix:
    enabled: true

查询zipkin仪表板

此时zipkin就已经能检测微服务之间的链路调用关系

你还得主动让服务之间调用,才会生成锚点,以及访问链路关系。

http://127.0.0.1:10000/apis/bill/bill/user/22

debug日志记录

image-20230519145824100

run query

image-20230519145907655

image-20230519150052400

微服务依赖关系

当你整个系统中,有很多服务互相调用,可以直观看到微服务调用的关系。

image-20230519150319887

这个插件对服务调用是有一定影响的。

可以理解如

于超老师从昌平 > 朝阳,每到一个站都要登记记录,必然会影响你的行动速度。

skywalking

https://github.com/apache/skywalking

Apache SkyWalking是一个开源的分布式系统跟踪、监控和性能分析工具。

它旨在帮助开发人员和运维团队对复杂的分布式系统进行可视化追踪和监控。

SkyWalking提供了以下功能:

  1. 链路追踪:SkyWalking可以追踪请求在分布式系统中的流向,从而帮助开发人员理解请求经过的服务和组件,以及每个组件的处理时间。
  2. 性能监控:SkyWalking可以监控应用程序的性能指标,例如响应时间、吞吐量和错误率。它能够帮助开发人员识别性能瓶颈并进行性能优化。
  3. 分布式追踪:SkyWalking支持多种语言和框架,可以跟踪不同语言和跨语言的微服务,以及常见的框架和中间件,如Spring、Dubbo、gRPC等。
  4. 告警和可视化:SkyWalking提供了告警功能,可以根据自定义规则触发告警。同时,它还提供了直观的用户界面,可视化展示跟踪数据、性能指标和告警信息。

总之,Apache SkyWalking是一个功能强大的分布式系统跟踪和监控工具,可帮助开发人员和运维团队理解分布式系统的运行情况,识别性能问题,并提供可视化的数据展示和告警功能。它被广泛用于微服务架构和云原生应用程序的监控和优化。

image-20230519153053822

总结微服务开发

微服务开发是一种软件开发方法论,它将应用程序拆分成一组小型、独立的服务。每个服务都有自己的特定功能,并使用轻量级的通信机制来相互交互。微服务开发的理解可以从以下几个方面进行:

  1. 服务拆分:微服务开发强调将应用程序拆分成多个小型服务,每个服务专注于解决一个特定的业务问题。这种拆分有助于降低系统的复杂性,提高可维护性和可扩展性。
  2. 独立部署:每个微服务都可以独立部署,这意味着对一个服务的修改和更新不会对其他服务产生影响。这种独立性简化了开发、测试和部署过程,并提供了更快速的发布周期。
  3. 轻量级通信:微服务之间通过轻量级的通信机制进行交互,常见的方式包括使用RESTful API、消息队列或事件驱动架构。这种松耦合的通信方式使得各个服务可以独立演化,并能够使用不同的技术栈来实现。
  4. 分布式治理:微服务开发需要解决分布式系统中的一些挑战,例如服务发现、负载均衡、容错处理和监控等。采用适当的分布式治理策略可以确保服务之间的可靠通信和高可用性。
  5. 弹性设计:微服务开发强调弹性设计,即系统应对故障和负载变化具有弹性。通过使用自动扩展、容错机制和监控手段,微服务能够应对不同的运行时条件,并保持高可用性和性能。

总之,微服务开发是一种将应用程序拆分成小型、独立的服务,并通过轻量级通信实现服务之间相互协作的软件开发方法。它能够提高开发效率、系统的可维护性和可扩展性,适用于构建复杂、分布式的应用系统。

微服务哪些技术栈

微服务开发通常涉及多种技术栈,具体选择哪些技术栈取决于你的项目需求、团队技术能力和个人偏好。以下是一些常见的技术栈和工具,可以作为学习微服务开发的参考:

  1. 服务框架:Spring Boot、Node.js、Django等。这些框架提供了快速构建微服务的能力,具有成熟的生态系统和丰富的功能。
  2. 通信协议与API设计:RESTful API是常见的微服务通信方式,可以使用工具如Swagger或OpenAPI规范来设计和文档化API。
  3. 容器与编排:Docker和Kubernetes是常用的容器化和部署工具,它们提供了跨平台、可移植和可扩展的部署环境。
  4. 服务发现与负载均衡:Consul、Eureka、ZooKeeper等用于服务发现和注册,Nginx、HAProxy等用于负载均衡。
  5. 数据存储:常见的数据库技术包括关系型数据库(如MySQL、PostgreSQL)、NoSQL数据库(如MongoDB、Redis)和分布式存储(如Apache Cassandra)。
  6. 日志和监控:ELK Stack(Elasticsearch、Logstash、Kibana)、Prometheus、Grafana等用于日志和指标收集、分析和可视化。
  7. 安全和身份验证:OAuth、JWT(JSON Web Tokens)、Spring Security等用于实现身份验证和授权机制。
  8. 消息队列和事件驱动:Apache Kafka、RabbitMQ、ActiveMQ等用于实现异步通信和事件驱动架构。
  9. 自动化测试和部署:使用工具如JUnit、TestNG、Jenkins、GitLab CI等实现自动化测试和持续集成/持续部署(CI/CD)。

除了上述技术栈,还有其他许多工具和框架可用于微服务开发。选择适合你的项目需求和技术栈的组合,并深入学习和实践这些技术,以便更好地开发和管理微服务应用。

image-20230519154401800

对微服务的理解,就是上述架构,每一个组件的作用了。

为什么学本系列知识点

  • 从零到一,从源码创建,开发单个的java服务应用,并且完成服务调用,bill > user。
  • 理解微服务为什么会需要注册中心、微服务互相调用时,必须考虑处理的异常情况,断路器,以及网关、链路追踪的作用。
  • 并且服务拆分开发之后,以k8s容器化部署的流程,这就是微服务架构的开发、与运维的基本逻辑。
  • 下一步就是学习微服务容器化运行之后,想要更好的调度pod负载均衡的流量,得学习如Istio工具。
Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2024-03-31 19:43:26

results matching ""

    No results matching ""