SpringCloud

SpringCloud介绍

spring cloud 是一系列框架的集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。spring cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起=,通过 spring boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包

spring cloud 对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用 spring cloud 一站式解决方案能在从容应对业务发展的同时大大减少开发成本。同时,随着近几年微服务架构和 docker 容器概念的火爆,也会让 spring cloud 在未来越来越“云”化的软件开发风格中立有一席之地,尤其是在目前五花八门的分布式解决方案中提供了标准化的、一站式的技术方案,意义可能会堪比当年 servlet 规范的诞生,有效推进服务端软件系统技术水平的进步。

SpringCloud技术组成

在这里插入图片描述

  • eureka 微服务治理,服务注册和发现
  • ribbon 负载均衡、请求重试
  • hystrix 断路器,服务降级、熔断
  • feign ribbon + hystrix 集成,并提供声明式客户端
  • hystrix dashboard 和 turbine hystrix 数据监控
  • zuul API 网关,提供微服务的统一入口,并提供统一的权限验证
  • config 配置中心
  • bus 消息总线, 配置刷新
  • sleuth+zipkin 链路跟踪

Spring Cloud 对比 Dubbo

在这里插入图片描述

  • Dubbo
    • Dubbo只是一个远程调用(RPC)框架
    • 默认基于长连接,支持多种序列化格式
  • Spring Cloud
    • 框架集
    • 提供了一整套微服务解决方案(全家桶)
    • 基于http调用, Rest API

Service服务(暂留)

在这里插入图片描述

Spring MVC接收参数的几个注解

在这里插入图片描述

1.eureka注册于发现(2001)

spring:
  application:
    name: eureka-server
    
server:
  port: 2001

eureka:
  server:
  	#eureka 的自我保护状态:心跳失败的比例,在15分钟内是否超过85%,如果出现了低于的情况,
  	#Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,
  	#Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务
    enable-self-preservation: false
  instance:
    #eureka 集群服务器之间,通过 hostname 来区分
    hostname: eureka1
  client:
    #不向自身注册
    register-with-eureka: false
    #不从自身拉取注册信息
    fetch-registry: false
- eureka.instance.lease-expiration-duration-in-seconds
  最后一次心跳后,间隔多久认定微服务不可用,默认90
- eureka.instance.lease-renewal-interval-in-seconds
  心跳间隔时间,默认 30 秒  
- eureka.client.registry-fetch-interval-seconds
  拉取注册信息间隔时间,默认 30 秒

主程序

添加@EnableEurekaServer

修改hosts文件,添加eureka域名映射

127.0.0.1 eureka1
127.0.0.1 eureka2

把user-service 和 order-service等微服务注册到eureka服务器

yml添加eureka注册配置

eureka:
  client:
    service-url:
      #defaultZone,默认位置,可以修改为具体地理位置,比如:beiJing, shangHai, shenZhen 等,表示 eureka 服务器的部署位置, 需要云服务器提供
      defaultZone: http://eureka1:2001/eureka

user-service 和 order-service的主程序

添加@EnableDiscoveryClient

2.eureka 和 “服务提供者”的高可用

item-service 高可用

启动参数 --server.port 可以覆盖yml中的端口配置
–server.port=8001

eureka 高可用

添加两个服务器的 profile 配置文件
application-eureka1.yml

eureka:
  instance:
    hostname: eureka1
  client:
    register-with-eureka: true  #profile的配置会覆盖公用配置
    fetch-registry: true        #profile的配置会覆盖公用配置
    service-url: 
      defaultZone: http://eureka2:2002/eureka  #eureka1启动时向eureka2注册

application-eureka2.yml

eureka:
  instance:
    hostname: eureka2
  client:
    register-with-eureka: true  #profile的配置会覆盖公用配置
    fetch-registry: true        #profile的配置会覆盖公用配置
    service-url: 
      defaultZone: http://eureka1:2001/eureka  #eureka2启动时向eureka1注册

配置启动参数 --spring.profiles.active 和 --server.port

  • eureka1 启动参数:
    –spring.profiles.active=eureka1 --server.port=2001
  • eureka2 启动参数:
    –spring.profiles.active=eureka2 --server.port=2002

eureka客户端注册时,向两个服务器注册

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

3.ribbon服务消费者(3001)

ribbon 提供了负载均衡和重试功能, 它底层是使用 RestTemplate 进行 Rest api 调用

RestTemplate

RestTemplate 是StringBoot提供的一个Rest远程调用工具

它的常用方法:

  • getForObject() - 执行get请求
  • postForObject() - 执行post请求
    之前的系统结构是浏览器直接访问后台服务
    在这里插入图片描述
    后面我们通过一个Demo项目演示 Spring Cloud 远程调用
    在这里插入图片描述
    我们先不使用ribbon, 单独使用RestTemplate来执行远程调用

主程序

  • 创建 RestTemplate 实例
    RestTemplate 是用来调用其他微服务的工具类,封装了远程调用代码,提供了一组用于远程调用的模板方法,例如:getForObject()、postForObject() 等
	//创建 RestTemplate 实例,并存入 spring 容器
	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

RibbonController

	@Autowired
	private RestTemplate rt;
	
	@GetMapping("/item-service/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
	    //向指定微服务地址发送 get 请求,并获得该服务的返回结果 
	    //{1} 占位符,用 orderId 填充
		return rt.getForObject("http://localhost:8001/{1}", JsonResult.class, orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
	    //发送 post 请求
		return rt.postForObject("http://localhost:8001/decreaseNumber", items, JsonResult.class);
	}

4.ribbon负载均衡和重试

在这里插入图片描述

Ribbon 负载均衡

在这里插入图片描述

RestTemplate 设置 @LoadBalanced

@LoadBalanced 负载均衡注解,会对 RestTemplate 实例进行封装,创建动态代理对象,并切入(AOP)负载均衡代码,把请求分发到集群中的服务器

@LoadBalanced //负载均衡注解
	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

访问路径设置为服务id

@Autowired
	private RestTemplate rt;
	
	@GetMapping("/item-service/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
	    //这里服务器路径用 service-id 代替,ribbon 会向服务的多台集群服务器分发请求
		return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
		return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
	}

ribbon 重试

在这里插入图片描述

application.yml 配置 ribbon 重试

ribbon:
  MaxAutoRetriesNextServer: 2
  MaxAutoRetries: 1
  OkToRetryOnAllOperations: true
  • ConnectionTimeout
  • ReadTimeout
  • OkToRetryOnAllOperations=true
    默认只对GET请求重试, 当设置为true时, 对POST等所有类型请求都重试
  • MaxAutoRetriesNextServer
    更换实例的次数
  • MaxAutoRetries
    当前实例重试次数,尝试失败会更换下一个实例

主程序设置 RestTemplate 的请求工厂的超时属性

@LoadBalanced
	@Bean
	public RestTemplate getRestTemplate() {
		SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
		f.setConnectTimeout(1000);
		f.setReadTimeout(1000);
		return new RestTemplate(f);
		
		//RestTemplate 中默认的 Factory 实例中,两个超时属性默认是 -1,
		//未启用超时,也不会触发重试
		//return new RestTemplate();
	}

item-service 的 ItemController 添加延迟代码,以便测试 ribbon 的重试机制

@Value("${server.port}")
	private int port;
	
	@GetMapping("/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) throws Exception {
		log.info("server.port="+port+", orderId="+orderId);

        ///--设置随机延迟
		if(Math.random()<0.6) { 
			long t = new Random().nextInt(5000);
			log.info("item-service-"+port+" - 暂停 "+t);
			Thread.sleep(t);
		}
		///~~
		
		List<Item> items = itemService.getItems(orderId);
		return JsonResult.ok(items).msg("port="+port);
	}

5.Hystrix 断路器(3001)

在这里插入图片描述

主程序添加 @EnableCircuitBreaker 启用 hystrix 断路器

启动断路器,断路器提供两个核心功能:

  • 降级,超时、出错、不可到达时,对服务降级,返回错误信息或者是缓存数据

  • 熔断,当服务压力过大,错误比例过多时,熔断所有请求,所有请求直接降级

  • 可以使用 @SpringCloudApplication 注解代替三个注解(@EnableCircuitBreaker@EnableDiscoveryClient@SpringBootApplication)

RibbonController 中添加降级方法

  • 为每个方法添加降级方法,例如 getItems() 添加降级方法 getItemsFB()
  • 添加 @HystrixCommand 注解,指定降级方法名
	@Autowired
	private RestTemplate rt;
	
	@GetMapping("/item-service/{orderId}")
	@HystrixCommand(fallbackMethod = "getItemsFB") //指定降级方法的方法名
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
		return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	@HystrixCommand(fallbackMethod = "decreaseNumberFB")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
		return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
	}

hystrix 超时设置

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds

hystrix等待超时后, 会执行降级代码, 快速向客户端返回降级结果, 默认超时时间是1000毫秒

为了测试 hystrix 降级,我们把 hystrix 等待超时设置得非常小(500毫秒)

此设置一般应大于 ribbon 的重试超时时长,例如 10 秒

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

6.hystrix dashboard 断路器仪表盘

在这里插入图片描述
hystrix 对请求的降级和熔断,可以产生监控信息,hystrix dashboard可以实时的进行监控

sp07-hystrix 项目添加 actuator,并暴露 hystrix 监控端点(3001)

actuator 是 spring boot 提供的服务监控工具,提供了各种监控信息的监控端点

management.endpoints.web.exposure.include 配置选项,
可以指定端点名,来暴露监控端点

如果要暴露所有端点,可以用 “*”
在这里插入图片描述

调整 application.yml 配置,并暴露 hystrix.stream 监控端点

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

Hystrix dashboard 仪表盘(4001)

在这里插入图片描述

主程序添加 @EnableHystrixDashboard 和 @EnableDiscoveryClient

访问 hystrix dashboard

http://localhost:4001/hystrix

填入 hystrix 的监控端点,开启监控

http://localhost:3001/actuator/hystrix.stream

hystrix 熔断

整个链路达到一定的阈值,默认情况下,10秒内产生超过20次请求,则符合第一个条件。
满足第一个条件的情况下,如果请求的错误百分比大于阈值,则会打开断路器,默认为50%。
Hystrix的逻辑,先判断是否满足第一个条件,再判断第二个条件,如果两个条件都满足,则会开启断路器

断路器打开 5 秒后,会处于半开状态,会尝试转发请求,如果仍然失败,保持打开状态,如果成功,则关闭断路器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值