SpringCloudAlibaba 技术栈—Sentinel

news2025/1/3 4:44:21

1、什么是sentinel?

Sentinel是一个用于微服务架构的流量管理和控制系统,它通过限制和控制进入系统的流量,来保护系统免受过载和故障的影响,确保服务的稳定性。简而言之,它就是一个帮助微服务在高负载情况下也能稳定运行的工具。在分布式系统中,服务之间的相互调用会生成分布式流量。如何通过组件进行流量防护,并有效控制流量,是分布式系统的技术挑战之一。

什么是服务雪崩

假设我有一个微服务系统,这个系统内包含了 ABCD 四个微服务,这四个服务都是以集群模式构建的。

 现在因为访问人数太多了,服务D堵住了,用户调用服务D没反应了。突然D死机了引发一系列的问题,这就是服务雪崩。

解决方案

 Sentinel 服务容错的思路

Sentinel 是 Spring Cloud Alibaba 的⼀款服务容错组件,我们也经常把它叫做“防流量哨 兵”。它是阿里巴巴双十一促核心场景的保护神,内置了丰富的服务容错应用场景。它以流 量作为切入点,通过各种内外防控手段达到维持服务稳定性的目的。

 在 Sentinel 中,我们可以采用降级和熔断的方式处理内部的异常。 所谓降级,是指当服务调用发生了响应超时、服务异常等情况时,我们在服务内部可以执行一段“降级逻辑”,说人话就是让用户等一下。

而所谓熔断,是指当异常调用量达到一定的判定条件,比如在异常降级和慢调用请求的比例达到⼀个阈值、窗口时间内降级请求达到⼀定数量的情况下,微服务在一段时间内停止对⽬标服务发起调用,所有来访请求直接执行降级逻辑。所以,熔断是“多次服务调用异常”累积的结果。

限流是流量整形流控方案的一种。在 Sentinel 中我们可以根据集群的处理能力,为每个服务设置⼀个限流规则,从 QPS 维度或者并发线程数的维度控制外部的访问流量。⼀旦访问量超过阈值,后续的请求就会被 “fast fail”,这是最为常用的⼀种限流手段。 

Sentinel 基本概念

资源

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。 

规则

围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

Sentinel 的主要特性

特性:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 分为两个部分

控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。

核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

注意:

Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果。

 Sentinel 是如何工作的

Sentinel 的主要工作机制如下:

  • 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
  • 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
  • Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。

Sentinel 与 Hystrix、resilience4j 的对比

SentinelHystrixresilience4j
隔离策略信号量隔离(并发线程数限流)线程池隔离/信号量隔离线程池隔离/信号量隔离
熔断降级策略基于响应时间、异常比率、异常数基于异常比率基于异常比率、响应时间
实时统计实现滑动窗口(LeapArray)滑动窗口(基于 RxJava)Ring Bit Buffer
动态规则配置支持多种数据源支持多种数据源有限支持
扩展性多个扩展点插件的形式接口的形式
基于注解的支持支持支持支持
限流基于 QPS,支持基于调用关系的限流有限的支持Rate Limiter
流量整形支持预热模式、匀速器模式、预热排队模式不支持简单的 Rate Limiter 模式
系统自适应保护支持不支持不支持
控制台提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等简单的监控查看不提供控制台,可对接其它监控系统

 2、安装Sentinel控制台

可以从Releases · alibaba/Sentinel · GitHub下载最新版本的控制台 jar 包。

后台启动 Sentinel 控制台

注意:

启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

nohup java -server -Xms64m -Xmx256m -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=192.168.66.100:8080-Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar >> /opt/sentinel.log 2>&1 &

 访问 Sentinel 控制台

在浏览器输入http://192.168.66.100:8080即可,登录用户名密码都是sentinel。

3、将应用接入Sentinel

创建testSentinel父项目。添加依赖。

  <dependencies>


      <!-- SpringCloud 微服务 -->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>


      <!-- SpringCloud Alibaba 微服务 -->
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>


      <!-- SpringBoot 依赖配置 -->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>

创建子模块pay-service.添加依赖。

    <dependencies>

        <!--nacos服务注册中心,主要是为了实现授权服务的-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--springboot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--借用监控开放端口-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--lombok注解-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        
    </dependencies>

创建配置文件application.yml

spring:
  application:
    name: pay-service
  cloud:
#Sentinel 控制台地址
    sentinel:
      transport:
        dashboard: 192.168.66.100:8080
#      关闭context整合
      web-context-unify: false
    # nacos地址,主要是实现授权服务的
    nacos:
      discovery:
        server-addr: 192.168.66.100:8848
server:
  port: 8081

创建启动类

@SpringBootApplication
@EnableDiscoveryClient
public class payServiceApplication
{
    public static void main( String[] args )
    {
        SpringApplication.run(payServiceApplication.class, args);
    }
}

编写测试controller

@RestController
public class payController {

    /*测试*/
    @GetMapping("/testA")
    public String testA(){
        return "testA";
    }
}

查看sentinel控制台

注意:

Sentinel采用懒加载,发送一次请求即可localhost:8081/testA。

发送http://192.168.66.100:8080打开面板。

4、流量控制

流量控制就是:监控应用流量的 QPS 或并发线程数,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

流量控制设计理念

流量控制有以下几个角度:

  • 资源的调用关系:例如资源的调用链路,资源和资源之间的关系;
  • 运行指标:例如 QPS、线程池、系统负载等;
  • 控制的效果:例如直接限流、冷启动、排队等。

为/testA资源设置流控模式

sentinel默认设置controller层的接口为资源。

表示1秒钟内查询1次就ok,若超过1次,就直接快速失败,报默认错误。 

参数:

  • 资源名

        其实就是我们请求的资源路径

  • 针对来源

        这个是此流控规则对应那些微服务进行流控管理,一般填写调用方的微服务名称,多个用","分割

  • 阈值类型

        一般有2中类型,QPS(每秒的最大请求数2)和线程数(并发线程数)

  • 单机阈值

        单机状态下的最大限制值

  • 是否集群

根据实际情况选择

  • 直接

        直接作用于当前资源,如果访问压力大于某个阈值,后续请求将被直接拦下来;

  • 关联

        统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流

  • 链路

        当指定链路上的访问量⼤于某个阈值时,对当前资源进⾏限流,这⾥的“指定链 路”是细化到 API 级别的限流维度

  • 快速失败

        默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException

  • Warm Up

        即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压。

  • 排队等待

        匀速排队方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法 。这种方式主要用于处理间隔性突发的流量。

流控模式之直接模式

当 QPS 超过某个阈值的时候,则采取措施进行流量控制。

注意:

若使用除了直接拒绝之外的流量控制效果,则调用关系限流策略(strategy)会被忽略。

一直点刷新出现这个,这就说明配置生效啦。

流控模式之关联模式

当关联的资源达到阈值时,就限流自己。

流控模式之链路模式

假设有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求流控,并设置限流。

创建PaymentService类并添加一个queryGoods方法:

@Service
public class goodService {

    /**
     * @SentinelResource表示该资源受sentinel监控
     * @return
     */
    @SentinelResource("/goods")
    public String queryGoods(){
        return "the information of goods";
    }
}

默认情况下,OrderService中的方法是不被Sentinel监控的,需要我们自己通过注解来标记要监控的方法。给OrderService的queryGoods方法添加@SentinelResource注解

 控制层创建方法

@GetMapping("/save")
public String saveOrder() {
  // 查询商品
  orderService.queryGoods();
  // 查询订单
  System.err.println("新增订单");
  return "新增订单成功";
}

重启服务,访问query和save,可以查看到sentinel的簇点链路规则中,出现了新的资源。

点击goods资源后面的流控按钮,在弹出的表单中填写下面信息

 流控效果之预热

预热:项目刚开始上线的时候访问数量很大,缓存很少,数据库压力很大。慢慢把流量开大。

给/payment/index这个资源设置限流,最大QPS为10,利用warm up效果,预热时长为5秒。

5秒钟之内将流量慢慢增大到10

QPS为10.刚刚启动时,大部分请求失败,成功的只有3个,说明QPS被限定在3,随着时间推移,成功比例越来越高。

热点参数限流

什么是热点? 热点即经常访问的数据

例子:

手机热点: 华为手机、苹果手机等

化妆品热点: 迪奥口红、香奈儿香水等

创建GoodsController

@RestController
public class GoodsController {

    @SentinelResource("hot")  //热点资源标记
    @GetMapping("/getGood")
    public String getGoods(String goodName){
        return goodName;
    }

}

热点参数限流规则

jemter测试:

参数是口红的话正好是10个:

线程隔离

限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。

假设1000个用户访问商品服务,但是出现了堵塞,请求迟迟没有返回,将用户服务的资源消耗完了;但是又有些请求向访问支付服务和地址服务等其他的服务,因为线程都用完了,因此造成其他服务不可访问。造成了服务雪崩。我们为每个服务创建个线程池, 只要用户想请求商品服务就需要从商品服务的线程池获取线程才能访问商品服务,这样就不会抢占其他服务的线程了。如果线程池的线程用完了就被限流了。

 熔断降级

熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。

就是家里的保险丝,电路出问题了保险丝就烧断了。

断路器控制熔断和放行是通过状态机来完成的

状态机包括三个状态:

  • closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态。
  • open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态5秒后会进入half-open状态
  • half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。 请求成功:则切换到closed状态 请求失败:则切换到open状态

熔断降级策略

慢调用

业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。

controller模拟慢调用

    @GetMapping("/testC")
    public String testC(Integer id) throws InterruptedException {
        if (id == 1){
            //模拟异常睡眠两秒钟
            Thread.sleep(2000);
        }
        return "testC";
    }

超过50ms的请求都会被认为是慢请求,当异常比例达到百分之40,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了。过5秒钟由断路器又打开状态变为半开状态放一部分请求进来。 

未使用Jemeter情况下测试/testC接口

 使用Jemeter情况下测试/testC接口

 后续我停止Jmeter,没有这么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK。

异常比例

统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。

当资源每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态。异常比率的阈值范围是 [0.0,1.0]。

/**
   * 测试异常比例
   * RT 平均响应时间
   * @return
   */
  @GetMapping("testD")
  public String testD(Integer id)  {
    if (id == 1){
      throw new RuntimeException("故意抛出异常,触发异常比例熔断。");
     }
    return "testD";
   }

在5次请求中,只要异常比例超过0.4,也就是有2次以上的异常,就会触发熔断

发送请求localhost:8001/testD?id=2

异常数

当资源近1分钟的异常数目超过阈值之后会进行熔断。

    /*
     * 测试异常数
     */
    @GetMapping("/testF")
    public String testF()
    {
        int age = 10/0;
        return "------testF 测试异常数";
    }

请求http://localhost:8081/testF,第一次访问绝对报错,因为除数不能为零, 我们看到error窗口

 

但是达到5次报错后,进入熔断后降级。

授权规则

授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。

  • 白名单:来源(origin)在白名单内的调用者允许访问
  • 黑名单:来源(origin)在黑名单内的调用者不允许访问

主要是对不走网关的请求的限制。只要请求走网关就会加上权限,不走网关就没权限,无法访问微服务。

我们允许请求从gateway到payment服务,不允许浏览器访问payment,那么白名单中就要填写网关的来源名称(origin)

@RestController
@RequestMapping("/pay")
public class GoodsController {

    @GetMapping("/auth")
    public String auth()
    {
        return "auth";
    }
    

}

添加一个解析请求的类 

/*获取origin,如果是从网关过来的请求,网关会给请求加上个请求头origin*/
@Component
public class getOrigin implements RequestOriginParser {

    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String origin = httpServletRequest.getHeader("origin");
        if (StringUtils.isEmpty(origin)) {
            return "origin is blank";
        }
        return origin;
    }
}

注意:

这个方法的作用就是从request对象中,获取请求者的origin值并返回。默认情况下,sentinel不管请求者从哪里来,返回值永远是default,也就是说一切请求的来源都被认为是一样的值default。因此,我们需要自定义这个接口的实现,让不同的请求,返回不同的origin。

 先访问一下:localhost:8081/auth

再配置sentinel对/auth资源的授权。

不走网关再访问一下,被拦截住了。

打开Higress网关

systemctl start docker

docker ps -a

docker start b2

访问Higress

先创建路由

添加header设置

只要是通过网关的请求都会被添加一个origin=getway的参数。

走网关访问,没被拦截住。

系统自适应限流

这是个全局概念就是全部的资源作限流。

引入系统自适应限流的主要的目的

  • 保证系统不被拖垮
  • 在系统稳定的前提下保证系统的吞吐量。
系统规则

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5

查看cpu核数

cat /proc/cpuinfo | grep "processor" | wc -l

  • CPU usage:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。

top  查看cup使用情况

  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

5、SentinelResource注解配置详解之只配置fallback

服务降级功能,但是只是限制后,返回不可控的结果肯定是不行的,我们还要保证调用者在调用那些被限制的服务时候,不管是不是被限制,都要让他们拿到一个合理的结果,而不是扔回去一个异常就完事了。

Sentinel提供了这样的功能,让我们可以另外定义一个方法来代替被限制或异常服务返回数据,这就是fallback和blockHandler

  • fallback:针对Java本身出现的异常进行处理的对应属性。
  • blockHandler:针对违反Sentinel控制台配置规则时触发BlockException异常时对应处理的属性

@SentinelResource注解用于定义资源,并提供可选的 BlockException 异常处理(仅处理Sentinel控制台配置相关异常) 和 fallback 配置项(运行时异常以及自定义异常)。

    @GetMapping("/testA")
    public String testA(Integer id){
        if(id==1){
            throw new RuntimeException("异常");
        }
        return "testA";
    }
}

不配置fallback之前

    @GetMapping("/testA")
    @SentinelResource(value = "testB",fallback = "testB")
    public String testA(Integer id){
        if(id==1){
            throw new RuntimeException("异常");
        }
        return "testA";
    }

    /*testA出现异常后调用这个方法*/
    public String testB(Integer id,Throwable throwable){
        return "业务繁忙,请稍等( ̄︶ ̄)↗ ";
    }
}

fallback中的参数名称就是testB方法名称。

测试一下:

可以单独创建个类或者是package专门存放这些fallback的方法。

package com.zj.fallback;

public class payFallBack {

    /*testA出现异常后调用这个方法*/
    public static String testA(Integer id,Throwable throwable){
        return "业务繁忙,请稍等( ̄︶ ̄)↗ ";
    }

}
    @GetMapping("/testA")
    @SentinelResource(value = "testA",fallback = "testA",fallbackClass = payFallBack.class)
    public String testA(Integer id){
        if(id==1){
            throw new RuntimeException("异常");
        }
        return "testA";
    }

推荐使用外置的方法,更有条理。 

效果是一样的。

6、SentinelResource配置详解之只配置blockHandler

    @GetMapping("block")
    public String block(Integer id) {
        if (id==1){
            System.out.println(1/0);
        }
        return "block";
     }

先请求一下:localhost:8081/pay/block?id=2

再配置熔断规则:

出现熔断:

package com.zj.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;



@Service
public class blockHandler {

    /*block出现异常后调用这个方法*/
    public static String block(Integer id, BlockException throwable){
        return "业务繁忙,请稍等>﹏< ";
    }

}

 

    @SentinelResource(value = "block",blockHandlerClass = blockHandler.class,blockHandler = "block")
    @GetMapping("block")
    public String block(Integer id) {
        if (id==1){
            System.out.println(1/0);
        }
        return "block";
     }
    }

 

7、SentinelResource配置详解之fallback和blockHandler都配置

    @SentinelResource(value = "test",blockHandlerClass = blockHandler.class,blockHandler = "block",
                        fallbackClass = payFallBack.class,fallback = "test")
    @GetMapping("test")
    public String test(Integer id) {
        if (id==1){
            System.out.println(1/0);
        }
        return "test";
    }

没有出现熔断异常之前是fallback处理,出现熔断就是blockHander处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初学STM32 ---高级定时器互补输出带死区控制

互补输出&#xff0c;还带死区控制&#xff0c;什么意思&#xff1f; 带死区控制的互补输出应用之H桥 捕获/比较通道的输出部分&#xff08;通道1至3&#xff09; 死区时间计算 举个栗子&#xff08;F1为例&#xff09;&#xff1a;DTG[7:0]250&#xff0c;250即二进制&#x…

RoboMIND:多体现基准 机器人操纵的智能规范数据

我们介绍了 RoboMIND&#xff0c;这是机器人操纵的多体现智能规范数据的基准&#xff0c;包括 4 个实施例、279 个不同任务和 61 个不同对象类别的 55k 真实世界演示轨迹。 工业机器人企业 埃斯顿自动化 | 埃夫特机器人 | 节卡机器人 | 珞石机器人 | 法奥机器人 | 非夕科技 | C…

Hadoop HA安装配置(容器环境),大数据职业技能竞赛模块A平台搭建,jdk+zookeeper+hadoop HA

HA概述 &#xff08;1&#xff09; 所谓HA&#xff08;High Availablity&#xff09;,即高可用&#xff08;7*24小时不中断服务&#xff09;。 &#xff08;2&#xff09; 实现高可用最关键的策略是消除单点故障&#xff0c;HA严格来说应该分为各个组件的HA机制&#xff0c;H…

国产文本编辑器EverEdit - 如何让输出窗口的日志具有双击跳转到文件指定行的功能

1 开发参考&#xff1a;编写脚本时如何向输出窗口打印可跳转到文件位置的日志 1.1 应用场景 编写脚本时&#xff0c;有时对文本进行分析&#xff0c;需要将提示信息打印到输出窗口&#xff0c;同时希望将文本的行、列信息也打印在日志中&#xff0c; 最好是双击日志信息可以跳…

《云原生安全攻防》-- K8s安全配置:CIS安全基准与kube-bench工具

在本节课程中&#xff0c;我们来了解一下K8s集群的安全配置&#xff0c;通过对CIS安全基准和kube-bench工具的介绍&#xff0c;可以快速发现K8s集群中不符合最佳实践的配置项&#xff0c;及时进行修复&#xff0c;从而来提高集群的安全性。 在这个课程中&#xff0c;我们将学习…

3、redis的集群模式

主从模式 哨兵模式 集群 主从模式&#xff1a;这是redis高可用的基础&#xff0c;哨兵模式和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的&#xff0c;主负责写入&#xff0c;然后把写入的数据同步到从&#xff0c; 从节点只能读不能写&#xff0c;rea…

计算机图形学知识点汇总

一、计算机图形学定义与内容 1.图形 图形分为“图”和“形”两部分。 其中&#xff0c;“形”指形体或形状&#xff0c;存在于客观世界和虚拟世界&#xff0c;它的本质是“表示”&#xff1b;而图则是包含几何信息与属性信息的点、线等基本图元构成的画面&#xff0c;用于表达…

自动化测试模型(一)

8.8.1 自动化测试模型概述 在自动化测试运用于测试工作的过程中&#xff0c;测试人员根据不同自动化测试工具、测试框架等所进行的测试活动进行了抽象&#xff0c;总结出线性测试、模块化驱动测试、数据驱动测试和关键字驱动测试这4种自动化测试模型。 线性测试 首先&#…

医疗数仓数据仓库设计

医疗数仓数据仓库设计 数据仓库构建流程数据调研明确数据域构建业务总线矩阵明确统计指标交易主题医生主题用户主题评价主题 维度模型设计汇总模型设计 数据仓库构建流程 数据仓库分层规划 优秀可靠的数仓体系&#xff0c;需要良好的数据分层结构。合理的分层&#xff0c;能够…

Go-知识 注释

Go-知识 注释 行注释块注释包注释结构体&接口注释函数&方法注释废弃注释文档 在 go 语言中注释有两种&#xff0c;行注释和块注释 行注释 使用双斜线 // 开始&#xff0c;一般后面紧跟一个空格。行注释是Go语言中最常见的注释形式&#xff0c;在标准包中&#xff0c;…

1230作业

思维导图 作业 将广播发送和接收端实现一遍&#xff0c;完成一个发送端发送信息&#xff0c;对应多个接收端接收 自实验 //广播发送端 #include <myhead.h> #define G_PORT 8765 #define G_IP "192.168.124.255" int main(int argc, const char *argv[]) {//…

U盘格式化工具合集:6个免费的U盘格式化工具

在日常使用中&#xff0c;U盘可能会因为文件系统不兼容、数据损坏或使用需求发生改变而需要进行格式化。一个合适的格式化工具不仅可以清理存储空间&#xff0c;还能解决部分存储问题。本文为大家精选了6款免费的U盘格式化工具&#xff0c;并详细介绍它们的功能、使用方法、优缺…

Windows系统使用Koodo Reader轻松搭建在线私人图书馆远程看书

文章目录 前言1. Koodo Reader 功能特点1.1 开源免费1.2 支持众多格式1.3 多平台兼容1.4 多端数据备份同步1.5 多功能阅读体验1.6 界面简洁直观 2. Koodo Reader安装流程2.1 安装Git2.2 安装Node.js2.3 下载koodo reader 3. 安装Cpolar内网穿透3.1 配置公网地址3.2 配置固定公网…

开关电源调试思维导图

开关电源辐射发射问题调试一直以来都是工程师们非常头疼的事情&#xff0c;也不知道如何下手&#xff0c;今天就通过几个思维导图把开关电源辐射发射问题调试的思路呈现给广大工程师们&#xff0c;希望能照亮大家辐射调试的黑暗道路。 01、反激电路辐射发射问题调试思维导图 0…

【brainpan靶场渗透】

文章目录 一、基础信息 二、信息收集 三、反弹shell 四、提权 一、基础信息 Kali IP&#xff1a;192.168.20.146 靶机 IP&#xff1a;192.168.20.155 二、信息收集 似乎开放了9999&#xff0c;10000端口&#xff0c;访问页面没有太多内容&#xff0c;扫描一下目录 dirs…

使用MFC编写一个paddleclas预测软件

目录 写作目的 环境准备 下载编译环境 解压预编译库 准备训练文件 模型文件 图像文件 路径整理 准备预测代码 创建预测应用 新建mfc应用 拷贝文档 配置环境 界面布局 添加回cpp文件 修改函数 报错1解决 报错2未解决 修改infer代码 修改MFCPaddleClasDlg.cp…

html+css+js网页设计 美食 美食家6个页面

htmlcssjs网页设计 美食 美食家6个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xf…

【第四期书生大模型实战营基础岛】L1G5000——XTuner 微调个人小助手认知任务

基础任务————使用 XTuner 微调 InternLM2-Chat-7B 实现自己的小助手认知&#xff0c;如下图所示&#xff08;图中的尖米需替换成自己的昵称&#xff09;&#xff0c;记录复现过程并截图。 环境配置与数据准备 步骤 0. 使用 conda 先构建一个 Python-3.10 的虚拟环境 cd …

android知识巩固(二.非线性数据结构)

非线性结构:是从逻辑结构上划分,其元素存在一对多或者多对多的相互关系 1.前言 在前一章中,我们了解了数据结构的基本思想,学习了部分基本的线性数据结构,了解了计算机是如何表示和存储数据的,良好的数据结构思想有助于我们写出性能优良的应用 2.目录 目录.png 3.非线性数据结构…

列车票务信息系统|Java|SSM|JSP|

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html 5⃣️数据库可…