配置中心(SpringCloud config)
注册中心(SpringCloud netflix eurka)
API网关(SpringCloud netflix zuul)
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
SpringCloud Alibaba Github地址
SpringCloud的几大缺点
1.部分组件停止维护和更新给开发带来不便(eurka)
2.部分环境搭建复杂,没有完善的可视化界面,需要大量的二次开发
3.配置复杂难上手部分配置差别较细
SpringCloud Alibaba的优点
阿里使用的组件经过实际考验,性能强悍,设计合理,开源成套的产品搭配完善的可视化界面给开发和运维带来极大便利,且搭建简单,学习难度低。
spring-cloud-alibaba版本的选择,见
SpringCloud Alibaba Github地址
在父项目pom文件中引入一
<!-- dependencyManagement实际不引用依赖只提供版本号与scope信息 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
application:
name: wwmall-product
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
#该文件会优先于application.yml/application.properties加载
spring.application.name=wwmall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
/*---------------------测试代码start----------------------------------------------*/
@Value("${coupon.user.name}")
private String username;
@Value("${coupon.user.age}")
private Integer age;
@RequestMapping("/test")
public R test(){
return R.ok().put("username",username).put("age",age);
}
注:如果配置中心和当前应用的配置文件中由相同的项,则优先使用配置中心中的配置信息
#指定使用的命名空间
spring.cloud.nacos.config.namespace=ad0d2241-8cfc-4c30-a83f-1bd2c72eb62d
#指定使用的命名空间
spring.cloud.nacos.config.namespace=ad0d2241-8cfc-4c30-a83f-1bd2c72eb62d
#指定使用的分组
spring.cloud.nacos.config.group=dev
本项目采用:每个微服务创建自己的命名空间,使用配置分组区分环境(desv,test,prod)
配置文件不会全写在application.yml中会根据配置项分出多个配置集,我们关心在nacos中如何加载多个配置集
将配置文件拆分成多个datasource.yml,mybatis.yml,other.yml并在配置中心创建对应的配置集
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
spring.cloud.nacos.config.extension-configs[0].group=dev
#开启动态刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true
spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml
spring.cloud.nacos.config.extension-configs[1].group=dev
spring.cloud.nacos.config.extension-configs[1].refresh=true
spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true
https://www.cnblogs.com/larscheng/p/11422909.html
熔断
降级
两者相同点
两者不同点
限流
对打入服务的请求流量进行控制,使服务能承担不超过自己的流量压力
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
官方文档 https://github.com/alibaba/spring-cloud-alibaba/wiki
整合springboot/springcolud https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
控制台
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
下载,启动,配置控制台
下载地址 https://github.com/alibaba/Sentinel/releases 命令java -jar 启动
配置控制台
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
在控制台设置流控设置即可,设置的留空规则是保存在内存中的,重启就会失效
两个问题
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.修改springboot配置
#允许 Endpoints 的访问。
management.endpoints.web.exposure.include=*
@RestController
public class TestController {
// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
@SentinelResource(blockHandler = "blockHandlerForGetUser", fallback = "blockHandlerForGetUser")
@RequestMapping("/hello")
public String hello(String id) {
return "Hello Sentinel";
}
public String blockHandlerForGetUser(String id,BlockException exception) {
System.out.println(id+"--------------------");
return id+"访问频繁...";
}
}
流控模式:链路 假设现在需要流控的资源名C,设置A为请求入口,有一个请求A调用了B调用了C,那么只有请求只有入口为A落到C的请求才被流控,从其他入口调用C都不会被流控
流控模式:关联 当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。流控资源为C 关联资源为A,当C被流控时也流控A
使用sentinel来保护feign远程调用,熔断
调用方的熔断保护
引入依赖spring-cloud-starter-alibaba-sentinel,spring-cloud-starter-openfeign
配置文件配置:feign.sentinel.enabled=true
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
调用方控制台手动指定远程服务的降级策略,远程服务被降级处理会触发我们的熔断回掉方法
超大流量的时候必须牺牲一下远程服务,在服务的提供方指定降级策略.提供方是在执行方法,但是执行自己的业务逻辑,返回的是默认的降级数据(限流的数据)
1.抛出异常的方式定义资源
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
// 被保护的业务逻辑
// do something here...
} catch (BlockException ex) {
// 资源访问阻止,被限流或被降级
// 在此处进行相应的处理操作
}
2.注解方式定义资源
注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。请注意 blockHandler 和 fallback 函数的形式要求,https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81
// 原本的业务方法.
@SentinelResource(blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
throw new RuntimeException("getUserById command failed");
}
// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(String id, BlockException ex) {
return new User("admin");
}
引入依赖(sentinel与网关的整合版本与cloud alibaba吻合)-提供了自动配置,官方文档给的依赖还需要编写配置类
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
可以在配置文件中配置被限流降级的回调信息
使用代码方式编写回调操作
@Configuration
public class SentinelGatewayConfig {
public SentinelGatewayConfig(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Mono<ServerResponse> mono = ServerResponse.ok().body(Mono.just("网关限流降级"), String.class);
return mono;
}
});
}
}
https://www.jianshu.com/p/609961eb6a6e
Feign是声明式的Http客户端,它让微服务之间的调用变得更简单了,Fegin提供了Http请求的模板,通过编写简单的接口和插入注解,就可以定义好Http请求的参数、格式、地址等信息。
Spring Cloud Fegin集成了Ribbon(负载均衡),可在让我们不在显式的使用这个组件。
Spring Cloud openFegin在NetfilxFeign基础上扩展了对SpringMVC注解的支持,在其实现下我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了Spring Cloud Ribbon自行封装服务调用客户端的开发量。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
模仿会员(wwmall-member)模块调用优惠券(wwmall-coupon)模块
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@RequestMapping("/member-coupon/couponList")
public R getCouponListByMemberId(String memberName){
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("五折优惠.....");
return R.ok().put("memberName",memberName).put("couponEntity",Arrays.asList(couponEntity));
}
package com.walkwind.wwmall.member.feign;
@FeignClient("wwmall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member-coupon/couponList")
public R getCouponListByMemberId(String memberName);
}
@RestController
@RequestMapping("member/member")
public class MemberController {
@Autowired
private MemberService memberService;
@Autowired
CouponFeignService couponFeignService;
@RequestMapping("/getCouponList")
public R getCouponList(){
R coupon = couponFeignService.getCouponListByMemberId("张三");
return coupon;
}
@SpringBootApplication
@EnableDiscoveryClient
//明确告诉fegin远程调用接口处在哪个包下,不配置的话会自动扫描所有标注了@FeignClient("wwmall-coupon")的接口
@EnableFeignClients(basePackages="com.walkwind.wwmall.member.feign")
public class WwmallMemberApplication {
public static void main(String[] args) {
SpringApplication.run(WwmallMemberApplication.class, args);
}
}
登录后远程调用请求头数据cookie丢失
解决方法:fegin在调用之前要构造请求,调用很多的拦截器,我们可以加上fegin远程调用的拦截器在请求进入后,获取请求头数据,将请求头放入新的requestTemplate中。RequestContextHolder使用ThreadLocal去获取原请求上下文信息
fegin异步情况丢失上下文问题
解决方法
在主方法中获取老请求的请求头数据,在创建的每个子线程类中为请求头放入数据
1.简介
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制。springcloud gateway作为springcloud官方推出的第二代网关框架,取代了zuul网关。
2.概念
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。
3.工作原理
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
4.使用gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.walkwind.wwmall</groupId>
<artifactId>wwmall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
spring:
application:
name: wwmall-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
4.配置文件中配置,配置中心信息及使用的命名空间信息
bootstrap.properties
spring.application.name=wwmall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=ac252e0f-5dc4-4a9c-9175-08937b6ddcd9
spring.cloud.nacos.config.name=wwmall-gateway.yml
spring.cloud.nacos.config.group=dev
5.配置网关路由信息
spring:
cloud:
nacos:
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com/
predicates:
- Path=/baidu
- id: qq_route
uri: https://www.qq.com
predicates:
- Path=/qq
更多路由配置参考说明文档
官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.2.2.RELEASE/reference/html/#introduction