微服务架构的环境搭建及简单测试
目录
一、系统架构的演变过程
1.0 前言
1.1 单体应用架构
1.2 垂直应用架构
1.3 分布式架构
1.4 SOA架构
1.5 微服务架构
二、微服务架构搭建
2.1 微服务架构简介
2.2 微服务案例准备
2.3 创建父工程、基础模块
2.4 创建微服务
一、系统架构的演变过程
1.0 前言
网络环境下应用范围持续扩大与系统架构随之发生相应的变化。自早期互联网发展时期以来,在这一过程中系统架构经历了几个关键阶段。
单体应用架构--- >垂直应用架构--->分布 式架构--->SOA架构--->微服务架构
当然还有悄然兴起的Service Mesh(服务网格化)。
接下来我们就来认识每种系统架构的具体形态及其各自的优缺点吧~
1.1 单体应用架构
早期的网络环境中,网站的应用流量通常较为有限。因此,在这种情况下即使只有一个功能模块的应用也需要将所有功能代码整合到一个项目中以便能够显著降低开发、部署和维护的资源消耗。例如一个电商系统它会包含多个用户管理系统、商品管理系统、订单管理系统以及物流管理系统等多个功能模块这些都需要整合到同一个Web项目后通过配置好的tomcat服务器实现高效运行。

优点:
项目架构简单,小型项目的话, 开发成本低
项目部署在一个节点上, 维护方便
缺点:
全部功能集成在一个工程中,对于大型项目来讲不易开发和维护
项目模块之间紧密耦合,单点容错率低
无法针对不同模块进行针对性优化和水平扩展
1.2 垂直应用架构
随着访问量持续增长, 单一应用需要通过增加节点来应对部分功能模块的高负载问题, 但很快就会发现并非所有功能模块都会出现明显的流量高峰. 以电商系统为例, 用户流量的增长主要牵连的是用户信息和订单信息两大块内容, 而消息系统相关的功能则不会受到太大影响. 因此,在这种情况下我们只需要再新建几个订单功能即可, 这样就能避免给消息系统带来额外负担. 然而, 单体架构难以满足这种需求, 所以垂直化的架构模式应运而生. 这种垂直化的设计理念就是将原本单一的应用拆分成若干个互不相干的应用组, 从而提升系统的整体效能. 具体来说我们可以将电商系统的单体架构拆分为:
电商系统(用户管理 商品管理 订单管理)
后台系统(用户管理 订单管理 客户管理)
CMS系统(广告管理 营销管理)
完成之后,在用户的访问量上升时,就不再需要为电商系统添加节点了;相反地,则不需要额外添加后台系统或者CMS相关的节点。

优点:
系统通过划分功能模块实现了流量的均衡分配,并有效克服了处理多个请求时的性能瓶颈;同时支持根据不同业务需求进行功能调优,并具备良好的可扩展性
一个系统的问题不会影响到其他系统,提高容错率
缺点:
系统之间相互独立, 无法进行相互调用
系统之间相互独立, 会有重复的开发任务
1.3 分布式架构
随着垂直应用数量的增多以及复杂度提升,在开发过程中会逐渐出现大量的重复性代码片段。面对这种情况,在深入思考之后我们开始探索是否可以将这些重复的代码提取出来形成一个统一的业务层框架,并将其作为独立的服务提供给前端控制层去调用不同的功能模块。这种探索最终催生出了新的分布式系统架构模式。该架构将整个工程划分为表现层和一个服务层框架,在其中服务层面主要负责存储管理和各种核心功能逻辑实现而表现层面则专注于与前端页面交互的各种事务处理工作。具体而言,在这种架构下每一个功能模块都会被分配到特定的服务组件中负责相应的实现工作

优点:
抽取公共的功能为服务层,提高代码复用性
缺点:
系统间耦合度变高,调用关系错综复杂,难以维护
1.4 SOA架构
基于分布式架构的环境下,在服务数量不断增加的过程中,在系统容量评估方面暴露出了诸多问题,并且这些问题逐渐变得越来越显著。特别是在这种情况下需要引入一个调度中心来实现对集群运行状态的有效监控与优化管理,在这种情况下需要引入一个调度中心来实现对集群运行状态的有效监控与优化管理,在这种情况下需要引入一个调度中心来实现对集群运行状态的有效监控与优化管理,在这种情况下需要引入一个调度中心来实现对集群运行状态的有效监控与优化管理。为了实现对集群运行状态的有效监控与优化管理,在这种情况下需要引入一个调度中心来实现对集群运行状态的有效监控与优化管理。为此而言,在这种特定的情境下, 采用SOA Service Oriented Architecture(面向服务的架构)作为解决方案将是最为合适的方案。

优点:
使用注册中心解决了服务间调用关系的自动调节
缺点:
服务间会有依赖关系,一旦某个环节出错会影响较大( 服务雪崩 )
服务关系复杂,运维、测试部署困难
1.5 微服务架构
可以说它是面向服务架构SOA发展的进一步阶段,并且特别强调服务实现的完全分解。这种架构特别重视将服务进行完全分解,并将其作为其核心特征之一。

优点:
对服务进行原子化拆分,并实现独立打包、部署和升级流程。该过程确保每个微服务拥有明确且独立的功能定位,并有助于系统整体架构的模块化发展。
微服务之间采用Restful等轻量级http协议相互调用
缺点:
分布式系统开发的技术成本高(容错、分布式事务等)
二、微服务架构搭建
2.1 微服务架构简介
微服务架构的基本概念上讲, 它是指将一个相对复杂的单体应用分解为若干个相对独立的小型服务, 这些服务各自具备明确的功能边界, 并能够以相对较低的成本进行维护和扩展. 每个服务都被设计成一个能够独立完成特定功能的小系统, 这不仅有助于提高系统的灵活性和可管理性, 而且还能通过灵活组合这些小型服务来实现复杂的功能需求.
2.2 微服务案例准备
在之前的讨论中都涉及到了系统架构的发展脉络及其基本概念的概述。随后我们将重点在于采用微服务架构来进行深入探讨,并构建一个微服务架构来评估其实现效果;
**** 我们本次是使用的电商项目中的商品、订单、用户为案例进行讲解。
模块设计
端口: 8070
实体类

微服务调用
在现代微服务架构中,默认情况下最典型的应用场景就是各子系统间的交互协作。举例而言,在电商系统中最为常见的用户下单流程能够很好地展现这一特点:当客户向订单管理模块发出下单请求时,在完成订单信息存储前需先访问商品管理模块以获取相关信息。其中作为主动发起交互的一方通常被称为'消费者'角色而被被动接收请求的那一方则被视为'提供者'角色在此背景下我们研究的就是如何实现不同角色之间的高效协作机制

2.3 创建父工程、基础模块
创建一个maven项目作为父工程,不用勾选任何配置;
然后添加以下pom依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.leaf</groupId>
<artifactId>spcloud-shop</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>shop-common</module>
</modules>
<packaging>pom</packaging>
<!--依赖版本的锁定-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
然后再创建一个基础模块,同样也是maven项目;
添加以下pom依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spcloud-shop</artifactId>
<groupId>com.leaf</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-common</artifactId>
<!--依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
</dependencies>
</project>
2.4 创建微服务
接下来就是分别创建我们的三个微服务,这些就是都为springboot项目;
并且导入以下pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spcloud-shop</artifactId>
<groupId>com.leaf</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 除了下面这两灵活替换,其他都一样 -->
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-user</artifactId>
<dependencies>
<!--springboot-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--shop-common-->
<dependency>
<groupId>com.leaf</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
然后我们就可以创建我们的controller层进行一个简单的测试啦:
UserController
package com.leaf.shopuser.controller;
import com.leaf.model.User;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** * @author Leaf
* @site 2977819715
* @company 玉渊工作室
* @create 2022-11-25 2:12
*/
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/get/{id}")
public User get(@PathVariable("id") Integer id){
return new User(id,"Leaf","999","123456789");
}
}
ProductController
package com.leaf.shopproduct.controller;
import com.leaf.model.Product;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** * @author Leaf
* @site 2977819715
* @company 玉渊工作室
* @create 2022-11-25 2:16
*/
@RestController
@RequestMapping("/product")
public class ProductController {
@RequestMapping("/get/{pid}")
public Product get(@PathVariable("pid") Integer pid){
return new Product(pid,"《西游记》",99d,36);
}
}
OrderController
package com.leaf.shoporder.controller;
import com.leaf.model.Order;
import com.leaf.model.Product;
import com.leaf.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/** * @author Leaf
* @site 2977819715
* @company 玉渊工作室
* @create 2022-11-25 2:11
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/get/{uid}/{pid}")
public Order get(@PathVariable("uid") Integer uid,
@PathVariable("pid") Integer pid){
/** * 在订单微服务中调用:用户微服务、商品微服务,也就是跨项目调用
*/
User user = restTemplate.getForObject("http://localhost:8070/user/get/" + uid, User.class);
Product product = restTemplate.getForObject("http://localhost:8080/product/get/" + pid, Product.class);
Order order = new Order();
order.setUsername(user.getUsername());
order.setUid(user.getUid());
order.setPprice(product.getPprice());
order.setPname(product.getPname());
order.setPid(product.getPid());
order.setOid(System.currentTimeMillis());
order.setNumber(product.getStock());
return order;
}
}
需要注意的是,在微服务项目的开发过程中,在调用另外两个外部的服务时所使用的RestTemplate体系结构上需特别注意以下几点:首先,在订单类的服务启动过程中必须引入Bean管理机制;其次,在配置相关依赖项时应遵循特定的方式进行编排
代码如下:
package com.leaf.shoporder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication(exclude= DataSourceAutoConfiguration.class)
public class ShopOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ShopOrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
然后我们让三个微服务正常运行,并直接运行该URL地址:http://localhost:8090/order/get/5/9就可以完成任务啦:

