ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringCloud & Cloud Alibaba学习笔记

2022-07-23 14:33:01  阅读:156  来源: 互联网

标签:spring 配置 springframework Alibaba Cloud SpringCloud org cloud 客户端


SpringCloud Alibaba学习笔记

工程依赖:

 <properties>
         <springboot.version>2.2.2.RELEASE</springboot.version>
         <springcloud.version>Hoxton.SR1</springcloud.version>
         <springcloud.alibaba.version>2.1.0.RELEASE</springcloud.alibaba.version>
         <lombok.version>1.18.12</lombok.version>
         <mybatis.version>1.3.2</mybatis.version>
         <mysql.version>8.0.21</mysql.version>
         <druid.version>1.1.10</druid.version>
         <slf4j.version>1.7.25</slf4j.version>
         <logback.version>1.2.3</logback.version>
     </properties>
 ​
     <dependencyManagement>
         <dependencies>
 ​
             <!--springboot-->
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-dependencies</artifactId>
                 <version>${springboot.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
 ​
             <!--springcloud-->
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-dependencies</artifactId>
                 <version>${springcloud.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
 ​
             <!--springcloud alibaba-->
             <dependency>
                 <groupId>com.alibaba.cloud</groupId>
                 <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                 <version>${springcloud.alibaba.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
 ​
             <!--lombok-->
             <dependency>
                 <groupId>org.projectlombok</groupId>
                 <artifactId>lombok</artifactId>
                 <version>${lombok.version}</version>
             </dependency>
 ​
             <!--mybatis-->
             <dependency>
                 <groupId>org.mybatis.spring.boot</groupId>
                 <artifactId>mybatis-spring-boot-starter</artifactId>
                 <version>${mybatis.version}</version>
             </dependency>
 ​
             <!--mysql-->
             <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <version>${mysql.version}</version>
             </dependency>
 ​
             <!--druid-->
             <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>druid-spring-boot-starter</artifactId>
                 <version>${druid.version}</version>
             </dependency>
 ​
             <!--slf4j-->
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-api</artifactId>
                 <version>${slf4j.version}</version>
             </dependency>
 ​
             <!--logback-->
             <dependency>
                 <groupId>ch.qos.logback</groupId>
                 <artifactId>logback-core</artifactId>
                 <version>${logback.version}</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

 

 

1、SpringCloud整合Zookeeper,代替Eureka

1、Linux上安装Zookeeper

 

2、导入jar包

 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
 </dependency>

 

3、主启动类上加上@EnableDiscoveryClient注解

 

2、OpenFeign

作用:主要用来做服务之间的调用

web客户端的接口绑定服务端的接口

 

OpenFeign在Feign的基础上支持SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方法产生实现类,实现类中做负载均衡并调用其它服务。

 

1、OpenFeign的基本使用

1、依赖

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>

 

2、主启动类上加上@EnableFeignClients注解

 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 import org.springframework.cloud.openfeign.EnableFeignClients;
 ​
 @SpringBootApplication
 @EnableEurekaClient
 @EnableFeignClients
 public class OpenFeignConsumerOrderApplication80 {
     public static void main(String[] args) {
         SpringApplication.run(OpenFeignConsumerOrderApplication80.class,args);
    }
 }
 ​

 

3、消费端接口上加上@FeignClient(name = "服务名")与服务端接口进行绑定

  1. 服务端接口

     @RestController
     @RequestMapping("/payment")
     public class PaymentController {
     ​
         @Autowired
         private PaymentService paymentService;
     ​
         @PostMapping
         public CommonResult add(@RequestBody Payment payment){
             int result = paymentService.insert(payment);
     ​
             if (result > 0){
                 return new CommonResult(200,"订单保存成功!,serverPort:" + serverPort,result);
            } else {
                 return new CommonResult(444,"订单保存失败!,serverPort:" + serverPort);
            }
        }
     ​
         @GetMapping
         public CommonResult list(){
             List<Payment> paymentList = paymentService.getPaymentList();
     ​
             if (!paymentList.isEmpty()){
                 return new CommonResult(200,"查询成功!,serverPort:" + serverPort,paymentList);
            } else {
                 return new CommonResult(443,"无数据!,serverPort:" + serverPort);
            }
        }
     ​
         @GetMapping("/{id}")
         public CommonResult get(@PathVariable("id") Long id){
             Payment payment = paymentService.getPaymentById(id);
     ​
             if (payment != null){
                 return new CommonResult(200,"查询成功!,serverPort:" + serverPort,payment);
            } else {
                 return new CommonResult(443,"无数据!,serverPort:" + serverPort);
            }
        }
     }
  2. 消费端接口

     @FeignClient(name = "服务名")
     @RequestMapping("/payment")
     public interface PaymentService {
     ​
         @PostMapping
         CommonResult add(@RequestBody Payment payment);
     ​
         @GetMapping
         CommonResult list();
     ​
         @GetMapping("/{id}")
         CommonResult get(@PathVariable("id") Long id);
     }

     

2、OpenFeign客户端设置超时时间

OpenFeign客户端默认的超时时间为1s,超过1秒会报错

我们可以通过配置设置我们客户端的超时时间

1、application.yml配置

 # 设置feign客户端的超时时间(OpenFeign默认支持Ribbon)
 ribbon:
   # 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
   # 指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

 

3、OpenFeign日志增强

1、日志级别

 NONE:默认的,不显示任何日志
 ​
 BASIC:仅记录请求方法、URL、响应状态码及执行时间
 ​
 HEADERS:除了BASIC中定义的信息除外,还有请求和响应的头信息
 ​
 FULL:除了HEADERS定义的信息除外,还有请求和响应的正文及元数据

 

2、配置类

 @Configuration
 public class FeignConfig {
 ​
     @Bean
     Logger.Level feignLoggerLevel(){
         return Logger.Level.FULL;
    }
 }

 

3、application.yml配置

 logging:
  level:
     # feign日志以哪个级别监控哪个接口
    com.study.springcloud.controller.FeignPaymentService: debug

 

 

3、Hystrix

导入jar包

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

 

1、服务降级

1、服务端

  • 主启动类上加@EnableCircuitBreaker注解

  • 接口上加上@HystrixCommand(fallbackMethod = "要降级调用的接口名")

 

2、客户端第一种解决办法

  • 主启动类上加@EnableHystrix

  • application.yml配置

     # 开启hystrix
     feign:
      hystrix:
        enabled: true
  • 接口上加上@HystrixCommand(fallbackMethod = "要降级调用的方法名")

 

问题:每一个接口都要配置一个对应的服务降级的方法,代码冗余,业务逻辑也混在一块。

解决:在类上加==@DefaultProperties(defaultFallback = "要降级调用的方法名")==,接口上只要加上==@HystrixCommand==即可

 

3、客户端第二种解决办法

  • Feign接口再创建一个进行服务降级的实现类与之对应,然后通过@FeignClient(name = "服务名",fallback= 降级实现类.class)fallback 属性进行指定

 

2、服务熔断

 @HystrixCommand(fallbackMethod = "f",commandProperties = {
         @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), // 是否开启断路器
         @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), // 请求次数
         @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
         @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") // 失败率达到多少后跳闸
 })

 

3、服务限流

 

 

4、Gateway服务网关

1、Gateway三大核心理念

  1. 路由(Route)

  2. 断言(predicate)

  3. 过滤(Filter)

 

2、环境搭建

  1. 导入jar包

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
     </dependency>

    注意:以下jar包无需导入,如果有要去掉,否则报错

     <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>
  2. application.yml配置

     spring:
      application:
        name: springcloud-gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
          routes:
            - id: payment_route # 路由的id,没有固定的规则,但要求唯一,建议配合服务名
               # uri: http://localhost:8001 # 匹配后提供服务的路由地址
              uri: lb://SPRINGCLOUD-PAYMENT-SERVER # 匹配后提供服务的路由地址
              predicates:
                - Path=/payment/** # 断言,路径相匹配则进行路由

 

也可以在代码里面配置,示例:

 @Configuration
 public class GatewayConfig {
 ​
     @Bean
     public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
         RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
 ​
         routes.route("path_route",
                 r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
 ​
         return routes.build();
    }
 }

 

3、配置自定义全局过滤器

 @Component
 @Slf4j
 public class MyGatewayFilter implements GlobalFilter, Ordered {
 ​
     /**
      * 判断是否带用户名,没有则过滤
      * @param exchange
      * @param chain
      * @return
      */
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         log.info("***********com in MyGatewayFilter:" + new Date());
         String name = exchange.getRequest().getQueryParams().getFirst("username");
         if (name == null){
             log.info("用户名为空,非法用户!");
             exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
             return exchange.getResponse().setComplete();
        }
         return chain.filter(exchange);
    }
 ​
     @Override
     public int getOrder() {
         return 0;
    }
 }

 

5、Config配置中心

Config也分为服务端与客户端,服务端也是单独的一个服务。

 

1、服务端配置

  1. 导入jar包

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
     </dependency>
  2. application.yml配置

     spring:
      cloud:
        config:
          server:
            git:
              uri: https://..... # 远程仓库地址
               # 搜索目录
              search-paths:
                - springcloud-config
               # 读取分支
              label: master
  3. 主启动类上添加@EnableConfigServer注解

 

2、客户端配置

  1. 导入jar包

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
     </dependency>
  2. bootstrap.yml配置文件

     spring:
      cloud:
         # 配置中心客户端
        config:
          label: master # 分支名
          name: springcloud-config-client # 配置文件名称
          profile: dev # 读取后缀名称
          uri: http://localhost:3344 # 配置中心地址
  3. 主启动类上添加@EnableEurekaClient注解

 

问题:当远程仓库配置文件内容改动后,客户端读取不到最新配置。

解决:

  • 第一步:bootstrap.yml配置文件添加如下配置:

    # 暴露监控端点
    management:
    endpoints:
    web:
    exposure:
    include: "*"
  • 第二步:在我们的Controller类上加上@RefreshScope注解

  • 第三步:也是最关键的一步,需要手动向客户端发送一个指定的POST请求http://主机:端口号/actuator/refresh进行手动刷新

 

 

6、Bus消息总线

Config客户端虽然解决了动态刷新配置,但需要手动刷新,如果有多台服务就要刷新多台。如果我们只想刷新一次,全局广播怎么办呢?

 

什么是消息总线?

在微服务架构系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有的微服务实例都连接上来。由于该主题中产生的消息会被所有的实例监听和消费,所以称他为消息总线。在总线的各个实例,都可以广播一些需要让其它连接在该主题上的实例都知道的消息。

 

基本原理:

所有ConfigClient实例都监听MQ中的同一个topic(默认是springCloudBus)。但一个服务刷新数据的时候,他会把这个信息放入Topic中,这样其它监听同一个Topic的服务就能得到通知,然后去更新自身的配置。

 

==环境:需要消息中间件,这里使用的是RabbitMQ==

1、Config配置中心服务端配置

1、导入jar包

<!--RabbitMQ bus-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

<!--Config-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

 

2、application.yml配置


spring:
cloud:
config:
server:
git:
uri: https://... # 远程仓库地址
# 搜索目录
search-paths:
- springcloud-config
# 读取分支
label: master

# RabbitMQ相关配置
rabbitmq:
host: localhost
port: 15672
username: guest
password: guest

# rabbitmq相关配置,暴露bus,刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'

 

3、主配置类上添加@EnableConfigServer注解

 

2、Config配置中心客户端配置

1、导入jar包

<!--RabbitMQ bus-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

<!--Config client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

 

2、bootstrap.yml配置

spring:
application:
name: springcloud-config-client
cloud:
# 配置中心客户端
config:
label: master # 分支名
name: cloudalibaba-config-client # 配置文件名称
profile: dev # 读取后缀名称
uri: http://localhost:3344 # 配置中心地址

# RabbitMQ相关配置
rabbitmq:
host: localhost
port: 15672
username: guest
password: guest

# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"

 

3、Controller类上加上@RefreshScope注解

 

3、配置刷新

1、全局通知刷新

向Config配置中心服务端发送指定POST请求:http://服务端ip:端口/actuator/bus-refresh

 

2、指定服务刷新

向Config配置中心服务端发送指定POST请求:http://服务端ip:端口/actuator/bus-refresh/{客户端服务名:端口号}

 

7、SpringCloud Stream

 

 

 

 

3、重复消费问题:

在Stream中处于同一group中的多个消费者是竞争关系,就能够保证消息只会被其中一个应用消费一次。

不同组是可以重复消费的

同一组内会发生竞争关系,只有其中一个可以消费

 

 

4、消费持久化:

 

 

8、Nacos

什么是Nacos?

Nacos是一个服务注册中心和配置中心,相当于等于SpringCloud的 Eureka + Config + Bus

 

 

 

 

 

9、Seata

TC - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:spring,配置,springframework,Alibaba,Cloud,SpringCloud,org,cloud,客户端
来源: https://www.cnblogs.com/zhouqiangshuo/p/16511963.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有