前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >🌍从 MVC 到微服务:架构演化的历程与应用场景(含代码演示)

🌍从 MVC 到微服务:架构演化的历程与应用场景(含代码演示)

原创
作者头像
bug菌
发布2024-11-30 18:58:38
发布2024-11-30 18:58:38
1660
举报

好事发生

  这里推荐一篇实用的文章:《功能上线后,系统崩了!我怎么把它救回来的?》,作者:【喵手】。

  这篇文章作者主要讲解一次线上紧急“救火”的经历:一个看似无害的功能上线后引发了全系统性能崩溃,从混乱中找到问题根源,到实施应急修复,再到彻底优化的全过程。这不仅是一场技术硬仗,更是一场心理考验。让我们回到那个“灾难现场”,重温这段惊险的经历吧...借此好文安利给大家。

  OK,那本期正文即将拉开帷幕。

🏆本文收录于「滚雪球学Java」专栏中,这个专栏专为有志于提升Java技能的你打造,覆盖Java编程的方方面面,助你从零基础到掌握Java开发的精髓。赶紧关注,收藏,学习吧!

代码语言:java
复制
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

前言:架构的变革与发展 🛠️

在软件开发的历程中,架构设计一直是开发者的心头大石。从简单的 MVC 模式到复杂的微服务架构,每一种架构的演化背后,都是对业务需求、扩展性、性能优化和可维护性的深思熟虑。在这篇文章中,我们将深入探讨 MVC、三层架构以及微服务架构的演化过程,并结合具体的代码示例来帮助大家更好地理解每种架构的优缺点及适用场景。

💡 1. 从 MVC 开始:解耦与可维护性

MVC 架构代码示例

MVC(Model-View-Controller)是经典的分层架构,它将应用的不同功能分成三个主要部分:模型(Model)、视图(View)和控制器(Controller)。下面是一个简单的 Spring Boot MVC 示例。

Model:数据模型(Product.java)

代码语言:java
复制
public class Product {
    private Long id;
    private String name;
    private double price;

    // Getter and Setter methods

    public Product(Long id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}

View:视图(product.html)

代码语言:html
复制
<!DOCTYPE html>
<html>
<head>
    <title>Product Page</title>
</head>
<body>
    <h1>Product List</h1>
    <ul>
        <th:block th:each="product : ${products}">
            <li th:text="${product.name}">Product Name</li>
        </th:block>
    </ul>
</body>
</html>

Controller:控制器(ProductController.java)

代码语言:java
复制
@Controller
public class ProductController {
    private List<Product> productList = Arrays.asList(
        new Product(1L, "Laptop", 999.99),
        new Product(2L, "Smartphone", 499.99)
    );

    @GetMapping("/products")
    public String getProducts(Model model) {
        model.addAttribute("products", productList);
        return "product"; // name of the view (product.html)
    }
}

MVC 适用的场景

MVC 适合于以下场景:

  • 小型应用:例如,传统的 Web 应用、CRUD 系统等。
  • 单一用户界面:如果你只需要一个前端展示的页面,MVC 是一个非常合适的选择。

MVC 的局限性

随着应用功能的增加,MVC 开始暴露出一些问题,特别是在大型系统中:

  • 代码耦合:虽然模型和视图分离,但控制器依然是代码的中心,随着功能复杂度增加,控制器会变得过于庞大。
  • 性能瓶颈:所有的业务逻辑都在同一应用中运行,不利于扩展。

🏗️ 2. 三层架构:提升分层与模块化

三层架构将应用分为三个层级,通常是表现层、业务逻辑层和数据访问层。这种架构能够更好地支持复杂应用。

三层架构代码示例

表现层(ProductController.java)

代码语言:java
复制
@Controller
public class ProductController {
    private ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/products")
    public String getProducts(Model model) {
        model.addAttribute("products", productService.getAllProducts());
        return "product";
    }
}

业务逻辑层(ProductService.java)

代码语言:java
复制
@Service
public class ProductService {
    private ProductRepository productRepository;

    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }
}

数据访问层(ProductRepository.java)

代码语言:java
复制
@Repository
public class ProductRepository {
    private static List<Product> productList = Arrays.asList(
        new Product(1L, "Laptop", 999.99),
        new Product(2L, "Smartphone", 499.99)
    );

    public List<Product> findAll() {
        return productList;
    }
}

三层架构适用的场景

三层架构适合于以下场景:

  • 中型应用:在多种前端平台(如 Web 客户端、移动客户端)访问同一个后端时,三层架构非常有用。
  • 长期维护的系统:代码模块化,有助于团队协作和长期维护。

三层架构的局限性

尽管三层架构在很多场景下表现出色,但它仍然有一些缺点:

  • 单体部署问题:所有的层都部署在一个应用中,这限制了扩展性。
  • 灵活性不足:在面对复杂的分布式系统需求时,三层架构往往显得不够灵活。

🔄 3. 微服务架构:解构与分布式的崛起

微服务架构通过将应用拆解为多个独立服务来解决传统架构的扩展问题。每个服务负责一个特定的功能,并通过 API 进行通信。以下是一个简单的微服务实现例子,演示如何将服务拆分成独立的模块。

微服务代码示例

代码示例

产品服务(ProductService.java)

代码语言:java
复制
@SpringBootApplication
@RestController
@RequestMapping("/products")
public class ProductService {

    @GetMapping
    public List<Product> getAllProducts() {
        return Arrays.asList(
            new Product(1L, "Laptop", 999.99),
            new Product(2L, "Smartphone", 499.99)
        );
    }

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

订单服务(OrderService.java)

代码语言:java
复制
@SpringBootApplication
@RestController
@RequestMapping("/orders")
public class OrderService {

    @GetMapping
    public List<Order> getAllOrders() {
        return Arrays.asList(
            new Order(1L, 1L, "Laptop"),
            new Order(2L, 2L, "Smartphone")
        );
    }

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

API 网关(GatewayService.java)

代码语言:java
复制
@SpringBootApplication
@EnableZuulProxy  // 启用网关代理
public class GatewayService {
    public static void main(String[] args) {
        SpringApplication.run(GatewayService.class, args);
    }
}
代码解析

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

上述这些代码展示了一个典型的微服务架构,其中包括一个产品服务 (ProductService)、一个订单服务 (OrderService) 和一个 API 网关 (GatewayService)。下面是对每个部分的详细解析:

1. 产品服务 (**ProductService.java**)
代码语言:java
复制
@SpringBootApplication
@RestController
@RequestMapping("/products")
public class ProductService {

    @GetMapping
    public List<Product> getAllProducts() {
        return Arrays.asList(
            new Product(1L, "Laptop", 999.99),
            new Product(2L, "Smartphone", 499.99)
        );
    }

    public static void main(String[] args) {
        SpringApplication.run(ProductService.class, args);
    }
}
  • @SpringBootApplication:这是一个组合注解,包含了 @Configuration@EnableAutoConfiguration@ComponentScan,它标志着这是一个 Spring Boot 应用的入口。
  • @RestController:表明该类是一个 REST 控制器,用于处理 HTTP 请求并返回 JSON 或其他数据格式。
  • @RequestMapping("/products"):定义了请求的基础路径 /products,所有的方法都会相对于此路径进行映射。
  • @GetMapping:映射 HTTP GET 请求,用于获取所有的产品数据。
  • List<Product> getAllProducts():返回一个简单的静态产品列表(假设 Product 类已经定义)。在实际应用中,产品数据可能会从数据库中获取。
  • public static void main(String[] args):Spring Boot 启动方法,调用 SpringApplication.run() 来启动 Spring Boot 应用。
2. 订单服务 (**OrderService.java**)
代码语言:java
复制
@SpringBootApplication
@RestController
@RequestMapping("/orders")
public class OrderService {

    @GetMapping
    public List<Order> getAllOrders() {
        return Arrays.asList(
            new Order(1L, 1L, "Laptop"),
            new Order(2L, 2L, "Smartphone")
        );
    }

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

解析:

  • 结构与 ProductService 类似,定义了一个 RESTful API 来处理订单数据。
  • @RequestMapping("/orders"):定义了订单服务的基础路径 /orders
  • @GetMapping:用于处理 GET 请求,返回一个静态的订单列表。在实际应用中,这些数据通常是从数据库中读取的。
  • public static void main(String[] args):启动方法,用于启动 Spring Boot 应用。
3. API 网关 (**GatewayService.java**)
代码语言:java
复制
@SpringBootApplication
@EnableZuulProxy  // 启用网关代理
public class GatewayService {
    public static void main(String[] args) {
        SpringApplication.run(GatewayService.class, args);
    }
}

解析:

  • @SpringBootApplication:与前两个服务中的配置相同,标记这是一个 Spring Boot 应用。
  • @EnableZuulProxy:启用 Netflix Zuul 作为 API 网关的代理。Zuul 是一个用于处理请求路由的工具,它可以帮助将不同的服务暴露为一个统一的接口。通过 Zuul,客户端可以访问多个后端微服务,而无需直接了解它们的地址和端口。
    • 这里并没有直接定义路由规则(例如,哪些请求转发到哪个服务),Zuul 默认会根据服务名称(比如 product-serviceorder-service)来路由请求。
  • public static void main(String[] args):启动方法,启动 API 网关服务。
4.微服务架构总结
  1. 产品服务 (**ProductService**)
    • 这个服务处理与产品相关的操作(如获取产品列表)。它暴露了一个 RESTful API,允许其他系统或服务访问。
  2. 订单服务 (**OrderService**)
    • 该服务负责订单数据的处理,暴露了一个类似的 RESTful API。它可以独立运行,但也可以与其他服务交互。
  3. API 网关 (**GatewayService**)
    • API 网关作为微服务架构中的入口点,代理和转发请求到实际的服务。在这个示例中,使用了 Zuul 作为网关代理。它充当了请求的路由器,将请求转发到相应的微服务(如 ProductServiceOrderService)。
    • 在实际应用中,网关通常还会处理跨域、身份认证、日志、限流等功能。
5.启动顺序与工作流程
  1. 启动顺序:可以分别启动 ProductServiceOrderServiceGatewayService。网关服务需要先启动,确保路由和代理的功能可用。
  2. 客户端访问:客户端(可能是浏览器或其他应用)通过访问 API 网关(GatewayService)的统一入口点,来请求 ProductServiceOrderService 提供的资源。例如,http://localhost:8080/products 会被转发到 ProductServicehttp://localhost:8080/orders 会被转发到 OrderService

微服务架构适用的场景

微服务适用于以下场景:

  • 大规模系统:例如,电商平台、社交媒体等,业务逻辑复杂,单体架构难以满足需求。
  • 需要高可用性和高扩展性的系统:微服务能够针对不同的服务进行独立扩展,避免性能瓶颈。
  • 多团队协作开发:微服务允许不同团队独立开发、部署和维护各自负责的服务,适合大团队合作。

微服务架构的优势与挑战

优势:
  • 高可扩展性:每个微服务可以独立扩展,满足不同的业务需求。
  • 独立部署和迭代:微服务架构支持独立部署和版本迭代,降低了系统更新的复杂性。
  • 灵活的技术栈:每个服务可以选择最适合的技术栈,不必在整个系统中使用同一种技术。
挑战:
  • 服务间通信问题:微服务架构中,服务之间的通信需要通过 API 或消息队列等方式进行,增加了复杂度。
  • 数据一致性:微服务架构下,每个服务的数据通常是独立的,如何保证分布式系统中的数据一致性是一个需要解决的难题。
  • 运维复杂性:微服务的管理和监控相对复杂,需要引入容器化、日志聚合、服务发现等技术。

🛠️ 4. 从单体架构到微服务:迁移之路

分步迁移示例

  1. 拆分服务:首先,你需要将现有的单体应用拆分成独立的服务。例如,可以先将订单服务、产品服务、用户服务等单独拆分出来。
  2. 容器化:使用 Docker 等工具将每个微服务容器化,方便部署和管理。
  3. 引入 API 网关:通过网关(如 Zuul 或 Spring Cloud Gateway)来统一管理和路由微服务请求。
  4. 服务间通信:引入 RESTful API 或消息队列来实现服务间通信。

实际步骤:

  • 逐步迁移,不要一次性重构整个系统。
  • 保证数据的迁移和一致性,使用数据库分片或数据库复制等技术。
  • 完成微服务拆分后,可以采用 CI/CD 管道实现自动化部署。

结语:架构选择的艺术 🖌️

选择合适的架构是成功开发的关键。无论是经典的 MVC、三层架构,还是灵活的微服务,架构的选择都应当根据具体的业务需求、团队能力、以及预期的系统规模来决定。在微服务架构中,我们不仅仅是在拆分应用,更是在为更高的扩展性、灵活性以及更短的迭代周期做准备。

☀️建议/推荐你

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。

  码字不易,如果这篇文章对你有所帮助,帮忙给bug菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。   同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

  我是bug菌,CSDN | 掘金 | 腾讯云 | 华为云 | 阿里云 | 51CTO | InfoQ 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金等平台签约作者,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计30w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

-End-

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 好事发生
  • 前言:架构的变革与发展 🛠️
  • 💡 1. 从 MVC 开始:解耦与可维护性
    • MVC 架构代码示例
    • MVC 适用的场景
    • MVC 的局限性
  • 🏗️ 2. 三层架构:提升分层与模块化
    • 三层架构代码示例
    • 三层架构适用的场景
    • 三层架构的局限性
  • 🔄 3. 微服务架构:解构与分布式的崛起
    • 微服务代码示例
      • 代码示例
      • 代码解析
    • 微服务架构适用的场景
    • 微服务架构的优势与挑战
      • 优势:
      • 挑战:
  • 🛠️ 4. 从单体架构到微服务:迁移之路
    • 分步迁移示例
    • 实际步骤:
  • 结语:架构选择的艺术 🖌️
  • ☀️建议/推荐你
  • 📣关于我
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档