微服务架构与单体架构

发布于:2024-05-06 ⋅ 阅读:(27) ⋅ 点赞:(0)

微服务架构与与单体架构比较

微服务架构是一种将应用程序作为一组小的、独立服务的系统架构风格,每个服务运行在其自己的进程中,并通常围绕业务能力组织。这些服务通过定义良好且轻量级的机制(通常是HTTP REST API)进行通信。微服务架构旨在实现高度解耦和独立可伸缩的服务单元。
微服务架构的特点:
1. 模块化:将大型复杂应用分解成可单独开发、部署和维护的小服务。
2. 分布式部署:每个服务可以在不同的服务器或容器中运行,增强了部署的灵活性。
3. 去中心化:服务之间通信去中心化,不必依赖于一个单一的数据库或服务。
4. 灵活性:团队能够使用不同的编程语言和技术栈开发服务。
5. 敏捷性:微服务架构能够快速响应需求变更,便于实现持续集成和持续部署(CI/CD)。
6. 可伸缩性:可以只对需要扩展的服务进行独立扩容,而不是整个应用。
与单体架构比较:
单体架构可以被视为一个大型的、统一的应用程序。所有功能都在一个单一的进程中紧密集成,共享同一个数据库。
以下是一些与单体架构的主要比较点:
模块化
- 微服务: 基于业务功能定制服务。
- 单体: 功能紧密集成,可分为多个模块,但在运行时是统一的。
部署
- 微服务: 独立部署,一个服务的更新不会影响其他服务。
- 单体: 需要整体部署,任何小更新都需要重新部署整个应用程序。
扩展性
- 微服务: 可针对特定服务进行扩展,更加灵活。
- 单体: 整体扩展,可能存在资源浪费。
开发及团队结构
- 微服务: 可以利用不同的技术栈,更适合于跨功能团队。
- 单体: 通常限制为单一技术栈,可能需要大型而笨重的开发团队。
例子对比
假如我们正在开发一个电子商务应用程序:
- 使用单体架构,我们将拥有一个包含用户管理、产品管理、订单处理等所有功能的大型代码库。所有功能使用相同的语言编写,共享一个数据库。当我们需要添加新的功能或进行更新时,我们需要部署整个应用程序,这可能导致服务中断和复杂性增加。
- 使用微服务架构,我们将上述功能划分成多个独立的服务,例如用户服务、产品服务、订单服务等。每个服务可以独立更新和扩展,如果我们需要增加更多产品处理能力,我们可以单独扩展产品服务,而不会影响到用户服务或订单服务。
总的来说,微服务架构提供了更大的灵活性和可伸缩性,适合于快速发展和对可用性要求越来越高的应用。然而,它也带来了复杂性和服务间通信的挑战。而单体架构出于其简单性,在小型或者中等规模项目,以及产品早期可能更为合适。 

开发或使用微服务步骤

微服务是一种软件架构风格,它推崇将一个大型软件应用分解为一组小的、松耦合的服务,每个服务围绕特定的业务能力构建,可以独立部署、扩展和更新。这种架构使得应用程序更易于理解、开发和测试,并可以更灵活地使用不同的编程语言和技术堆栈。
个人或企业要自己开发或使用微服务,可以遵循以下步骤:
1. 需求评估:首先要评估项目是否真正需要微服务架构。对于小型项目,传统的单体应用可能更合适。
2. 设计微服务架构:如果确定使用微服务,接下来要确定如何拆分服务,每个服务将承担什么职责,以及它们如何相互通信(常用的通信方式包括HTTP REST APIs、gRPC、AMQP等)。
3. 选择技术栈:微服务架构不绑定特定的技术或语言。每个服务都可以根据其功能需求独立选择最合适的技术和编程语言。
4. 开发和部署:开发每个单独的服务,并考虑到服务的可发现性、配置管理、负载均衡、断路、降级等云原生特性。
5. 使用微服务框架和工具:有许多框架和工具可以帮助开发和管理微服务,例如Spring Boot、Docker、Kubernetes、Istio、Consul等。
6. 考虑安全性和监控:每个服务都应该有自己的安全措施,监控和日志记录对于跟踪问题和优化性能至关重要。
7. 持续集成和持续部署(CI/CD):微服务开发通常会伴随CI/CD流程,来确保代码变更可以被有效地集成、测试并且快速部署到生产环境。
8. 服务和数据管理:微服务通常意味着会有更多的数据库来管理,每个服务可能有自己的数据库实例,需要注意数据管理和一致性问题。
记住,虽然微服务带来很多好处,比如更易于扩展和维护,但它们也引入了复杂性。例如,服务之间的通信、服务的发现、分布式数据管理、服务的监控和故障排除都是需要特别考虑的挑战。因此,如果没有现成的微服务体系结构经验,小团队或个人可能会发现微服务架构的维护和管理相对困难。

Spring Boot建立微服务的示例

Spring Boot是创建独立的、生产级别的Spring应用程序的一个项目,它简化了基于Spring的应用开发。而Spring Cloud是在Spring Boot的基础上构建的,它提供了一系列工具来帮助开发者快速构建一些常见的分布式系统模式,如配置管理、服务发现、断路器等。Spring Boot和Spring Cloud共同为开发微服务提供了深度整合和自动配置的方式。
以下是一个简单的Spring Boot建立微服务的示例。
创建一个新的Spring Boot微服务项目:
1. 使用[Spring Initializr](https://start.spring.io/)生成一个基本的项目结构,选择需要的工程名称、打包类型、Java版本和依赖项。对于微服务,可能会选定`Eureka Client`(服务发现),`Config Client`(外部配置),`Spring Web`(构建RESTful应用)等。
2. 下载生成的项目并将其解压,使用IDE(比如 IntelliJ IDEA 或 Eclipse)打开这个项目。
加入`Eureka Client`依赖(如果要进行服务发现):
在`pom.xml`中,可以添加如下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

编写微服务应用代码:
以下是一个简单的RESTful service的例子:

package com.example.microservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class MicroserviceApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceApplication.class, args);
    }
    
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, this is a microservice example!";
    }
}

在这个例子中,通过添加`@SpringBootApplication`注解,Spring Boot将用它来配置你的应用程序,并启动Spring应用上下文。`@RestController`和`@GetMapping`组合提供了一种简单的方式来定义REST端点。
配置应用属性:
在`src/main/resources/application.properties`(或`application.yml`),可以添加微服务的配置属性:

properties
server.port=8080
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

这里设置了服务的端口号,并配置了Eureka客户端的服务注册中心地址。
运行应用:
用IDE运行这个Spring Boot应用,或者通过命令行:

mvn spring-boot:run

测试微服务:
当应用运行起来后,可以通过浏览器或者使用工具如`curl`访问注册的端点进行测试:

curl http://localhost:8080/hello

如果一切顺利,将得到响应 "Hello, this is a microservice example!"。
请注意,这只是一个十分简单的微服务例子。在现实中开发微服务时,还需要考虑服务发现、配置、负载均衡、熔断、安全、日志、监控、链路追踪等众多其他方面,并且考虑使用Spring Cloud针对这些领域提供的解决方案。

电子商务平台微服务示例

假设在构建一个电子商务平台,它由多个微服务组成,比如“用户服务”、“产品服务”、“订单服务”以及“购物车服务”。这些微服务可以像下面这样工作:
1. 用户服务:
   - 负责用户的注册、登录、资料管理等。
   - 例子:REST API 端点 /users/register 用于注册新用户,`/users/login` 用于用户登录。
2. 产品服务:
   - 管理产品目录,包括添加、更新和删除商品,查询商品列表等功能。
   - 例子:REST API 端点 /products 用于获取所有产品,`/products/{id}` 用于获取特定产品的详细信息。
3. 订单服务:
   - 处理订单的创建、修改、查询和删除等操作。
   - 例子:REST API 端点 /orders 用于创建新订单,`/orders/{id}` 用于查看特定订单的状态与详情。
4. 购物车服务:
   - 负责用户的购物车,包括添加或删除商品、结算等。
   - 例子:REST API 端点 /carts 用于检索用户的购物车,`/carts/add` 用于添加商品到购物车。
用户通过前端接口(例如,一个Web应用或移动应用)与这些服务进行交互,而服务之间也可能需要通过内部API进行交互。例如,当用户想要查看一个商品的详情时,前端应用将调用产品服务的API获取信息。当用户添加商品到购物车时,前端应用会调用购物车服务的API,购物车服务可能还需要调用产品服务来确认商品信息。
实际的应用中,每个服务还会有它自己的数据库和缓存机制,并且它们都可以独立地进行扩缩容。在部署的时候,可以使用容器化技术(如Docker)来包装每个服务,并通过Kubernetes这样的容器编排系统来管理每个服务的运行。
用户不需要知道背后有多少服务或它们是如何工作的,他们只需要通过前端应用与平台进行交互,所有的复杂性都被抽象和隐藏了起来。
为了实现服务间的高效通信,通常会引入API网关作为系统入口,它负责请求的路由、负载均衡、认证授权等,使得用户的请求可以被分发到正确的服务上。此外,服务间通信可能使用同步HTTP请求或异步消息队列,取决于具体需求。
微服务架构的目的是将复杂的应用分解为简单、独立的服务,每个服务都有明确的职责,并简化了扩展和维护工作。但各个服务需要协作,开发者需要处理分布式系统带来的挑战,比如网络延迟、消息传递、数据一致性以及服务故障。

微服务与传统意义上的“服务”之间区别

微服务的确是与传统意义上的“服务”相关,但它们之间存在一些区别:
1. 粒度:微服务通常比传统服务更加细粒度。它们聚焦于执行单一的、小的、明确定义的任务。
2. 独立性:每个微服务可以独立部署、升级和缩放,而不会影响系统中的其他部分。在单体架构中,所有功能通常耦合在一个应用程序中,需要一起部署。
3. 分布式开发:微服务架构支持不同服务由不同团队使用可能不同的编程语言和技术栈进行开发。
4. 去中心化:微服务可以拥有自己的数据库和状态管理机制,区别于传统单体架构中的集中式数据库。
微服务架构解决了单体架构中的一些问题,如缩放性能、敏捷开发、容错性等,但同样引入了一些复杂性,如服务间通信、数据一致性、服务发现和负载均衡等问题。云服务提供商往往提供工具和服务来帮助在云环境中部署和管理微服务,例如容器编排平台(如Kubernetes)和服务网格(如Istio)。
在实际运用中,企业也经常采用API Gateway或服务网关的模式来统一微服务入口。API Gateway可以隐藏微服务的具体端口,对外只暴露一个或几个端口,然后根据请求的路由信息将请求转发到相应的微服务上。这样的方式简化了客户端调用微服务的复杂性,并可以提供额外的服务如负载均衡、身份验证和授权。 

端口号

在微服务架构中,每个微服务通常都会部署为独立的应用程序,并且有可能分配一个唯一的端口号以便可以独立地访问它们。端口号是一个数字标识符,用来区分同一台主机上运行的不同服务。微服务之间可以通过网络调用的方式进行通信,同样可以通过HTTP协议和REST API端点的形式暴露其功能。
每个微服务可能会运行在不同的端口上。比如:
- 用户服务可能运行在端口5000上。
- 产品服务可能运行在端口5001上。
- 订单服务可能运行在端口5002上。
- 购物车服务可能运行在端口5003上。
这只是一个示例,端口号可以根据需要和网络策略来进行分配。当通过网络调用这些服务时,需要知道相应服务的端口号,例如:
- 调用用户服务注册API可能是:`http://<user-service-host>:5000/users/register`
- 调用产品服务获取产品列表API可能是:`http://<product-service-host>:5001/products`
- 等等...
在实际部署时,服务的主机名(如 <user-service-host>)可以是本地主机(localhost)、服务的IP地址,或者当部署到云端时使用的DNS名称。
在云环境或使用容器技术(如Docker)时,可以使用服务发现和负载均衡的机制来简化服务间通信。这样的话,可能不必直接指定端口号,因为服务发现机制会帮助解析服务名称到具体的主机和端口。
在文档中不提及端口号只是因为通常文档会聚焦于API接口本身的描述。具体的端口号分配和部署细节则会在微服务的配置文件或部署说明中定义。

REST API端点

使用REST API端点与使用端口号并不是对立或者不同的概念,而是相互关联的。端口号是网络通信中的一个概念,它用于在同一个服务器上区分不同的服务或应用程序。而REST API端点则是服务或应用程序提供的具体的接口,用于执行特定的操作。
简单来说:
1. 端口号:端口是服务器上特定服务的一个接入点。对于基于HTTP协议的通信,例如Web服务和REST API,端口号通常是80(不加密的HTTP)或443(加密的HTTPS)。自定义服务通常使用1024以上的端口号,避免冲突。服务器上的每个服务都会监听特定的端口号等待传入请求。
2. REST API 端点:端点是指服务上的一个特定的URL,它定义了资源的位置以及如何访问那些资源。它通常关联于一个HTTP方法,如GET、POST、PUT或DELETE,这些方法定义了客户端可以对这些资源执行的动作。
当用户或客户端应用程序需要与微服务进行交互时,他们会使用服务器的地址(IP地址或域名)、端口号以及特定的REST API端点。举个例子,如果用户服务的端口号是5000,那么完整的URL来注册一个用户可能是:
http://example.com:5000/users/register
在这个例子中:
- http://example.com 是服务器的地址,
- :5000 是端口号,
- /users/register 是REST API端点。
REST API端点是可以提供给最终用户直接使用的,尤其是在业务上需要客户端应用程序调用这些服务来完成特定的功能(如用户注册、查询产品等)。然而,在实践中,特别是在生产环境中,最终用户通常是通过前端应用程序,如一个WEB应用的用户界面或移动应用,来间接使用这些API。API的直接使用通常是由开发者在客户端应用程序、服务间的集成或自动化脚本中进行。
为了安全性和简易性,生产环境下的微服务往往部署在内部网络中,使用API网关作为单一入口点,这样的话外界用户只需知道API网关的地址,而不需要每个微服务的具体端口号和地址。API网关负责将外部请求路由到相应的服务端点。这样可以提供路由、认证、速率限制等额外的控制和功能。

在URL http://example.com:5000/users/register 中:
- http://example.com 是服务器的主机名或地址。
- :5000 是用于访问用户服务的端口号,在这个实例中,它指的是用户服务所监听的TCP端口。
- /users/register 是在用户服务中定义的具体的REST API端点。
一个端口号可以承载一个服务中的许多不同API端点。以用户服务为例,它可能会在端口5000上有多个端点,如:
- /users/register 用于注册新用户。
- /users/login 用于用户登录。
- /users/profile 用于获取或更新用户资料。
所有这些API端点都在端口5000上提供,通过相同的用户服务进行处理。因此,URL中的端口号(如5000)是微服务在网络层面的接入点,而API端点(如`/users/register`)是在HTTP层面定义的路径,用来区分不同的服务操作。只有一个端口号与整个用户服务相关联,而不是每个API端点各自有一个端口号。

微服务架构和单体架构技术

微服务架构和单体架构在技术栈上可以有很多共通的技术,但它们的组织方式、分布式的设计理念和交互模式有所不同。下面是它们各自使用的一些技术:
微服务架构技术:
1. 容器化技术:比如Docker和Kubernetes,它们帮助微服务实现了快速部署、扩展和管理。
2. 服务网格技术:如Istio、Linkerd等,帮助处理服务之间的交互以及监控、安全问题。
3. 服务发现技术:例如Consul、Eureka,允许服务彼此发现和交流。
4. API网关:如Kong、Zuul,用于处理外部请求并将它们路由到相应的微服务。
5. 分布式追踪系统:如Zipkin、Jaeger,帮助跟踪请求在各服务间的流动情况。
6. 消息队列:例如RabbitMQ、Apache Kafka,用于异步通信和缓冲请求。
7. 配置管理:如Spring Cloud Config,集中管理服务配置。
8. 断路器模式的实现:如Hystrix,用于处理服务之间的调用失败。
单体架构技术:
1. 传统的Web框架:如Java的Spring MVC、PHP的Laravel,Ruby on Rails,用于处理HTTP请求和业务逻辑。
2. 关系型数据库:如MySQL、PostgreSQL,集中存储数据。
3. 持久层框架:如Hibernate、JPA,用于抽象数据库操作。
4. 应用服务器和Web服务器:如Apache Tomcat、Nginx,它们用于托管和运行应用程序。
5. 单体应用部署工具:如传统的CI/CD工具Jenkins、Bamboo,用于自动化部署。
6. 集中式日志和监控解决方案:比如ELK(Elasticsearch, Logstash, Kibana)堆栈,用于监控和分析日志。
尽管单体架构和微服务架构可以使用相似或者相同的技术栈,但微服务架构特别侧重于服务的独立部署、扩展性、隔离性和分布式的管理。相对地,单体架构则更偏向于一体化管理和部署。微服务架构适合大型、复杂的应用,它需要更多的管理和运维技术,同时也可能带来更复杂的系统设计和通信成本。而单体架构可能更适合中小型项目,简化部署和管理过程。

Spring Boot在微服务架构和单体架构的技术

Spring Boot是Spring框架的一个扩展,它简化了基于Spring的应用的创建和开发流程。我们可以把Spring Boot同时放在微服务架构和单体架构技术中考虑。
微服务架构中的Spring Boot:
在微服务架构中,Spring Boot通常被用来创建可以独立运行的小型服务,这些服务可以被部署在各自的容器中。Spring Boot的自动配置和外部化配置功能使得开发微服务更加方便。
Spring Boot与Spring Cloud结合使用时,可以为微服务架构提供更加全面的支持,包括服务发现、配置管理、负载均衡、断路器等微服务相关的模式和工具。
单体架构中的Spring Boot:
在单体应用中,Spring Boot也非常流行,因为它减少了许多项目初期的设置工作,并允许开发者更加专注于业务逻辑。Spring Boot在单体架构中提供了一个整合所有业务逻辑的独立运行的应用程序,通常这个程序会连接到一个单一的数据库,并且在一个服务器或服务器集群上运行。
无论是微服务还是单体架构,Spring Boot为开发者提供了快速创建基于Spring的应用的能力,同时也有大量的开始指导和库,支持各种场景下的应用开发。
概括来说,Spring Boot是现代Java应用开发中的关键技术,无论是构建微服务还是单体应用都扮演了至关重要的角色。 


网站公告

今日签到

点亮在社区的每一天
去签到