其他分享
首页 > 其他分享> > SpringCloud & Cloud Alibaba学习笔记

SpringCloud & Cloud Alibaba学习笔记

作者:互联网

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、服务端

 

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

 

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

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

 

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

 

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注解

 

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

解决:

 

 

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