1.微服务
简单来说,微服务架构风格[1]是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在 自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并 且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开 发,使用不同的数据存储技术
1.1单体架构
优点:
1:部署简单:由于是完整的结构体,可以直接部署在一个服务器上即可。
2:技术单一:项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发。
缺点:
1:系统启动慢,一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重 启时间周期过长;
2:系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机;
3:可伸缩性差:系统的扩容只能只对这个应用进行扩容,无法结合业务模块的特点进行伸缩。
4: 线上问题修复周期长:任何一个线上问题修复需要对整个应用系统进行全面升级。
5: 跨语言程度差-
6: 不利于安全管理,所有开发人员都拥有全量代码。 项目规模比较小。
WMS OA办公系统
1.2微服务的特点
1:微服务是一种 项目架构思想(风格)
2:微服务架构是一系列小服务的组合(组件化与多服务)
3:任何一个微服务,都是一个独立的进程(独立开发、独立维护、独立部署)
4:轻量级通信http协议(跨语言,跨平台)
5:服务粒度(围绕业务功能拆分---模块拆分【系统管理服务】【日志服务】【焦虑测试】【抑郁测试系 统】)
6:去中心化管理(去中心化"地治理技术、去中心化地管理数据)
1.3微服务框架的优势
1.易于开发和维护 一个微服务只关注一个特定的业务功能,所以它的业务清晰、代码量较少。开发和维护单个微服务相对 比较简单,整个应用是由若干个微服务构建而成,所以整个应用也会维持在可控状态;
⒉.单个微服务启动较快 单个微服务代码量较少,所以启动会比较快;
3.局部修改容易部署 单体应用只要有修改,就要重新部署整个应用,微服务解决了这样的问题。一般来说,对某个微服务进 行修改,只需要重新部署这个服务即可
4.技术栈不受限 在微服务中,我们可以结合项目业务及团队的特点,合理地选择技术栈
5.按需伸缩 焦虑系统访问量大,只需要对焦虑系统进行扩展
1.4SpringCloud与微服务关系
Springcloud为微服务思想提供了完美的解决方案
Springcloud是一些列框架的集合体(服务的注册与发现【注册中心】、服务间远程调用、服务降级、服务熔断、服务限流、分布式事务,网关等等)
一般我们说springc1oud 其实指的是Springc1oud-netflix,Springcloud并不是造轮子,只是把Netflix公司的组件做二次开发。
1.6SpringBoot和SpringCloud关系
SpringBoot专注于快速方便的开发单个个体微服务。
SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。
SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系。
2.搭建
springboot要3.0.0
1.父模块的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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ghx</groupId>
<artifactId>demowei02-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demowei02-parent</name>
<description>demowei02-parent</description>
<modules>
<module>springcloud-common</module>
<module>springcloud-product</module>
<module>springcloud-order</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>
<!-- springcloud的版本 -->
<spring-cloud.version>2022.0.0</spring-cloud.version>
<!-- springcloud阿里巴巴的版本 -->
<spring-cloud-alibaba.version>2022.0.0.0-RC1</spring-cloud-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-cloud-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>
</plugin>
</plugins>
</build>
</project>
2.1
package com.ghx.order.service.impl;
import com.ghx.common.entity.Order;
import com.ghx.common.entity.Product;
import com.ghx.order.dao.OrderDao;
import com.ghx.order.feig.ProducFeign;
import com.ghx.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
import java.util.Random;
/**
* @author :guo
* @date :Created in 2025/2/28 15:07
* @description:
* @version:
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderDao orderDao;
@Override
public String insert(int num,int pid) {
Order order = new Order();
order.setNumber(num);
order.setUid(1);
order.setUsername("guo");
//获取商品的信息===>通过HTTP协议调用其他微服务。===>自己封装Http工具===》spring提供RestTemplate 没有交于spring管理
//url: 路径--服务提供者的路径
//Class: 返回值类型反射类
Product product=restTemplate.getForObject("http://localhost:8001/product/getById?pid="+pid, Product.class);
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setPid(product.getPid());
int insert = orderDao.insert(order);
return insert > 0 ? "下单成功" : "下单失败";
}
}
3.服务治理
服务治理是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现。
服务注册:在服务治理框架中,都会构建一个*注册中心*,每个服务单元向注册中心登记自己提供服务的详细信息。并在注册中心形成一张服务的*清单*,服务注册中心需要以*心跳30s 90s*的方式去监测清单中 的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。
服务发现:服务调用方向服务注册中心咨询服务,并获取*所有服务*的实例清单,实现对具体服务实
3.1常见的注册中心软件
Zookeeper
zookeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式
应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用
配置项的管理等。
Eureka
Eureka是Springcloud Netflix中的重要组件,主要作用就是做服务注册和发现。但是现在已经闭
源 ,停更不停用。
Consul
Consul是基于GO语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现
和配置管理的功能。Consul的功能都很实用,其中包括:服务注册/发现、健康检查、Key/Value
存储、多数据中心和分布式一致性保证等特性。Consul本身只是一个二进制的可执行文件,所以
安装和部署都非常简单,只需要从官网下载后,在执行对应的启动脚本即可。
Nacos (服务治理 配置中心)
Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它是 Spring
Cloud Alibaba 组件之一,负责服务注册发现和服务配置. [服务治理的作用和微服务配置管理]
3.2nacos服务治理
1.引入依赖
<!-- nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
2.配置注册中心的地址和名称,例如:
#设置注册中心的地址 spring.cloud.nacos.server-addr=localhost:8848 spring.application.name=springcloud-product
3.获取
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderDao orderDao;
@Autowired//可以获取注册中心的服务
private DiscoveryClient discoveryClient;
@Override
public String insert(int num,int pid) {
Order order = new Order();
order.setNumber(num);
order.setUid(1);
order.setUsername("guo");
//获取商品的信息===>通过HTTP协议调用其他微服务。===>自己封装Http工具===》spring提供RestTemplate 没有交于spring管理
//url: 路径--服务提供者的路径
//Class: 返回值类型反射类
List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-product");
ServiceInstance serviceInstance = instances.get(0);
String path = serviceInstance.getUri().toString();
// Product product=restTemplate.getForObject("http://localhost:8001/product/getById?pid="+pid, Product.class);
Product product=restTemplate.getForObject(path+"/product/getById?pid="+pid, Product.class);
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setPid(product.getPid());
int insert = orderDao.insert(order);
return insert > 0 ? "下单成功" : "下单失败";
}
}
4.负载均衡
4.1手动写
package com.ghx.order.service.impl;
import com.ghx.common.entity.Order;
import com.ghx.common.entity.Product;
import com.ghx.order.dao.OrderDao;
import com.ghx.order.feig.ProducFeign;
import com.ghx.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
import java.util.Random;
/**
* @author :guo
* @date :Created in 2025/2/28 15:07
* @description:
* @version:
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderDao orderDao;
@Autowired//可以获取注册中心的服务
private DiscoveryClient discoveryClient;
@Override
public String insert(int num,int pid) {
Order order = new Order();
order.setNumber(num);
order.setUid(1);
order.setUsername("guo");
//获取商品的信息===>通过HTTP协议调用其他微服务。===>自己封装Http工具===》spring提供RestTemplate 没有交于spring管理
//url: 路径--服务提供者的路径
//Class: 返回值类型反射类
List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-product");
int index = new Random().nextInt(instances.size());
ServiceInstance serviceInstance = instances.get(index);
String path = serviceInstance.getUri().toString();
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setPid(product.getPid());
int insert = orderDao.insert(order);
return insert > 0 ? "下单成功" : "下单失败";
}
}
4.2使用springcloud LoadBalancer
1.添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
2.在RestTemplate类上使用@LoadBalanced
3.修改代码
package com.ghx.order.service.impl;
import com.ghx.common.entity.Order;
import com.ghx.common.entity.Product;
import com.ghx.order.dao.OrderDao;
import com.ghx.order.feig.ProducFeign;
import com.ghx.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
import java.util.Random;
/**
* @author :guo
* @date :Created in 2025/2/28 15:07
* @description:
* @version:
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderDao orderDao;
@Autowired//可以获取注册中心的服务
private DiscoveryClient discoveryClient;
@Override
public String insert(int num,int pid) {
Order order = new Order();
order.setNumber(num);
order.setUid(1);
order.setUsername("guo");
//获取商品的信息===>通过HTTP协议调用其他微服务。===>自己封装Http工具===》spring提供RestTemplate 没有交于spring管理
//url: 路径--服务提供者的路径
//Class: 返回值类型反射类
List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-product");
int index = new Random().nextInt(instances.size());
ServiceInstance serviceInstance = instances.get(index);
String path = serviceInstance.getUri().toString();
Product product=restTemplate.getForObject("http://springcloud-product/product/getById?pid="+pid, Product.class);
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setPid(product.getPid());
int insert = orderDao.insert(order);
return insert > 0 ? "下单成功" : "下单失败";
}
}
4.3使用openfeign完成服务调用
原来使用restTemplate完成服务之间的调用: 它不符合我们的编程习惯。---在某层需要另一层的对象时,直接通过@Autowire注入,并通过对象调用其他的方法,传入相关的参数。
4.3.1什么是OpenFeign
OpenFeign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。
Nacos很好的兼容了OpenFeign, OpenFeign负载均衡默认集成了SpringCloudLoadBalance, 所以在Nacos下使用OpenFegin默认就实现了负载均衡的效果。
4.3.2使用
1.引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.创建openfeign接口
package com.ghx.order.feig; import com.ghx.common.entity.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; /** * @author :guo * @date :Created in 2025/3/3 11:34 * @description: * @version: */ @FeignClient(value = "springcloud-product") public interface ProducFeign { @GetMapping("/product/getById") public Product getById(@RequestParam Integer pid); }
3.开启openfeign注解驱动
4.修改代码