SpringCloud的简单使用

SpringCloud

SpringCloud是一系列微服务技术的结合体,springCloud对这些技术进行了封装,使用起来更加方便和快捷。

服务架构的演变
服务架构演变
微服务
将一个完整的项目拆分成若干个相对独立的模块,模块之间可以相互通信,并进行分布式集群开发,实现了高可用,高并发的特性。

SpringCloud对比Dubbo

  • 共同点

Dubbo与SpringCloud都可以实现分布式集群开发,都是实现微服务的有效工具;

  • 相同点
    Dubbo使用RPC(Remote Process Call 远程过程调用) 底层通过Socket进行通信,传输的时二进制数据,相较于SpringCloud使用的RESTful的HTTP进行调用,传输的数据格式为JSON,Dubbo传输的效率更高,但SpringCloud具有 更高的通用性(JSON数据具有跨语言特性),且具有更加齐全的功能。

Eureka服务治理(注册中心)

Eureka与DUbbo的zookeep功能相似,eurekaServer自己本身也是个服务,需要用户自己搭建:
Eureka内主要分为Server和Client两种角色:EurekaServer负责服务治理,EurekaClient负责将自己注册到EurekaServer上以及调用EurekaServer上所注册的服务(即生产者与消费者同属于EurekaClient);

导入对应jar包:

//EurekaServer选择EurekaServer包 对于EurekaClient选择EurekaClient包
	 <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.2.3.RELEASE</version>
    </dependency>

	 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

Eureka配置

EurekaServer可以通过把自己注册到其他EurekaServer上实现EurekaServer的集群

//一下为EurekaClinet配置,EurekaServer与其类似
eureka:
  client:
    service-url: 
       defaultZone: http:localhost:8761/eureka #EurekaServer的ip&port 当有集群时 此输可指定多个EurekaServer ip
    register-with-eureka: true #是否把自己注册到eurekaServer上
    fetch-registry: true  #是否从eurekaServer拉取注册的服务列表
  instance:
    hostname: clazz-provider #指定注册到eurekaServer上当前应用的服务名

开启Eureka注解

对于eurekaServer 使用@EnableEurekaServer, 对于


@SpringBootApplication
@EnableAdminServer
@EnableEurekaServer //EurekaClient则选择@EnableEurekaClient
public class SpringbootAdminApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootAdminApplication.class, args);
    }

}

Ribbon负载均衡组件

Ribbon可以实现Eureka内部服务的负载均衡,通过在Eureka服务端配置Ribbon同时可以实现客户端的负载均衡,同时Ribbon还可以相对简化服务间的远程调用过程;

导入jar包:

 <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        <version>2.2.3.RELEASE</version>
    </dependency>

原始远程调用服务通过RestTemplate和DiscoveryClient实现,需要通过DiscoveryClient获取指定服务的端口与ip并与参数进行字符串的拼接成url,再通过restTemplate发送http请求并封装返回结果实现服务的远程调用。通过Ribbon可以简化部分过程:

  • 在对应的RestTemplate对象上加上@LoadBalanced注解
  • 将原本的请求URL中的host与port替换为调用服务的名称
//其中clazz-provider为需要调用的服务名 id为参数,Clazz.class为返回值类型
 Clazz clazzs = restTemplate.getForObject("http://clazz-provider/clazz/" + id, Clazz.class);

负载均衡策略

ribbon实现的负载均衡共有7中负载均衡策略:
  • RoundRobbinRule : 轮询(默认策略)
  • RandomRule : 随机
  • BestAvailableRule : 最小并发
  • AvailabilityFilteringRule : 过滤条件
  • ** WeightedResponseTimeRule** : 最小相应时间
  • RetryRule : 轮询重试
  • ZoneAvoidanceRule : 性能可用性

修改Ribbon负载均衡策略有配置文件和编码实现两种方式:

编码实现: 推荐使用

  1. 像容器注入IRule的实现类(以上七种)
  2. 在启动类上添加@RibbonClient注解并用name属性指定负载均衡的服务名,使用configuration属性指定配置了IRule实现类的bean的Cnfiguration配置类

配置文件实现

在配置文件添加:

服务提供方的服务名.ribbon.NFloadbalancerRuleClassname: 策略类的全限定类名

OpenFeign

openFeign可以实现声明式服务调用,简化客户端调用服务的配置,原始的服务调用需要RestTemplate和DiscoveryClient来共同实现,Feign可以将其省略:

导入jar包:

 <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>
  • 开启**@EnableFeignClients**注解,在启动类上
  • 编写Fiegn调用服务的接口,并加上@FeignClient注解,name属性指定对应的服务名
  • 接口方法使用@GetMapping等Restful标记对应方法的url,且方法参数必须以@PathVariable&@RequestParam指定对应服务内的方法参数名一致;
  • 在容器中注入该接口,使用接口的方法即可完成远程调用
@FeignClient(name = "clazz-provider")//指定服务名
public interface ClazzFeign {

    @GetMapping("/clazz/{id}")
    Map<String,Object> getClazz(@PathVariable("id") Integer id);

    @GetMapping("/clazz/getByIds")
    List<Clazz> getClazzList(@RequestParam("ids") List<Integer> ids);
}

//容器中注入clazzFeign,调该对象即可实现远程调用
 Map<String, Object> clazz = clazzFeign.getClazz(Integer.valueOf(student.getClazzId()));

Feign的超时配置

Feign底层利用Ribbon实现服务调用,默认等待调用结果时间为1秒,默认与服务连接超时时间为1秒,可以在配置文件设定自定义值:

	Ribbon.ConnectionTimeout=1000
	Ribbon.ReadTimeout=1000

Feign的日志记录

Feign支持日志记录,通过在创建配置类,在配置类中编写 返回 Logger.level的对象的Bean,同时在@FeignClient注解的Configuration属性指定该配置类。即可完成Feign的日志记录。

日志分为:

  • 操作日志:此种类型的日志会记录所有系统内用户的行为,并将数据保存在数据库(一般可以通过AOP实现)
  • 系统日志: 即系统运行时控制台所打印的日志,在生产环境中可以将其设置保存在文件中

Consul&Nacos

Consul与Nacos均属于服务治理组件,其使用方法均与Eureka类似,且该两个组件均有服务端App不需要自己编码实现;

Consul :

Consul服务端启动命令:

consul agent -dev

配置如下:

 consul:
  discovery:
    hostname: localhost #指定当前应用的主机名称
    port: 8500  #指定当前应用的端口
    instance-id: thisisaid #指定注册到Consul的ID
    service-name: clazz-provider #指定注册到Consul的服务名

Nacos

Nacos(Dynamic Naming and Configuration Service)在三个组件中性能最高,是一个注册中心和配置中心

配置如下:

cloud:
nacos:
  discovery:
    server-addr: http://localhost:8848 #指定nacosServer的位置

Hystrix 熔断器

Hystrix具有延迟和容错,隔离访问的远程服务,防止级联失败而导致的系统雪崩效应的功能;

隔离

Hystrix默认会开启服务的线程隔离功能,能对应用内的服务分别分配一个具有一定数量的线程的线程池,当应用内某一个服务崩溃,仅会对自己线程池内的线程占用,从而保证了其他服务线程池内线程不受影响,实现了应用内部的隔离性。

熔断

Hstrix会默认开启服务的熔断功能,能对指定不稳定的服务进行断开连接操作
默认情况下一个服务在5S内发生20次调用失败,Hystrix便会打开断路器,该服务被关闭连接,从而保证应用的相应时间和运行速度,过一段时间后(默认5s)Hystrix断路器会进入半断开状态,一部分对该服务的请求能连接,Hystirx会自动判断连接是否成功来决定是否断开断路器。

	//熔断的参数如下
	circut.SleepWindowInMillSeconds:断路器计数周期
	circut.RequestThreshold:   单位计数周期内请求失败数量的阈值
	circut.ErrorThresholdPercent: 单位计数周期内请求失败的比列阈值

Hystrix 熔断监控

Hystrix支持对当前(微服务)应用的运行状态的监控,利用其Hystrix-Dashboard组件

熔断监控端

  1. 导入jar包:

    Hysrtix-Dashboard  Turbine  Actuator  Eureka-Client  Web
    
  2. 在启动类加上@EnableHystrixDashboard @EnableTurbine

  3. 配置文件:

spring:
  application.name: hystrix-monitor
server:
  port: 8769
turbine:
  combine-host-port: true
  # 配置需要监控的服务名称列表
  app-config: clazz-consumer
  cluster-name-expression: "'default'"
  aggregator:
    cluster-config: default
  #instanceUrlSuffix: /actuator/hystrix.stream
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  1. 进入http://localhost:8769/hystrix/ 输入http://localhost:8769/turbine.stream完成指定应用的监控

熔断被监控端

在指定被监控端:

  1. 导入jar包

    Actuator  Hystrix-Dashboard  Hystrix
    
  2. 注入指定bean:

@Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetrceStreamServlet");
        return registrationBean;
    }

GateWay 网关&路由

GateWat能为微服务架构的应用提供一种简单有效且统一的API路由管理方式,同时GateWay作为系统的入口,可以实现封装系统的内部结构,以及与业务无关的公用逻辑的处理;

  1. 导入jar包:

    GateWay  Eureka
    
  2. 配置文件:

server:
  port: 80 #一般指定为80 为浏览器默认IP的端口
spring:
  application:
    name: GateWay
  cloud:
    gateway:
      routes:
        - id: clazz-provider  #路由Id
          uri: lb://CLAZZ-PROVIDER #动态路由clazz-provider为Eureka内注册的服务名
          predicates:
            - Path=/clazz/**  #路由转发匹配路径
        - id: eureka-consumer
          uri: lb://CLAZZ-CONSUMER
          predicates:
            - Path=/student/**
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka #拉取Eureka服务的Id
  instance:
    hostname: gateWay

其中URI可以有两种配置方式:

  • 静态配置

即uri为一个定值

  	uri: http://服务的IP:服务端口

动态配置

uri为从eureka拉取的服务名,其中lb为指定的通信协议(类似于http)

 uri: lb://CLAZZ-CONSUMER

同样,gateWay能从eureka拉取指定的服务,其肯定具有自己的负载均衡实现

GateWay自动去除uri中服务名
通过:

	  discovery:
    	locator:
      	enabled: true  #GateWay支持自动将URI的一级路径中的ServiceID去除
      	lower-case-service-id: true #GateWay支持ServiceId小写格式(大写格式失效反之小写失效)

配置GateWay能自动监测请求的URI中一级路径中包含的服务名,能自动去除对应的服务名;
即如下配置一个请求为localhost/clazz/**与localhost/clazz-provider能相同进入该路由规则

 gateway:
      routes:
        - id: clazz-provider  #路由Id
          uri: lb://CLAZZ-PROVIDER #动态路由
          predicates:
            - Path=/clazz//**  #路由转发匹配路径
          filters:
            - StripPrefix=1 #局部过滤器 将指定层级的uri路径删除再转发到指定服务a
       discovery:
        	locator:
          		enabled: true  #GateWay支持自动将URI的一级路径中的ServiceID去除
          		lower-case-service-id: true #GateWay支持ServiceId小写格式(大写格式失效反之小写失效)

GateWay实现过滤功能

GateWay可以实现对请求的统一过滤处理功能,gateWay中的过滤分为前置(pre)过滤和后置(post)过滤,以及局部过滤器和全局过滤器;

局部过滤器
局部过滤器可直接在配置文件中指定:过滤器详解

	- id: eureka-consumer
      uri: lb://CLAZZ-CONSUMER
      predicates:
        - Path=/testFilter/student/**
      filters:
        - StripPrefix=1 #局部过滤器 将指定层级的uri路径删除再转发到指定服务

全局过滤器
全局过滤器可以直将实现了GlobalFilter&Ordered接口的过滤器注入gateWay所在应用容器内实现:

@Component
public class MyFilter implements GlobalFilter, Ordered {
    @Override //执行过滤逻辑
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println(exchange.getRequest().getPath());
        System.out.println(Objects.requireNonNull(exchange.getApplicationContext()).getApplicationName());
        return chain.filter(exchange);//过滤器放行该请求
    }

    @Override
    public int getOrder() {//返回该过滤器的执行优先级 0开始递增
        return 0;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值