SpringCloud

一:前言

        使用 Spring Boot 开发分布式微服务时,我们面临以下问题:

  1. 与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题。
  2. 服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
  3. 冗余-分布式系统中的冗余问题。
  4. 负载平衡 --负载平衡改善跨多个计算资源 的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。
  5. 性能-问题 由于各种运营开销导致的性能问题。
  6. 部署复杂性-Devops 技能的要求。

        因此,当遇到该问题时需要用到SpringCloud

 二:什么是SpringCloud

        基于 Spring Boot 的 Spring 集成应用程序,它利用 Spring Boot 的开发便利性简化了分布式系统的开发,提供与外部系统的集成。 如服务注册与发现、配置中心、负载均衡、断路器、消息总线、数据监控等;换句话说:Spring Cloud 提供了构建分布式系统所需的“全家桶”。

核心组件 

  • Eureka:服务注册与发现。
  • Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。
  • Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。
  • Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。
  • Config:配置中心组件,它可以集中管理微服务的配置信息,从而实现配置的动态管理和更新。
  • Bus:消息总线组件,它可以实现微服务之间的消息传递和事件触发,从而实现微服务之间的解耦和通信
  • Zuul:API网关组件,它可以在微服务架构中起到网关的作用,从而实现请求路由、负载均衡、安全控制等功能。

三:为什么要学SpringCloud 

(1)互联网应用和传统应用的区别

        传统应用用于企业内部管理,面向企业内部人员

① 典型传统应用

        ① ERP 企业资源计划

        ② CRM 客户关系管理

        ③ WMS 仓储管理系统

        ④ OA 办公自动化

        ⑤ 各种后台管理系统,物业、物流、银行、金融.....

 特点:

  1. 使用的是特定人群,数量不多

  2. 对用户体验要求不高

  3. 对数据的一致性要求高

        互联网应用面向所有互联网用户  

② 典型互联网应用

        ① 电商

        ② 视频

        ③ 社交媒体

        ④ 新闻

         ⑤ 游戏

 特点:

  1. 面对所有互联网用户,用户量大

  2. 对用户体验要求高(界面、人性化、性能)

  3. 数据一致性要求相对不高

  4. 可用性要求高

  5. 三高问题(并发量、可用性、性能)

(2)微服务架构和单体应用架构的区别 

        传统应用大多数使用单体应用架构,互联网应用大多数采用微服务架构

① 微服务架构

        微服务架构是一种架构风格和架构思想,它倡导我们在传统软件应用架构的基础上,将系统业务按照功能拆分为更加细粒度的服务,所拆分的每一个服务都是一个独立的应用,这些应用对外提供公共的API,可以独立承担对外服务的职责,通过此种思想方式所开发的软件服务实体就是“微服务”,而围绕着微服务思想构建的一系列体系结构(包括开发、测试、部署等),我们可以将它称之为“微服务架构”。

        总的来说:N个项目达成N个包部署到服务器,将传统单体应用拆分为多微服务项目,每个微服务可以相互通信,部署到各自的服务器

优点: 

  1. 每个微服务项目复杂性降低

  2. 技术更新迭代快

  3. 可用性高

  4. 并发量提高

  5. 性能提高

 弊端:

  1. 整体项目复杂性大大提升

  2. 运维、硬件等成本高

  3. 项目之间通信、跟踪麻烦

 ② 单体应用架构

        单体应用架构是一种传统的软件架构模式,将整个应用程序作为一个单一的、紧密耦合的单元。在单体应用架构中,应用程序的所有组件,包括用户界面、业务逻辑和数据访问层,都封装在同一个应用程序中。

        总的就是:一个项目打成一个包部署到一台服务器

              

特点:

  1. 单一代码库:整个应用程序的所有代码都保存在一个代码库中。这使得开发团队可以更容易地理解和维护代码。

  2. 单一部署:整个应用程序作为一个整体进行部署。这意味着如果需要对应用程序进行更新、升级或修复,需要重新部署整个应用程序。

  3. 紧耦合:在单体应用架构中,各个组件之间通常是紧密耦合的,因为它们共享同一个代码库和数据库。这使得修改一个组件可能会影响其他组件。

  4. 技术一致性:单体应用架构通常要求使用相同的技术栈和工具。这使得开发团队可以共享相同的技术知识和经验。

  5. 扩展困难:由于组件之间的紧耦合关系,单体应用架构在面对高负载和需要更高性能的场景时,扩展性可能会受到限制。

 弊端:

  1. 项目复杂性高

  2. 技术更新迭代慢

  3. 单体故障,可用性差

  4. 并发量有限,只能垂直扩展,不能水平扩展

  5. 性能比较差

(3)SpringCloud的作用 

        Spring Cloud 是一个用于构建分布式系统的开发工具集合,它基于 Spring Framework 提供了一系列功能丰富的组件和库,用于简化分布式系统开发和管理。

其功能包含:

  • 分布式配置中心 Config、Nacos

  • 服务注册和发现 Eureka、Nacos、Zookeeper、Consul

  • 路由 Gateway、Zuul

  • 服务之间的调用 Feign、Dubbo

  • 负载均衡 Ribbon、LoadBalancer

  • 熔断器 Hystrix、Sentinel

  • 全局锁

  • 集群状态管理

  • 分布式消息 Bus

四:SpringCloud的优缺点 

优点:

(1)前后端分离开发,便于快速开发
(2)采用去中心化思想,服务之间采用Restful等轻量级通讯,比ESB更轻量
(3)利于扩展模块,乐高积木一般
(4)Springcloud的节点不会影响另一个节点
(5)适于互联网时代,产品迭代周期更短,如果用来做电商网站的话,性能是非常好的

缺点:

 配置复杂,节点多,涉及的知识点多,所以治理成本高,不利于维护系统,且对团队挑战大

五:微服务入门案例 

 提供数据的服务叫服务提供者,使用数据的服务叫服务消费者

订单微服务能够查询订单信息,订单信息中包含商品数据,订单微服务要调用商品微服务完成查询

                 

订单服务数据库为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;
  1. 编写商品服务,完成按商品id查询商品的功能

  2. 编写订单服务,完成按查询订单的功能

  3. 订单微服务调用商品微服务

@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注册中心的使用

(一)服务注册和发现机制

        服务注册:就是将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到1个公共的组件上去(比如: zookeeper\consul)。

        服务发现:就是新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增和服务删减都能实现自动发现。

可以理解为:

  •         服务注册 NameServer->register(newServer);
  •         服务发现 NameServer->getAllServer();

                 

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服务器项目

①继承父项目

    <parent>
        <groupId>com.blb</groupId>
        <artifactId>springcloud_demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

②引入服务器依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

③配置文件

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

④在启动类上加@EnableEurekaServer

 (四)配置Eureka客户端

①继承父项目

②引入客户端依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

③ 配置文件

# 服务名称
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

④启动类加 @EnableEurekaClient或 @EnableDiscoveryClient

⑤在RestTemplate配置类方法上加@LoadBalanced

⑥调用服务时修改

//调用商品微服务获得商品信息 将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服务端为了防止Eureka客户端本身是可以正常访问的,但是由于网路通信故障等原因,造成Eureka服务端失去于客户端的连接,从而形成的不可用。

        因为网络通信是可能恢复的,但是Eureka客户端只会在启动时才去服务端注册。如果因为网络的原因而剔除了客户端,将造成客户端无法再注册到服务端。

        如何关闭自我保护机制? 

​         配置eureka.server.enable-self-preservation = false关闭自我保护机制。

​         配置eureka.server.eviction-interval-timer-in-ms = 2000让服务端每隔2秒扫描一次,是服务能尽快的剔除。

eureka:
  server:
    #服务端是否开启自我保护机制 (默认true)
    enable-self-preservation: false
    #扫描失效服务的间隔时间(单位毫秒,默认是60*1000)即60秒
    eviction-interval-timer-in-ms: 2000

 八: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

 服务提供者和消费者注册到集群上

eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8012/eureka,http://127.0.0.1:8011/eureka

九:总结

        Spring Cloud提供了丰富的功能和组件,使得开发和管理分布式系统变得更加简单和高效。它的模块化设计和与Spring Boot的无缝集成,为开发者提供了强大的工具和框架,帮助构建稳定、可靠的微服务应用程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值