SpringCloud知识点总结

220 阅读6分钟

Eureka

基本使用

在服务中添加eureka-server的依赖,配置eureka-server,在启动类上添加@EnableEurekaServer注解

# eureka服务端的名称
eureka.instance.hostname=eureka-server-7001
# 是否向注册中心注册自己
eureka.client.register-with-eureka=false
# 表示自己为注册中心,客户端的这个设置应该为true
eureka.client.fetch-registry=false
# 配置eureka集群,单一时配置自己即可,集群时配置其他eureka的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

在服务中添加eureka-client的依赖,配置eureka-client,在启动类上添加@EnableEurekaClient注解

# 向eureka server注册
eureka.client.service-url.defaultZone=http://localhost:7001/eureka/
# 服务的消费者这里可以关闭,不向eureka-server中注册自己
eureka.client.register-with-eureka=false

Eureka,Zookeeper,Nacos区别

AP,CP,AP模型中的数据可能保持的不是那么的真,数据实时性不高

Zookeeper保证CP,从Zookeeper各个节点取回来的数据都是一致的;当master节点宕机,剩余节点会重新进行leader选举。在此期间无法提供注册和查询服务。

Eureka保证AP,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。只不过查到的信息可能不是最新的。

Nacos有CP和AP模式可以切换,除了服务的注册发现之外,还支持动态配置服务。

Ribbon

基本使用

在配置类中给RestTemplate Bean对象加上@LoadBalanced注解即可

@Configuration
public class ConfigBean {

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

}

负载均衡算法

ribbon是客户端负载均衡,因为他是在客户端进行负载均衡算法的,而nginx是一个服务端,负载均衡算法是在nginx做的,所以是服务端负载均衡。

使用自定义的负载均衡算法,写一个配置类(不要和启动类在同级目录下),返回一个IRule Bean对象,在启动类上使用该算法@RibbonClient(name="需要使用的服务名", configuration = 配置类.class)。

自带的负载均衡算法有

  • RoundRobinRule(轮询,默认)
  • RandomRule(随机)
  • AvailabilityFilteringRule(会先过滤掉故障服务)
  • RetryRule(按轮询获取服务,获取失败在指定时间内重试)

可以自己根据这些模板来进行改写。

Feign

基本使用

编写需要调用的接口,接口添加@FeignClient(value="服务名")注解,并在启动类添加@EnableFeignClients注解。在服务的消费者中直接注入这个接口的实例即可使用。

@FeignClient(name = "message", fallbackFactory = HystrixTest.class)
// @FeignClient(url = "http://localhost:port")
public interface MessageService {

    // @GetMapping("/sendNewUserMessage/{name}")
    // boolean sendNewUserMessage(@PathVariable String name);

    @GetMapping("/sendNewUserMessage")
    boolean sendNewUserMessage(@RequestParam String name);
}

当@FeignClient注解中使用url的时候,则不会去注册中心拉服务列表,而是直接单点请求。接口中的方法上需要添加@GetMapping("/sendNewUserMessage")好让Feign知道要对哪个接口发起请求。

参数传递的形式:

  1. @RequestParam:?param=value&...
  2. @PathVariable:
    • 修饰的参数,在链接中有相应的{name},转换成RESTful形式
    • 修饰的参数,在链接中无相应的{name},转换成Content-Type: application/json
  3. @RequestBody/无注解:消息体传参
    • 当单个参数是基本类型或String时转换成Content-Type: text/plain;charset=UTF-8的形式
    • 参数是对象类型时转换成Content-Type: application/json的形式

Hystrix

服务熔断与服务降级

熔断亦称为过载保护,是某个服务(下游服务)故障引起。降级是整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。一般需要对业务有层级之分,关闭一些对主要业务影响不大的服务。

实现熔断: 在服务提供者编写熔断的方法,在相应业务的方法上添加@HystrixCommand(fallbackMethod = "熔断方法名")注解。

实现降级: 在服务消费者结合Feign的接口,编写一个实现FallbackFactory的类,实现其create方法,返回一个新的Feign接口实体。

熔断要在启动类上添加@EnableHystrix注解,早些版本熔断是加@EnableCircuitBreaker注解。服务降级要在配置文件中配置feign.circuitbreaker.enable=true,早些版本是配置feign.hystrix.enable=true

Zuul

作用

提供动态路由,访问过滤,身份认证和安全等服务。

基本使用

添加依赖

编写配置文件

server:
  port: 8000
spring:
  application:
    name: zuul
zuul:
  routes:
    # 标识你服务的名字,这里可以自己定义,一般方便和规范来讲还是跟自己服务的名字一样
    EUREKA-CLIENT-PRODUCER:
      # 服务映射的路径,通过这路径就可以从外部访问你的服务了,目的是为了不爆露你机器的IP
      # 这里zuul是自动依赖hystrix,ribbon的,不是面向单机
      path: /EUREKA-CLIENT-PROVIDER/**
      # 这里一定要是你Eureka注册中心的服务的名称,是因为这里配置serviceId因为跟eureka结合了,
      serviceId: EUREKA-CLIENT-PROVIDER
  ignored-services: # 不可访问的服务名,可以将原有的服务名隐藏起来
eureka:
  client:
    service-url:
      defaultZone: http://admin:123456@127.0.0.1:8761/eureka/

在启动类上添加@EnableZuulProxy注解

通过zuul访问服务的,URL地址默认格式为:http://zuulHostIp:port/服务名称/服务中的URL

# URL匹配:
# ? 单个字符
# * 任意多个字符,不包含多级路径
# ** 任意多个字符,包含多级路径
zuul.routes.eureka-application-service.path=/api/**
# 路由前缀配置
zuul.prefix=/api
# 配置不被zuul管理的原服务列表。多个服务名称使用逗号’,'分隔。下面是通配方式配置排除列表,隐藏了全部的原服务,只能通过path的路径进行请求
zuul.ignored-services=*

配置中心

Server端

编写配置文件上传到git仓库

# 默认激活的环境
spring:
  profiles:
    active: dev
    
# dev配置文件
---
spring:
  profiles: dev
  application:
    name: spring-config-dev

# test配置文件
---
spring:
  profiles: test
  application:
    name: springcloud-config-test

新建配置中心server的项目,编写配置,启动类上加@EnableConfigServer注解

spring.cloud.config.server.git.uri=git仓库的地址
spring.cloud.config.label=分支

client端

编写配置文件,读取云端相应的配置。在SpringCloud 2020.* 版本把bootstrap禁用了,要把bootstrap依赖导入项目才可。

spring:
  cloud:
    config:
      name: git上读取资源的名称,不要后缀
      profile: 读取配置文件中的哪个配置
      label: 分支
      uri: server端的访问地址http://ip:port

热部署

手动配置热更新某个服务

  1. 开启actuator中的refresh端点
  2. Controller中添加@RefreshScope注解
  3. 向客户端 url http://localhost:91/actuator/refresh发送Post请求

批量更新使用消息队列

Acuator

暂未总结

对于一些报错如何寻找根源

例如SpringCloud Ribbon 解决 No instances available。spring-cloud-starter-netflix-eureka-client 3.0版本的已经内置ribbon,再导入的spring-cloud-starter-netflix-ribbon可能会产生冲突,自己应该如何去找到这种错误的根源。

java.lang.NoClassDefFoundError

通过Debug发现问题并解决。由于jdk的ext目录下的fastjson的版本有冲突造成的。NoClassDefFoundError是由于编译能找到class但是运行时找不到class。在一些特定条件下就会出现编译时可以加载到类,运行时不可以加载到类,这时候就会出现java.lang.NoClassDefFoundError异常。