当前位置: 首页 > news >正文

网站开发应聘问题开发直播app赚钱吗

网站开发应聘问题,开发直播app赚钱吗,杭州外贸网站建设,网站模板织梦免费文章目录 1 Gateway组件1.1 Gateway简介1.2 Gateway入门1.3 网关路由流程图1.4 路由工厂1.5 过滤器1.5.1 过滤器简介1.5.2 内置过滤器1.5.3 路由过滤器1.5.4 默认过滤器1.5.5 全局过滤器1.5.6 过滤器执行顺序 2 Nacos配置中心2.1 统一配置管理2.2 Nacos入门2.2.1 Nacos中添加配… 文章目录 1 Gateway组件1.1 Gateway简介1.2 Gateway入门1.3 网关路由流程图1.4 路由工厂1.5 过滤器1.5.1 过滤器简介1.5.2 内置过滤器1.5.3 路由过滤器1.5.4 默认过滤器1.5.5 全局过滤器1.5.6 过滤器执行顺序 2 Nacos配置中心2.1 统一配置管理2.2 Nacos入门2.2.1 Nacos中添加配置2.2.2 微服务集成配置中心2.2.3 读取自定义配置ValueConfigurationProperties 2.3 配置热更新2.4 配置内容共享2.5 配置优先级 3 Sentinel组件3.1 初识sentinel3.1.1 雪崩效应3.1.2 解决方案超时处理隔离处理熔断处理流量控制 3.1.3 sentinel介绍 3.2 sentinel入门3.2.1 下载sentinel3.2.2 启动sentinel3.2.3 访问sentinel3.2.4 整合sentinel 3.3 流量控制3.3.1 相关概念3.3.2 快速入门3.3.3 流控模式流控模式简介关联模式链路模式 3.3.4 流控效果warm up排队等待 3.3.5 热点参数限流配置介绍案例演示 3.4 隔离处理3.4.1 实现方式3.4.2 sentinel实现3.4.3 案例演示3.4.4 降级逻辑 3.5 熔断处理3.5.1 工作原理3.5.2 慢调用比例3.5.3 异常比例和异常数 3.6 规则持久化3.6.1 规则持久化概述3.6.2 规则持久化实战Nacos添加规则配置读取nacos规则配置 1 Gateway组件 1.1 Gateway简介 Gateway服务网关组件是我们服务的守门神所有微服务的统一入口。 网关的核心功能特性 1、请求路由 2、权限控制 3、流量监控 4、统一日志处理 架构图 权限控制网关作为微服务入口需要校验用户是是否有请求资格如果没有则进行拦截。 路由和负载均衡一切请求都必须先经过Gateway但网关不处理业务而是根据某种规则把请求转发到某个微服务这个过程叫做路由。当然路由的目标服务有多个时还需要做负载均衡。 限流当请求流量过高时在网关中按照下流的微服务能够接受的速度来放行请求避免服务压力过大。 在SpringCloud中网关的实现包括两种 1、Gateway 2、Zuul Zuul是基于Servlet的实现属于阻塞式编程。而Spring Cloud Gateway则是基于Spring5中提供的WebFlux属于响应式编程的实现具备更好的性能。 1.2 Gateway入门 下面我们就演示下网关的基本路由功能。 基本步骤如下 1、创建一个spring boot项目作为gateway引入如下依赖 !--网关-- dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId /dependency!--nacos服务发现依赖-- dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency!-- 负载均衡组件 -- dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-loadbalancer/artifactId /dependency2、编写启动类 // com.atguigu.spzx.cloud.gateway SpringBootApplication public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);} }3、在application.yml配置文件中编写基础配置和路由规则 server:port: 8888 spring:application:name: spzx-cloud-gatewaycloud:nacos:discovery:server-addr: 192.168.136.142:8848gateway:routes:- id: spzx-cloud-user # 路由id可以自定义只要唯一即可uri: lb://spzx-cloud-user # 路由的目标地址 lb就是负载均衡后面跟服务名称predicates:- Path/api/user/** # 这个是按照路径匹配只要以/user/开头就符合要求4、重启测试 重启网关访问http://localhost/api/user/findUserByUserId/1时符合/api/user/**规则 请求转发到urihttp://spzx-cloud-user/api/user/findUserByUserId/1得到了结果 1.3 网关路由流程图 整体访问流程如下所示 1.4 路由工厂 思考问题我们在配置文件中只是配置了一个访问路径的规则怎么就可以实现路由呢? 底层原理框架底层会自动读取配置文件中的内容然后通过制定的路由工厂将其转换成对应的判断条件然后进行判断。 在Gateway中提供了很多的路由工厂如下所示https://docs.spring.io/spring-cloud-gateway/docs/4.0.6/reference/html/#gateway-request-predicates-factories 大致有12个每一种路由工厂的使用Spring Cloud的官网都给出了具体的示例代码我们可以参考示例代码进行使用。以After Route Predicate Factory路由工厂举例如下所示 spring:cloud:gateway:routes:- id: spzx-cloud-useruri: lb://spzx-cloud-userpredicates:- Path/api/user/**- After2023-05-01T08:00:00.008:00 # 断言在此时间后请求才会被匹配- Before2023-05-01T09:0808:00 # 断言在此时间前请求才会被匹配- Between2023-05-01T08:00:00.008:00,2023-05-02T09:1008:00 # 断言在此时间区间内访问的请求才会被匹配- Cookieusername,atguigu # 断言请求头中携带Cookie: usernameatguigu才可以匹配- Cookieid,9527- HeaderX-Request-Id,\d # 断言请求头中要有X-Request-Id属性并且值为整数的正则表达式- MethodPOST # 断言请求方式为post方式才会被匹配- Querypwd,[a-z0-9_-]{6} # 断言请求参数中包含pwd并且值长度为6才会被匹配1.5 过滤器 1.5.1 过滤器简介 在gateway中要实现其他的功能权限控制、流量监控、统一日志处理等。就需要使用到gateway中所提供的过滤器了。过滤器可以对进入网关的请求和微服务返回的响应做处理 1.5.2 内置过滤器 spring gateway提供了31种不同的过滤器。 官网地址https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/#gatewayfilter-factories 例如 名称说明AddRequestHeader给当前请求添加一个请求头RemoveRequestHeader移除请求中的一个请求头AddResponseHeader给响应结果中添加一个响应头RemoveResponseHeader从响应结果中移除有一个响应头RequestRateLimiter限制请求的流量 在Gateway中提供了三种级别的类型的过滤器 1、路由过滤器只针对当前路由有效 2、默认过滤器针对所有的路由都有效 3、全局过滤器针对所有的路由都有效需要进行自定义 1.5.3 路由过滤器 需求给所有进入spzx-cloud-user的请求添加一个请求头Truthatguigu 实现 1、修改gateway服务的application.yml文件添加路由过滤 spring:cloud:gateway:routes:- id: spzx-cloud-useruri: lb://spzx-cloud-userpredicates:- Path/api/user/**filters:- AddRequestHeaderTruth, atguigu # 配置路由基本的过滤器给访问user微服务的所有接口添加Truth请求头当前过滤器写在spzx-cloud-user路由下因此仅仅对访问spzx-cloud-user的请求有效。 2、在spzx-cloud-user的接口方法中读取请求头数据进行测试 GetMapping(value /findUserByUserId/{userId}) public User findUserByUserId(PathVariable(value userId) Long userId , RequestHeader(name Truth)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , header);return userService.findUserByUserId(userId) ; }1.5.4 默认过滤器 如果要对所有的路由都生效则可以将过滤器工厂写到default下。格式如下 spring:cloud:gateway:routes:- id: spzx-cloud-useruri: lb://spzx-cloud-userpredicates:- Path/api/user/**default-filters:- AddRequestHeaderTruth, atguigu is good1.5.5 全局过滤器 上述的过滤器是gateway中提供的默认的过滤器每一个过滤器的功能都是固定的。但是如果我们希望拦截请求做自己的业务逻辑默认的过滤器就没办法实现。 此时就需求使用全局过滤器全局过滤器的作用也是处理一切进入网关的请求和微服务响应与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义处理逻辑是固定的而GlobalFilter的逻辑需要自己写代码实现。 需求定义全局过滤器拦截请求判断请求的参数是否满足下面条件 1、请求参数中是否有authorization 2、authorization参数值是否为admin 如果同时满足则放行否则拦截 步骤 1、定义一个类实现GlobalFilter接口 2、重写filter方法 3、将该类纳入到spring容器中 4、实现Ordered接口定义该过滤器的顺序 代码 Component public class AuthorizationFilter implements GlobalFilter , Ordered {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1、获取请求参数MultiValueMapString, String params exchange.getRequest().getQueryParams();// 2、判断是否包含authorizationString authorization params.getFirst(authorization);if(authorization null || .equals(authorization)) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED) ; // 设置一个响应状态码401return exchange.getResponse().setComplete() ; // 结束请求}// 3、校验请求参数的值是否为admin如果是放行如果不是拦截if(!admin.equals(authorization)) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED) ; // 设置一个响应状态码401return exchange.getResponse().setComplete() ; // 结束请求}// 放行return chain.filter(exchange);}Overridepublic int getOrder() {return -1;}}1.5.6 过滤器执行顺序 请求进入网关会碰到三类过滤器当前路由的过滤器、DefaultFilter、GlobalFilter 请求路由后会将当前路由过滤器和DefaultFilter、GlobalFilter合并到一个过滤器链集合中排序后依次执行每个过滤器 排序的规则是什么呢 1、按照order的值进行排序order的值越小优先级越高执行顺序越靠前。 2、路由过滤器和默认过滤器会按照order的值进行排序这个值由spring进行指定默认是按照声明顺序从1递增 3、当过滤器的order值一样时会按照 globalFilter defaultFilter 路由过滤器的顺序执行 核心源码分析org.springframework.cloud.gateway.handler.FilteringWebHandler#handle方法会加载全局过滤器与前面的过滤器合并后根据order排序组织过滤器链 public MonoVoid handle(ServerWebExchange exchange) {Route route (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);// 获取路由级别的过滤器和默认过滤器的集合ListGatewayFilter gatewayFilters route.getFilters();// 获取全局过滤器的集合ListGatewayFilter combined new ArrayList(this.globalFilters);// 将取路由级别的过滤器和默认过滤器的集合中的元素添加到全局过滤器的集合中combined.addAll(gatewayFilters);// 进行排序AnnotationAwareOrderComparator.sort(combined);if (logger.isDebugEnabled()) {logger.debug(Sorted gatewayFilterFactories: combined);}// 调用过滤器链中的filter方法return (new DefaultGatewayFilterChain(combined)).filter(exchange); }2 Nacos配置中心 Nacos除了可以做注册中心同样可以做配置管理来使用。 2.1 统一配置管理 当微服务部署的实例越来越多达到数十、数百时逐个修改微服务配置就会让人抓狂而且很容易出错。我们需要一种统一配置管理方案可以集中管理所有实例的配置。 nacos一方面可以将配置集中管理另一方可以在配置变更时及时通知微服务实现配置的热更新。 2.2 Nacos入门 2.2.1 Nacos中添加配置 在Nacos服务端创建一个配置如下所示 然后在弹出的表单中填写配置信息 2.2.2 微服务集成配置中心 微服务需要进行改造从Nacos配置中心中获取配置信息进行使用。 步骤 1、在spzx-cloud-user微服务中引入spring-cloud-starter-alibaba-nacos-config依赖 !-- nacos作为配置中心时所对应的依赖 -- dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId /dependency2、在spzx-cloud-user项目的 /src/main/resources/application.yml 配置文件中配置 Nacos Config 地址并引入服务配置 # 配置数据库的连接信息 spring:cloud:nacos:config:server-addr: 192.168.136.142:8848config:import:- nacos:spzx-cloud-user-dev.yml2.2.3 读取自定义配置 Value 通过Value注解读取自定义配置如下所示 RestController RequestMapping(value /api/user) Slf4j public class UserController {Autowiredprivate UserService userService ;Value(${pattern.dateformat})private String pattern ;GetMapping(value /findUserByUserId/{userId})public User findUserByUserId(PathVariable(value userId) Long userId , RequestHeader(name Truth)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , pattern);return userService.findUserByUserId(userId) ;}}ConfigurationProperties 也可以通过实体类配合ConfigurationProperties注解读取自定义配置代码如下所示 1、定义一个实体类代码如下所示 Data ConfigurationProperties(prefix pattern) public class PatternProperties {private String dateformat ;}2、在启动类上添加EnableConfigurationProperties注解如下所示 SpringBootApplication EnableConfigurationProperties(value { PatternProperties.class }) public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class , args) ;}}3、使用该实体类代码如下所示 RestController RequestMapping(value /api/user) Slf4j public class UserController {Autowiredprivate UserService userService ;Value(${pattern.dateformat})private String pattern ;Autowired // 注入实体类private PatternProperties patternProperties ; GetMapping(value /findUserByUserId/{userId})public User findUserByUserId(PathVariable(value userId) Long userId , RequestHeader(name Truth)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , patternProperties.getDateformat());return userService.findUserByUserId(userId) ;}}2.3 配置热更新 我们最终的目的是修改Nacos中的配置后微服务中无需重启即可让配置生效也就是配置热更新。实现配置的热更新有两种方式 方式一在Value注入的变量所在类上添加注解 RefreshScope 方式二通过实体类配合ConfigurationProperties注解读取配置信息自动支持热更新 2.4 配置内容共享 如果多个环境存在相同的配置那么此时就可以将相同的配置抽取到一个新的配置中然后在微服务中再次导入新的配置。那么此时就实现了多环境配置共享。 案例演示 1、在Nacos上创建一个不带环境的配置 2、微服务读取共享配置在实体类中添加对应的属性 Data ConfigurationProperties(prefix pattern) public class PatternProperties {private String dateformat ;private String envSharedValue ; // 读取共享配置属性}3、在微服务的配置文件中通过spring.config.import导入最新的配置 spring:config:import:- nacos:spzx-cloud-user-dev.yml- nacos:spzx-cloud-user.yml # 导入共享配置 # 项目中的配置提取时所有的环境都相同的配置我们会抽取到一个公共配置中 # 其他的不同值的配置 会创建不同命名空间、分组、环境后缀的配置文件编写配置 # 项目中可以引入公共配置当前环境需要的配置文件2.5 配置优先级 思考问题如果在application.yml文件中和Nacos配置中心中都定义了相同的配置内容那么哪一个配置的优先级较高呢? 优先级顺序Nacos配置中心的配置(后导入的配置 先导入的配置) application.yml 3 Sentinel组件 3.1 初识sentinel 3.1.1 雪崩效应 概述在微服务系统架构中中服务间调用关系错综复杂一个微服务往往依赖于多个其它微服务。一个服务的不可用导致整个系统的不可用的现象就被称之为雪崩效应。 如下图所示 当服务D出现了问题了以后调用服务D的服务A的线程就得不到及时的释放在高并发情况下随着时间的不断推移服务A的系统资源会被线程耗尽最终导致服务A出现了问题同理就会导致其他的服务也不能进行访问了。 3.1.2 解决方案 超时处理 超时处理设定超时时间请求超过一定时间没有响应就返回错误信息不会无休止等待 隔离处理 隔离处理将错误隔离在可控的范围之内不要让其影响到其他的程序的运行。 这种设计思想来源于船舱的设计如下图所示 船舱都会被隔板分离为多个独立空间当船体破损时只会导致部分空间进入将故障控制在一定范围内避免整个船体都被淹没。于此类似我们业务系统也可以使用这种思想来防止出现雪崩效应常见的隔离方式线程隔离 熔断处理 熔断处理由断路器统计业务执行的异常比例如果超出阈值则会熔断该业务拦截访问该业务的一切请求。 断路器会统计访问某个服务的请求数量异常比例如下所示 请求了三次两次出现异常一次成功。当发现访问服务D的请求异常比例过高时认为服务D有导致雪崩的风险会拦截访问服务D的一切请求形成熔断 触发熔断了以后当在访问服务A的时候就不会在通过服务A去访问服务D了立马给用户进行返回返回的是一种默认值这种返回就是一种兜底方案。这种兜底方案也将其称之为降级逻辑。 流量控制 流量控制限制业务访问的QPS(每秒的请求数)避免服务因流量的突增而故障。 限流是一种预防措施避免因瞬间高并发流量而导致服务故障进而避免雪崩。其他的处理方式是一种补救措施在部分服务故障时将故障控制在一定范围避免雪崩。 3.1.3 sentinel介绍 官网地址https://sentinelguard.io/zh-cn/ 具有的特征: 3.2 sentinel入门 3.2.1 下载sentinel sentinel管理后台下载地址https://github.com/alibaba/Sentinel/releases 下载完毕以后就会得到一个jar包 3.2.2 启动sentinel 将jar包放到任意非中文目录执行命令 java -jar sentinel-dashboard-2.0.0-alpha-preview.jar如果要修改Sentinel的默认端口、账户、密码可以通过下列配置 配置项默认值说明server.port8080服务端口sentinel.dashboard.auth.usernamesentinel默认用户名sentinel.dashboard.auth.passwordsentinel默认密码 例如修改端口 java -Dserver.port8090 -jar sentinel-dashboard-2.0.0-alpha-preview.jar3.2.3 访问sentinel 访问http://localhost:8080页面就可以看到sentinel的控制台了 需要输入账号和密码默认都是sentinel 登录后发现一片空白什么都没有 这是因为我们还没有与微服务整合。 3.2.4 整合sentinel 我们在spzx-cloud-user中整合sentinel并连接sentinel的控制台步骤如下 1、引入sentinel依赖 !--sentinel-- dependencygroupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-sentinel/artifactId /dependency2、配置控制台 修改application.yaml文件添加下面内容 spring:cloud:sentinel:transport:dashboard: localhost:8080 # 配置sentinel控制台地址3、访问spzx-cloud-user的任意接口 打开浏览器访问http://localhost:10100/api/user/findUserByUserId/1这样才能触发sentinel的监控。然后再访问sentinel的控制台查看效果 3.3 流量控制 雪崩问题虽然有四种方案但是限流是避免服务因突发的流量而发生故障是对微服务雪崩问题的预防。我们先学习这种模式。 3.3.1 相关概念 簇点链路当请求进入微服务时首先会访问DispatcherServlet然后进入Controller、Service、Mapper这样的一个调用链就叫做簇点链路。 资源簇点链路中被监控的每一个接口就是一个资源流控、熔断等都是针对簇点链路中的资源来设置的。 默认情况下sentinel会监控spring mvc的每一个端点Endpoint也就是controller中的方法因此spring mvc的每一个端点就是调用链路中的一个资源。 例如我们刚才访问的spzx-cloud-user中的UserController中的端点/api/user/findUserByUserId/{userId} 我们可以点击对应资源后面的按钮来设置规则 1、流控流量控制 2、降级降级熔断 3、热点热点参数限流是限流的一种 4、授权请求的权限控制 3.3.2 快速入门 需求给 /api/user/findUserByUserId/{userId}这个资源设置流控规则QPS不能超过 5然后测试。 步骤 1、首先在sentinel控制台添加限流规则 2、利用jmeter测试(模拟并发请求) Apache JMeter 是 Apache 组织基于 Java 开发的压力测试工具用于对软件做压力测试。 下载地址https://archive.apache.org/dist/jmeter/binaries/ 课前资料提供了编写好的Jmeter测试样例 通过如下命令打开jmeter java -jar ApacheJMeter.jar导入课前资料提供的测试样例 选择流控入门 10个线程1秒内运行完QPS是10超过了5。 选中流控入门QPS5右键运行 注意不要点击菜单中的执行按钮来运行。 点击查看结果树理想的请求执行结果应该如下所示 可以看到成功的请求每次只有5个。 注意如果测试结果不是上述情况那是因为sentinel在统计请求的时候把一部分的请求统计到了下一秒中导致的。 3.3.3 流控模式 流控模式简介 在添加限流规则时点击高级选项可以选择三种流控模式 1、直接统计当前资源的请求触发阈值时对当前资源直接限流也是默认的模式 2、关联统计与当前资源相关的另一个资源触发阈值时对当前资源限流 3、链路统计从指定链路访问到本资源的请求触发阈值时对指定链路限流 如下所示 快速入门测试的就是直接模式。 关联模式 关联模式统计与当前资源相关的另一个资源触发阈值时对当前资源限流 配置方式 语法说明对/api/user/updateUserById资源的请求进行统计当访问流量超过阈值时就对/api/user/findUserByUserId/{userId}进行限流避免影响/api/user/updateUserById资源。 使用场景比如用户支付时需要修改订单状态同时用户要查询订单。查询和修改操作会争抢数据库锁产生竞争。业务需求是优先支付和更新订单的业务因此当修改订单业务触发阈值时需要对查询订单业务限流。 案例实现 1、在UserController新建一个端点/api/user/updateUserById无需实现业务 // 修改用户数据端点 GetMapping(value /updateUserById) public String updateUserById() {return 修改用户数据成功; }2、重启服务访问对应的端点让其产生簇点链路 3、配置流控规则当/api/user/updateUserById资源被访问的QPS超过5时对/api/user/findUserByUserId/1请求限流。对哪个端点限流就点击哪个端点后面的按钮。我们是对用户查询/api/user/findUserByUserId/1限流因此点击它后面的按钮 4、在Jmeter中进行测试 选择《流控模式-关联》 可以看到1000个线程100秒因此QPS为10超过了我们设定的阈值5 查看http请求 请求的目标是/api/user/updateUserById这样这个端点就会触发阈值。但限流的目是/api/user/findUserByUserId/1我们在浏览器访问可以发现 确实被限流了。 关联流控模式的使用场景 1、两个有竞争关系的资源 2、一个优先级较高一个优先级较低 对高优先级的资源的流量进行统计当超过阈值对低优先级的资源进行限流。 链路模式 链路模式只针对从指定链路访问到本资源的请求做统计判断是否超过阈值如果超过阈值对从该链路请求进行限流。 配置方式 1、/api/user/save -- users 2、/api/user/query -- users 如果只希望统计从/api/user/query进入到users的请求并进行限流操作则可以这样配置 案例实现 1、在UserService中添加一个queryUsers方法不用实现业务 public void queryUsers(){System.err.println(查询用户); }2、在UserController中添加两个端点在这两个端点中分别调用UserService中的queryUsers方法 GetMapping(value /save) public String save() {userService.queryUsers();System.out.println(保存用户);return 订单保存成功 ; }GetMapping(value /query) public String query() {userService.queryUsers();System.out.println(查询用户);return 查询用户成功 ; }4、通过**SentinelResource**标记UserService中的queryUsers方法为一个sentinel监控的资源(默认情况下sentinel只监控controller方法) SentinelResource(users) public void queryUsers(){System.err.println(查询用户); }5、更改application.yml文件中的sentinel配置 链路模式中是对不同来源的两个链路做监控。但是sentinel默认会给进入spring mvc的所有请求设置同一个root资源会导致链路模式失效。因此需要关闭这种资源整合。 spring:cloud:sentinel:web-context-unify: false # 关闭context整合6、重启服务访问/api/user/save和/api/user/query可以查看到sentinel的簇点链路规则中出现了新的资源 7、添加流控规则 点击users资源后面的流控按钮在弹出的表单中填写下面信息 只统计从/api/user/query进入/users的资源QPS阈值为2超出则被限流。 8、jmeter测试 选择《流控模式-链路》 可以看到这里200个线程50秒内发完QPS为4超过了我们设定的阈值2。 一个http请求是访问/api/user/save 另一个是访问/api/user/query 运行测试察看结果树 访问/api/user/save,没有进行限流 访问/api/user/query,进行限流了 3.3.4 流控效果 在流控的高级选项中还有一个流控效果选项 流控效果是指请求达到流控阈值时应该采取的措施包括三种 1、快速失败达到阈值后新的请求会被立即拒绝并抛出FlowException异常是默认的处理方式 2、warm up预热模式对超出阈值的请求同样是拒绝并抛出异常但这种模式阈值会动态变化从一个较小值逐渐增加到最大阈值 3、排队等待让所有的请求按照先后次序进入到一个队列中进行排队当某一个请求最大的预期等待时间超过了所设定的超时时间时同样是拒绝并抛 出异常 warm up 阈值一般是一个微服务能承担的最大QPS但是一个服务刚刚启动时一切资源尚未初始化冷启动如果直接将QPS跑到最大值可能导致服务 瞬间宕机。 warm up也叫预热模式是应对服务冷启动的一种方案。阈值会动态变化从一个较小值逐渐增加到最大阈值。 工作特点请求阈值初始值是 maxThreshold / coldFactor, 持续指定时长(预热时间)后逐渐提高到maxThreshold值而coldFactor的默认值是3。 例如我设置QPS的maxThreshold为10预热时间为5秒那么初始阈值就是 10 / 3 也就是3然后在5秒后逐渐增长到10。 案例需求给/api/user/findUserByUserId/{userId}这个资源设置限流最大QPS为10利用warm up效果预热时长为5秒 1、配置流控规则 2、jmeter测试 选择《流控效果warm up》 QPS为10 刚刚启动时大部分请求失败成功的只有3个说明QPS被限定在3 随着时间推移成功比例越来越高 到sentinel控制台查看实时监控 排队等待 排队等待让所有的请求按照先后次序进入到一个队列中进行排队当某一个请求最大的预期等待时间超过了所设定的超时时间时同样是拒绝并抛出 异常 例如QPS 5意味着每200ms处理一个队列中的请求timeout 2000意味着预期等待时长超过2000ms的请求会被拒绝并抛出异常。 那什么叫做预期等待时长呢 比如现在一下子来了12 个请求因为每200ms执行一个请求那么 1、第6个请求的预期等待时长 200 * 6 - 1 1000ms 2、第12个请求的预期等待时长 200 * 12-1 2200ms 现在第1秒同时接收到10个请求但第2秒只有1个请求此时QPS的曲线这样的 如果使用队列模式做流控所有进入的请求都要排队以固定的200ms的间隔执行QPS会变的很平滑 平滑的QPS曲线对于服务器来说是更友好的。 案例需求给/api/user/findUserByUserId/{userId}这个资源设置限流最大QPS为10利用排队的流控效果超时时长设置为5s 1、添加流控规则 2、jmeter测试 QPS为15已经超过了我们设定的10。 运行测试用例察看结果树 全部都通过了。 再去sentinel查看实时监控的QPS曲线 QPS非常平滑一致保持在10但是超出的请求没有被拒绝而是放入队列。因此响应时间等待时间会越来越长。 3.3.5 热点参数限流 配置介绍 之前的限流是统计访问某个资源的所有请求判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求判断是否超过QPS阈值。 例如一个根据id查询商品的接口 访问/goods/{id}的请求中id参数值会有变化热点参数限流会根据参数值分别统计QPS统计结果 当id1的请求触发阈值被限流时id值不为1的请求不受影响。 配置方式(点击资源中的热点按钮) 代表的含义是对hot这个资源的0号参数第一个参数做统计每1秒相同参数值的请求数不能超过2。这种配置是对查询商品这个接口的所有商品 一视同仁QPS都限定为5。而在实际开发中可能部分商品是热点商品例如秒杀商品我们希望这部分商品的QPS限制与其它商品不一样高一 些。那就需要配置热点参数限流的高级选项了 案例演示 案例需求给/api/user/findUserByUserId/{userId}这个资源添加热点参数限流规则如下 1、默认的热点参数规则是每1秒请求量不超过2 2、给2这个参数设置例外每1秒请求量不超过4 3、给3这个参数设置例外每1秒请求量不超过10 注意事项热点参数限流对默认的spring mvc资源无效需要利用SentinelResource注解标记资源 实现步骤 1、标记资源 给UserController中的/api/user/findUserByUserId/{userId}资源添加注解 SentinelResource(hot) // 声明资源名称 GetMapping(value /findUserByUserId/{userId}) public User findUserByUserId(PathVariable(value userId) Long userId ,RequestHeader(name Truth , required false)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , patternProperties.getDateformat());return userService.findUserByUserId(userId) ; }2、热点参数限流规则 访问该接口可以看到我们标记的hot资源出现了 这里不要点击hot后面的按钮页面有BUG 点击左侧菜单中热点规则菜单 3、jmeter测试 选择《热点参数限流 QPS1》 这里发起请求的QPS为5。 包含三个请求参数分别为101 102 103运行测试程序察看结果树 | 101 | | | ---- | ------------------------------------------------------------ | | 102 | | | 103 | | 3.4 隔离处理 隔离处理将错误隔离在可控的范围之内不要让其影响到其他的程序的运行。 3.4.1 实现方式 线程隔离有两种方式实现 1、线程池隔离 2、信号量隔离sentinel默认采用 如图 线程池隔离给每个服务调用业务分配一个线程池利用线程池本身实现隔离效果 信号量隔离不创建线程池而是计数器模式记录业务使用的线程数量达到信号量上限时禁止新的请求 两者比对 线程池隔离信号量隔离线程请求线程和调用provider线程不是同一个线程请求线程和调用provider线程是同一个线程开销存在线程上下文切换开销较大不存在线程上下文切换开销较小异步支持不支持超时支持主动超时处理不支持主动超时处理 使用场景 线程池隔离请求并发量大并且耗时长(请求耗时长一般计算量大或者读数据库)采用线程池隔离策略这样的话可以保证大量的容器(tomcat)线程可用不会由于服务原因一直处于阻塞或者等待状态。 信号量隔离请求并发量大并且耗时短(请求耗时长一般计算量小或者读缓存)采用信号量隔离策略因为这类服务的返回通常会非常快不会占用容器线程太长时间而且也减少了线程切换的开销提高了缓存服务的效率。 3.4.2 sentinel实现 在添加限流规则时可以选择两种阈值类型 1、QPS就是每秒的请求数在服务之外直接进行拦截处理(类似于银行的保安) 2、并发线程数设置该资源能使用的tomcat线程数的最大值在服务之内通过指定的线程数来处理请求线程处理不过来触发限流(类似于银行业务员) 3.4.3 案例演示 需求给spzx-cloud-order服务中的UserFeignClient的查询用户接口设置流控规则线程数不能超过1然后利用jemeter测试。 步骤 1、在spzx-cloud-order微服务中添加sentinel的依赖 !--sentinel-- dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId /dependency2、feign整合sentinel # 微服务整合sentinel spring:cloud:sentinel:transport:dashboard: localhost:8080# feign整合sentinel feign:sentinel:enabled: true3、重启服务访问根据订单id查询订单接口方法产生簇点链路 4、配置隔离规则 单机阈值设置为1表示针对这个资源最多同时有1个线程进行访问。 5、为了让测试效果更加明显一点可以让访问/api/user/findUserByUserId/{userId}接口的线程主动休眠一段时间 SentinelResource(hot) GetMapping(value /findUserByUserId/{userId}) public User findUserByUserId(PathVariable(value userId) Long userId ,RequestHeader(name Truth , required false)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , patternProperties.getDateformat());try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}return userService.findUserByUserId(userId) ; }6、jmeter测试 选择《阈值类型-线程数2》 1s内发生10个请求10个请求由一个线程进行处理而一个线程处理的请求时长是1s有很大的可能一部分的请求处理不了就会报错。 查看运行结果 3.4.4 降级逻辑 上述请求失败以后直接返回返回500的错误状态码给用户 而这个错误请求并不是由于用户访问查询订单信息报错导致的而是由于根据订单查询用户时报错的。因此直接给用户返回500的错误状态码其实不太友好友好的做法当远程调用失败以后返回一个默认的用户信息给前端这种备用方案就是我们的降级方案。 实现步骤 1、在spzx-feign-api模块中定义一个类让其实现UserFeignClient接口重写queryById方法在该方法中编写降级逻辑 // com.atguigu.spzx.cloud.feign.fallback; Slf4j public class UserFeignClientFallback implements UserFeignClient {Overridepublic User queryById(Long userId) {log.info(UserFeignClientFallback...queryById...方法执行了...);return new User();}}2、在UserFeignClient接口中注册配置该降级类 FeignClient(value spzx-cloud-user, fallback UserFeignClientFallback.class) public interface UserFeignClient {GetMapping(/api/user/findUserByUserId/{userId})public abstract User queryById(PathVariable(userId) Long userId) ; // 根据userId查询用户信息的接口方法}3、把该降级类纳入到spring容器中 方案一在spzx-cloud-order的启动类上通过Import注解进行导入 方案二使用Spring Boot3的自动化配置原理完成 4、重启服务重新配置隔离规则并进行测试 此时发现所有请求都是成功的但是有一部分的用户数据为空。 3.5 熔断处理 3.5.1 工作原理 熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、异常数、慢请求比例如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求而当服务恢复时断路器会放行访问该服务的请求。 断路器控制熔断和放行是通过状态机来完成的 状态机包括三个状态 1、closed关闭状态断路器放行所有请求并开始统计异常比例、异常数、慢请求比例。超过阈值则切换到open状态 2、open打开状态服务调用被熔断访问被熔断服务的请求会被拒绝快速失败直接走降级逻辑。Open状态5秒后会进入half-open状态 3、half-open半开状态放行一次请求根据执行结果来判断接下来的操作。 ① 请求成功则切换到closed状态 ② 请求失败则切换到open状态 断路器熔断判断策略有三种慢调用、异常比例、异常数 3.5.2 慢调用比例 慢调用业务的响应时长RT大于指定时长的请求认定为慢调用请求。sentinel会统计指定时间内请求数量超过设定的最小数量的请求并且慢调用比例的比例。 如果慢调用比例大于设定的阈值则触发熔断。 例如下述配置 含义RT超过50ms的调用是慢调用统计最近10000ms内的请求如果请求量超过5次并且慢调用比例不低于0.4则触发熔断熔断时长为5秒。 然后进入half-open状态放行一次请求做测试。 案例演示 需求给 UserFeginClient的查询用户接口设置降级规则慢调用的RT阈值为50ms统计时间为1秒最小请求数量为5失败阈值比例为0.4熔断时长为5s 1、修改spzx-cloud-user中的/api/user/findUserByUserId/{userId}这个接口的业务。通过休眠模拟一个延迟时间 SentinelResource(hot) GetMapping(value /findUserByUserId/{userId}) public User findUserByUserId(PathVariable(value userId) Long userId ,RequestHeader(name Truth , required false)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , patternProperties.getDateformat());try {TimeUnit.MILLISECONDS.sleep(60); // 休眠60ms} catch (InterruptedException e) {throw new RuntimeException(e);}return userService.findUserByUserId(userId) ; }此时orderId101的订单关联的是id为1的用户调用时长为60ms 2、设置熔断规则 下面给feign接口设置降级规则 超过50ms的请求都会被认为是慢请求。 3、测试 在浏览器访问http://localhost:10200/api/order/findOrderByOrderId/102快速刷新5次以上可以发现 在浏览器访问http://localhost:10200/api/order/findOrderByOrderId/103竟然也被熔断了! 3.5.3 异常比例和异常数 异常比例或异常数统计指定时间内的调用如果调用次数超过指定请求数并且出现异常的比例达到设定的比例阈值或超过指定异常数则触发熔断。 例如一个异常比例设置 配置示例含义异常比例统计最近1000ms内的请求如果请求量超过5次并且异常比例不低于0.4则触发熔断。异常数统计最近1000ms内的请求如果请求量超过5次并且异常比例不低于2次则触发熔断。 案例演示 需求给 UserFeginClient的查询用户接口设置降级规则统计时间为1秒最小请求数量为5异常失败阈值比例为0.4熔断时长为5s。 步骤 1、修改spzx-cloud-user中的/api/user/findUserByUserId/{userId}这个接口的业务。手动抛出异常以触发异常比例的熔断 SentinelResource(hot) GetMapping(value /findUserByUserId/{userId}) public User findUserByUserId(PathVariable(value userId) Long userId ,RequestHeader(name Truth , required false)String header) {log.info(UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} , header , patternProperties.getDateformat());if(userId 2) {throw new RuntimeException(手动抛出异常触发异常比例熔断规则) ;}return userService.findUserByUserId(userId) ; }也就是说id为2时就会触发异常。 2、设置熔断规则 下面给feign接口设置降级规则 在5次请求中只要异常比例超过0.4也就是有2次以上的异常就会触发熔断。 3、测试 在浏览器快速访问http://localhost:10200/api/order/findOrderByOrderId/102快速刷新5次以上触发熔断 此时我们去访问本来应该正常的103 3.6 规则持久化 3.6.1 规则持久化概述 默认情况下sentinel没有对规则进行持久化让对服务进行重启以后Sentinel规则将消失生产环境需要将配置规则进行持久化 持久化思想 将限流配置规则持久化进Nacos保存只要刷新spzx-cloud-order某个rest地址sentinel控制台的流控规则就能看到只要Nacos里面的配置不删除针对spzx-cloud-order上Sentinel上的流控规则持续有效 3.6.2 规则持久化实战 Nacos添加规则配置 在nacos配置中心中添加规则配置 规则配置内容如下所示 [{resource: /testA,limitApp: default,grade: 1,count: 1,strategy: 0,controlBehavior: 0,clusterMode: false } ]规则说明 读取nacos规则配置 微服务可以从nacos配置中心读取规则配置信息然后进行使用。 具体步骤如下所示 1、在spzx-cloud-order微服务中的pom.xml文件中添加如下依赖 dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId /dependency2、在spzx-cloud-order微服务的application.yml文件添加如下配置 # 配置数据库的连接信息 spring:cloud:sentinel:transport:dashboard: localhost:8080datasource:ds1:nacos:serverAddr: 192.168.136.142:8848dataId: sentinel-rulesgroupId: DEFAULT_GROUPdataType: jsonruleType: flow3、重启spzx-cloud-order微服务访问任意一个接口此时就可以在sentinel的控制台看到对应的流控规则了 4、重新启动spzx-cloud-order微服务服务再看sentinel控制台是否还存在该规则信息 如果没有稍等一会儿,多次调用 http://localhost:10200/api/order/findOrderByOrderId/101重新配置出现了持久化验证通过
http://www.ho-use.cn/article/10819442.html

相关文章:

  • 高端企业网站建设核心合肥专业手机网站制作价格
  • 南昌本地生活网站有哪些wordpress怎么重新初始化
  • 昆明网站做的好的公司简介商务网站建设公司排名
  • wordpress dz 整合兰州做系统优化的公司
  • 德州做网站的关键词排名优化公司推荐
  • 郑州正规网站设计价格友情链接怎么连
  • 苏州高端建站公司wordpress将404跳转主页
  • 国外网站设计师wordpress 分割线
  • 外贸网站注册wordpress 多重筛选模板
  • 广州贝勤网络科技有限公司女装标题优化关键词
  • 门户网站建设询价函公司网站地址
  • 怎么看公司网站做的好不好哦襄阳住房和城乡建设局网站首页
  • 金华兰溪网站建设开发一个软件需要什么技术
  • 金融网站设计方向广州十大科技公司
  • 新建网站网络空间长春网站制作诚推源晟
  • 怎么建立一个网站放图片c++软件开发需要学什么
  • 长沙建个网站一般需要多少钱专门做灯具海报的网站
  • 怎么做hs网站智慧治水网站系统建设
  • 网站集群建设是广西住房建设厅网站
  • 公司网站后台是什么怎样在阿里巴巴做网站
  • WordPress微博qq登录插件北京网站优化解决方案
  • 建立一个网站 优帮云西安建站套餐
  • 沈阳网站制作建设辽阳专业网站开发公司
  • 直播视频网站深圳seo优化排名优化
  • 网站逻辑结构优化苏州设计网站
  • 十大免费货源网站免费版本湖南网站营销推广设计
  • 网站开发有名的公司装饰工程造价
  • 苏州建设厅网站首页网络广告人社区
  • 个人网站是请人做还是自己编写好做外贸在哪个网站比较好
  • 电子商务网站商品怎么来wordpress 色