微服务三大配件深度解析、实现

一、背景知识

随着信息技术的飞速发展,企业应用系统的规模和复杂度日益增加。传统的单体架构已经难以满足现代应用对高可用性、可扩展性和灵活性的需求。微服务架构作为一种新兴的架构模式,通过将复杂的系统拆分为多个小型、自治的服务单元,有效解决了单体架构面临的诸多问题。微服务架构的核心在于其三大配件:服务注册与发现、API网关和配置中心。这些配件共同协作,确保了微服务系统的稳定运行和高效管理。

二、概念
1. 服务注册与发现

服务注册与发现是微服务架构中的基础组件之一。在微服务架构中,每个服务实例启动时都会将自己的服务信息(如IP地址、端口号、服务名称等)注册到服务注册中心。服务注册中心会维护一个服务实例列表,供服务消费者查询和调用。服务消费者通过服务注册中心获取可用的服务实例列表,然后根据负载均衡策略选择合适的服务实例进行调用。

2. API网关

API网关是微服务架构的入口点,负责管理和处理外部请求。它充当着反向代理的角色,将外部请求转发到内部的微服务实例。API网关不仅提供了路由和负载均衡功能,还可以实现身份验证、授权、请求转换、协议转换等多种功能。通过API网关,开发者可以集中管理和控制对微服务的访问,提高系统的安全性和可维护性。

3. 配置中心

配置中心是微服务架构中用于集中管理和动态更新应用程序配置信息的组件。在微服务架构中,每个服务实例都需要访问一些配置信息,如数据库连接信息、消息队列连接信息等。传统的方式是将这些配置信息硬编码在应用程序中,但这种方式存在诸多问题,如配置信息的更新需要重新部署应用程序、配置信息的分散管理导致难以维护等。配置中心通过集中管理配置信息,支持动态更新配置,解决了这些问题,提高了系统的灵活性和可维护性。

三、功能点
1. 服务注册与发现的功能点
  • 服务注册:服务实例启动时,将自己的服务信息注册到服务注册中心。
  • 服务发现:服务消费者通过服务注册中心获取可用的服务实例列表。
  • 负载均衡:服务注册中心可以根据服务实例的负载情况,为服务消费者提供合适的服务实例。
  • 健康检查:服务注册中心可以定期检查服务实例的健康状态,确保服务消费者不会调用到不可用的服务实例。
  • 服务治理:服务注册中心可以提供服务治理功能,如熔断降级、限流等,提高系统的稳定性和可用性。
2. API网关的功能点
  • 路由与负载均衡:根据请求的路径、参数或标头将流量路由到相应的微服务实例,实现请求的分发和负载均衡。
  • 身份验证与授权:管理用户身份验证和授权,确保只有经过授权的用户才能访问特定的微服务。
  • 请求转换:对请求进行转换和修改,使其符合后端微服务的期望格式和协议。
  • 协议转换:处理不同协议之间的转换,使得系统能够支持多种通信协议。
  • 流量控制:对流量进行限流、熔断等控制,防止系统过载。
3. 配置中心的功能点
  • 集中管理配置:提供集中式的位置来管理微服务系统的配置信息。
  • 动态更新配置:支持动态更新配置,无需重新启动服务即可应用新的配置。
  • 版本控制:支持配置的版本控制,能够追踪配置的变更历史。
  • 安全性管理:提供安全的配置管理机制,确保敏感信息得到保护。
  • 实时监控:提供实时监控和统计,了解各个微服务当前使用的配置信息。
四、业务场景
1. 服务注册与发现的业务场景

在电子商务平台中,商品管理、订单管理、支付服务等多个微服务共同协作完成业务流程。当支付服务需要调用订单服务时,支付服务通过服务注册中心获取订单服务的实例列表,然后根据负载均衡策略选择合适的订单服务实例进行调用。如果某个订单服务实例出现故障,服务注册中心会将其从实例列表中移除,确保支付服务不会调用到不可用的订单服务实例。

2. API网关的业务场景

在社交网络平台中,API网关作为系统的入口点,负责管理和处理外部请求。当外部用户请求访问某个用户的主页时,API网关会根据请求的路径将流量路由到相应的用户管理服务实例。同时,API网关还会对用户进行身份验证和授权,确保只有经过授权的用户才能访问特定用户的主页。如果某个用户管理服务实例出现故障,API网关会自动将其从负载均衡列表中移除,确保外部请求不会被转发到不可用的服务实例。

3. 配置中心的业务场景

在银行核心系统中,配置中心集中管理各个微服务的配置信息。当某个微服务的数据库连接信息发生变化时,管理员可以通过配置中心动态更新配置信息,而无需重新启动服务。同时,配置中心还提供了版本控制功能,使得管理员可以追踪配置的变更历史,方便进行回滚和版本管理。此外,配置中心还提供了实时监控功能,使得管理员可以了解各个微服务当前使用的配置信息,方便进行故障排查和性能优化。

五、底层原理
1. 服务注册与发现的底层原理

服务注册与发现的底层原理主要涉及服务注册中心的实现方式和服务发现机制。服务注册中心通常采用分布式集群部署来保证高可用性,并通过分布式一致性协议来确保集群中不同节点之间的数据保持一致。在服务注册阶段,服务实例通过调用服务注册中心的注册接口将自己的服务信息注册到服务注册中心。服务注册中心接收到注册请求后,会将这些服务信息存储在一个内存数据结构(如Map)中,并为其分配一个唯一的标识符(如服务ID)。在服务发现阶段,服务消费者通过调用服务注册中心的服务订阅接口获取可用的服务实例列表。服务注册中心会根据服务消费者的请求参数(如服务名称)从内存数据结构中查询相应的服务实例列表,并将其返回给服务消费者。服务注册中心还会定期检查服务实例的健康状态,如果某个服务实例出现故障或超时未响应心跳请求,服务注册中心会将其从内存数据结构中移除,并通知所有订阅该服务的服务消费者刷新本地缓存的服务实例列表。

2. API网关的底层原理

API网关的底层原理主要涉及反向代理、路由与负载均衡、身份验证与授权等机制。在反向代理方面,API网关通常采用Nginx、HAProxy等高性能反向代理服务器来分发流量。在路由与负载均衡方面,API网关会根据请求的路径、参数或标头将流量路由到相应的微服务实例,并实现负载均衡。负载均衡算法通常包括轮询、随机、最少连接数等。在身份验证与授权方面,API网关可以采用OAuth2、JWT等身份验证机制来管理用户身份验证和授权。当外部请求到达API网关时,API网关会首先进行身份验证和授权检查,确保只有经过授权的用户才能访问特定的微服务。如果身份验证和授权检查通过,API网关会将请求转发到相应的微服务实例;如果身份验证和授权检查失败,API网关会返回相应的错误响应。

3. 配置中心的底层原理

配置中心的底层原理主要涉及配置信息的存储、动态更新和版本控制等机制。在配置信息的存储方面,配置中心通常采用分布式键值存储系统(如etcd、Consul等)来集中管理配置信息。这些分布式键值存储系统具有高可用性、一致性、分区容错性等特性,能够满足微服务架构对配置信息存储的需求。在动态更新方面,配置中心提供了RESTful API等接口供客户端调用以动态更新配置信息。当客户端调用这些接口时,配置中心会将新的配置信息存储到分布式键值存储系统中,并通知所有订阅该配置的服务实例刷新本地缓存的配置信息。在版本控制方面,配置中心为每个配置项分配一个唯一的版本号,并记录每次配置变更的历史记录。这使得管理员可以追踪配置的变更历史,方便进行回滚和版本管理。

六、Java Demo实现

以下是一个基于Spring Cloud的Java Demo,用于演示微服务三大配件(服务注册与发现、API网关和配置中心)的实现。

1. 服务注册与发现的Java Demo
服务提供者(OrderService)
java复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
@RestController
class OrderController {
@Value("${server.port}")
private String port;
@GetMapping("/order")
public String getOrder() {
return "Order Service is running on port: " + port;
    }
}

application.yml中配置Eureka客户端信息:

yaml复制代码
server:
port: 8081
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
服务消费者(PaymentService)
java复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class PaymentServiceApplication {
public static void main(String[] args) {
        SpringApplication.run(PaymentServiceApplication.class, args);
    }
}
@FeignClient(name = "order-service")
interface OrderServiceClient {
@GetMapping("/order")
    String getOrder();
}
@RestController
class PaymentController {
@Autowired
private OrderServiceClient orderServiceClient;
@GetMapping("/payment")
public String getPayment() {
return "Payment Service calls Order Service: " + orderServiceClient.getOrder();
    }
}

application.yml中配置Eureka客户端信息和Feign客户端信息:

yaml复制代码
server:
port: 8082
spring:
application:
name: payment-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
feign:
hystrix:
enabled: true
Eureka服务注册中心
java复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

application.yml中配置Eureka服务器信息:

yaml复制代码
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
2. API网关的Java Demo
java复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
                .route("order_route", r -> r.path("/order/**")
                        .filters(f -> f.stripPrefix(1))
                        .uri("http://localhost:8081"))
                .route("payment_route", r -> r.path("/payment/**")
                        .filters(f -> f.stripPrefix(1))
                        .uri("http://localhost:8082"))
                .build();
    }
}

application.yml中配置API网关信息:

yaml复制代码
server:
port: 8080
spring:
application:
name: api-gateway
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
3. 配置中心的Java Demo
配置中心服务器(ConfigServer)
java复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

application.yml中配置配置中心服务器信息:

yaml复制代码
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/your-repo/config-repo.git
配置客户端(OrderService作为配置客户端)

OrderServiceApplication中添加对配置中心的依赖:

java复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.annotation.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer // 这里启用配置客户端功能
public class OrderServiceApplication {
public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

bootstrap.yml中配置配置客户端信息:

yaml复制代码
spring:
application:
name: order-service
cloud:
config:
uri: http://localhost:8888
profile: dev # 指定配置文件的profile
label: master # 指定配置文件的分支

在Git仓库中创建配置文件order-service-dev.yml

yaml复制代码
server:
port: 8081
my:
config:
value: This is a configuration value from Config Server

OrderController中使用配置信息:

java复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
class OrderController {
@Value("${server.port}")
private String port;
@Value("${my.config.value}")
private String configValue;
@GetMapping("/order")
public String getOrder() {
return "Order Service is running on port: " + port + ". Config Value: " + configValue;
    }
}
七、具体底层原理介绍
1. 服务注册与发现的底层原理详细介绍
Eureka的注册机制

Eureka是Netflix开源的服务注册与发现组件,它通过简单的配置即可实现微服务的自动注册与发现。在服务注册阶段,服务实例(如OrderService)启动时会向Eureka服务器发送注册请求。注册请求中包含了服务实例的元数据信息,如服务名称、IP地址、端口号、健康状态等。Eureka服务器接收到注册请求后,会将这些元数据信息存储在一个内存数据结构(如ConcurrentHashMap)中,并为其分配一个唯一的标识符(如服务ID)。同时,Eureka服务器还会将注册信息同步到其他Eureka服务器节点上,确保服务注册信息的一致性。

Eureka的发现机制

在服务发现阶段,服务消费者(如PaymentService)通过调用Eureka服务器的服务订阅接口获取可用的服务实例列表。Eureka服务器会根据服务消费者的请求参数(如服务名称)从内存数据结构中查询相应的服务实例列表,并将其返回给服务消费者。服务消费者接收到服务实例列表后,会根据负载均衡策略(如轮询、随机等)选择一个合适的服务实例进行调用。Eureka服务器还会定期检查服务实例的健康状态,如果某个服务实例出现故障或超时未响应心跳请求,Eureka服务器会将其从内存数据结构中移除,并通知所有订阅该服务的服务消费者刷新本地缓存的服务实例列表。

Eureka的心跳机制

Eureka的心跳机制用于确保服务实例的可用性。服务实例在启动后会定期向Eureka服务器发送心跳请求,以表明自己仍然处于活动状态。Eureka服务器接收到心跳请求后,会更新服务实例的最后活动时间戳。如果Eureka服务器在一段时间内没有收到某个服务实例的心跳请求(如默认30秒),则会认为该服务实例已经下线,并将其从内存数据结构中移除。同时,Eureka服务器还会通知所有订阅该服务的服务消费者刷新本地缓存的服务实例列表。

2. API网关的底层原理详细介绍
反向代理机制

API网关通常采用Nginx、HAProxy等高性能反向代理服务器来分发流量。反向代理服务器作为客户端和服务器之间的中间层,负责接收客户端的请求并将其转发到相应的服务器实例上。在API网关中,反向代理服务器会根据请求的路径、参数或标头将流量路由到相应的微服务实例上。同时,反向代理服务器还可以实现负载均衡功能,将请求分发到多个可用的微服务实例上,以提高系统的可伸缩性和性能。

路由与负载均衡机制

API网关的路由与负载均衡机制是实现微服务调用的关键。在路由方面,API网关会根据请求的路径、参数或标头将流量路由到相应的微服务实例上。这通常通过配置路由规则来实现,如基于路径的路由规则、基于参数的路由规则

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

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

相关文章

Docker 环境中搭建 Redis 哨兵模式集群的步骤与问题解决

在 Docker 环境中搭建 Redis 哨兵模式集群的步骤与问题解决 在 Redis 高可用架构中,哨兵模式(Sentinel)是确保 Redis 集群在出现故障时自动切换主节点的一种机制。通过使用 Redis 哨兵,我们可以实现 Redis 集群的监控、故障检测和…

数据结构:时间复杂度和空间复杂度

我们知道代码和代码之间算法的不同,一定影响了代码的执行效率,那么我们该如何评判算法的好坏呢?这就涉及到了我们算法效率的分析了。 📖一、算法效率 所谓算法效率的分析分为两种:第一种时间效率,又称时间…

《Vue3实战教程》39:Vue3无障碍访问

如果您有疑问,请观看视频教程《Vue3实战教程》 无障碍访问​ Web 无障碍访问 (也称为 a11y) 是指创建可供任何人使用的网站的做法——无论是身患某种障碍、通过慢速的网络连接访问、使用老旧或损坏的硬件,还是仅处于某种不方便的环境。例如,…

GESP2024年6月认证C++五级( 第三部分编程题(1)黑白格)

参考程序&#xff08;二维前缀和&#xff09; #include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {int n, m, k;cin >> n >> m >> k;// 输入网格图vector<vector<int>> grid(n, v…

二、SQL语言,《数据库系统概念》,原书第7版

文章目录 一、概览SQL语言1.1 SQL 语言概述1.1.1 SQL语言的提出和发展1.1.2 SQL 语言的功能概述 1.2 利用SQL语言建立数据库1.2.1 示例1.2.2 SQL-DDL1.2.2.1 CREATE DATABASE1.2.2.2 CREATE TABLE 1.2.3 SQL-DML1.2.3.1 INSERT INTO 1.3 用SQL 语言进行简单查询1.3.1 单表查询 …

js按日期按数量进行倒序排序,然后再新增一个字段,给这个字段赋值 10 到1

效果如下图&#xff1a; 实现思路&#xff1a; 汇总数据&#xff1a;使用 reduce 方法遍历原始数据数组&#xff0c;将相同日期的数据进行合并&#xff0c;并计算每个日期的总和。创建日期映射&#xff1a;创建一个映射 dateMap&#xff0c;存储每个日期的对象列表。排序并添加…

用uniapp写一个播放视频首页页面代码

效果如下图所示 首页有导航栏&#xff0c;搜索框&#xff0c;和视频列表&#xff0c; 导航栏如下图 搜索框如下图 视频列表如下图 文件目录 视频首页页面代码如下 <template> <view class"video-home"> <!-- 搜索栏 --> <view class…

【three.js】光源

光源 光源特点 当使用MeshLambertMaterial材质时&#xff0c;会受到光线的影响&#xff0c; 我们代码里面如果没有设置光线&#xff0c;则使用MeshLambertMaterial材质修饰的模型不可见&#xff0c;这个时候&#xff0c;我们添加光线后&#xff0c;便可以看见。 环境光 定义&a…

U8G2库使用案例(stm32)

U8G2官网&#xff1a; 自己移植的U8g2库&#xff0c;OLED库超好用&#xff0c;自己封装了用户层不需要再去查资料使用&#xff0c;注释写的很多很详细&#xff0c;有示例上手就会&#xff0c;初始化也很简单 个人移植的U8g2库&#xff1a; 超简单的stm32 U8g2移植 大家可以自…

Linux 上安装 PostgreSQL

文章目录 前言一、安装PostgreSQL二、修改数据库默认数据存储目录 1.自定义数据存放目录2.修改自定义服务3.初始化数据库4.运行数据库 三、配置数据库信息 四、权限 异常处理 前言 提示&#xff1a;本次博客是centos7.9安装PostgreSQL12版本 名称 版本 Centos 7.9 postg…

HTML——56.表单发送

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单发送</title></head><body><!--注意&#xff1a;1.表单接收程序&#xff0c;放在服务器环境中(也就是这里的www文件目录中)2.表单发送地址&#x…

logback之pattern详解以及源码分析

目录 &#xff08;一&#xff09;pattern关键字介绍 &#xff08;二&#xff09;源码分析 &#xff08;一&#xff09;pattern关键字介绍 %d或%date&#xff1a;表示日期&#xff0c;可配置格式化%d{yyyy-MM-dd HH:mm:ss} %r或%relative&#xff1a;也是日期&#xff0c;不过…

vLLM结构化输出(Guided Decoding)

简介 vLLM 的结构化输出特性是通过“引导式解码”&#xff08;Guided Decoding&#xff09;实现的&#xff0c;这一功能允许模型在生成文本时遵循特定的格式约束&#xff0c;例如 JSON 模式或正则表达式&#xff0c;从而确保生成的内容符合预期的结构化要求。 后端引擎 启动…

CM3/CM4时钟系统

CM3/4时钟系统 1. CM3时钟系统1.1 输入时钟源------------------A1.2 锁相环PLL------------------B1.3 系统时钟SYSCLK--------C/D/E/F/G 2. CM4时钟系统2.1 输入时钟源------------------A2.2 锁相环PLL------------------B2.3 系统时钟SYSCLK--------C/D/E2.4 时钟信号输出M…

RabbitMQ实现生产者消费者

一.启动MQ 注意管理员身份进入cmd才行,我这里是在本地安装的MQ,推荐使用虚拟机安装 二.思路 官方解释RabbitMQ结构: 自我理解RabbitMQ结构: 其实RabbitMQ的服务器就像邮局一样,我们的生产者和消费者对于这个服务器来说都是消费者,因为服务器都可以向两者发送消息 环境准备 …

MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?

目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 外键约束 约束规则 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码&#xff0c;在mysql当中有许多常见的内置函数&#xff0c;接下来开始对这些内置函数及其作用进行简单的讲解和使用&#xf…

OpenLinkSaas使用手册-待办事项和通知中心

在OpenLinkSaas工作台上&#xff0c;你可以查看待办事项和未读通知。 待办事项 目前待办事项支持: 个人待办项目待办:在项目中指派给你的任务/缺陷Git待办:在Git仓库中指标给你的Issue,目前只有在AtomGit和Gitee账号登录时才支持。 通知中心 通知中心支持Git通知和邮件通知两种…

【Unity】 HTFramework框架(五十八)【进阶篇】资源及代码热更新实战演示(Deployment + HybridCLR)

更新日期&#xff1a;2025年1月2日。 Github源码&#xff1a;[点我获取源码] 索引 资源及代码热更新实战演示运行演示Demo1.克隆项目工程2.更新子模块3.打开项目4.打开入口场景5.设置远端资源服务器地址6.导入HybridCLR7.初始化HybridCLR8.发布项目9.部署资源版本10.运行Exe11.…

路由基本配置实验

路由器用于实现不同类型网络之间的互联。 路由器转发ip分组的基础是路由表。 路由表中的路由项分为直连路由项、静态路由项和动态路由项。 通过配置路由器接口的ip地址和子网掩码自动生成直连路由项。 通过手工配置创建静态路由项。 热备份路由器协议允许将由多个路由器组…

CTFshow—远程命令执行

29-35 Web29 代码利用正则匹配过滤了flag&#xff0c;后面加了/i所以不区分大小写。 可以利用通配符绕过 匹配任何字符串&#xff0f;文本&#xff0c;包括空字符串&#xff1b;*代表任意字符&#xff08;0个或多个&#xff09; ls file * ? 匹配任何一个字符&#xff08;不…