springcloud
Posted xue_yun_xiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springcloud相关的知识,希望对你有一定的参考价值。
一、概念
Feign,中文意义就是伪装, feign 就会将restTemplate 发起的get post请求封装起来,伪装成程 service接口,我们只需要调用接口,其他交给 Feign来完成
feign 将调用远程的请求 伪装成本地的接口,让应用调用,非常的方便
springcloud微服务之间,互相调用是通过restTemplate互相调用,传入路径和参数,就可以完成http请求
实例
1、创建一个feign 子应用,在springcloud(一)代码基础上
2、引入依赖
<dependencies>
<!--springBoot 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- alibaba.cloud 相关-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- feign 相关依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 引入公共 模块-->
<dependency>
<groupId>com.qfedu</groupId>
<artifactId>springcloudalibaba-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
3、配置 配置文件
server.port=8093
#为当前应用起 一个名字 改名字也是一个服务名 ,注意服务名 不可以使用下划线,使用下划线有可能找不到服务
spring.application.name=springcloudalibaba-customer-feign
#配置nacos 服务地址 作用包含了spring.cloud.nacos.discovery.server-addr
spring.cloud.nacos.server-addr=localhost:8848
#spring.cloud.nacos.discovery.server-addr=localhost:8848
#暴漏端点 将所有的的接口进行监控
management.endpoints.web.exposure.include=*
4、启动类
@EnableFeignClients // 激活feign 注解
@EnableDiscoveryClient // 激活nacos注解
@SpringBootApplication
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class,args);
}
}
5、创建伪装接口
/**
* feign 会为 当前接口生成 实现类 封装restTemplate 请求
*
* 当前接口实现类是要调用 Provider 接口
* 1.将 Provider HelloController接口 拷贝过来
* 2.将方法体 去掉
*
*/
@FeignClient(value = "springcloudalibaba-provider") //告诉feign 去springcloudalibaba-provider 服务请求数据
public interface FeignService {
// rest风格 请求
@RequestMapping("/getMessage/{msg}")
public String getMessage(@PathVariable("msg") String msg);
// key value键值对
@RequestMapping("/say")
public String say(@RequestParam("msg") String msg);
// 更新学生 当前服务提供者 需要Student
// 服务消费者 也需要Student
// 所以 我们需要将 Student 写在公共的 模块中(一个子工程)
/**
* 当前 方法 需要被消费者 远程调用 通过RestTemplate
* 调用使用 传递对象 接受 的必须是json @RequestBody Student student
* @param student
* @return
*/
// 接受json 转对象
@RequestMapping("/updateStudent")
public Student updateStudent(@RequestBody Student student);
}
6、实现伪装接口
package com.qfedu.service;
import com.qfedu.entity.Student;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* @author xue_yun_xiang
* @create 2021-06-17-11:16
*/
@Service
public class FeignServiceImpl implements FeignService{
public String getMessage(String msg) {
return "feign容错-getMessage--" + msg;
}
public String say(String msg) {
return "feign容错-say--" + msg;
}
public Student updateStudent(Student student) {
student.setName("feign容错student");
return student;
}
}
7、调用
@RestController
public class FeignController {
@Autowired
private FeignService feignService;
@RequestMapping("/test1")// 目标是调用 @RequestMapping("/getMessage/{msg}")
public String test1(){
return feignService.getMessage("hello test1");
}
@RequestMapping("/test2")
public String test2(){
return feignService.say("hello test2");
}
/**
* 调用 服务提供者 springcloudalibaba-provider 中的 /updateStudent 并且传递json数据
* @return
*/
@RequestMapping("/test3")
public Student test3(){
Student student = new Student();
student.setId(1000);
student.setAge(18);
student.setName("xxx");
student.setSex("F");
return feignService.updateStudent(student);
}
}
7、启动 feign-customer 测试
feign: restTemplate + Ribbon + 容错
网络请求 + 负载均衡 + 容错
feign 负载均衡
启动两个服务提供者 ,一个 feign 消费者
测试:
feign容错
概念
消费者依赖服务提供者,如果服务提供者有异常,则消费者也会有异常,如果我们配置 feign 的容错,就算服务提供者挂了或者 有异常,消费者可以 激活容器接口,继续提供服务
实际开发工程中非常重要,可以保证你服务的高可用(类似于汽车上的备胎,短暂使用,大部分时候容错返回的数据都是死数据)
实现
1、在子模块中开启容错功能
#开启feign 容错功能
feign.hystrix.enabled=true
2、配置容错实现类,并加入到容器中
/**
* feign 容错实现类
*/
@Component // 加入到容器中
public class FeignServiceImpl implements FeignService {
@Override
public String getMessage(String msg) {
return "容错--getMessage--:"+msg;
}
@Override
public String say(String msg) {
return "容错--say--msg:"+msg;
}
@Override
public Student updateStudent(Student student) {
student.setName("容错 student");
return student;
}
}
3、配置feign 容错
// fallback = FeignServiceImpl.class 当服务提供者出现 异常 或者 无法提供服务时 调用
@FeignClient(value = "springcloudalibaba-provider",fallback = FeignServiceImpl.class) //告诉feign 去springcloudalibaba-provider 服务请求数据
public interface FeignService {
。。。。。
}
二、Nacos Config
概念
nacos 分布式配置中心
将同一服务的配置文件放置到nacos 中,每次应用启动时,会从nacso拉取最新的配置文件,初始化到应用中,并且如果配置中的的配文件值发生变化,应用也会立即感知到。
application.properties application.yaml
在springboot 还有配置文件bootstrap.properties bootstrap.yaml ,bootstrap.*开头的配置文件是最有限加载的,在容器启动之前加载
bootstrap.properties > bootstrap.yaml >application.properties > application.yaml
从左到右,优先级依次降低
实现
1、创建一个congfig子 工程
2、引入依赖
<dependencies>
<!--springBoot 相关 -->
<!--
spring web 必须引入
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring 监控相关依赖 可以查看当前 jvm 的内存占用 有哪些conteroller 有哪些bean -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- alibaba.cloud 相关-->
<!--
alibaba-nacos 服务注册 发现 jar
-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--
-alibaba-nacos 服务配置 jar
-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 引入公共 模块-->
<dependency>
<groupId>com.qfedu</groupId>
<artifactId>springcloudalibaba-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
3、创建配置文件bootstrap.properties
server.port=8094
#为当前应用起 一个名字 改名字也是一个服务名
spring.application.name=springcloudalibaba-config
#配置nacos 服务地址 作用包含了spring.cloud.nacos.discovery.server-addr
spring.cloud.nacos.server-addr=localhost:8848
#spring.cloud.nacos.discovery.server-addr=localhost:8848
#暴漏端点 将所有的的接口进行监控
management.endpoints.web.exposure.include=*
student.name=xiaoming
4、启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class,args);
}
}
5、获取配置文件数据
@RestController
public class ConfigController {
@Value("${student.name}") // 启动时候获取一次
private String studentName;
@Autowired // 获取配置文件中的内容 实时获取配置文件中的内容
private ConfigurableApplicationContext applicationContext;
@RequestMapping("/getStudentName")
public String getStudentName(){
return "student.name:"+studentName +"------ConfigurableApplicationContext--student.name:"+applicationContext.getEnvironment().getProperty("student.name");
}
}
6、在nacos服务中创建
7、启动config 应用 ,可以从nacos 配置中心获取配置文件
8、动态修改nacos 配置文件
config 应用接收到修改的数据
总结:
读取配置文件顺序:
先去bootstrap.properties/ bootstrap.yaml ,如果配置了nacos,并且nacos配置中心有对应的该服务的额配置文件也会去nacos配置中心拉取配置文件, 再去本地 application.properties/application.yaml
bootstrap.properties/ bootstrap.yaml ---->线上nacos 服务名.properties -----》本地 application.properties/application.yaml
bootstrap.properties是在应用启动之前读取,所以如果想读取nacos 中的内容,必须配置到bootstrap.properties、bootstrap.yaml
属性优先级
bootstrap.properties > bootstrap.yaml >application.properties > application.yaml
从左到右,优先级依次降低
如果配置了nacos 中的配置文件 则同一个属性 nacos 中的配置文件的属性会把bootstrap.properties 中的属性进行覆盖
nacos 配置文件多环境配置
实际开发过程中 需要 开发环境 测试环境
1、创建nacos 开发环境配置文件
2、.创建开发环境配置文件bootstrap-dev.properties
#当前文件该应用的开发环境 开发环境默认情况下不会被激活
server.port=8094
#为当前应用起 一个名字 改名字也是一个服务名 如果当前配置文件有-dev 字样 ,读取该服务配置文件时会自动加上dev
# 会自动去寻找springcloudalibaba-config-dev.properties
spring.application.name=springcloudalibaba-config
#配置nacos 服务地址 作用包含了spring.cloud.nacos.discovery.server-addr
spring.cloud.nacos.server-addr=localhost:8848
#spring.cloud.nacos.discovery.server-addr=localhost:8848
#暴漏端点 将所有的的接口进行监控
management.endpoints.web.exposure.include=*
student.name=xiaoming
3、激活开发环境
第一种方式:
bootstrap.properties
#激活当前应用 dev 环境 --》让该应用读取bootstrap-dev.properties配置文件
#激活 dev 方式 1
#spring.profiles.active=dev
第二种方式:
Sentinel
概念
springcloud中的Sentinel,是一个组件,作用监控各个应用中接口的流量,并且可以根据流量的大小完成
流量熔断(超过流量触发熔断),异常熔断(一定时间内超过一定数量的异常触发熔断),超时熔断(超过响应时长的比例触发熔断),容错(如果被调用的服务挂了,哨兵也有容错功能和feign容错类似)等功能
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
哨兵容错功能
1、在customer-feign 应用中引入哨兵依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、开启哨兵
#开启哨兵 容错功能
feign.sentinel.enabled=true
3、给对应的方法配置哨兵
/**
* 调用 服务提供者 springcloudalibaba-provider 中的 /updateStudent 并且传递json数据
* @return
*/
// 配置哨兵
@SentinelResource(value = "test3",fallback = "fallbackTest3")
@RequestMapping("/test3")
public Student test3(){
Student student = new Student();
student.setId(1000);
student.setAge(18);
student.setName("xxx");
student.setSex("F");
return feignService.updateStudent(student);
}
/**
* 在 test3调用的方法 出现错误 调用 该容错犯法
* @return
*/
public Student fallbackTest3(){
Student student = new Student();
student.setId(1000);
student.setAge(18);
student.setName("哨兵触发容错");
student.setSex("F");
return student;
}
4、测试
在服务提供者 有异常 或者 挂了 都会触发容错
注意在测试时关闭feign 的容错功能
#开启feign 容错功能
feign.hystrix.enabled=false
// fallback = FeignServiceImpl.class 当服务提供者出现 异常 或者 无法提供服务时 调用
@FeignClient(value = "springcloudalibaba-provider") //告诉feign 去springcloudalibaba-provider 服务请求数据
public interface FeignService {
。。。。
}
流量监控功能
1、安装哨兵控制台
2、启动
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
3、访问http://localhost:8080
4、登录哨兵管理界面
5、将customer-feign应用的哨兵监控信息提交到管理平台
#开启哨兵 容错功能
feign.sentinel.enabled=true
#配置哨兵地址 将哨兵监控的信息发送给哨兵监控平台
spring.cloud.sentinel.transport.dashboard=localhost:8080
6、重新启动引用
流控规则 &降级规则
流控规则 &降级规则 都是配置降级策略,一旦达到一定的条件就会熔断(触发降级策略)
流控规则
QPS:线程数
降级规则
配置自定义降级策略
/**
* 调用 服务提供者 springcloudalibaba-provider 中的 /updateStudent 并且传递json数据
*fallback = "fallbackTest3" 服务提供者 异常 挂了
* ,blockHandler = "blockHandlerTest3" 配置熔断降级策略 (限流 降级)
*
* @return
*/
// 配置哨兵
@SentinelResource(value = "test3",fallback = "fallbackTest3",blockHandler = "blockHandlerTest3")
@RequestMapping("/test3")
public Student test3(){
Student student = new Student();
student.setId(1000);
student.setAge(18);
student.setName("xxx");
student.setSex("F");
return feignService.updateStudent(student)以上是关于springcloud的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端Eureka 服务信息Eureka 发现管理Eureka 安全配置Eureka-HA(高可用) 机制Eur(代码片段
SpringCloud+Feign环境下文件上传与form-data同时存在的解决办法
SpringCloud环境搭建服务提供者 我们需要拿到实体类,所以要配置api module, 在这时报错