SpringCloud


前言

本文是通过观看b站尚硅谷的BV18E411x7eT视频而产生的一些笔记和总结。

对应代码的gitee仓库


父工程

父pom:涉及maven知识点:

  • 必须设置packaging为pom。
  • 用来做和springboot-dependence里类似的版本规定,只规定不导入,子工程需要声明但是不用设置version。跟springboot里的starter差不多。
  • 子模块还会继承maven的groupid和version,创建子模块的时候自动填装。
<packaging>pom</packaging>

<dependencyManagement>
	<dependencies>
dependencyManagement下的dependence只规定版本,并不会真的导入,
可以看idea中或者maven的外部库,不会有包引入。

支付模块

生产者

创建子模块后,父pom里会生成modules。子工程也有artifactId指向父工程。
接下来就是编码存在一些情况:

  • 设置这两个属性useGeneratedKeys=“true” keyProperty="id"可以让插入完毕返回主键自增的id。
  • 返回类型为实体类推荐写resultMap。

消费者模块

使用spring自带的restTemplate连接支付模块。

@Configuration
public class ApplicationContextConfig {
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

配置这个只是为了实现spring 的ioc思想,能够使用autowire注入,之后也能开启负载均衡。

restTemplate.postForObject(PAYMENT_URL + "/payment/create",payment,CommonResult.class);
restTemplate.getForObject(PAYMENT_URL + "/payment/get/"+id,CommonResult.class);

由于消费者模块也需要payment等相同实体类,所以要进行工程重构。

工程重构

建立一个common模块,复制公共实体类等包,使用maven进行install打成jar包。
然后删除消费者生厂者中的公共实体类包,再pom中引入common模块。

Eureka注册中心

生产者多了,不知道调哪个跟好,所以需要注册中心。

Eureka Server

创建server模块作为注册中心。

Eureka Client

生产者消费者入住Eureka Server。

Eureka集群

相互守望,a指向b,b指向a。

多生产者

构建多生产者,只需要修改tomcat端口即可。

消费者负载均衡

在消费者的RestTemplate上添加@LoadBalanced开启负载均衡,并将url由ip+端口 改为http://生产者服务名字 即可。

Eureka页面优化

配置eureka.instance.instance-id为服务的status展示名称。
再加上eureka.instance.prefer-ip-address: true可以显示ip。

服务发现

生产者提供一个对外的rest接口,返回用DiscoveryClient得到的服务信息。
启动类还需要加@EnableDiscoveryClient。

Eureka自我保护

一个微服务不能用了,Eureka不会立即清理。

禁止自我保护:

注册中心配置
eureka:
	server:
    	enable-self-preservation: false
    	eviction-interval-timer-in-ms: 2000

服务端配置
eureka:
	instance:
		#发送心跳间隔
		lease-renewal-interval-in-seconds: 1
    	lease-expiration-duration-in-seconds: 2

CAP:强一致性、高可用性、分区容错。

Ribbon

消费者的进程内的本地负载均衡工具。
负载均衡+RestTemplate。
eureka的starter已经引入了ribbon的starter。

RestTemplate
restTemplate.getForObject/postForObject 返回json。
getForEntity/postForEntity 返回ResponseEntity对象,包含状态码等。

更改负载均衡规则

官方提供了一些规则,IRule的实现类,
需要在启动类包上一级建立一个配置类,配置IRule。

@Configuration
public class MySelfRule {
    @Bean
    public IRule myRule(){
        return new RandomRule();
    }
}
并在启动类加上
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
表明对于哪个服务采用什么配置策略,还一个RibbonClients注解应该是配置多个服务对应策略。

负载均衡原理

轮询:请求次数 对于 选取的服务的数量 取余,作为服务器列表的下标。

可以通过查看源码中对于IRule的方法的实现得到。

手写轮询算法

public interface LoadBalancer {
    ServiceInstance instances(List<ServiceInstance> serviceInstances);
}

@Component
public class MyLb implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement(){
        int current;
        int next;
        do{
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current+1;
        }while (!this.atomicInteger.compareAndSet(current,next));

        System.out.println("***次数 next: " + next);
        return next;
    }

    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size();

        return serviceInstances.get(index);
    }
}

    @GetMapping("/consumer/payment/lb")
    public String getPaymentLb(){
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if (instances==null||instances.size()<=0){
            return null;
        }
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        URI uri = serviceInstance.getUri();

        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }

OpenFeign

简化ribbon的restTemplate操作,实际还是ribbon。feign配好了负载均衡配置类。

Ribbon是在Controller层操作,而feign集成到service层,更符合操作习惯。

@Component
@FeignClient("CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {

    @GetMapping("/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

OpenFeign超时控制

openfeign默认1秒钟没得到返回就报错。

设置时间
ribbon:
  ReadTimeout: 5000
  ConnectTimeout: 5000

OpenFeign日志增强

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}
logging:
  level:
    com.atguigu.springcloud.service.PaymentFeignService: debug

Hystrix断路器

在多个微服务连锁调用过程中,中间某个微服务出现问题,会影响到整个系统的高可用性。

当一个接口被高并发,tomcat的线程池不够用,另一个接口也会受影响。

服务降级

返回一个友好提示的响应。

程序异常,超时,服务熔断,线程池满都会导致降级。

生产者,消费者都应该有降级策略,提供备用响应。

生产者:

@HystrixCommand(fallbackMethod = "paymentInfo_TimeoutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    })
    public String paymentInfo_Timeout(Integer id){

        int t = 5;
        try {
            TimeUnit.SECONDS.sleep(t);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "  paymentInfo_Timeout , id: "
                + id + "\t" + "耗时:" + t;
    }

    public String paymentInfo_TimeoutHandler(Integer id){
        return "线程池:" + Thread.currentThread().getName() + "  8001系统繁忙,稍后再试 , id: "
                + id + "\t" + "ε(┬┬﹏┬┬)3";
    }

消费者

@GetMapping("/consumer/payment/hystrix/Timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id") Integer id){
        String result = paymentHstrixService.paymentInfo_Timeout(id);
        return result;
    }


    public String paymentInfo_TimeoutHandler(Integer id){
        return "消费者的服务降级: ε(┬┬﹏┬┬)3";
    }

可以配置统一处理结果。
@DefaultProperties写在类上。

避免service和controller混乱。
可以定义一个类实现openfeign的调用service接口,实现方法的返回值即为降级的响应。十分方便。

@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)

@Component
public class PaymentFallbackService implements PaymentHstrixService {
    @Override
    public String paymentInfo_Ok(Integer id) {
        return "---PaymentFallbackService  ok";
    }

    @Override
    public String paymentInfo_Timeout(Integer id) {
        return "---PaymentFallbackService  timeout";
    }
}

服务熔断

先降级,熔断,再恢复调用链路。

熔断了就算是对的,也会触发降级。

服务限流

仪表盘

用来监控经过hystrix的请求。

Gateway服务网关

路由转发,执行过滤链,底层netty,异步非阻塞。

  • Predicate断言
  • Route路由
  • Filter过滤

路由

url条件跟断言匹配则可以走网关。

不能引入web依赖,因为它用的netty,会冲突。

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh
          uri: http://localhost:8001
          predicates:
            - Path=/payment/get/**

        - id: payment_routh2
          uri: http://localhost:8001
          predicates:
            - Path=/payment/lb/**

动态路由

网关侧的负载均衡,不指定地址,而是通过服务名。

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh
          #uri: http://localhost:8001
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/get/**

        - id: payment_routh2
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/lb/**
      discovery:
        locator:
          enabled: true

过滤器

前置,后置,全局,单一。

可以通过过滤器修改url地址

predicates:
   - Path=/api/thirdparty/**
filters:
   - RewritePath=/api/(?<segment>.*),/$\{segment}

自定义全局过滤器

@Slf4j
@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("======come in MyLogGateWayFilter: "+ LocalTime.now());
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null){
            log.info("=====用户名为空,非法");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //表示顺序
        return 0;
    }
}

Config配置中心

统一配置的外部配置中心。

Bus消息总线

对于config的动态刷新的加强,广播,差异化管理。

Stream消息驱动

屏蔽MQ的差异,提供统一操作,类似mvc中返回一个前后端都识别的result类。

binder对象作为中间层。input消费 output生产。

生产者:source推送管道 channel发送管道。
消费者:sink

消息分组,相同组轮询消费,避免重复消费。

Sleuth请求链路跟踪

对服务调用进行监控。

Cloud Alibaba

Nacos

注册中心 + 配置中心

nacos官方文档

注册中心

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

nacos集成了ribbon支持负载均衡.

nacos支持cp ap切换。

配置中心

新建的配置,data id需要按照官方的规则。

nacos就会按照这个规则自动查找配置。

nacos修改配置后,动态刷新立马更新,无需其他配置。

分组配置

namespace+group+dataId

dataid匹配spring的profiles.active环境。

group和namespace匹配nacos的设置。

Nacos集群和持久化

nacos自带derby数据库,持久化只支持mysql。
nacos自带sql脚本。

nacos持久化mysql8.0

docker nginx配置

Sentinel熔断与限流

跟nacos一样,已经写好打成jar包,直接启动就可以,对Hystrix的取代。

需要被监控的服务先随便调用一个请求。

流控规则

QPS每秒请求数。

达到QPS进行限流。

qps是外部,线程是内部。

关联,a->b,b顶不住了,a就少放点请求。

预热,设定多少秒后才把阈值由初始升至最高,秒杀系统。

排队等待,进了之后排队处理。匀速处理请求。

降级规则

RT:秒级平均响应时间,1秒超过5个请求并且平均处理时间大于阈值才触发。

异常比例:1秒超过5个请求并且异常比例超过阈值。

异常数

热点规则

针对热点参数进行判断,

@GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false)String p1,
                             @RequestParam(value = "p2",required = false)String p2){
        return "------testHotKey";
    }

    public String deal_testHotKey(String p1, String p2, BlockException exception){
        return "-----deal_testHotKey";
    }

sentinel熔断没有半开状态。

系统规则

对整个系统限流。

@SentinelResuorce

官网描述

fallback只处理java异常,blockHandler只处理配置异常。

Sentinel持久化

官方文档

例子 from 暴裂无球

Seata处理分布式事务

seata官方文档

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

分布式事务处理:

  • 全局唯一事务id

  • TC (Transaction Coordinator) - 事务协调者
    维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器
    定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器
    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。


总结

进入cloud开发后,大多都是配置+注解,建议少花点时间了解怎么用。

Spring Cloud是一个用于构建分布式系统的开发工具集合。它提供了一些常用的组件和框架,包括服务注册和发现、负载均衡、断路器、分布式配置等等。在使用Spring Cloud时,有一些常见的错误和注意事项需要注意。 首先,关于Spring Boot和Spring Cloud版本对应错误。在使用Spring Cloud时,需要确保Spring Boot和Spring Cloud的版本兼容。不同版本之间可能存在依赖冲突或不兼容的情况,因此需要根据官方文档或者相关文档来选择合适的版本。 另外,Spring Cloud Config是一个用于集中管理和动态获取配置的工具。它支持从Git、SVN或本地文件系统中获取配置文件,并提供了服务器和客户端支持。你可以通过官方使用说明文档了解更多关于Spring Cloud Config的详细信息。 此外,关于选择使用Nacos还是Eureka作为服务注册和发现组件的问题。Nacos是一个功能更强大的服务注册和发现组件,它整合了Spring Cloud Eureka、Spring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的中心动态刷新,而不需要为配置中心新增集群或使用消息队列。另一方面,Eureka是Spring Cloud原生全家桶的一部分,相对来说更加稳定一些。选择使用哪个组件需要根据具体的需求和项目特点来决定。 综上所述,Spring Cloud是一个用于构建分布式系统的开发工具集合,它提供了一些常用的组件和框架。在使用Spring Cloud时,需要注意Spring Boot和Spring Cloud版本的兼容性,并可以使用Spring Cloud Config来动态获取配置。同时,可以选择使用Nacos或Eureka作为服务注册和发现组件,具体选择需要根据项目需求来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值