背景
微服务
# 微服务解决的四个核心问题
1. 服务有很多,客户端怎么访问
2. 这么多服务之间如果通信
3. 这么服务如何治理
4. 服务挂了怎么办
# 微服务的解决方案
1. Spring Cloud NetFlix 一站式解决方案
api网关 ————》 zuul组件
Fegin-----》httpClient------》http通信的方式,同步,阻塞
服务注册与发现------》Eureka
熔断机制----------》 Hystrix
2. apache Dubbo + Zookeeper
API网关-----》 没有,可以选用第三方组件,或者自己实现
Dubbo-------》 服务通信
Zookeeper------》 服务治理
熔断机制没有
3. Spring Cloud Alibaba
# 万变不离其宗 ,都存在一下几个
1. API(客户访问?)
2. 服务通信Http RPC
3. 服务注册与发现
4. 熔断机制
微服务是一种架构模式
它提倡将单一的应用程序划分为一组小的服务,而这些服务,
- 独立在自己的进程内
- 服务之间相互协调,相互配置
- 一起为用户提供最终价值
- 服务之间采用轻量级的通信机制
- 每个服务围绕具体的业务进行构建,并且能够独立部署到生产环境中
# 微服务优点
1. 单一职责原则
2. 每个服务足够内聚
3. 开发简单,每个服务专一的干一件事
4. 微服务之间松耦合
5. 微服务只是业务逻辑代码,不会有html.css等混合
6. 每个微服务都有自己的存储能力 ,可以有自己的数据库,也可以有统一的数据库
#微服务缺点
1. 处理分布式系统的复杂性
2. 运维难度大
3. 系统部署依赖
4. 数据一致性
5. 服务间的通信成本
6. 系统的集成测试,性能监控等进行时复杂
大型网站架构图
构建SpringCloud
版本选择
1.创建父工程
- 创建空的maven项目,可删除src目录
- 打包方式选择pom
<package>pom</package>
- 父工程管理依赖
<dependecyManagemt>
<dependecies>
...
</dependecies>
</dependecyManagemt>
此时jar包未导入,只是进行了管理
- 依赖管理
- spring-cloud-dependencies
- spring-boot-dependencies
- mysql-connector-java
- druid
- mybatis-spring-boot-starter
- 日志与测试
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chen</groupId>
<artifactId>Spring-Cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.16.18</lombok.version>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>pom</type>
<scope>import</scope>
<version>2.1.4.RELEASE</version>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--springboot启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--以下四个为日志与测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
</build>
</project>
2.创建子工程springcloud-api
- 引入自己需要的父工程中的依赖
- 创建数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PMCygAyk-1608684019481)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201208215228887.png)]
- 编写表对应的实体类
-
实体类必须实现序列化,否则传输时报错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oG2FGsz1-1608684019482)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201208221220233.png)]
此微服务只管pojo
3.创建子工程(提供服务)
- 引入依赖(创建maven项目)
- springcloud-api 工程
- mysql-connnector-java
- druid
- spring-boot-starter
- mybatis-spring-boot-starter
- spring-boot-devtools
- spring-boot-test
- spring-boot-starter-web
- spring-boot-starter-jetty
- 日志
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Spring-Cloud</artifactId>
<groupId>com.chen</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-provider-dept-8001</artifactId>
<dependencies>
<!--需要实体类,所以导入api module-->
<dependency>
<groupId>com.chen</groupId>
<artifactId>springcloud_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!--同tomcat一样-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
</dependencies>
</project>
- 编写配置文件 application.yml
- 端口配置
- mybatis配置
- spring配置(name和DataSource的配置)
server:
port: 8002
mybatis:
#pojo文件的位置
type-aliases-package: chen.springcloud.pojo
config-location: classpath:mybatis-config.xml
#注意是mapper-locations而不是mapper-location
mapper-locations: classpath:mapper/*.xml
#spring的配置
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
username: root
password: 1234
- 编写dao
- @Mapper
- @Repositroy
- 编写mapper文件
-
注意位置:
mybatis: #pojo文件的位置 type-aliases-package: chen.springcloud.pojo #注意是mapper-locations而不是mapper-location mapper-locations: classpath:mapper/*.xml
因为此处为实体类起了别名,mapper文件中可以直接用类名引入实体类,可不用全限定名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U1yPVo04-1608684019483)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201209210347163.png)]
- 编写service和controller
- 使用restful风格api
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqNC9xiO-1608684019484)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201209210517007.png)]
- 编写启动类
- 注解 @SpringBootApplication
@SpringBootApplication
public class Provider {
public static void main(String[] args) {
SpringApplication.run(Provider.class,args);
}
}
启动的时候,发生包依赖之间的冲突,通过重新引入包解决
- 测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zXSL4PWP-1608684019485)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201209210853341.png)]
4. 创建子工程(消费者)
创建maven项目
- 导入依赖
- 实体类:springcloud-api
- spring-boot-starter-web
- spring-boot-devtools (热部署)
- 编写application.yml
- 配置端口即可
- 使用RestTemplate完成服务调用
- 通过以下方式生成RestTemplate 的bean对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDfHxZ9H-1608684019487)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211202228246.png)]
- Contoller中使用RestTemplate
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RNJ3KFkm-1608684019488)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211202436650.png)]
- 编写启动类
- @SpringBootApplication
- SpringApplication.run(Class,args);
Eureka
- 基于CS架构
- Eureka Server提供服务注册Eureka Server的服务注册表中拥有所有可用节点的信息
- Eureka Client 是一个java客户端,应用启动后将会个Eureka Server发送心跳,周期为30秒,如果Eureka Server在多个心跳周期中没有接受到某个节点心跳,Eureka Server将会把此节点从服务注册表中删除(默认为90秒)
- 基于REST服务,完成服务注册与发现(Zookeeper也完成同样的功能)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fY2lUcwv-1608684019490)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211203218509.png)]
-
Eureka的三大角色
- Eureaka Server : 提供服务注册与发现
- Service Provider:将自身服务注册到Eureka中,从而使消费者能够找到
- Service Consumer:服务消费方,从Eureka获得服务注册列表
-
配置此类中间件的思路
- 导入依赖
- 编写配置文件
- 开启这个功能 @EnableXXX
- 配置类
创建Eureka Server
- 导入依赖
- spring-cloud-starter-netflix-eureka-server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
- 编写配置
- register-with-eureka: false
- fetch-registry: false
server:
port: 7001
#Eureka的配置
#eureka服务端的实例名称
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #是否向eureka注册自己,因为自己就是服务器,false
fetch-registry: false # false表明自己是服务端
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- 开启功能
- @EnableEurekaServer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HVCSCjHX-1608684019491)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211220440027.png)]
访问http://localhost:7001/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ud4zzwgV-1608684019492)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211223220191.png)]
创建Eureka Clinet(使用提供服务的子工程)
1. 服务注册
- 导入依赖
- spring-cloud-starter-netflix-eureka-client
<!--eureka client-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
- 编写配置
- service-url :注册中心的位置
# eureka client的配置
eureka:
client:
service-url:
#公共信息可以配置中心来维护?
defaultZone: http://localhost:7001/eureka/
- 开启功能
- @EnableEurekaClient
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqfK9Wa6-1608684019493)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211221556414.png)]
可以看到已经注册成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y2YjPNTx-1608684019494)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211222740204.png)]
我们可以配置instance-id 来改变 Status下的描述信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2TQGRhlz-1608684019495)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211223026606.png)]
已发生改变:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KzCy1Iq3-1608684019496)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211223140199.png)]
2. 信息监控actuator
- 导入actuator的依赖
<!--信息监控actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
- 直接放问一些相关信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SESnQPID-1608684019499)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211224849826.png)]
- 可以配置info 供信息监控访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMiJjFr6-1608684019500)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211225216517.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bxpRfVtw-1608684019501)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211225158560.png)]
3.服务发现(获取服务信息)
- 使用到的类
-
DiscoveryClient
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CUmUkq3j-1608684019502)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211231104907.png)]
- 获取服务信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r7ZsXM8p-1608684019503)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211231052262.png)]
注意 serviceid是application的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RNTMPPiB-1608684019504)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201211231212242.png)]
配置Eureka集群
- 先创建多个Eureka Server
- 导入依赖
- 编写配置文件
- 在主启动类上添加注解 @EnableEurekaServer
- 配置集群,将几个Eureka Server进行关联
- 在hosts文件中将域名eureka1,eureka2,eureka3映射到127.0.0.1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Msi6GZB-1608684019505)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212225128261.png)]
- 在一个Eureka Server中关联其他的Eureka Server
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-04K4DpRP-1608684019506)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212224858590.png)]
- 将服务注册到每个集群当中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PNCw2UF6-1608684019507)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212225205427.png)]
其他配置都不变,就是改变defaultZone
- 测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pCxSNEaK-1608684019508)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212225329708.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nThsb26l-1608684019509)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212225401095.png)]
集群的模型如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rilj4iHc-1608684019510)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212225502641.png)]
CAP&Eureka和Zookeeper的对比
CAP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ByaXt878-1608684019511)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212230854238.png)]
分区容错性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u9dUPwZs-1608684019512)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212231047904.png)]
Zookeeper与Eureka对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJ4XgOo2-1608684019513)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201212231626872.png)]
因此,Eureka能够很好的应对因网络故障导致的部分节点失去联系的情况,而不会像Zookeeper那样整个注册服务宕机。
Ribbon
- LB 负载均衡(Load Balance)在微服务或者分布式集群中的一种应用
- 负载均衡 就是将用户的请求平均的分配到多个服务器上,从而达到系统的高可用性HA
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZOcB8Vnz-1608684019514)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213204023710.png)]
使用
在消费者中导入ribbon的依赖,并且同时导入erueka client的依赖
- rabbion 从Eureka集群中获取服务提供者的地址,因此也需要Eureka client的依赖
<!--ribbon-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<!--从Eureka集群中获取服务提供者的地址,因此也需要Eureka client的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
配置eureka
eureka:
client:
register-with-eureka: false
# ribbon 从以下Eureka中选择一个来获取 服务提供者
service-url:
defaultZone: http://eureka1:7001/eureka/,http://eureka2:7002/eureka/,http://eureka3:7003/eureka/
开启eureka客户端
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oqBvqS0N-1608684019515)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213211930499.png)]
给RestTemplate 添加负载均衡的注解 @LoadBalance
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qua2zwY-1608684019516)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213212040268.png)]
通过eureka中注册的服务提供者的名称(application的值) 获取服务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NroVewGP-1608684019518)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213212152013.png)]
访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mOgjdFox-1608684019519)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213212325784.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w71Yh93x-1608684019520)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213212344663.png)]
ribbon和eureka整合之后,客户端可以直接调用,不用关心端口号和ip地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3iEbna5Q-1608684019521)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213212602849.png)]
使用ribbon实现负载均衡
创建多个服务提供者,且spring.application.name都保持一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zM6wyLmA-1608684019523)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213215617668.png)]
创建多个数据库,db01 db02 db03
测试
- ribbon的负载均衡通过轮询的方式选择服务
可以看到存在两个提供相同服务的服务:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T4S4rtqP-1608684019524)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213223938225.png)]
访问服务:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBjlUdCr-1608684019525)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213224014990.png)]
刷新变为db02
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pFs3BnpA-1608684019526)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201213224109758.png)]
自定义负载均衡的策略
在主启动类的目录外 编写负载均衡的选择服务的策略
- **实现IRule接口,可以参照其他实现类,写自己的实现类 **
- 将自己的实现类 加入spring容器内
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FqOjWAQr-1608684019528)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201214213959447.png)]
- 此时@LoadBalanced就会使用我们自己的负载均衡策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56l07Poy-1608684019529)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201214214124619.png)]
Feign替代RestTemplate
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
Feign集成了ribbon
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lo4Zed2n-1608684019530)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201216000413815.png)]
在api工程中添加接口,feign是面向接口编程
方法上的请求对应的是服务提供者的方法的uri
Feign集成了ribbon,通过轮询的方式来访问provider
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TUZNnXeY-1608684019531)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201216230639113.png)]
- 编写feign的服务消费者 注入api接口下的DeptClientservice
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B1WDKxqq-1608684019532)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201216230727404.png)]
- 开启feign 并且扫描api工程下下的包含注解 @FeignClient的service
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMtb95Wa-1608684019533)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201216230951444.png)]
Hystrix
服务雪崩
多个微服务调用时,假设微服务A调用微服务B,B又调用微服务C,C又调用其他服务,这就是所谓的扇出,如果扇出的链路上一个微服务崩了,从而使得整套服务崩溃,进而引起系统崩溃,这就是所谓的雪崩效应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQYTV95T-1608684019535)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215220924328.png)]
Hystrix的功能:
- 服务熔断
- 服务降级
- 服务限流
- 接近实时的监控
服务熔断
是对雪崩效应的一种微服务链路保护机制
熔断机制的注解是@HystrixCommand
服务熔断的使用
- 导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
- 在要熔断的方法上添加解决方案(方法)
- 写在服务提供方
- 服务熔断使用的注解为@HystrixCommand
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JsgeCjnr-1608684019536)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215223919140.png)]
点开注解@HystrixCommand:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LNdy23Nu-1608684019538)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215223638423.png)]
fallbackMethod属性用来当本方法调用失败时回调方法
- 在主启动类上添加断路器的支持
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Ak9AxIY-1608684019539)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215224953589.png)]
- 测试
调用不存在的id:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zMluKoW6-1608684019540)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215224501778.png)]
而没有使用服务熔断的provider,调用id=9 就会发生错误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XSrnweM-1608684019541)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201215224913406.png)]
服务降级
-
服务降级是在客户端(consumer),而服务熔断则是在服务端(provider)
-
服务降级,就是在整个系统中,当A服务访问量巨大,而B服务几乎没有访问,为了让A占用更多的资源以应对高访问量,从而停掉B服务,但是当B服务停掉之后,访问B服务就会发生错误,但是可以通过服务降级,来为用户反馈停掉服务的原因,而不是直接展示错误信息
-
配合面向接口的feign使用
- 实现FallbackFactory 用来返回服务降级时的提示信息
- 在DeptClientService添加
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4eBbA6F-1608684019542)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201216233043304.png)]
- 在消费者微服务中开启服务降级
-
feign.hystrix.enable=true
-
没法获取到FallbackFactory的bean对象,直接扫描对应的包
-
或者在本项目中继承api这样就不用去扫描
- 关掉服务提供者(provider)进行测试
536)]
点开注解@HystrixCommand:
[外链图片转存中…(img-LNdy23Nu-1608684019538)]
fallbackMethod属性用来当本方法调用失败时回调方法
- 在主启动类上添加断路器的支持
[外链图片转存中…(img-2Ak9AxIY-1608684019539)]
- 测试
调用不存在的id:
[外链图片转存中…(img-zMluKoW6-1608684019540)]
而没有使用服务熔断的provider,调用id=9 就会发生错误
[外链图片转存中…(img-3XSrnweM-1608684019541)]
服务降级
-
服务降级是在客户端(consumer),而服务熔断则是在服务端(provider)
-
服务降级,就是在整个系统中,当A服务访问量巨大,而B服务几乎没有访问,为了让A占用更多的资源以应对高访问量,从而停掉B服务,但是当B服务停掉之后,访问B服务就会发生错误,但是可以通过服务降级,来为用户反馈停掉服务的原因,而不是直接展示错误信息
-
配合面向接口的feign使用
- 实现FallbackFactory 用来返回服务降级时的提示信息
- 在DeptClientService添加
[外链图片转存中…(img-U4eBbA6F-1608684019542)]
- 在消费者微服务中开启服务降级
-
feign.hystrix.enable=true
-
没法获取到FallbackFactory的bean对象,直接扫描对应的包
-
或者在本项目中继承api这样就不用去扫描
- 关掉服务提供者(provider)进行测试