微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

M12. SpringCloud

█ 1.名词

RPC是远程过程调用(Remote Procedure Call)的缩写形式。

SpringCloud 负载均衡 性能  高并发
避免任何单一资源的过载

○ 1.1 Maven

通过 dependencyManagement 来管理以来版本号,,出现在 最顶层的 父POM中

只声明,不引入
子项目要用,就 自己再声明,,否则 不会继承父的

maven 有clean install 这些来生成jar

○ 1.2 热部署 devtools Run Dashboard

○ 1.3 RestTemplate:

便捷访问 远程http 服务 的模板方法

参数:

@LoadBalanced 让 RestTemplate 负载均衡

restTemplate.postForObject《json》 || postForEntity《响应头、响应状态码、响应体》
restTemplate.getForObject || getForEntity

█ 2.注解汇总:

@Data
@AllArgsConstructor
@NoArgsConstructor
@LoadBalanced 让 RestTemplate 负载均衡
@EnablediscoveryClient 服务发现

@SpringBootApplication
@EnableEurekaServer
@EnableEurekaClient
@EnablediscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务

@Resource
@Value("${server.port}")
@PostMapping(value = "/payment/create") (@RequestBody Payment payment)
@GetMapping(value = "/payment/get/{id}") (@PathVariable("id") Long id)
@GetMapping(value = "/payment/discovery")


@Component
@RestController
@Slf4j
@Mapper
@Service
@Configuration


@SpringBootConfiguration
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration=MySelfRule.class)
@LoadBalanced


@SpringBootApplication
@EnableFeignClients 主启动

@FeignClient 微服务调用接口处
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")


@SpringBootApplication @EnableFeignClients @EnableHystrix
@SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")

@HystrixCommand

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})


@SpringBootApplication
@EnableHystrixDashboard


@SpringBootApplication
@Enableconfigserver

@SpringBootApplication
@EnableEurekaClient

@RestController
@RefreshScope


@EnableBinding(Source.class)
@Component
@EnableBinding(Sink.class)
{函数上@StreamListener(Sink.INPUT)}


█ 3.服务发现discovery

拿到server上的注册信息

List<String> services = discoveryClient.getServices();
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");

█ 10.(×)Hystrix --- 服务降级 (短路器)

在生产/消费侧 都可

@SpringBootApplication @EnableFeignClients @EnableHystrix
@SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")

@HystrixCommand


@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
    @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
    })


而且 只有 Feign的时候是不用给service 写implement的。

Hystrix 处理 分布式 系统的 延迟和容错, 超时 异常, 避免级联故障。不会让他 长时间等待,出现故障 该 服务降级 // 服务熔断 /// 服务限流。

○ 10.1 名词:

扇出: 微服务a调用bc, bc又调用其他的

服务雪崩:扇出 链路中有一个崩了,都崩了。 级联故障。 单一后端依赖。

服务降级fallback 1. 程序运行异常 2.超时 3.服务熔断 触发 服务降级 4. 线程池/信号量 打满也会导致 服务降级

服务熔断break 微服务出错 || 响应时间过长,就会进行 降级,进而熔断,达到最大服务访问,直接拒绝访问 《降级--> 熔断 --> 恢复调用链路》

服务限流flowlimit 高并发,避免过度 拥挤


运行 超时 宕机


高并发测试 Jmeter

feign:
  hystrix:
    enabled: true

○ 10.2 服务熔断

服务熔断break 微服务出错 || 响应时间过长,就会进行 降级,进而熔断,达到最大服务访问,直接拒绝访问 《降级--> 熔断 --> 恢复调用链路》

参数:


payment 生产者 : service的impl里定义了 @Hystrix  和对应的fallbackMethod
order 消费者:controller里面定义了 @Hystrix  和他自己对应的 fallbackMethod
生产/消费 都可
service serviceimpl controller 主启动类
payment class @Service null @RestController @Slf4j @SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker
---- ---- ---- ---- ----
order interface @Component @FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackService.class) @Component 同上+ @DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") @SpringBootApplication @EnableFeignClients @EnableHystrix

○ 10.3 Hystrix Dashboard 准实时 调用监控 (黑白熊)

@SpringBootApplication
@EnableHystrixDashboard

把这个包启动起来,再启动上provider和eureka,还需要在provider的主启动上 加@Bean getServlet()《reason认路径不对》


需要有:
actuator监控信息完善 + web图形化界面


█ 11.Gateway 服务网关

@SpringBootApplication
@EnableEurekaClient
@Component
@Slf4j

网关也要注册进Eureka
Feign Hystrix 都要


gateway 是 非阻塞API

三大核心概念 : Route(路由) || Predicate(断言 --- 匹配条件) || Filter(过滤 ---- 拦截器) 《 2 + 目标uri = 1路由》


zuul跳票,so

动态路由:可以 反向代理 || 鉴权 || 流量控制 || 熔断 || 日志监控。 安全,监控/指标 限流。


○ 11.1 断言 predicate:

Gateway predicate是一种匹配规则 配置有:


○ 11.2 过滤 filter:

implements GlobalFilter, Ordered 重写 filter和getorder()。



@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        log.info("***********come in MyLogGateWayFilter:  "+new Date());

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if(uname == null)
        {
            log.info("*******用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

    @Override
    public int getorder(){ return 0; }
}

○ 11.3 路由 route:

predicate + filter + uri = route

网关路由的配置方式:

  1. 在yml中配置
  2. 代码中注入RouteLocator的Bean
@Configuration
public class GateWayConfig
{
    @Bean
    public RouteLocator customrouteLocator(RouteLocatorBuilder routeLocatorBuilder)
    {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

        routes.route("path_route_atguigu",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();

        return routes.build();
    }
}

█ 4.(×)Eureka --- 服务注册 (黑绿条界面)

@SpringBootApplication
@EnableEurekaServer
@EnablediscoveryClient
@EnableEurekaClient

netflix 的 eureka 实现服务治理,


两个组件:

Eureka server端 是 服务注册中心,
Eureka client 把自己的地址 注册到server,server监控他的心跳状态 认30s一回,90s没有就移除,就是不能用了 也不会立即清理,。

他是CAP《强一致性||可用性——性能||分区容错》 里面的AP


集群是 yml文件中 service-url defaultZone 互相指向,,client就是填上两个

○ 4.1 LoadBalance 负载均衡

避免任何单一资源的过载

@LoadBalanced 让 RestTemplate 负载均衡,里面还有高并发的 CAS思想 + 自旋锁。

    //负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标  ,每次服务重启动后rest接口计数从1开始。
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances)
    {
        int index = getAndIncrement() % serviceInstances.size();

        return serviceInstances.get(index);
    }

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


CAS

CAS = unsafe+自旋
比较并交换Compare-And-Swap
cpu并发原语。是硬件的,就是原子性的。

自旋锁和unsafe类

1) unsafe

rt.jar 里 sun.misc.unsafe

CAS保证线程安全 靠的是 unsafe类,没有加锁。


2) 自旋

unsafe类里都是native方法,unsafe可以直接操作 特定内存数据
unsafe unsafe.getAndAddInt() 传一个内存偏移地址,里面有个do-while,根据jmm内存模型 直到工作内存跟主内存的值一样,才退出循环,,,自旋。
do-while循环里面的 compareAndSwapInt,就是cpu并发原语,保证原子性。有Atomic

value用volatile修保证可见性**。

█ 5.Ribbon --- 服务调用 eureka中自带了 ribbon。

@SpringBootConfiguration
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration=MySelfRule.class)


警告:自定义配置类 不能放在@ComponentScan所扫描的包以及子包下,@ComponentScan(excludeFilters(@Filter(name="",))《@SpringBootConfiguration里面有》,所以就新建一个包,让MySelfRule在这个新包里。

避免任何单一资源的过载


### Ribbon 是本地负载均衡 && 进程内LB《集成到消费方》

Nginx 是服务器负载均衡

负载均衡分为: 集中式LB《消费&&提供方之间》 和 进程内LB《集成到消费方》

具体的方法有: IRule是爸爸


之前的Eureka中也是有LoadBalance 同样也放在了 RestTemplate 消费端。


如果要更换 负载均衡的方式,基于IRule 重写一下,

@Configuration
public class MySelfRule
{
    @Bean
    public IRule myRule()
    {
        return new Randomrule();//定义为随机
    }
}

█ 6.zookeeper --- 服务注册

@SpringBootApplication
@EnablediscoveryClient

他是CAP《强一致性||可用性——性能||分区容错》 里面的CP

zookeeper的节点分为 临时节点(带序号的临时节点)和持久节点(带序号的**)

zookeeper的服务节点 是 临时节点。

./zkServer.sh start
./zkCli.sh  --> 之后 ls /service/流水号 用 get 日志名 

其中老师讲到, dependency ---> exclusions 排除版本jar包

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }

█ 7.Consul --- 服务注册 (红色 8500)

@SpringBootApplication
@EnablediscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务

他是CAP《强一致性||可用性||分区容错》 里面的CP

服务发现: HTTP 和 DNS 两种发现方式。

KV存储

可视化web界面

健康检测: 支持 HTTP TCP Docker Shell

█ 8.区别 联系 相比 zookeeper 和 eureka 和 consul 服务注册

CAP《强一致性||可用性——性能||分区容错》



█ 9.OpenFeign --- 服务调用 并发LB(负)

服务接口调用

@SpringBootApplication
@EnableFeignClients 主启动 

@FeignClient 微服务调用接口处
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")

openFeign集成了 Ribbon + RestTemplate,只要创建 接口 并使用 注解就行。 超时设置 + 打印日志。


openFeign这个是 不需要RestTemplate,以前有ribbon 用 RestTemplate时需要config就不用service,直接通过函数 getForObject || getForEntity 拿到生产者的东西。
openFeign 要service ,当然可以写配置类 比如打印日志。

    @Resource
    private PaymentFeignService paymentFeignService;

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")

但是 在payment生产者里面 只有imp有@Service,,
@Configuration
public class FeignConfig
{
    @Bean
    Logger.Level feignLoggerLevel()
    {
        return Logger.Level.FULL;
    }
}

○ 9.1 超时设置

OpenFeign 认等待1s,超过后报错。

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

○ 9.2 打印日志

对Feign接口的调用情况 进行监控和输出

@Configuration
public class FeignConfig
{
    @Bean
    Logger.Level feignLoggerLevel()
    {
        return Logger.Level.FULL;
    }
}
logging:
  level:
    # feign日志以什么级别监控哪个接口
    com.atguigu.springcloud.service.PaymentFeignService: debug

█ 12.(×)Config --- 服务配置

@SpringBootApplication
@Enableconfigserver

@EnableEurekaClient
@SpringBootApplication

@RestController
@RefreshScope

中心化的外部配置

分为客户端 和 服务端《分布式配置中心,=独立的微服务应用 获取配置信息/加密/解密》《客户端:git来存储配置信息》

git add || git clone || git commit || git push

application.yml 是用户级的 资源配置项
bootstrap.yml 是系统级的 优先级 更高

动态刷新:

1)pom + actuator
2)yml + 暴露监控端口

management:
  endpoints:
    web:
      exposure:
        include: "*"

3)@RefreshScope controller上面加

@RestController
@RefreshScope

4)运维人员发送 Post请求
curl -X POST "http://localhost:3355/actuator/refresh"

为了一次发送post 处处生效 so bus---消息总线

█ 13. Bus --- 消息总线 RabbitMQ

为了一次发送post 处处生效 so bus---消息总线

动态刷新全局广播,,动态刷新定点通知

spring cloud bus是用来将 分布式系统的节点 与 轻量级消息系统 链接起来的 框架,整合了 java的事件处理机制消息中间件功能


轻量级消息代理 构建 共用的消息主题该topic中产生的消息会被所有 实例监听和消费

BUS设计思想:

可以利用 消息总线 触发一个客户端/bush/refresh,而刷新到所有 客户端的配置
可以利用 消息总线 触发一个服务端configserver的/bus/refresh
服务端的更合适,
打到 客户端

○ 13.1 RabbitMQ 15672

Bus支持两种 消息代理 :RabbitMQ 和 Kafka


RabbitMQ是一个消息中间件,是一个实现了AMQP(高级消息队列协议)的开源消息代理软件,同类的产品还有kafka,rocketMQ,但是目前springcloud只集成了RabbitMQ和kafka,

RabbitMQ的作用就是实现 系统之间 消息传递 的 解耦,对一些 实时性要求 不是 很高 的 服务 或者 并发 很高 的系统 来说是一个不错的选择,同时因为RabbitMQ是以AMQP协议实现的,所以支持多操作系统,多编程语言。


AMQP协议(高级消息队列协议)基于此协议的客户端 与 消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。



rabbitmq相关配置,暴露bus刷新配置的端点

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

服务端
http:localhost:3344/actuator/bus-refresh/{destination}
http:localhost:3344/actuator/bus-refresh/config-client:3355
http:localhost:3344/actuator/bus-refresh

RabbitMQ 安装

先安装 erlang
命令启动管理功能: rabbitmq-plugins enable rabbitmq_management
http://127.0.0.1:15672/
guest guest

█ 14.SpringCloud Stream --- 消息驱动


他甚至都没有写@EnableEurekaClient

@EnableBinding(Source.class)
@Component
@EnableBinding(Sink.class)
{函数上@StreamListener(Sink.INPUT)}

包括 支持 持久化 的发布/订阅消费组 以及消费分区这三个核心概念。

因为不同的中间件 存在差异,stream 做的 是把他们 解耦, 屏蔽掉 底层消息中间件 的差异,降低切换成本,统一 消息的 编程模型。


stream 通过 定义绑定器 Binder 作为中间层,实现 应用程序 与 消息中间件 细节 之间的隔离。

Binder input对应于消费者 ; output对应于生产者

stream 中消息通信方式 遵循了 发布--订阅模式,,topic主题进行广播《RabbitMQ是Exchange;;kafka topic》

sink--消费者 source ---生产者

○ 14.1 标准MQ:

生产者/消费者 之间靠 消息媒介 传递 信息内容 Message

消息必须 走特定的 通道 MessageChannel

消息通道里的信息 是 MessageChannel的子接口 SubscribableChannel,由 MessageHandler 消息处理器 所订阅

○ 14.2 消息中间件

https://blog.csdn.net/wqc19920906/article/details/82193316
1、概述
2、消息中间件的组成
3 消息中间件模式分类
4 消息中间件的优势
5 消息中间件应用场景
6 消息中间件常用协议
7 常见消息中间件MQ介绍

○ 14.3 stream 消息分组 重复消费

分到同一个组的消费者,是竞争关系,不能重复消费。
修改yml,group

○ 14.4 持久化

如果停了,且没有配置 group 属性,就会出现消息丢失;
如果停了, 配置 group 属性,会补上 之前的消息。

█ 15.SpringCloud Sleuth --- 分布式请求链路跟踪

Spring Cloud Sleuth提供了一套完整的服务跟踪的解决方

█ 16.zipkin 9411

java -jar zipkin-server-2.12.9-exec.jar
localhost:9411/zipkin/

一条链路 通过Trace id 唯一标识,Span标识 发起的请求信息,各Span通过 parent id 关联起来。
span 相当于 一次请求信息。

█ 17. SpringCloud Alibaba

○ 17.1 Nacos 8848

Nacos = 注册中心 + 配置中心 = Eureka + Config + Bus

startup.cmd
http://localhost:8848/nacos   nacos nacos

○ 17.2 sentinel

@SentinelResource(value = "byUrl")

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")

流控模式:直接 关联 链路

降级策略:平均响应时间 || 异常比例 || 异常数

sentinel = ribbon + openFeign + fallback

sentinel 有三个核心Api SphU定义资源 || Tracer定义统计 || ContextUtil定义了上下文

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐