SpringCloud常用组件总结
SpringCloud
什么是SpringCloud?
SpringCloud是基于Spring Framework的一套开源工具集,用于构建分布式系统和微服务架构的解决方案。它提供了一系列的开发工具和组件,简化了分布式系统中常见的开发、配置、服务注册和发现、负载均衡、断路器、路由、配置管理等任务。
常用组件
1、Eureka注册中心
(1)使用场景
Eureka主要是用来进行服务的管理,考虑到服务的增加,对于服务提供者来说,服务者要对外暴露自己的调用地址,对于调用者来说,它要记录提供者的服务地址,如果微服务的数量增大,或者说提供者的端口、ip等信息发生变更,而调用者不知道,就会给项目带来问题,不利于项目的维护。
那么Eureka就负责管理、记录服务提供者的信息,服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。
提供者与注册中心之间维持“心跳”机制,提供者向注册中心定时发送自己还“活着”的信息,防止被Eureka从服务列表中移除。
(2)使用方法
①:搭建EurekaServer项目
引依赖:
<!-- SpringCloud依赖管理 -->
<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>
版本管理:
<properties>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
注意:版本要和SpringBoot的版本使用一致
②:引入Eureka依赖
Eureka服务端:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
客户端:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
③:修改配置文件(提供端口、ip等信息)
server:
port: 10086 # eureka访问服务端口
spring:
application:
name: eureka-server # 应用名称 会在Eureka中显示
eureka:
client:
service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
defaultZone: http://127.0.0.1:10086/eureka
④:服务提供端与调用端也要注册到Eureka上
eureka: #服务提供方
client:
service-url: # EurekaServer地址,提供方注册地址
defaultZone: http://localhost:10086/eureka/
eureka: #服务调用方
client:
service-url:
defaultZone: http://localhost:10086/eureka/
⑤:启动类上加注解
@EnableEurekaServer //启用Eureka服务端
@EnableDiscoveryClient //两个客户端的启动类上
如果要搭建Eureka集群,参考另外一个文章。
2、负载均衡Ribbon
(1)使用场景
为了降低某个提供者服务的压力,或者说把服务部署在多个实例上,用来提高系统的可用性和容错性(一个坏了,可以调其他的服务)根据预定义的负载均衡策略将请求分发到不同的实例,提高系统的性能和可靠性。
(2)使用方法
Eureka中已经帮我们集成了负载均衡组件,在此无需引入新的依赖。因为负载均衡是指针对服务调用者来说,这个不行调另外的,所以改动consumer模块的代码
①:引入依赖:无
②:在调用者的启动类中注入
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
③:修改服务的调用方式如:
String url = "http://service-provider/provider/findById/" + id;
User user = restTemplate.getForObject(url, User.class);
可以打断点跟踪负载均衡策略(默认是简单的轮询策略)也可以修改
3、Hystrix
(1)使用场景
主要起到一个保护机制。作用是隔离访问远程服务、第三方库,防止出现级联失败等问题。
以雪崩问题为例:(在微服务中,完成一个服务请求可能需要依赖多个服务接口才能实现。形成非常复杂的调用链路。如果其中的某个服务出现了异常,用户得不到响应,但是Tomcat也不会释放线程,越来越多的线程堵塞。形成雪崩)
使用Hystrix做一些容错保护(服务熔断)、弹性控制(线程池控制请求)。
(2)使用方法
线程隔离、服务降级
弹性控制中使用线程隔离,服务降级处理雪崩问题。通过提供线程池,控制资源的请求数来限制访问服务,如果线程池数满,或者请求超时,就会进行降级处理并返回给用户友好的提示信息。
①:在服务调用方引入Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
②:引导类上加注解
@EnableCircuitBreaker
③:定义降级方法(局部/全局)
局部:
3.1:写降级方法
//降级方法要和被降级方法的参数列表一致,返回值类型一致
public String queryUserByIdFallBack(Integer id){
return "系统繁忙,请稍后再试";
}
3.2:在需要降级的方法上打注解
@HystrixCommand(fallbackMethod = "queryUserByIdFallBack") //用来声明一个降级逻辑的方法
全局:
3.1:写全局降级方法
// 设置全局降级方法,如果谁需要降级熔断。就在谁上指定注解
//降级方法要和被降级方法的参数列表一致 不能有参数
public String queryUserByIdFallBack(){
return "系统繁忙,请稍后再试";
}
3.2:在需要降级的方法上打注解 并指定属性
@HystrixCommand //使用了全局降级方法 在指定的controller方法上添加注解@HystrixCommand
@DefaultProperties(defaultFallback = "queryUserByIdFallBack") //全局指定默认的降级方法,Contrller类上面
服务熔断
服务熔断就是说如果请求时存在大量请求超时或者反应慢的情况,调用方会自行熔断,变为打开状态,不让请求过去,但是这个打开状态不是永久的,在打开状态后会进行5s的休眠时间,变为半打开状态,放一部分请求过去探路,如果没问题,会变为关闭状态,所有请求正常访问。
4、Feign
(1)使用场景
进一步简化,学会“伪装”,改变之前服务调用者在Controller层,这种看着很硬编码的方式,把这些地址以SpringMVC +注解的方式做到“返璞归真,回归原始”。
String url = "http://" + instance.getHost()+":"+instance.getPort()+"/provider/findById/" + id;
String url = "http://service-provider/provider/findById/" + id;
Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样
(2)使用方法
①:添加依赖(服务调用方)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
②:是否需要覆盖默认配置(比如使Feign的熔断机制生效)
feign:
hystrix:
enabled: true # 开启Feign的熔断功能
③:在启动类上添加注解
@EnableFeignClients //开启Feign功能
④:编写Fiegn的客户端,在接口上添加@FeignClient注解(以下都是以Feign的熔断机制为例)
//声明这是一个Feign客户端,类似`@Mapper`注解。同时通过`value`属性指定服务名称
//fallback 属性为熔断策略的实现类。熔断策略实现类应实现 Feign 客户端接口,并提供处理熔断逻辑的方法。
@FeignClient(value = "service-provider",fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
//把Controller中对应的方法声明放在这里
@GetMapping("/provider/findById/{id}")
User findById(@PathVariable Integer id);
}
⑤:编写熔断策略(其实就是Fiegn的客户端的一个实现类,实现具体的降级逻辑)
@Component
public class UserFeignClientFallback implements UserFeignClient{
//这里编写的是接口方法中的具体的降级逻辑
@Override
public User findById(Integer id) {
User user = new User();
user.setUsername("系统繁忙,请稍后再试");
return user;
}
}
⑥:Controller层注入并进行调用
@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
UserFeignClient userFeignClient;
public String findById(@PathVariable Integer id){
User user = userFeignClient.findById(id);
System.out.println(user);
return user.toString();
}
}
5、Zuul
(1)使用场景
- 权限认证
- 服务路由
- 负载均衡
(2)使用方法
①:搭建Zuul-server网关服务
②:引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
③:修改配置文件,配置路由规则
server:
port: 10010 #服务端口
spring:
application:
name: api-gateway #指定服务名
zuul:
routes:
service-provider: service-provider/**
service-consumer: service-consumer/**
④在启动类上加注解
@EnableZuulProxy //开启网关功能
过滤器
Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。
①:自定义过滤器 实现IZuulFilter
public abstract ZuulFilter implements IZuulFilter{
abstract public String filterType();
abstract public int filterOrder();
boolean shouldFilter();// 来自IZuulFilter
Object run() throws ZuulException;// IZuulFilter 编写过滤规则
}