1.微服务架构
单体服务架构,将所有的功能模块(service)打包到一起并放在一个web容器中运行。
微服务架构,就是将复杂臃肿的单体应用进行细粒度的服务拆分,每个微服务可以交给小的团队进行开发和维护,拆分出来的服务各自独立打包部署。
1.1单体微服务架构
1.什么是单体架构
一个归档包(如war包)包含了应用所有功能的应用程序。常言道:一个war包打天下。
2.单体架构的优缺点:
优点:简单,没有什么花哨的问题需要解决,部署非常简单。
缺点:
①系统各个功能耦合度高,不利于业务扩展(改一个点可能会影响到整个系统)。
②部署慢(功能多而复杂)
③扩展成本高,不能针对性的适配各个服务。比如有的服务模块是CPU密集型,对服务器的cpu要求更高,有的服务模块是IO密集型,对内存和磁盘要求更高。单体架构不能针对各个模块进行扩展,只能都选择。
1.2微服务架构
1.什么是微服务?
核心就是根据业务将单机应用拆分为各个服务,彻底解耦,每个服务都提供特定的功能,一个服务只做一件事情,每个服务都单独部署,它们可以拥有自己的数据库。
举例说明:例如传统的单机应用电商项目:订单、库存、物流、支付、积分等模块。我们可以将其拆分为订单服务、物流服务、支付服务、积分服务。不拆分的情况下,如果积分模块出现重大问题,内存溢出,会导致整个系统崩溃。而拆分之后,只有积分服务不可用,其他服务照常运行。
2.微服务的特点
(1)独立部署、灵活扩展
微服务是以每个独立组件(订单服务、物流服务等)为单位进行部署的。
(2)资源的有效隔离
每一个微服务都会有独立的数据源。例如,A服务想要读写B服务的数据库,必须要通过B服务对外暴露的接口完成,这样就有效的避免了服务之间争用数据库和缓存资源所带来的问题。
(3)组织团队架构的调整
不同于传统的水平团队组织架构:前端团队、后端团队、DAB团队、测试团队。微服务的组织团队架构更倾向于垂直架构,比如一个订单服务是由一个团队来负责,这个团队包括:前端、后端、DAB、测试。
3.什么是微服务架构
微服务架构风格是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。 这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署。 这些服务的集中管理最少,可以用不同的编程语言编写,并使用不同的数据存储技术。SOA架构强调的是异构系统之间的通信和解耦合,而微服务架构强调的是系统按业务边界做细粒度的拆分和部署。
微服务架构是一个架构风格,它提倡:
①将一个单一应用程序开发为一组小型服务.
②每个服务运行在自己的进程中
③服务之间通过轻量级的通信机制(http rest api)
④每个服务都能够独立的部署
⑤每个服务甚至可以拥有自己的数据库
微服务与微服务架构的是两个完全不同的概念。微服务强调的是服务的大小和对外提供的单一功能,而微服务架构是指把一个一个的微服务组合管理起来,对外提供一套完整的服务。
4.微服务架构的优缺点
优点:
①每个服务足够小,足够内聚,开发只需专注一个业务功能点。
②开发简单,一个服务只干一个事情。
③按需伸缩,服务松耦合,每个服务都能够开发部署
④前后端分离
⑤一个服务可用拥有自己的数据库,也可以多个服务连接同一个数据库。
缺点:
①增加了运维人员的工作量,以前只要部署一个war包,现在可能需要部署成百上千个war包(k8s+docker+jenkins )
②服务之间相互调用,增加通信成本
③数据一致性问题(分布式事务问题)
④性能监控等,问题定位
微服务的适用场景
合适
①大型复杂的项目
②快速迭代的项目
③并发高的项目
不合适
①业务稳定
②迭代周期长
2.springboot与springcloud的关系
-
SpringBoot专注于快速方便的开发单个个体微服务。
-
SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。
-
SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系
3.创建基于商城微服务框架
3.1 创建一个父工程
src可以删除
配置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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aaa</groupId>
<artifactId>springcloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>springcloud-parent</name>
<description>springcloud-parent</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--spring-cloub 版本-->
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<!--spring-cloub阿里巴巴版本-->
<spring-cloub-alibaba.version>2.2.3.RELEASE</spring-cloub-alibaba.version>
</properties>
<!--dependencyManagement:他只负责jar的管理 不负责jar的下载。子模块在引用时无需在指定版本号-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloub-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.2创建基于maven公共模块
加入依赖
<!--加入依赖-->
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
创建Order实体类
@Data
@TableName(value = "shop_order")
public class Order {
@TableId(value = "oid",type = IdType.AUTO)
private Integer oid;
private Integer uid;
private String username;
private Integer pid;
private String pname;
private BigDecimal pprice;
private Integer number;
}
创建product实体类
@Data
@TableName(value = "shop_product")
public class Product {
@TableId(value = "pid",type = IdType.AUTO)
private Integer pid;
private String pname;
//小数必须使用 BigDecimal类型
private BigDecimal pprice;
private Integer stock;
}
3.3 创建基于maven的product商品微服务
加入依赖
<dependencies>
<dependency>
<groupId>com.xal</groupId>
<artifactId>springcloub-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.xal</groupId>
<artifactId>spring-cloub-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
创建主实体类
@SpringBootApplication
@MapperScan(basePackages = "com.aaa.dao")
public class ProductApp {
public static void main(String[] args) {
SpringApplication.run(ProductApp.class,args);
}
}
创建并配置propertis
# duan kou hao
server.port=8080
spring.datasource.username=root
spring.datasource.password=chuxin0920
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///springcloud_product?serverTimezone=Asia/Shanghai
创建dao层
public interface ProductDao extends BaseMapper<Product> {
}
创建service层
public interface ProductService {
public Product findById(Integer pid);
}
创建Impl
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductDao productDao;
@Override
public Product findById(Integer pid) {
Product product = productDao.selectById(pid);
return product;
}
}
创建controller层
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("findById/{pid}")
public Product find(@PathVariable Integer pid){
Product product = productService.findById(pid);
return product;
}
}
3.4基于maven创建order微服务
配置依赖
<dependencies>
<dependency>
<groupId>com.aaa</groupId>
<artifactId>springcloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.aaa</groupId>
<artifactId>springcloud-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
创建dao层
public interface OrderDao extends BaseMapper<Order> {
}
创建service层
public interface OrderService {
public Integer save(Order order);
}
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
public OrderDao orderDao;
@Override
public Integer save(Order order) {
return orderDao.insert(order);
}
}
创建controller层
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private RestTemplate restTemplate;
@GetMapping("insert")
public String save(Integer pid , Integer num){
Order order =new Order();
//用户id
order.setUid(1);
//用户姓名
order.setUsername("sss");
order.setNumber(num);
Product product = restTemplate.getForObject("http://localhost:8080/findById/" + pid, Product.class);
if (product==null){
return "下单失败";
}
product.setPid(product.getPid());
product.setPname(product.getPname());
product.setPprice(product.getPprice());
orderService.save(order);
if (product.getStock()>=num){
return "下单成功";
}else {
return "库存不足";
}
}
}