微服务架构:从组织影响到技术实现
微服务对组织的影响
微服务在技术决策和部署方面赋予了团队独立性,众多小团队可以共同参与大型项目,减少了团队间的沟通开销,降低了项目的整体风险。以下是关于微服务组织影响的详细内容:
1.
团队组建与代码所有权
- 理想情况下,团队应按不同领域方面独立工作。若无法实现或协调成本过高,集体代码所有权是一种替代方案。此时每个开发者可修改所有代码,但每个微服务仍有负责团队,对该微服务的更改需与负责团队协调。
- 例如,在一个电商项目中,商品管理、用户管理和订单管理可以分别由不同团队负责,但在一些情况下,一个团队可能需要修改其他团队的微服务代码。
2.
宏观架构与微观架构
- 微服务存在宏观架构和微观架构。宏观架构涉及所有微服务的决策,微观架构则因微服务而异。在技术、运营、领域架构和测试等方面的决策,可分配给团队(微观架构)或集中定义(宏观架构)。将决策权分配给团队更符合实现高度独立性的目标,通常是更好的选择。
- 宏观架构的责任与技术领导概念密切相关。较少的宏观架构意味着微服务团队承担更多责任,中央架构团队责任相应减少。
3.
DevOps与微服务
- 尽管微服务可从开发与运维融合的DevOps模式中受益,但并非严格要求引入DevOps才能实施微服务。若无法或不想采用DevOps,运维可在宏观架构层面定义准则,统一某些方面,确保基于微服务的系统平稳运行。
4.
业务部门与微服务匹配
- 每个微服务最好能对应业务端的特定部门,以实现独立需求的实施。若无法实现,产品负责人需协调不同部门的需求,明确每个微服务的优先级。采用集体代码所有权时,产品负责人及其团队可修改其他团队的微服务,减少沟通开销。负责被修改微服务的团队可审查并调整引入的更改。
5.
代码复用
- 在微服务项目中,若将代码视为开源项目,代码可被复用。内部项目可当作内部开源项目处理,甚至转化为公共开源项目。但实际开源项目的工作量较大,需谨慎考虑。此外,开源项目开发者需在领域需求和项目更改之间进行优先级排序,这有时是个难题。
6.
组织架构变革
- 若开发层面的组织结构不改变,引入微服务在实际中难以奏效。若无专注于特定领域的团队独立开发某些领域方面,几乎不可能并行开发多个功能,无法在相同时间内将更多功能推向市场,而这正是微服务的目标所在。不过,可持续开发、轻松引入持续交付、单个微服务独立扩展或简单处理遗留系统等仍有可能实现。运维和架构团队可定义宏观架构,不一定需要改变该领域的组织结构。理想情况下,部门需求应由一个微服务反映;若无法实现,产品负责人需协调并确定所需更改的优先级。
微服务组织影响的要点总结
- 微服务对组织有重大影响,独立小团队共同参与大型项目是微服务的重要优势。
- 将组织视为架构的一部分是微服务的重要创新。
- DevOps与微服务的结合有利但非必需。
微服务架构示例的领域架构
下面通过一个基于Java、Spring、Spring Boot、Spring Cloud、Netflix栈和Docker的微服务架构示例,详细介绍微服务的技术实现。
1.
示例应用概述
- 示例应用有简单的Web界面,用户可提交订单。包含三个微服务:
- “Catalog”:管理产品,可添加或删除商品。
- “Customer”:管理客户,可注册新客户或删除现有客户。
- “Order”:可显示订单并创建新订单。
- “Order”微服务需访问“Customer”和“Catalog”微服务获取数据,内部通信通过REST实现,用户可通过HTML/HTTP接口与三个微服务交互。
2.
数据存储
- 三个微服务的数据存储完全独立,每个微服务仅了解自身业务对象信息。“Order”微服务仅保存商品和客户的主键,用于通过REST接口访问。实际系统应使用人工键作为内部主键,避免其对外可见。微服务中的SpringRestDataConfig类可配置Spring Data REST以暴露主键。
3.
通信问题
- 显示订单时,“Order”微服务需调用“Customer”获取客户数据,调用“Catalog”获取每个订单行的商品价格。同步顺序请求会导致延迟累加,影响应用响应时间。可使用异步并行请求解决此问题。
- 数据的序列化和反序列化需要大量计算资源,在小型示例应用中可接受,但在生产环境中需考虑替代方案,如缓存。客户数据变化不频繁,商品数据变化相对较快但缓存仍可行。可在微服务接口甚至HTTP层面实现缓存,如为REST服务添加HTTP缓存,无需大量编程工作。
4.
边界上下文问题
- 缓存可解决响应时间过长的技术问题,但过长的响应时间可能暗示存在根本问题。微服务应包含边界上下文,特定领域模型仅在边界上下文中有效。此示例中按领域模型将系统模块化的方式与该理念相悖,订单、商品和客户的数据原则上应模块化到不同的边界上下文中。
- 这种模块化虽在低领域复杂度下实现了包含三个微服务的系统,便于理解和展示微服务间的通信,但在实际系统中,“Order”微服务可处理与订单流程相关的商品信息,必要时可将其他微服务的数据复制到自己的数据库中,以提高访问效率。
- 按数据模块化也有优势,当“Order”微服务处理客户和产品数据变得庞大时,模块化数据处理是合理的,且数据可被其他微服务使用。系统架构设计没有唯一正确的方法,最佳方法取决于系统及其特性。
示例应用的技术栈
示例应用基于Java实现,使用了以下技术:
1.
Spring框架
:提供依赖注入和Web框架,支持实现基于REST的服务。
2.
HSQL数据库
:是一个用Java编写的内存数据库,数据仅存储在RAM中,重启应用数据丢失。虽可将数据写入硬盘,但不太适合生产环境。不过无需额外安装数据库服务器,便于示例应用使用,数据库在相应Java应用中运行。
3.
Spring Data REST
:微服务使用Spring Data REST轻松通过REST提供领域对象并写入数据库。直接提供对象会导致内部数据表示泄露到服务接口中,更改数据结构困难,因为客户端也需调整。但Spring Data REST可隐藏某些数据元素,灵活配置以解耦内部模型与接口的紧密耦合。
4.
Spring Boot
:进一步简化Spring开发。Spring Boot启动器提供预定义包,包含特定类型应用所需的一切。可生成WAR文件安装在Java应用或Web服务器上,也可生成JAR文件,使用Java运行时环境(JRE)运行,JAR文件包含应用运行所需的一切以及处理HTTP请求的代码,比使用应用服务器更简单。
- 以下是一个简单的Spring Boot应用示例:
@RestController
@SpringBootApplication
public class ControllerAndMain {
@RequestMapping("/")
public String hello() {
return "hello";
}
public static void main(String[] args) {
SpringApplication.run(ControllerAndMain.class, args);
}
}
-
Spring Cloud
:便于访问Netflix栈。Spring Cloud通过Spring Cloud Connectors提供对PaaS(平台即服务)Heroku和Cloud Foundry的访问,以及对亚马逊云服务的接口,但这部分对微服务实现帮助不大。其他子项目为微服务实现提供了良好基础:
- Spring Cloud Security:支持实现微服务所需的安全机制,如单点登录,用户使用微服务时无需重复登录,用户令牌会自动传递到其他REST服务调用中,确保正确的用户权限。
- Spring Cloud Config:可集中动态调整微服务的配置。为确保服务器状态可重现,配置更改时应启动新的微服务实例,而非动态调整现有服务器。若动态调整服务器,无法保证新服务器以正确配置生成。
总结
微服务架构在组织和技术层面都有独特的优势和挑战。在组织方面,合理的团队组建、架构划分和流程设计能充分发挥微服务的独立性和灵活性;在技术方面,选择合适的技术栈和工具能有效解决微服务开发和部署中的各种问题。通过本文介绍的示例应用,我们可以看到如何将这些理念和技术应用到实际项目中,为进一步的实践和创新提供了参考。
示例应用架构图
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Customer):::process -->|REST| C(Order):::process
B(Catalog):::process -->|REST| C(Order):::process
D(User):::process -->|HTTP/HTML| A(Customer):::process
D(User):::process -->|HTTP/HTML| B(Catalog):::process
D(User):::process -->|HTTP/HTML| C(Order):::process
Spring Cloud子项目功能表
| 子项目 | 功能 |
|---|---|
| Spring Cloud Security | 支持微服务安全机制,如单点登录,自动传递用户令牌 |
| Spring Cloud Config | 集中动态调整微服务配置 |
微服务架构:从组织影响到技术实现
示例应用的构建与部署工具
-
构建工具
:示例应用在构建过程中,会使用特定的构建工具来确保项目的顺利搭建。虽然文中未详细提及具体构建工具,但结合Spring Boot等技术,通常会使用Maven或Gradle。它们能帮助管理项目依赖,将Spring Boot启动器等所需的库引入项目,如示例代码中依赖的
spring - boot - starter - web,构建工具会自动拉取相关的Web服务器、Spring Framework及其他依赖类。 -
Docker部署
- Docker是用于部署示例应用的重要技术。它需要在Linux环境中运行,能将应用及其依赖打包成独立的容器,实现环境的隔离和应用的可移植性。例如,可将“Catalog”“Customer”和“Order”这三个微服务分别打包成Docker容器,每个容器包含各自所需的数据库(如HSQL数据库)、Spring相关框架等。
-
具体操作流程如下:
- 编写Dockerfile:为每个微服务编写Dockerfile,定义容器的基础镜像、安装依赖、复制应用代码等步骤。以“Order”微服务为例,Dockerfile可能如下:
# 使用基础Java镜像
FROM openjdk:11
# 设置工作目录
WORKDIR /app
# 复制项目JAR文件到容器
COPY target/order - service.jar .
# 暴露端口
EXPOSE 8080
# 启动应用
CMD ["java", "-jar", "order - service.jar"]
- 构建Docker镜像:在包含Dockerfile的目录下,使用`docker build`命令构建镜像。例如:`docker build -t order - service:1.0 .`
- 运行Docker容器:使用`docker run`命令运行容器。如:`docker run -p 8080:8080 order - service:1.0`
-
Vagrant生成环境
:Vagrant可用于生成Docker所需的Linux环境。它能通过配置文件(Vagrantfile)快速创建和管理虚拟机。操作步骤如下:
- 安装Vagrant和VirtualBox(或其他虚拟机提供商)。
- 创建Vagrantfile:定义虚拟机的配置,如使用的基础镜像、网络设置等。示例Vagrantfile如下:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.network "private_network", ip: "192.168.33.10"
end
- 启动虚拟机:在包含Vagrantfile的目录下,运行`vagrant up`命令启动虚拟机。
-
Docker Machine与Docker Compose
- Docker Machine是生成Docker环境的另一种工具,可与Docker Compose结合使用来协调多个Docker容器。Docker Compose使用YAML文件定义多个容器的配置和它们之间的关系。
-
例如,创建一个
docker - compose.yml文件来定义“Catalog”“Customer”和“Order”三个微服务的容器:
version: '3'
services:
catalog - service:
build: ./catalog - service
ports:
- "8081:8081"
customer - service:
build: ./customer - service
ports:
- "8082:8082"
order - service:
build: ./order - service
ports:
- "8080:8080"
depends_on:
- catalog - service
- customer - service
- 运行`docker - compose up`命令,即可同时启动这三个微服务的容器,并根据依赖关系进行有序启动。
微服务的服务发现与通信
- 服务发现 :在微服务架构中,服务发现是确保各个微服务能够相互找到并通信的关键。示例应用中虽未详细说明具体的服务发现实现方式,但结合Spring Cloud,通常会使用Netflix Eureka等工具。其工作原理是,每个微服务在启动时会向服务注册中心(如Eureka Server)注册自己的信息(包括服务名称、IP地址、端口等),其他微服务需要调用该服务时,会从服务注册中心获取其信息。
-
微服务间通信
- 示例应用中微服务间的通信主要通过REST实现。“Order”微服务需要访问“Customer”和“Catalog”微服务获取数据。为了提高通信的可靠性和性能,使用了Hystrix实现服务的容错和熔断机制。当某个微服务出现故障或响应时间过长时,Hystrix会进行熔断,避免故障的扩散。
- 例如,在“Order”微服务中调用“Catalog”微服务获取商品信息时,可使用Hystrix进行封装:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class CatalogServiceClient {
private final RestTemplate restTemplate;
public CatalogServiceClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@HystrixCommand(fallbackMethod = "getCatalogItemFallback")
public CatalogItem getCatalogItem(String itemId) {
return restTemplate.getForObject("http://catalog - service/items/" + itemId, CatalogItem.class);
}
public CatalogItem getCatalogItemFallback(String itemId) {
// 提供降级处理逻辑
return new CatalogItem();
}
}
- 负载均衡 :负载均衡可将请求均匀地分配到多个微服务实例上,提高系统的性能和可用性。在示例应用中,负载均衡与服务发现密切相关。当多个“Catalog”微服务实例存在时,负载均衡器(如Spring Cloud Netflix Ribbon)会根据一定的算法(如轮询、随机等)将请求分配到不同的实例上。
非Java技术集成与测试
- 非Java技术集成 :示例应用主要基于Java技术栈,但也考虑了非Java技术的集成。文中未详细说明具体集成方式,但在实际项目中,可通过REST接口等标准方式实现不同技术栈之间的通信。例如,若有一个使用Python开发的数据分析微服务,可通过REST接口与Java开发的“Order”微服务进行数据交互。
-
测试
:测试是确保微服务质量的重要环节。示例应用中虽未详细介绍测试方法,但结合Spring Boot和相关框架,可使用单元测试框架(如JUnit)对单个微服务的方法进行测试,使用集成测试框架(如Spring Test)测试微服务之间的集成。例如,对“Order”微服务的
createOrder方法进行单元测试:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(OrderController.class)
public class OrderControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testCreateOrder() throws Exception {
mockMvc.perform(post("/orders"))
.andExpect(status().isOk());
}
}
总结与展望
微服务架构在实际应用中展现出了强大的优势,通过独立小团队的协作、合适的技术栈选择以及有效的组织架构设计,能实现高效的开发和部署。从示例应用中可以看到,微服务架构涉及多个方面的技术和管理,包括组织架构的调整、技术栈的选择、构建部署工具的使用、服务发现与通信、负载均衡、非Java技术集成和测试等。在未来的项目中,可根据具体需求进一步优化和扩展这些技术和方法,不断提升微服务架构的性能和可靠性。
示例应用部署流程图
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke - width:2px;
A(编写代码):::process --> B(构建项目):::process
B --> C(编写Dockerfile):::process
C --> D(构建Docker镜像):::process
D --> E(使用Vagrant或Docker Machine创建环境):::process
E --> F(运行Docker容器):::process
F --> G(使用Docker Compose协调容器):::process
微服务技术栈功能表
| 技术栈 | 功能 |
|---|---|
| Spring Framework | 提供依赖注入和Web框架,支持REST服务实现 |
| HSQL数据库 | 内存数据库,用于存储微服务数据 |
| Spring Data REST | 轻松通过REST提供领域对象并写入数据库 |
| Spring Boot | 简化Spring开发,可生成WAR或JAR文件 |
| Spring Cloud | 提供安全、配置管理等微服务相关功能 |
| Docker | 用于应用的打包和部署,实现环境隔离 |
| Vagrant | 生成Docker所需的Linux环境 |
| Docker Machine | 生成Docker环境 |
| Docker Compose | 协调多个Docker容器 |
| Hystrix | 实现微服务的容错和熔断机制 |
| Netflix Eureka | 实现服务发现 |
| Spring Cloud Netflix Ribbon | 实现负载均衡 |
1972

被折叠的 条评论
为什么被折叠?



