1.简介
- 1.Spring Cloud 是微服务架构的一站式解决方案,它提供了一套简单易用的编程模型,能在 Spring Boot 的基础上轻松地实现微服务系统的构建
- 2.Spring Cloud 被称为构建微服务系统的“全家桶”,它并不是某一门技术,而是一系列微服务解决方案或框架的有序集合
- 3.Spring Cloud 将市面上成熟的、经过验证的微服务框架整合起来,并通过 Spring Boot 的思想进行再封装,屏蔽其中复杂的配置和实现原理,最终提供的一套简单易懂、易部署和易维护的系统开发工具包
- 4.Spring Cloud 提供了服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案
- 5.Spring Cloud 本身并不是一个拿来即可用的框架,它是一套微服务规范,共有两代实现。
- 1.Spring Cloud Netflix 是 Spring Cloud 的第一代实现,主要由 Eureka、Ribbon、Feign、Hystrix 等组件组成
- 2.Spring Cloud Alibaba 是 Spring Cloud 的第二代实现,主要由 Nacos、Sentinel、Seata 等组件组成
- 6.微服务除了Spring Cloud架构外还有Dobbo+Zookeeper架构
2.历史
- 根据SpringCloud版本的命名方式的改变可以分为两个阶段:
- 1.伦敦地铁站名
- 在Spring Cloud 2020.0.0版本之前,SpringCloud的所有版本均按照伦敦地铁站站名从A-Z的排序进行命名
- 2.日历化版本
- 从 Spring Cloud 2020.0.0-M1 开始,Spring Cloud 废除了这种英国伦敦地铁站的命名方式,而使用了全新的 “日历化” 版本命名方式。
Spring Cloud 使用了 YYYY.MINOR.MICRO 的命名规则:
- YYYY:表示 4 位年份;
- MINOR:代表一个递增的数字,每年以 0 开始递增;
- MICRO:代表版本号后缀,就和之前使用的 .0 类似>于 .RELEASE 一样,.2 类似于 .SR2。
例如:2020.0.0版本的变化给SpringCloud带来了什么样的改变呢?
Netflix 网飞
SpringCloud的改变目前来说主要体现在对Netflix套件的支持上,早期SpringCloud主要是封装了Netflix套件实现服务注册发现,负载均衡,熔断等功能,但是随着版本的迭代,由于Netflix停止开源项目的更新,所以SpringCloud开始逐步减少对Netflix套件的支持。
从2020版本开始,SpringCloud弃用Netflix套件,进入一个新的时代,但是对于企业开发而言,现在未必需要立马更新最新版本。一方面大量项目还是采用Netflix组件进行开发,目前来看并没有替换的必要性。另一方面部分技术并不能完全兼容新版本,例如SpringCloud Alibaba就不能完全兼容新版本。
3.特性
4.适用场景
5.演变流程
1.单体应用架构
- 定义:将多个模块的系统做成一个web项目并部署到一台服务器上
优点
- 1.项目架构简单,开发成本低
- 2.项目部署在一个节点上,维护方便
缺点
- 1.全部功能集成在一个系统中,不利于维护
- 2.项目模块之间紧密耦合,单点容错率低
- 3.无法针对不同模块进行针对性优化和水平扩展
2.垂直应用架构
- 产生原因:单体应用访问量逐渐增大,并发问题增多,但并非所有功能模块都会有较大的访问量
- 定义:将单体应用拆分成几个互不相关的几个系统(例:电商单体拆分成电商系统,后台系统等)
优点
- 1.系统拆分实现了流量分担,解决了并发问题
- 2.可以针对不同的模块进行优化和扩展
- 3.一个系统的问题不会影响到其他系统,提高容错率
缺点
- 1.系统之间相互独立,无法进行相互调用
- 2.系统时间相互独立,会有重复的开发任务
3.分布式架构
- 产生原因:垂直应用增多,重复的业务代码也增多,将重复的代码抽取出来做成统一的业务层
- 定义:将垂直应用中重复的代码抽取出来提供独立的功能
优点
- 1.抽取公共的功能为业务层,提高代码复用性
缺点
- 1.系统间耦合度变高,调用关系错综复杂,难以维护
集群
- 产生原因:某些服务的访问量很大(商品,首页),单台服务器无法支撑巨大的访问量可能会宕机,为了解决该问题将多台服务器协同合作形成集群以面对巨大的访问量
- 定义:同一个系统放在了多台服务器上,且每个服务器上内容相同,提供相同的服务
3.SOA架构
- 产生原因:分布式架构下,将抽取出来的公共模块当成一个个独立的服务,当服务越来越多,需要一个调度中心对集群进行实时管理
- 定义:使用调度中心对多个服务进行统一的调度和管理
优点
- 1.使用治理中心解决了服务间调用关系的自动调节
缺点
- 1.服务间会有依赖,一旦某个环节出错会影响较大
- 2.服务关系复杂,运维,测试部署困难
4.微服务架构
- 产生原因:SOA架构拆分的粒度不够精细,服务之间耦合度大,服务关系复杂
- 定义:将SOA架构中的服务进行更细致的拆分,使每个服务之间互不干扰(单独数据库),独立运行,独立部署
优点
- 1.服务原子化拆分,独立打包,部署和升级,保证每个微服务清晰的任务划分,利于扩展
- 2.微服务之间采用Restful等轻量级http协议互相调用
缺点
- 1.分布式系统开发的技术成本高(容错,分布式事务等)
- 2.复制性更高,各个微服务进行分布式独立部署,当进行模块调用的时候,分布式将会变得更加麻烦
1.SOA
- 面向服务的架构:把每个项目当成一个服务来看待,而不是当成一个独立的项目
2.RPC
- 远程调用过程:微服务和SOA架构中需要服务与服务之间相互调用,这种调用不像本地方法,需要通过网络远程调用
6.微服务架构常见问题
- 1.服务如果进行管理( nacos:服务治理,注册中心)
- 2.服务之间怎么调用通讯(RPC:restTemplate,openfeign,dubbo)
- 2.服务消费者调用服务提供者(多个)时如何进行负载均衡(ribbon)
- 4.客户端如何访问服务(gateway:网关)
- 5.服务错误如何自处理(sentinel:容错)
- 6.服务出错如何排错(skywalking:链路追踪)
7.项目搭建
- 版本对应关系
1.创建项目
- 1.创建maven项目
- 2.删除src文件夹
- 3.pom.xml文件夹的打包方式改为pom
2.导入依赖
<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.0modelVersion> <groupId>org.examplegroupId> <artifactId>springcloudalibabaartifactId> <version>1.0-SNAPSHOTversion> <modules> <module>Ordermodule> <module>Stockmodule> <module>Order_Nacosmodule> <module>Stock_Nacosmodule> <module>Stockmodule> modules> <packaging>pompackaging> <description>统一依赖管理description> <properties> <java.version>1.8java.version> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <maven.compiler.source>1.8maven.compiler.source> <maven.compiler.target>1.8maven.compiler.target> properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-dependenciesartifactId> <version>2.2.2.RELEASEversion> <type>pomtype> <scope>importscope> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-dependenciesartifactId> <version>Hoxton.SR9version> <type>pomtype> <scope>importscope> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-alibaba-dependenciesartifactId> <version>2.1.2.RELEASEversion> <type>pomtype> <scope>importscope> dependency> dependencies> dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> dependencies> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
1.创建项目
- 1.在当前父项目中创建子模块
- 2.pom.xml文件夹的打包方式改为jar/war
2.导入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>OrderartifactId> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.修改配置文件
server: port: 8010
- 1
- 2
4.调用订单服务
- 1.启动类
package com.wd.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 2.RestTemplate配置类
package com.wd.order.config; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){ //官方建议使用构造器创建RestTemplate实例,也可以使用new RestTemplate restTemplate = restTemplateBuilder.build(); return restTemplate; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 3.接口
package com.wd.order.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/order") public class OrderController { @Resource RestTemplate restTemplate; @RequestMapping("/add") public String add(){ System.out.println("下单成功"); String msg = restTemplate.getForObject("http://localhost:8011/stock/reduce", String.class); return "add success" + msg; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
1.创建项目
- 1.在当前父项目中创建子模块
- 2.pom.xml文件夹的打包方式改为jar/war
2.导入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>StockartifactId> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.修改配置文件
server: port: 8011
- 1
- 2
4.提供服务
- 1.启动类
package com.wd.stock; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StockApplication { public static void main(String[] args) { SpringApplication.run(StockApplication.class, args); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 2.接口
package com.wd.stock.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/stock") public class StockController { @RequestMapping("/reduce") public String reduce(){ System.out.println("扣减库存"); return "reduce success"; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
8.快速搭建平台(Java工程脚手架)
2.Spring Cloud Alibaba
1.Nacos
- 1.一个更易于构建云原生应用的动态服务发现(Nacos Discovery),服务配置(Nacos Config)和服务管理平台
- 2.集:注册中心+配置中心+服务管理平台
1.Nacos特性
- 1.服务发现和服务监控检测
- 2.动态配置服务
- 3.动态DNS服务
- 4.服务及其元数据管理
2.Nacos注册中心
- 定义:管理所有微服务,解决微服务之间调用关系错综复杂,难以维护的问题
- 核心功能
- 1.服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据(ip地址,端口等信息)。Nocos Server接收到注册请求后,保存在一个双层的内存Map中
- 2.服务心跳:服务注册后,Nacos Client会维护一个定时心跳来持续通知NacosServer ,说明服务一直处于可用状态,防止被移除,默认5s发送一次心跳
- 3.服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性
- 4.服务发现:服务消费者在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在NacosClient本地开启一个定时任务,定时拉取服务器最新的注册表信息更新到本地缓存
- 5.服务健康检测:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false,如果某个实例超过30秒没有收到心跳,直接移除该实例
3.不同注册中心对比
- 1.Eureka属于Netflix,Netflix闭源不更新,很多组件不支持
- 2.Nacos功能最全,一般采用Nacos注册中心
1.下载安装包
- https://github.com/alibaba/nacos/releases
2.解压启动
- 1.解压文件
- 2.进入bin目录下的地址栏输入cmd
- 3.启动单机模式(临时,也可修改配置文件永久生效)
startup.cmd -m standalone
- 1
- 4.修改配置文件,永久生效
3.访问Nacos
- 路径:http://localhost:8848/nacos/index.html
- 账号密码:默认都是nacos
1.单机
2.集群
1.创建父项目
- 同上述7.1创建父项目
1.创建项目
- 1.在当前父项目中创建子模块
- 2.pom.xml文件夹的打包方式改为jar/war
- 注意:FeignConfig配置类和feign包是属于OpenFigen组件的试例
2.导入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>Order_NacosartifactId> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-actuatorartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency> dependencies> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
3.修改配置文件
server: port: 8020 spring: application: name: order-service cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos namespace: public
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
4.调用订单服务
- 1.启动类
package com.wd.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient //可省略 public class OrderNacosApplication { public static void main(String[] args) { SpringApplication.run(OrderNacosApplication.class, args); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 2.RestTemplate配置类
package com.wd.order.config; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @LoadBalanced //表示采用Ribbon负载均衡,如果不添加会报错 public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){ RestTemplate restTemplate = restTemplateBuilder.build(); return restTemplate; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 3.接口
package com.wd.order.controller; import com.wd.order.feign.StockFeignService; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/order") public class OrderController { @Value("${server.port}") String port; @Resource RestTemplate restTemplate; @RequestMapping("/add") public String add(){ System.out.println("下单成功"); String msg = restTemplate.getForObject("http://stock-service/stock/reduce", String.class); return port + "端口下单成功" + " : " + msg; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
1.创建项目
- 1.在当前父项目中创建子模块
- 2.pom.xml文件夹的打包方式改为jar/war
2.导入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>StockartifactId> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.修改配置文件
server: port: 8011
- 1
- 2
4.提供服务
- 1.启动类
package com.wd.stock; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StockApplication { public static void main(String[] args) { SpringApplication.run(StockApplication.class, args); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 2.接口
package com.wd.stock.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/stock") public class StockController { @RequestMapping("/reduce") public String reduce(){ System.out.println("扣减库存"); return "reduce success"; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2.Ribbon
- 1.Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具
- 2.通过Load Balance获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,权重等)去调用这些服务
- 3.Ribbon也可以实现自定义负载均衡算法
1.客户端负载均衡(ribbon)
- 一般客户端负载均衡,客户端会有一个服务器地址列表(注册中心),发送请求前通过负载均衡算法选择一个服务器,然后进行访问
2.服务器端负载均衡(nginx)
- 先发送请求,然后通过负载均衡算法,在多个服务之间选择一个进行访问
3.负载均衡算法
- 1.轮询:负载均衡默认实现方式,请求来之后排队处理;
- 2.加权轮询:通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力
- 3.地址Hash:通过客户端请求的地址的HASH值取模映射进行服务器调度
- 4.最小链接数:即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况(例:请求积压数等参数),将请求分
配到当前压力最小的服务器上
4.Nacos使用Ribbon
1.添加依赖
- nacos-discovery依赖了ribbon,可以不再进入ribbon依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>Order_NacosartifactId> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-actuatorartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency> dependencies> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
2.添加注解
package com.wd.order.config; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @LoadBalanced //表示采用Ribbon负载均衡,如果不添加会报错 public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){ RestTemplate restTemplate = restTemplateBuilder.build(); return restTemplate; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
3.修改controller
package com.wd.order.controller; import com.wd.order.feign.StockFeignService; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/order") public class OrderController { @Value("${server.port}") String port; @Resource RestTemplate restTemplate; @RequestMapping("/add") public String add(){ System.out.println("下单成功"); String msg = restTemplate.getForObject("http://stock-service/stock/reduce", String.class); return port + "端口下单成功" + " : " + msg; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
5.修改负载均衡策略
1.配置类
2.配置文件
server: port: 8020 spring: application: name: order-service cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos namespace: public # 负载均衡 stock-service: ribbon: # 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重) NFLoadBalanceRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
6.自定义负载均衡策略
- 通过实现IRule接口可以自定义负载策略
1.实现基于Nacos权重的负载均衡策略
2.配置自定义的策略
7.饥饿加载
8.Ribbon原理
3.OpenFigen
- 1.Spring Cloud OpenFeign对Feign进行了增强,使其支持Spring MVC注解
- 2.Spring Cloud OpenFeign整合了Nacos和Ribbon,使其使用更加方便
1.Feign
- 1.Feign是Netflix开发的声明式,模板化的HTTP客户端
- 2.Fegin可以帮助我们更加便捷,优雅地调用HTTP API
1.引入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>Order_NacosartifactId> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-actuatorartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency> dependencies> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
2.配置类
package com.wd.order.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //全局配置:将配置作用在所有服务提供方 //局部配置:如果只针对某一个服务进行配置,不需要加>@Configuration @Configuration public class FeignConfig { @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
3.测试
- 1.启动类
package com.wd.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication //@EnableDiscoveryClient @EnableFeignClients public class OrderNacosApplication { public static void main(String[] args) { SpringApplication.run(OrderNacosApplication.class, args); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 2.接口
package com.wd.order.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; /** * name 指定调用rest接口所对应的服务名 * path 指定stockController对应的RequestMapping(如果类上没有则不使用path) */ @FeignClient(name = "stock-service", path = "/stock") public interface StockFeignService { //声明需要调用打的rest接口对应的方法 @RequestMapping("reduce") String reduce(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 3.控制层
package com.wd.order.controller; import com.wd.order.feign.StockFeignService; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/order") public class OrderController { @Value("${server.port}") String port; @Resource StockFeignService stockFeignService; @RequestMapping("/add") public String add(){ System.out.println("下单成功"); String msg = stockFeignService.reduce(); return port + "端口下单成功" + " : " + msg; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
3.自定义配置
1.日志配置
2.契约配置
3.自定义拦截器
4.超时时间配置
5.客户端组件配置
6.压缩配置
4.Sentinel
- 面向分布式服务架构的流量控制组件
- 从流量为切入点,从限流,流量整形,熔断降级,系统负载保护,热点防护等多个维度保证微服务的稳定性
1.服务雪崩
- 定义:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程
- 服务不可用原因:
- 1.流量激增导致系统CPU飙高,无法正常处理请求
- 2.消息投递速度过快,导致消息积压
- 3.激增流量打垮冷系统(数据库连接未创建,缓存未预热)
- 根本原因:服务提供者不可用时,出现大量重试(用户重试,代码逻辑重试),导致大量请求线程同步等待(占用系统资源),造成计算机资源耗尽,从而造成服务雪崩
2.解决方案(容错机制)
- 1.超时机制
- 1.不做任何处理的情况下,服务提供者不可用会导致消费者请求线程强制等待,造成系统资源耗尽
- 2.一旦超时,就释放资源(由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题)
- 2.服务限流
- 1.当QPS(每秒请求次数)超过规定的次数,则采取直接拒绝或者其他策略
- 3.服务隔离
- 1.用户的请求不再直接访问服务,而是通过线程池中的空闲线程访问服务,如果线程池已满,则进行降级处理,用户的请求不会阻塞,至少可以看到一个执行结果(例:返回暂时无法访问,请稍后再试),而不是无休止的等待或者等到系统崩溃
- 4.服务熔断
- 1.远程服务部稳定或者网络抖动时暂时关闭
- 2.实现检测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就打开断路器,此时请求直接返回,而不去调用原本的逻辑
- 3.断路一段时间后(例:10秒),断路器会进入半开状态,只是一个瞬间太,此时允许一个请求调用该逻辑。如果成功,则断路器关闭,应用正常调用;如果失败,断路器继续回到打开状态。一段时间后再进去半开状态尝试
- 4.通过断路应用可以保护自己避免资源浪费,通过半开应用可以实现自我修复
- 5.服务降级
- 1.当某个服务熔断之后,服务将不再被调用。客户端调用本地的回退方法,返回一个默认值(例:备用接口/缓存/mock数据)
- 2.虽然服务水平下降,但是保证了可用性
3.Sentinel与Hystrix对比
4.Sentinel项目搭建
1.导入依赖
2.添加配置类
3.接口测试
5.启动Sentinel控制台
- 1.下载控制台jar包
- https://github.com/alibaba/Sentinel/releases
- 2.本地启动
- java -jar sentinel -dashboard-1.8.0.jar
- 3.参数配置
- 1.-Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;
- 2.-Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为
sentinel;- 3.-Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,
默认为 30 分钟;- 4.java Dserver.port=8858 Dsentinel.dashboard.auth.username=xushu Dsentinel.dashboard.auth.password=123456 jar sentineldashboard1.8.0.jar
- 4.访问
- http://localhost:8080/#/login
1.导入依赖
<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>springcloudalibabaartifactId> <groupId>org.examplegroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <artifactId>Order_NacosartifactId> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-actuatorartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-sentinelartifactId> dependency> dependencies> project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
2.修改配置文件
3.sentinel控制台中设置流控规则
5.Seata
- 一款开源的分布式事务解决方案,采用AT事务模式
Seata的三大角色
- TC:事务协调者
- 维护全局和分支事务的状态,驱动全局事务提交或回滚
- TM:事务管理器
- 定义全局事务的范围:开始全局事务、提交或回滚全局事务
- RM:资源管理器
- 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚
- 注意:TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端
1.2PC(两阶段提交协议)
- 将提交分成两个阶段:Prepare(预处理),Commit(提交)
2.AT模式
- AT是一种无侵入的分布式事务解决方案
3.TCC模式
- 侵入性比较强,并且需要自己实现相关事务控制逻辑
- 在整个过程中基本没有锁,性能更强
Seata Server(TC) 环境搭建
6.Gateway
7.Skywalking