微服务架构的一个重要特点是,它与开发中使用的具体编程语言或技术栈无关。每个微服务都可以使用最适合其功能需求的语言或技术来实现。例如,一个微服务可以用Java编写,另一个微服务可以用Python、Go、Node.js等编写。微服务架构允许这种灵活性,因为每个服务都是独立的,负责处理特定的业务功能,且每个服务都有独立的开发、部署和执行环境。
微服务之间通常需要通过某种通信机制进行交互,RESTful API是最常见的选择之一。RESTful风格基于HTTP协议,并使用标准的HTTP方法(如GET、POST、PUT、DELETE)来操作资源。由于HTTP协议是通用的,且每个编程语言都提供了对HTTP协议的强大支持,采用RESTful API可以使不同技术栈编写的微服务通过统一的接口进行通信。
RESTful
REST是一种架构风格,定义了如何设计系统以通过网络操作资源,而HTTP是一种传输协议,RESTful API通常使用HTTP作为底层协议来实现REST的设计理念。RESTful API是遵循REST原则并通过HTTP提供服务的API,利用HTTP的特性,如通过URL标识资源,使用GET、POST、PUT、DELETE等方法操作资源,并保持无状态通信。RESTful API通过合理应用HTTP方法和状态码来实现对资源的管理和操作,是一种特定的网络接口设计方式。
尽管RESTful API是非常常见的通信方式,但微服务并不强制要求使用RESTful架构风格。根据系统的需求和性能要求,微服务也可以使用其他通信协议,如:
- gRPC(基于HTTP/2的高效RPC框架)
- GraphQL(灵活的查询语言)
- 消息队列(如RabbitMQ、Kafka,用于异步通信)
微服务框架
第一代微服务架构:Spring Cloud由于基于REST的同步通信,服务之间的耦合性较高,调用链复杂时容易产生级联故障。此外,Spring Cloud的组件大多运行在应用层,随着服务数量的增加,管理复杂度上升。
Dubbo是阿里巴巴开源的面向服务的RPC框架,代表了第二代微服务架构。与Spring Cloud不同,Dubbo更强调高性能的RPC通信,适合服务数量较多、系统性能要求较高的场景。Dubbo的RPC通信方式虽然高效,但它的依赖更紧密,服务间的强耦合可能导致扩展性不如基于HTTP/REST的架构灵活。
Service Mesh代表了第三代微服务架构,它通过将服务间的网络通信功能下沉到基础设施层,使微服务更加关注业务逻辑,而不需要处理复杂的通信、负载均衡、监控等基础功能。
- 零侵入性:与Spring Cloud和Dubbo不同,Service Mesh不需要修改应用代码。所有的网络通信、流量管理、监控、策略控制等都由Sidecar代理完成。应用和基础设施解耦,开发者不再需要关心通信细节。
- 高级流量管理:Service Mesh能够提供更复杂的流量管理策略,如流量分割、灰度发布、熔断、限流等。这些功能可以通过配置实现,而无需在代码层面实现。
- 可观测性和安全性:Service Mesh可以通过Sidecar代理自动采集服务的监控数据、日志、分布式追踪等信息,提升了系统的可观测性。同时,它还能实现服务间的加密通信,提高数据传输的安全性。
典型实现:Service Mesh的典型实现包括Istio、Linkerd和Consul,其中Istio是目前最为流行的解决方案,广泛应用于Kubernetes环境下。
优点:Service Mesh实现了真正的“服务与基础设施分离”,开发者可以专注于业务逻辑,基础设施层自动处理复杂的网络通信、监控、安全等问题。此外,随着服务数量的增加,Service Mesh可以统一管理服务的流量和安全策略,适合大规模、复杂分布式系统的管理需求。
缺点:Service Mesh的引入增加了系统的复杂性,特别是在早期部署和维护时,Sidecar代理的管理和监控可能成为新的挑战。此外,由于Sidecar代理的存在,Service Mesh的性能开销也需要考虑。
统一的配置管理中心
在微服务架构中,每个服务通常都是独立的应用,具有各自的配置文件,例如数据库连接、API密钥、第三方服务地址等。然而,随着微服务数量的增加,配置管理变得复杂且难以维护,因此需要一个统一的配置管理中心来简化这个过程。
在微服务中有三种配置,第一种是几乎不变的配置,一般被打包在容器镜像中,第二种是启动的时候需要的配置,一般通过环境变量的方式放在创建pod的deployment或者deamonset文件中。第三种是微服务统一的配置,需要通过配置中心下发。
配置中心 SpringCloud Config
SpringCloud Config 是一个解决分布式系统的配置管理方案,它包含了 server 和 client 两个部分。 server 用来获取远程的配置信息(默认为 Git 仓库),并且以接口的形式提供出去,client 根据 server 提供的接口读取配置文件,以便于初始化自己的应用。如果配置中心出现了问题,将导致灾难性 的后果,因此在生产环境下配置中心都会做集群,来保证高可用。此处配置高可用实际就是把多个配置中 心(指定同一个 Git 远程仓库)注册到注册中心。
全链路监控
对系统的监控和对调用关系的监控。
zipkin,skywalking,pinpoint,prometheus。
Springcloud组件
eureka
服务发现和注册的组件。包含eureka client 和eureka server。
各个节点启动之后,就会将自己的ip等网络信息提供给eureka server。在微服务架构中,Eureka 客户端的下载和配置通常发生在微服务实例启动的过程中在构建微服务时,开发者需要在项目的依赖管理文件中(如 pom.xml 或 build.gradle)添加 Eureka 客户端的依赖。当微服务实例启动时,Spring Boot 应用会自动初始化 Eureka 客户端。在启动过程中,Eureka 客户端会读取配置文件中的信息,并尝试连接到配置的 Eureka 服务器。
Eureka Client 通常分为两个角色:服务提供者(Service Provider)和服务消费者(Service Consumer)。服务提供者是实现具体业务逻辑的微服务,它向 Eureka 服务器注册自己,以便其他服务可以发现并调用它。服务消费者是调用其他微服务的客户端,它从 Eureka 服务器获取需要调用的服务的实例信息。在构建项目时下载的依赖是 Eureka Client 的两个角色中的 服务提供者(Service Provider) 和 服务消费者(Service Consumer) 的通用实现。
eureka发起的操作有:
- 服务注册:当微服务实例启动的时候,Eureka 客户端会向 Eureka Server 发送注册请求,包含自身的 IP、端口和状态信息。
- 服务续约:Eureka 客户端会定期(通常每 30 秒)发送心跳请求,以续约其在 Eureka Server 上的注册状态,告知服务器它仍然活跃。
- 服务下线:当微服务实例关闭或不再需要注册时,Eureka 客户端会向 Eureka Server 发送取消请求,以从注册表中移除自身的信息。
其中服务消费者发起的是以下两个:
- 获取服务注册列表:服务消费者在需要调用其他服务时,会向 Eureka Server 查询当前的服务注册列表,以获取可用服务的实例信息。
- 远程调用:服务消费者根据从 Eureka Server 获取的服务实例信息,通过 HTTP 或其他协议调用目标服务。
而Eureka server发起的操作为:集群中数据同步。
- 在 Eureka 的集群模式中,Eureka Server 会在集群节点之间进行数据复制与同步,确保所有节点上的服务注册信息一致。
ribbon
ribbon是工作在消费者端的负载均衡,这意味着ribbon负载均衡是在服务消费者一侧执行的,而不是在服务提供者一侧或网关、代理等中间层执行的。Ribbon会通过服务注册中心(如Eureka)或通过配置文件中的静态列表,获取服务提供者的多个实例地址。通过某种负载均衡算法(如轮询、随机、权重等),ribbon选择一个服务实例来发送请求。这个负载均衡操作是发生在客户端的。
与eureka类似,ribbon也是一个嵌入在服务代码中的服务。假设服务 A 想调用服务 B,系统中可能存在多个服务 B 的实例(例如 B1
, B2
, B3
),Ribbon 的工作流程如下:
- 服务 A 通过 Ribbon 从服务注册中心(如 Eureka)获取服务 B 的所有可用实例的列表。
- Ribbon 根据负载均衡算法(例如轮询)选择一个实例,比如
B2
。 - 服务 A 通过 Ribbon 发送请求到
B2
实例。
与nginx的对比:
nginx是一个独立的服务,提供负载均衡。但是nginx抽象了服务之间的通信,服务发起方不需要知道服务提供者的信息,只需要知道nginx服务器的地址,而ribbon的服务发起端(服务A)需要知道服务提供者(服务B)的所有实例信息。
- Ribbon 可以实时检测服务实例的可用性和响应时间。如果某个实例的响应时间超过设定的阈值,Ribbon 会将其标记为不健康。
- 智能路由:在选择服务实例时,Ribbon 不仅考虑负载均衡策略(如轮询、随机等),还会优先选择那些符合 SLA 标准的实例。
- 容错处理:如果一个服务实例的性能下降到 SLA 标准以下,Ribbon 可以自动切换到其他健康的实例,避免影响用户体验。
Archaius 是 Netflix 提供的一个动态配置管理库,用于支持在运行时对应用配置进行动态更新。使用 Archaius 完成运行时配置的意思是,应用程序可以在不重新启动的情况下,实时更新和应用配置更改。Ribbon 作为客户端负载均衡器,可以根据不同的策略(如轮询、随机、权重)选择服务实例。通过 Archaius,Ribbon 的这些策略可以在运行时根据需求进行动态调整。
例如,如果当前的负载均衡策略是轮询,但系统负载增加时可以动态切换为权重负载均衡,Archaius 可以让你在不重启应用的情况下实现这一点。
Zuul
Hystrix
Netflix 开发的一个开源库,用于实现微服务架构中的容错管理。它的主要目的是在分布式系统中提高系统的稳定性和弹性,尤其是在面对服务调用失败或延迟时。Hystrix 在 SpringCloud 中负责服务熔断和服务降级的作用。
springCloud gateway
目前springcloud已经弃用了Zuul,转而使用springCloud gateway。springCloud gateway 已经集成了Hystrix,而且相比Zuul有更多的功能。