springCloudAlibaba之服务熔断组件---sentinel

sentinel组件学习

  • sentinel学习
    • sentinel容错机制
    • 使用代码方式进行QPS流控-流控规则初体验
      • 使用@SentinelResource注解进行流控
    • 通过代码方式设置降级规则-降级规则初体验
    • sentinel控制台部署
      • 客户端整合服务端
    • springcloud整合sentinel
      • QPS流控规则
      • 并发线程数-流控规则
      • BlockExceptionHandler统一异常处理,此时可以不加@SentinelResource注解
      • 关联流控模式
      • 链路流控模式
    • 流控效果介绍
      • 预热流控效果
      • 排队等待
    • 熔断降级规则
    • sentinel-整合openfeign降级
      • 消费端feing调用
    • 热点参数流控
    • sentinel规则持久化
      • 基于Nacos配置中心控制台实现推送

sentinel学习

  • 服务雪崩

服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。
在这里插入图片描述

sentinel容错机制

常见的容错机制有超时机制、服务限流、隔离、服务熔断

  • 超时机制
    在不做任何处理的情况下,服务提供者不可用回导致消费者请求线程强制等待,而造成系统资源耗尽。加入超时机制,一旦超时,就释放资源。由于释放资源较快,一定程度上可以抑制资源耗尽的问题。
  • 服务限流
    某个服务达到QPS设定最大值则抛异常。
  • 服务熔断
    在这里插入图片描述
  • 服务降级
    有服务熔断,必然要有服务降级。
    所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fellback(回退),回调,返回一个缺省值。例如:(备用接口/缓存/mock数据),这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。(服务熔断之后进入客户端降级方法)

使用代码方式进行QPS流控-流控规则初体验

  • 引入sentinel相关包
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--sentinel核心库-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-core</artifactId>
      <version>1.8.0</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>

    <!--sentinel注解方式-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-annotation-aspectj</artifactId>
      <version>1.8.0</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!--sentinel整合dashbaord控制台-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-transport-simple-http</artifactId>
      <version>1.8.0</version>
    </dependency>
  </dependencies>
  • 代码实现
package com.sentinel.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : zhouzhiqiang
 * @date : 2024/6/5 23:25
 * @description :
 */
@Slf4j
@RestController
@RequestMapping("/hello")
public class HelloController {

    private static final String RESOURCE_NAME="hello";
    private static final String USER_RESOURCE_NAME="user";
    private static final String DEGRADE_RESOURCE_NAME="degrade";

    @RequestMapping("/helloSentinel")
    public String hello(){

        Entry entry=null;
        try {
            entry= SphU.entry(RESOURCE_NAME);
            String str="hello world";
            log.info("======="+str+"=======");
            return str;
        } catch (BlockException e) {
            log.info("block");
            return "被限流了!";
        }catch (Exception e){
            Tracer.traceEntry(e,entry);
        }finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }

    @PostConstruct
    public static void initFlowRules(){
        //流控规则
        List<FlowRule> rules=new ArrayList<>();

        //流控
        FlowRule rule = new FlowRule();
        //为哪个资源进行流量控制
        rule.setResource(RESOURCE_NAME);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        //加载流控规则
        FlowRuleManager.loadRules(rules);
    }
}

使用@SentinelResource注解进行流控

要使用这个注解需要引入相关包和配置SentinelResourceAspect的bean

  • 引入包
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-annotation-aspectj</artifactId>
      <version>1.8.0</version>
    </dependency>
  • 配置bean
  @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
  • 使用注解方式

value:定义资源(接口名称)
blockHandler :设置流控降级后的处理方法,默认该方法,必须声明在一个类中
fallback:接口中出现异常了,就可以交给fellback指定的处理方法

@PostConstruct
    public static void initFlowRules(){
        //流控规则
        List<FlowRule> rules=new ArrayList<>();

        //流控
        FlowRule rule = new FlowRule();
        //为哪个资源进行流量控制
        rule.setResource(USER_RESOURCE_NAME);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        //加载流控规则
        FlowRuleManager.loadRules(rules);
    }

    @RequestMapping("/user")
    @SentinelResource(value = USER_RESOURCE_NAME,blockHandler = "blockHandlerForGetUser",fallback = )
    public User getUser(String id){
        return new User("zzq");
    }

    /**
     * 注意:
     * 1、一定是public
     * 2、返回值一定得和原方法返回值一致,包含方法的参数
     * 3、可以在参数的最后添加BlockException,可以区分是什么规则的处理方法
     * @param id
     * @param e
     * @return
     */
    //降级方法
    public User blockHandlerForGetUser(String id,BlockException e){
        e.printStackTrace();
        return new User("被流控了!");
    }

通过代码方式设置降级规则-降级规则初体验

@RestController
@RequestMapping("/test")
public class TestController {

    private static final String DEGRADE_RESOURCE_NAME="degrade";

    @RequestMapping("/degrade")
    @SentinelResource(value = DEGRADE_RESOURCE_NAME,entryType = EntryType.IN,blockHandler = "blockHandlerForJob")
    public User degrade(String id){
        int i=1;
        int sum=i/0;
        return new User("成功");
    }

    public User blockHandlerForJob(String id, BlockException e){
        e.printStackTrace();
        return new User("触发降级规则");
    }

    @PostConstruct
    public void initDegradeRule(){
        List<DegradeRule> rules=new ArrayList<>();

        DegradeRule rule = new DegradeRule();
        rule.setResource(DEGRADE_RESOURCE_NAME);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        //触发熔断异常数
        rule.setCount(2);
        //触发熔断的最小请求数
        rule.setMinRequestAmount(2);
        //统计时长:单位ms  1分钟
        rule.setStatIntervalMs(60*1000);
        //一分钟内:执行了两次 ,出现两次异常 就会触发熔断

        /**
         * 熔断持续时间,单位秒。一旦触发了熔断,再次请求接口则直接调用降级方法。
         * 10秒后,---半开状态,恢复接口调用。如果再次请求,则会熔断,不再根据熔断规则进入熔断,而是直接进入熔断
         */
        rule.setTimeWindow(10);


        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

流控规则一般设置在服务生产方,而降级规则一般设置在服务消费方

sentinel控制台部署

下载dashboard--https://github.com/alibaba/Sentinel/releases

运行jar包:java -jar sentinel-dashboard-1.8.0.jar。运行完毕进行访问,默认端口号8080。用户名和密码默认sentinel
在这里插入图片描述

客户端整合服务端

客户端需要引入Transport模块来与sentinel控制台进行通信

<!--sentinel整合dashbaord控制台-->
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-transport-simple-http</artifactId>
      <version>1.8.0</version>
    </dependency>
  • 配置启动
    客户端启动时需要加入JVM参数-Dcsp.sentinel.dashboard.server=192.168.1.15:8080,指定控制台地址和端口
    在这里插入图片描述

springcloud整合sentinel

  • 添加依赖
     <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  • yaml配置文件
server:
  port: 8081
spring:
  application:
    name: order-sentinel
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.184.15:8080
        port: 8719
        client-ip: 192.168.184.1

在虚拟机上部署dashboard的时候,主机和虚拟机一直网络不通,解决方法:
1、关闭本机和虚拟机的防火墙
在这里插入图片描述
2、本机不动,配置虚拟机ip,网段和本地vmnet8保持一致,网关查看虚拟网络编辑器
在这里插入图片描述

ONBOOT="yes"
IPADDR="192.168.184.15"
NETMASK="255.255.255.0"
GATEWAY="192.168.184.2"
DNS1="8.8.8.8"
DNS2="8.8.4.4"

3、最重要的一步,设置网络连接模式为net模式
在这里插入图片描述
原因:解释: 1:当我们安装VMware Workstation后,在宿主机(物理电脑)上会多出两个网卡,VMNet1、VMNet8。 2:vmnet1是为host-only方式服务的,vmnet8是为NAT方式服务的

QPS流控规则

添加流控规则:QPS为2,超过2触发流控降级
在这里插入图片描述
在这里插入图片描述

  • 代码中指定自定义降级方法,dashboard定义流控规则,代码自定义降级方法
    /**
     * 流控测试接口
     * @return
     */
    @RequestMapping("/flow")
    @SentinelResource(value = "flow",blockHandler = "blockHandlerForFlow")
    public String flow(){
        return "正常访问";
    }

    public String blockHandlerForFlow(BlockException e){
        e.printStackTrace();
        System.out.println("触发流控,快速失败");
        return "触发流控,快速失败";
    }

并发线程数-流控规则

  • dashboard配置
    在这里插入图片描述
  • 代码
    @RequestMapping("/flowThread")
    @SentinelResource(value = "flowThread",blockHandler = "blockHandlerForFlow")
    public String flowThread(){
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "正常访问";
    }

    public String blockHandlerForFlow(BlockException e){
        e.printStackTrace();
        System.out.println("触发流控,快速失败");
        return "触发流控,快速失败";
    }
  • 测试
    开两个浏览器模拟两个线程
  • 测试结果
    在这里插入图片描述

BlockExceptionHandler统一异常处理,此时可以不加@SentinelResource注解

  • 代码
@Data
public class Result <T>{
    private Integer code;
    private String msg;
    private T data;

    public Result(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Result(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static Result error(Integer code,String msg){
        return new Result(code,msg);
    }
}
@Component
@Slf4j
public class MyBlockExceptionHandler implements BlockExceptionHandler {

    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
        //规则的详细信息
        log.info("BlockExceptionHandler BlockException=============="+e.getRule());
        Result r = null;
        if (e instanceof FlowException) {
            r=Result.error(100,"接口被限流了!");
        }else if (e instanceof DegradeException){
            r=Result.error(101,"服务降级了!");
        }else if (e instanceof ParamFlowException){
            r=Result.error(102,"热点参数限流了!");
        }else if (e instanceof SystemBlockException){
            r=Result.error(103,"触发系统保护规则!");
        }else if (e instanceof AuthorityException){
            r=Result.error(104,"授权规则不通过!");
        }

        response.setStatus(500);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(response.getWriter(),r);
    }
}
  • 测试代码
    此时在dashboar的为这个接口设置流控规则后,可以看到设置的同一异常起效果了
 @RequestMapping("/exceptionHandler")
    public String exceptionHandler(){
        return "正常访问";
    }

关联流控模式

流控模式有三种直接、关联、链路
在这里插入图片描述

关联模式:当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写的速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢。

  • dashboard设置
    当生成订单QPS>=2的时候,查询订单接口就被限流
    在这里插入图片描述
  • 代码
 @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功");
        return "生成订单";
    }

    @RequestMapping("/get")
    public String get(){
        return "查询订单";
    }
  • 生成接口和查询接口测试
    生成接口和查询接口不好一起测试,生成接口使用apifox进行压测,查询接口手动点
    在这里插入图片描述
  • 测试结果
    查询接口触发流控规则
    在这里插入图片描述
  • 或者使用JMeter去做压测
    在这里插入图片描述
    在这里插入图片描述

链路流控模式

可以对资源进行流控
在这里插入图片描述

  • 代码
public interface IUserService {
    User getUser();
}

对getUser添加@SentinelResource注解

@Service
public class IUserServiceImpl implements IUserService{

    @SentinelResource(value = "getUser",blockHandler = "blockHandlerForUser")
    public User getUser() {
        User user = new User();
        user.setId("001");
        user.setName("针对业务方法进行流控");
        return user;
    }

    public User blockHandlerForUser(BlockException e){
        e.printStackTrace();
        User user = new User();
        user.setId("001");
        user.setName("ddddd");
        return new User();
    }
}

test1和test2调用getUser(),当getUser(),达到QPS2的时候,对test1或者test2做流控

@RestController
@RequestMapping("/link")
public class LinkController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/test1")
    public User test1(){
        return userService.getUser();
    }

    @RequestMapping("/test2")
    public User test2(){
        return userService.getUser();
    }
}
  • 配置文件配置
    web-context-unify: false # 默认将调用链路收敛了
server:
  port: 8081
spring:
  application:
    name: order-sentinel
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.184.15:8080
        port: 8719
        client-ip: 192.168.184.1
      web-context-unify: false  # 默认将调用链路收敛了
  • dashboar配置
    在这里插入图片描述
  • 测试结果
    当test1qps达到2的时候触发流控
    在这里插入图片描述

流控效果介绍

流控效果有快速失败、预热、排队等待。预热:适用于激增流量的情况
在这里插入图片描述

预热流控效果

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

  • dashboard配置
    qps最大为10,10秒内达到10
    在这里插入图片描述

排队等待

激增流量:长时间处于低水平,某个时间段处于高水平,可以使用预热的方式进行处理。

脉冲流量:一段时间处于低水平某个时刻到达高水平,然后又变为低水平,循环往复

匀速排队:严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过

  • 测试
    设置流控效果为快速失败,单机QPS阈值为5,使用JMeter测试,一秒执行10次循环5次
    在这里插入图片描述
    在这里插入图片描述
    测试结果:可以看到一秒内10个QPS5个通过,5个拒绝
    在这里插入图片描述
  • 使用排队等待流控效果
    dashboard配置:单机阈值5,超时时间5秒。比如有10个线程,每次进去5个,其他5个等待。执行完一个进去一个,如果5个线程在5秒内没有执行完则直接拒绝
    在这里插入图片描述
  • 测试结果
    所有请求都执行成功
    在这里插入图片描述

熔断降级规则

慢调用比例:慢调用占调用总数的比例

  • dashboard配置
    最大RT:单位毫秒,不能超过1秒,超过1秒则触发降级。比例阈值:慢调用占请求次数的比例。最小请求数:配合比例阈值,10次请求有一次触发慢调用则触发降级
    在这里插入图片描述
  • 使用Jmetter进行测试
    在这里插入图片描述
  • 测试结果
    触发降级
    在这里插入图片描述

sentinel-整合openfeign降级

nacos服务注册必须是一个web项目
按此步骤完成微服务搭建后,发现服务并没有注册到nacos注册中心,在官方文档查看springboot和springcloud版本也并没有冲突,尝试引入nacos管理依赖后还是不行,最后想到要在nacos注册中心注册的微服务应该必须是一个web项目,而在springboot环境下开发web项目需要引入springMvc的相关启动依赖,加上后发现服务成功注册到了nacos注册中心

  • 在消费端引入依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>


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

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
  • 消费端配置yml
    特别加上:server: port: 8084 spring: application: name: product-service cloud: nacos: username: zzq password: 1w2e3r4! server-addr: 192.168.184.15:8848 discovery: namespace: 31a14d31-cda4-4a37-a4ba-7717aaddd97d feign: sentinel: enabled: true
server:
  port: 8084
spring:
  application:
    name: product-service
  cloud:
    nacos:
      username: zzq
      password: 1w2e3r4!
      server-addr: 192.168.184.15:8848
      discovery:
        namespace: 31a14d31-cda4-4a37-a4ba-7717aaddd97d
feign:
  sentinel:
    enabled: true

消费端feing调用

  • feing
@FeignClient(value = "stock-service",path = "/person",fallback = IPersonServiceFallback.class)
public interface IPersonService {

    @RequestMapping("/getPerson")
    public Person getPerson();
}

必须要有一个feingclint的实现类,并且注入进spring

@Component
public class IPersonServiceFallback implements IPersonService {
    public Person getPerson() {
        Person person = new Person();
        person.setId("001");
        person.setName("未找到用户");
        return person;
    }
}

消费端调用服务端

   @RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private IPersonService personService;

    @RequestMapping("/getProduct")
    public String getProduct(){
        Person person = personService.getPerson();
        return "调用成功:"+person.getName();
    }
}

  • 测试结果
    调用异常执行降级方法
    在这里插入图片描述

热点参数流控

场景:接口参数对某些值的访问QPS比其他高。典型的电商系统中,商品查询接口,某些商品的访问QPS要远远高于其他商品,比如商品ID为1的商品,访问请求远远高于其他商品。

  • dashboard配置
    在这里插入图片描述

sentinel规则持久化

在这里插入图片描述
结合nacos配置中心使用推模式进行规则的持久化

基于Nacos配置中心控制台实现推送

  • 引入依赖
  <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
   </dependency>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kettle从入门到精通 第六十七课 ETL之kettle 再谈kettle阻塞,阻塞多个分支的多个步骤

想真正学习或者提升自己的ETL领域知识的朋友欢迎进群&#xff0c;一起学习&#xff0c;共同进步。由于群内人员较多无法直接扫描进入&#xff0c;公众号后台加我微信入群&#xff0c;备注kettle。 场景&#xff1a;ETL沟通交流群内有小伙伴反馈&#xff0c;如何多个分支处理完…

QT 使用资源文件的注意点

不要存放没有使用的资源文件 即使在代码中没有使用到的资源文件&#xff0c;也会编译到执行文件或者DLL里面去这样会增大它的体积。如下 在代码没有使用这个资源文件(10.4M的2k图片)&#xff0c;但是编译出来的程序有 12M左右的大小 1 假设我们有一个比较复杂的项目&#…

vAttention:用于在没有Paged Attention的情况下Serving LLM

文章目录 0x0. 前言&#xff08;太长不看版&#xff09;0x1. 摘要0x2. 介绍&背景0x3. 使用PagedAttention模型的问题0x3.1 需要重写注意力kernel0x3.2 在服务框架中增加冗余0x3.3 性能开销0x3.3.1 GPU上的运行时开销0x3.3.2 CPU上的运行时开销 0x4. 对LLM服务系统的洞察0x5…

【UML用户指南】-13-对高级结构建模-包

目录 1、名称 2、元素 3、可见性 4、引入与引出 用包把建模元素安排成可作为一个组来处理的较大组块。可以控制这些元素的可见性&#xff0c;使一些元素在包外是可见的&#xff0c;而另一些元素要隐藏在包内。也可以用包表示系统体系结构的不同视图。 狗窝并不复杂&#x…

《python程序语言设计》2018版第5章第35题求完全数,解题经历,我认为的正确代码放在最后

5.35从4月开始一直到成功&#xff0c;此文章将所有的记录和不同阶段代码展现给大家。但是没有配图&#xff0c;我最后成功的代码放在了最后。 2024.04.15 05.35.01version 求完整数&#xff0c;这个让我突然有点蒙。我什么时候能求完整数呢&#xff1f;&#xff1f; 正因子之和…

linux 网桥学习

前言&#xff1a; 本文来学习一下linux网桥概念和网桥配置 1. linux网桥概念 网桥&#xff0c;类似于中继器&#xff0c;连接局域网中两个或者多个网段。它与中继器的不同之处就在于它能够解析它收发的数据&#xff0c;读取目标地址信息&#xff08;MAC&#xff09;&#xff…

QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite用法

使用QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite数据库实现一个简单的界面查询 1. 创建Sqlite数据库&#xff0c;表 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "QSqlDatabase" #include "QSqlQuery&q…

ICRA 2024:北京工业大学马楠教授联合中科原动力公司推出番茄采摘自主机器人AHPPEBot,实现32.46秒快速准确采摘

当前&#xff0c;农业生产正深受劳动力短缺困扰&#xff0c;这一现状对生产规模的进一步拓展构成了严重制约。为了突破这一瓶颈&#xff0c;实施自动化已成为提升农业生产力的关键途径&#xff0c;这也使得机器人采收技术备受关注。 现今的机器人采收系统普遍采用先进感知方法&…

31-捕获异常(NoSuchElementException)

在定位元素的时候&#xff0c;经常会遇到各种异常&#xff0c;遇到异常又该如何处理呢&#xff1f;本篇通过学习selenium的exceptions模块&#xff0c;了解异常发生的原因。 一、发生异常 打开百度搜索首页&#xff0c;定位搜索框&#xff0c;此元素id"kw"。为了故意…

我的mybatis学习笔记之二

第一版学习笔记 1,接口是编程: 原生: Dao > DaoImpl mybatis: Mappper > XXXMapper.xml 2,SqlSession代表和数据库的一次会话:用完必须关闭 3,SqlSession和connection一样是非线程安全的.每次使用都必须去获取新的对象 4,mapper接口没有是一类,但是mybtis会为这个接口生…

JVisuaIVM监控Jstatd启动时报错

一、 启动监控Jstatd报错 当我们在windows系统上面启动的时候好好的&#xff0c;在linux上面启动报错&#xff0c;提示报错如下&#xff0c;好像每一什么权限之类的 在tomcat下面查看你的项目使用的java版本&#xff0c;vi /usr/local/tomcat7-8083/bin/catalina.sh 查看我的…

域内攻击 ----> DCSync

其实严格意义上来说DCSync这个技术&#xff0c;并不是一种横向得技术&#xff0c;而是更偏向于权限维持吧&#xff01; 但是其实也是可以用来横向&#xff08;配合NTLM Realy&#xff09;&#xff0c;如果不牵强说得话&#xff01; 那么下面&#xff0c;我们就来看看这个DCSyn…

基于AI大文本模型的智慧对话开发设计及C#源码实现,实现智能文本改写与智慧对话

文章目录 1.AI 大模型发展现状2.基于AI服务的智慧对话开发2.1 大模型API选择2.2 基于C#的聊天界面开发2.3 星火大模型API接入2.4 优化开发界面与显示逻辑 3.源码工程Demo及相关软件下载参考文献 1.AI 大模型发展现状 端午假期几天&#xff0c;关注到国内的AI大模型厂商近乎疯狂…

时序数据库是Niche Market吗?

引言 DB-Engines的流行程度排行从其评估标准[4]可以看出完全不能够做为市场规模的评估标准。甚至于在知道市场规模后可以用这个排行作为一个避雷手册。毕竟现存市场小&#xff0c;可预见增长规模小&#xff0c;竞争大&#xff0c;创新不足&#xff0c;那只能卷价格&#xff0c…

冲刺面试加油

1、HTML语义化&#xff1f; 对于开发者而言&#xff0c;语义化标签有着更好的页面结构&#xff0c;有利于代码的开发编写和后期的维护。 对于用户而言&#xff0c;当网络卡顿时有良好的页面结构&#xff0c;有利于增加用户的体验。 对于爬虫来说&#xff0c;有利于搜索引擎的…

你还不知道无线PLC?

随着技术的不断发展&#xff0c;工业控制系统也在经历着革新。无线PLC&#xff08;Programmable Logic Controller&#xff0c;可编程逻辑控制器&#xff09;是一种结合了无线通讯技术和传统PLC系统的创新型技术。它为工业自动化提供了一种更灵活、更便捷的解决方案&#xff0c…

跟我学,数据结构和组原真不难

我个人认为408中计算机组成原理和数据结构最难 难度排行是计算机组成原理>数据结构>操作系统>计算机网络。 计算机组成原理比较难的原因是&#xff0c;他涉及的硬件的知识比较多&#xff0c;这对于大家来说难度就很高了&#xff0c;特别是对于跨考的同学来说&#x…

保姆级讲解 Linux下FTP服务器的搭建、配置与管理

本来目录很长的 因为感觉不太美观 所以小标题都删掉了 本文介绍了 本地用户的FTP服务器搭建实例匿名用户的FTP服务器搭建实例虚拟用户的FTP服务器搭建实例企业常见类型搭建实验 配置与管理FTP服务器 配置与管理FTP服务器一、FTP相关知识二、项目设计与准备三、项目实施四、认识…

架构设计-web项目中跨域问题涉及到的后端和前端配置

WEB软件项目中经常会遇到跨域问题&#xff0c;解决方案早已是业内的共识&#xff0c;简要记录主流的处理方式&#xff1a; 跨域感知session需要解决两个问题&#xff1a; 1. 跨域问题 2. 跨域cookie传输问题 跨域问题 解决跨域问题有很多种方式&#xff0c;如使用springboot…

打造你的博客帝国:DjangoBlog带你飞向国际舞台!

你的网站加载速度还在慢如蜗牛吗&#xff1f;将为你揭开网站速度提升的神秘面纱。从缓存策略到数据库优化&#xff0c;再到高效的代码实践&#xff0c;我们深入探讨了如何让DjangoBlog飞速运行。不仅如此&#xff0c;我们还提供了实用的监控和日志管理技巧&#xff0c;确保你的…