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);


/**
 * 在 test3调用的方法 出现错误 调用 该容错犯法
 * @return

以上是关于springcloud的主要内容,如果未能解决你的问题,请参考以下文章

第13周学习进度条

第13周学习进度条

SpringCloud面试题

SpringCloud Sleuth 分布式请求链路跟踪

SpringCloud Hoxton——Sleuth服务链路监控

SpringCloud Hoxton——Sleuth服务链路监控