什么是SpringCloud
Spring Cloud是一个基于Spring框架的微服务架构的开源框架。它提供了一系列的工具和技术,用于开发、部署和管理分布式系统,帮助开发者构建微服务架构。
主要优点包括:
-
易于构建分布式系统:Spring Cloud是基于Spring Boot的,使用Spring Boot开发微服务架构变得非常简单。
-
完整的微服务工具集:Spring Cloud为开发者提供了一个完整的微服务工具集,包括配置管理、服务发现、断路器、负载均衡、智能路由、微代理、控制总线、一次性令牌、全局锁、决策竞速、分布式会话等等。
-
快速构建分布式系统:通过使用Spring Cloud,开发者可以轻松地构建分布式系统,而无需关心复杂的分布式系统的底层实现。
-
实现云原生架构:Spring Cloud支持云原生架构,可以帮助开发者实现微服务、容器化、云原生等。
-
易于接入新技术:Spring Cloud是基于Spring技术栈的,开发者可以轻松地接入新的技术,以满足业务需求。
SpingColud的作用
SpringCloud能够解决微服务架构带来的一系列挑战,提供一个工具包来开发分布式系统
功能包含:
-
分布式配置中心 Config、Nacos
-
服务注册和发现 Eureka、Nacos、Zookeeper、Consul
-
路由 Gateway、Zuul
-
服务之间的调用 Feign、Dubbo
-
负载均衡 Ribbon、LoadBalancer
-
熔断器 Hystrix、Sentinel
-
全局锁
-
集群状态管理
-
分布式消息 Bus
入门案例
提供数据的服务叫服务提供者,使用数据的服务叫服务消费者
订单微服务能够查询订单信息,订单信息中包含商品数据,订单微服务要调用商品微服务完成查询
订单服务数据库为sys_order
-- 订单表
create table sys_order
(
id int primary key auto_increment,
product_id int not null,
count int not null,
user_id int not null,
time datetime
);
insert into sys_order(product_id,count,user_id,time)
values(1,1,1,'2022-11-21 13:11:12'),
(2,2,1,'2022-12-21 13:11:12'),
(3,1,1,'2022-10-21 13:11:12');
select * from sys_order;
商品服务的商品数据库sys_product
-- 商品表
create table sys_product
(
id int PRIMARY key auto_increment,
name varchar(50) not null,
price double not null,
type varchar(10) not null
);
insert into sys_product(name,price,type)
values('华为笔记本',5000,'电器'),
('百事可乐',5,'饮料'),
('Nike篮球鞋',800,'鞋子');
select * from sys_product;
-
编写商品服务,完成按商品id查询商品的功能
-
编写订单服务,完成按查询订单的功能
-
订单微服务调用商品微服务
@Configuration
public class RestTemplateConfig {
/**
* 创建RestTemplate交给容器
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
订单包含商品信息
@Data
@TableName("sys_order")
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
private Long userId;
private Long productId;
private Long count;
private LocalDateTime time;
@TableField(exist = false)
private Product product;
}
订单service查询订单时远程调用商品服务
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderMapper orderMapper;
@Override
public Order getOrderById(Long id) {
Order order = orderMapper.selectById(id);
//调用商品微服务获得商品信息
ResponseEntity<Product> entity = restTemplate.getForEntity("http://localhost:8002/product/" + order.getProductId(), Product.class);
order.setProduct(entity.getBody());
return order;
}
}
Eureka注册中心的使用
服务注册和发现机制
1) 服务提供者将自己的IP和端口注册到注册中心上
2) 服务提供者每隔一段时间向注册中心发送心跳包
3) 服务消费者调用提供者之前,先向注册中心查询提供者的IP和端口
4) 获得服务清单中的IP和端口后,消费者调用提供者
5) 服务提供者的IP和端口改变后,通过心跳机制更新注册中心上的服务清单
SpringCloud的版本介绍
SpringCloud中一些组件是Netflix(网飞)公司开源的,其中有:Eureka、Ribbon、Hystrix、Zuul、Config
SpringCloud和SpringBoot版本兼容
修改父项目pom
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.blb</groupId> <artifactId>springcloud_demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springcloud_demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>8</java.version> <spring.cloud-version>Hoxton.SR8</spring.cloud-version> </properties> <!--固定SpringCloud依赖版本--> <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> </dependencies> </dependencyManagement>
创建Eureka服务器项目
pom修改
1) 继承父项目
<parent> <groupId>com.blb</groupId> <artifactId>springcloud_demo</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent>
2) 引入服务器依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
3) 配置文件
server.port=8000 # 服务器域名 eureka.instance.hostname=127.0.0.1 # 设置不拉取服务清单 eureka.client.fetch-registry=false # 设置不注册当前服务 eureka.client.register-with-eureka=false # 定义注册服务的地址 eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
4) 启动类加 @EnableEurekaServer
配置Eureka客户端
1) 继承父项目
2) 引入客户端依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
3) 配置文件
# 服务名称 spring.application.name=xxxx # 设置拉取服务清单 eureka.client.fetch-registry=true # 设置注册当前服务 eureka.client.register-with-eureka=true # 定义注册服务的地址 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8000/eureka
4) 启动类加 @EnableEurekaClient或 @EnableDiscoveryClient
5) 在RestTemplate配置类方法上加@LoadBalanced
6) 调用服务时修改
//调用商品微服务获得商品信息 将IP和端口写死 服务提供者ip和端口发生变化,调用出错 //改用Eureka后,调用时使用服务注册名称调用 ResponseEntity<Product> entity = restTemplate.getForEntity("http://product-service/product/" + order.getProductId(), Product.class);
Eureka自我保护机制
心跳机制:客户端注册到Eureka服务器后,每隔30s发送心跳包给服务器,如果90s没有发送心跳包,服务器就会把客户端从服务清单剔除
自我保护机制:网络可能出现波动,Eureka服务器发现15分钟内所有客户端正常心跳比例低于85%,Eureka就会把服务清单保护起来不剔除,网络恢复正常后,服务调用就能正常执行。
开发阶段可以关闭自我保护机制,上线阶段一般都要开启
# 关闭自我保护机制 eureka.server.enable-self-preservation=false
Eureka高可用
可以配置多台Eureka服务器形成集群,相互注册相互备份,提高注册中心的可用性
application-dev.properties
server.port=8011 spring.application.name=eureka-8011 # 服务器域名 eureka.instance.hostname=127.0.0.1 # 设置从其它eureka拉取服务清单 eureka.client.fetch-registry=true # 设置注册当前服务到其它eureka eureka.client.register-with-eureka=true # 定义注册服务的地址 eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:8012/eureka # 关闭自我保护机制 eureka.server.enable-self-preservation=false
application-test.properties
server.port=8012 spring.application.name=eureka-8012 # 服务器域名 eureka.instance.hostname=127.0.0.1 # 设置拉取服务清单 eureka.client.fetch-registry=true # 设置注册当前服务到其它eureka eureka.client.register-with-eureka=true # 定义注册服务的地址 eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:8011/eureka # 关闭自我保护机制 eureka.server.enable-self-preservation=false