spring Cloud

介绍

spring cloud 是一系列框架的集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。
在这里插入图片描述

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

Spring Cloud 对比 Dubbo

在这里插入图片描述

  • Dubbo

    • Dubbo只是一个远程调用(RPC)框架
    • 默认基于长连接,支持多种序列化格式
  • Spring Cloud

    • 框架集
    • 提供了一整套微服务解决方案(全家桶)
    • 基于http调用, Rest API

配置eureka 服务

添加 依赖 eureka server

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>
	</dependencies>
<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

application.yml

spring:
  application:
    name: eureka-server   
    
server:
  port: 2001
  
eureka:
  server:
    enable-self-preservation: false  # 关闭保护模式  方便测试
  instance:
    hostname: eureka1   # 在注册中心的名字
  client:
    register-with-eureka: false
    fetch-registry: false
  

  • eureka 集群服务器之间,通过 hostname 来区分
  • eureka.server.enable-self-preservation

eureka 的自我保护状态:心跳失败的比例,在15分钟内是否超过85%,如果出现了超过的情况,Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务

  • eureka.client.register-with-eureka=false
    不向自身注册
  • eureka.client.fetch-registry=false
    不从自身拉取注册信息
  • eureka.instance.lease-expiration-duration-in-seconds
    最后一次心跳后,间隔多久认定微服务不可用,默认90

在主程序上添加 @EnableEurekaServer

package cn.tedu.sp05;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class Sp05EurekaApplication {

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

}

eureka

注册中心 工作 机制
1. 服务提供者注册
一次一次的不提注册 直到注册成功
2. 心跳
eureka 提供者每30秒 向注册中心 发送一次心跳 如果eureka连续3次 接收不到 该服务的心跳 则会删除该服务
3. 消费者 拉取列表
每30秒 会从注册中心拉取一次列表 刷新列表
4.自我保护模式
是一种特殊情况,如果15分钟内,85%以上服务器都出现心跳异常(可能是网络不稳定),eureka会进入自我保护模式,所 有的注册信息都不删除。等待网络恢复后,可以自动退出保护模式
开发期间,为了影响测试,可以先关闭保护模式

eureka的高可用 搭建集群

因为需要向另一个eureka注册中心注册 所以也需要 添加 eureka 提供者 依赖
在这里插入图片描述

	<dependencies>
 		 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        </dependencies>
   <dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
hosts
        127.0.0.1   eureka1
        127.0.0.1   eureka2
​
spring:
  application:
    name: eureka-server
server:
  port: 2001
eureka:
  server:
    enable-self-preservation: false  # 关闭自动保护模式
  instance:
    hostname: eureka1
  client:
    register-with-eureka: false  # 关闭向注册中心注册自己
    fetch-registry: false  # 关闭向注册中心拉去信息
---
spring:
  profiles: eureka1
server:
  port: 2001
eureka:
  server:
    enable-self-preservation: true
  instance:
    hostname: eureka1
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone:  http://eureka2:2002/eureka
---
spring:
  profiles:
    - eureka2
server:
  port: 2002
eureka:
  instance:
    hostname: eureka2
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka
    register-with-eureka: true
    fetch-registry: true
​
通过 idea 启动配置  在 启动页面 编辑参数
        --spring.profiles.active=eureka1  --server.port=2001
        --spring.profiles.active=eureka2  --server.port=2002

在这里插入图片描述

eureka 提供者

  1. 添加 eureka 提供者依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.编辑yml配置文件 向eureka 注册

spring:
  application:
    name: item-service   # 将作为eureka查询地址的key

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

服务消费者

添加 依赖 eureka 消费者依赖 eureka-client 中已经包含 ribbon 依赖

		<dependencies>
 		 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        </dependencies>
   <dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

添加配置

spring:
  application:
    name: ribbon
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

RestTemplate

RestTemplate 是SpringBoot提供的一个Rest远程调用工具 可直接进行远程调用 走的是http协议
它的常用方法有
getForObject() - 执行get请求
postForObject() - 执行post请求

ribbon

对 RestTemplate 进行封装、增强,添加了负载均衡重试功能

package com.tedu.sp06;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

//@EnableDiscoveryClient  可以省略
@SpringBootApplication
public class Sp06RibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(Sp06RibbonApplication.class, args);
    }
    //创建 RestTemplate的实例 交给spring管理
    @Bean
    public RestTemplate restTemplate(){
        //设定重连
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
        //设定超时 时间
        f.setConnectTimeout(1000);
        f.setReadTimeout(1000);
        //将重连z注入给 RestTemplate
       return new RestTemplate(f);
    }
}
package com.tedu.sp06;

import com.tedu.sp01.pojo.Item;
import com.tedu.sp01.pojo.Order;
import com.tedu.sp01.pojo.User;
import com.tedu.sp01.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;
@Slf4j
@RestController
public class RestTemplateController {
    /**
     * RestTemplate  是springboot 提供的远程一种工具 走的是http协议 可以将返回的数据转换成java对象
     * 常用的有两种方法
     * restTemplate.getForObject("http://localhost:8001/{1}", JsonResult.class, orderId);
     * 第一个参数为url路径 其中{1} 是 template规定的占位符 表达式 1 2 3表示序号 参数顺序  需要在第三个参数中 具体的传参
     * 例如  restTemplate.getForObject("http://localhost:8101/{1}/score?score={2}",
     *                 JsonResult.class,
     *                 userId, score);
     *  post提交:
     * restTemplate.postForObject("http://localhost:8001/decreaseNumber", items, JsonResult.class);
     *
     *httpclient  偏底层工具
     * restTemplate  高度封装的工具
     *rabbit  对restTemplate的进一步增强  实现负载均衡  和 重试功能
     * rrabbit增强 负载均衡的实现
     *      1. 在restTemplate 方法上加上 @LoadBalanced 注解  为服务添加负载均衡
     *      2. 将地址信息 改成serviceName(提供者的名字) 直接从注册中心中获取服务者的地址信息
     *      实现负载均衡  例如http://localhost:8001/{1}   http://item-service/{1}*
     *rabbit增强 重试的实现
     */

    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping("/item-service/{orderId}")
    @LoadBalanced // 添加负载均衡 rabbit 增强
    public JsonResult<List<Item>> checkItem(@PathVariable String orderId){
            //RestTemplate  定义的占位符格式http://localhost:8001/{1}
            //"http://item-service/{1}" 直接从注册表 根据 名字 获取注册表 获取主机地址列表  实现负载均衡
           JsonResult result= restTemplate.getForObject("http://item-service/{1}", JsonResult.class, orderId);
            log.info("调用后台服务器成功");
           return result;
    }
    @RequestMapping("/item-service/decreaseNumber")
    public JsonResult decreaseNumber(@RequestBody  List<Item> items){
        JsonResult result=restTemplate.postForObject("http://localhost:8001/decreaseNumber", items, JsonResult.class);
        log.info("远程后台服务器 调用成功");
        return result;
    }
    @GetMapping("/user-service/{userId}")
    public JsonResult<List<User>> checkUser(@PathVariable String userId){
        JsonResult forObject = restTemplate.getForObject("http://localhost:8101/{1}", JsonResult.class, userId);
        log.info("远程后台服务器 调用成功");
        return forObject;
    }
    @GetMapping("user-service/{userId}/score")
    public JsonResult<List<User>> checkUser1(@PathVariable String userId,Integer score){
        JsonResult result = restTemplate.getForObject("http://localhost:8101/{1}/score?score={2}",
                JsonResult.class,
                userId, score);
        return result;
    }
    @GetMapping("/order-service/{orderId}")
    public JsonResult<List<Order>> checkOrder(@PathVariable String orderId){
        JsonResult forObject = restTemplate.getForObject("http://localhost:8201/{1}", JsonResult.class, orderId);
        log.info("远程后台服务器 调用成功");
        return forObject;
    }
    @GetMapping("/order-service")
   public JsonResult<List<Order>> checkOrder1(){
    JsonResult forObject = restTemplate.getForObject("http://localhost:8201", JsonResult.class, "");
    log.info("远程后台服务器 调用成功");
    return forObject;
}
}

feign

集成工具,集成了

  • 远程调用
  • ribbon
  • hystrix

依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

在主启动类上添加注解@EnableFeignClients

package com.tedu.sp09;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableCircuitBreaker //启用断路器
@EnableFeignClients //启用feign  客户端
@SpringBootApplication
public class Sp09FeignApplication {

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

}

远程调用

Feign 提供了一个声明式客户端接口,只需要定义一个接口,就可以通过接口远程调用服务,而不用写具体的代码
示例:

package com.tedu.sp09.feign;


import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import com.tedu.sp09.FeignImpl.ItemFeignClientFB;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
@FeignClient(name = "item-service",fallback = ItemFeignClientFB.class) //定义从注册表 拉取得是那个路径信息
public interface ItemFeignClient {
    @GetMapping("/{orderId}") //定义访问的路径
    JsonResult<List<Item>> getItems(@PathVariable  String orderId);
    @GetMapping("/{decreaseNumber}")
    JsonResult devrease(@RequestBody  List<Item> items);
}

@FeignClient() 注解 配合 @GetMapping 注解使用
其中 @FeignClient 注解中的name属性 指向的是 具体调用的服务名称 从而通过 eureka注册中心获取 该服务的地址,而@GetMapping注解主要作用就是通过该注解指定 具体访问该服务的那个路径
如 a服务远程调用b服务 则可以在a服务中声明Feign接口 通过@FeignClient注解定位到 b 服务 然后通过@GetMapping 中的路径决定具体的调用路径

//  a服务 Controller
@Slf4j
@RestController

public class feignController {
    @Autowired
    private ItemFeignClient itemFeignClient;
     @GetMapping("/item-service/{orderId}")
    public JsonResult<List<Item>> getItems(@PathVariable String orderId){
        System.out.println("======");
        return itemFeignClient.getItems(orderId);
    }
    

负载均衡 与 重连 feign整合ribbon

无需任何配置 ,feign默认启用了 负载均衡和重连
重试 默认参数值如下, 如需修改 在yml配置文件中修改即可

  • MaxAutoRetries: 0 # 最大重连次数 0 一台服务器 终会有初始连接(初始连接不计算在连接次数内)
  • MaxAutoRetriesServer: 1 #重连更换的 服务器台数 为1台
  • ReadTimeout:1000 # 秒 feign整合ribbon后 超时设定 不用再具体方法中设定 在配置文件中设定即可
    配置文件 还可以配置到具体的服务:
# 所有服务都有效
ribbon:
  MaxAutoRetries: 1
  
# 只对 item-service 有效
item-service:
  ribbon:
    MaxAutoRetries: 2

整合hystrix

feign 默认不启用 Hystrix ,不推荐启用 Hystrix

如需启用 则需要添加如下配置

  1. 添加 hystrix的完整依赖
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  1. 在springBoot的主启动类上加上注解@EnableCircuitBreaker 表示启动断路器
package com.tedu.sp09;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableCircuitBreaker //启用断路器
@EnableFeignClients //启用feign  客户端
@SpringBootApplication
public class Sp09FeignApplication {

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

}

  1. 在yml配置启用hystrix : feign.hystrix.enabled=true
feign:
  hystrix:
    enabled: true  #启用hystrix
  1. 添加降级代码
    在 @FeignClient注解中 添加属性 fallback=降级类.class
package com.tedu.sp09.feign;


import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import com.tedu.sp09.FeignImpl.ItemFeignClientFB;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
@FeignClient(name = "item-service",fallback = ItemFeignClientFB.class) //定义从注册表 拉取得是那个路径信息
public interface ItemFeignClient {
    @GetMapping("/{orderId}") //定义访问的路径
    JsonResult<List<Item>> getItems(@PathVariable  String orderId);
    @GetMapping("/{decreaseNumber}")
    JsonResult devrease(@RequestBody  List<Item> items);
}
  1. 创建 降级类 实现声明式客户端接口
package com.tedu.sp09.FeignImpl;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import com.tedu.sp09.feign.ItemFeignClient;
import org.springframework.stereotype.Component;

import java.util.List;
@Component
public class ItemFeignClientFB implements ItemFeignClient {
    @Override
    public JsonResult<List<Item>> getItems(String orderId) {
        return JsonResult.err().msg("查询 item失败");
    }

    @Override
    public JsonResult devrease(List<Item> items) {
        return JsonResult.err().msg("删除item  失败");
    }
}

监控 (Hystrix监控)

  1. 添加 监控依赖 actuator
		 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  1. 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream  # * 代表暴露所有端点
  1. 重启项目 调用后台服务
  2. 查看 监控端点
    http://localhost:3001/actuator/hystrix.stream // 根据个人配置访问
  3. 访问仪表盘
    http://localhost:4001/hystrix // 根据个人配置访问

Hystrix Dashboard 仪表盘

仪表盘 是一款 对hystrix 降级和熔断的监控 ,用图标的方式直观的看到系统的错误情况

暴露监控数据

使用 actuator 工具,暴露监控数据
actuator 是由 spring boot 提供的工具,可以暴露项目中的多种监控数据,例如:

  • spring容器中的所有对象
  • spring MVC的所有映射路径
  • 将康状态
  • 环境变量

  • Hystrix就是利用 actuator 来暴露自己的降级和熔断监控

actuator 的使用

  1. 添加actuator依赖

  2. 配置暴露的监控端点:

     	m.e.w.e.i="*" : 暴露所有的监控端点
     	m.e.w.e.i=health : 暴露健康状态端点
     	m.e.w.e.i=['health', 'mappings', 'beans'] :暴露多个监控端点
    
management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream  # * 代表暴露所有端点
management:
  endpoints:
    web:
      exposure:
        include: "*"  #  要有双引号
  1. 启动服务
    通过 访问服务的下一级路径 查看 监控的端点 如果 服务端口是3001
    http://localhost:3001/actuato 来查看所有的监控
    在这里插入图片描述

搭建仪表盘

仪表盘项目可以是一个完全独立的项目,可以不连接注册中心,不用注册,也不用发现其他服务
需要监控那个项目 只需要加上那个项目的路径 即可

  1. 新建 springboot项目 添加 hystrix dashboard 仪表盘依赖
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
  1. 添加主程序注解: @EnableHystrixDashboard
package com.tedu.sp08;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;


@EnableHystrixDashboard
@SpringBootApplication
public class Sp08HystrixDashboardApplication {

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

}

  1. 启动项目 用浏览器 访问下属路径 hystrix 即可
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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 EurekaSpring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的中心动态刷新,而不需要为配置中心新增集群或使用消息队列。另一方面,EurekaSpring 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、付费专栏及课程。

余额充值