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

token升级(考虑在分布式环境中布置token,结合session保证请求调用过程中token不会过期。)

思路: 首先,用户的需求是确保使用同一个Token的外部调用都在一个Session中处理。 需要考虑Token与Session绑定、安全措施、Session管理、分布式处理等。

  1. 使用Redis作为Session存储, 在Java中 通过Spring Data Redis或Lettuce库实现。

2.生成Token部分,Java中常用JWT,可以用jjwt库来生成和解析。需要将Session ID嵌入到JWT的claims中,这样每次请求都能获取到对应的Session。

接下来是Token验证的流程。在Spring中,可以通过拦截器或过滤器来验证请求中的Token,并从Redis中获取对应的Session信息。这里需要处理Token的解析、验证以及Session的检索。

Session的生命周期管理部分,需要设置自动过期时间,并且在每次访问时更新Session的过期时间。可能需要使用Redis的过期机制,每次访问时延长TTL。

分布式系统的处理,使用Redis Cluster来保证不同服务实例都能访问到同一个Session存储。此外,需要确保Token的生成和验证逻辑在分布式环境中一致。

安全措施方面,需要确保JWT使用强加密算法,比如HS256或RS256。Token的时效要短,并且通过HTTPS传输。此外,可以检查IP地址的一致性,但需要考虑用户可能处于动态IP的情况,这可能作为可选的安全措施。

客户端规范部分,需要确保客户端在每次请求携带Token,并在Token过期时使用Refresh Token来更新。这部分可能需要前端配合,但后端需要提供刷新Token的接口。

监控和审计方面,可以在拦截器中记录请求的日志,存储到数据库或日志系统中。例如,使用Spring AOP来记录Session的活动。

现在需要将这些思路转化为具体的Java代码示例。例如,生成Token的方法,使用Jwts.builder()来创建JWT,添加claims,包括sessionId。存储到Redis时,使用RedisTemplate来操作键值对。

验证Token的过滤器需要继承OncePerRequestFilter,在doFilterInternal方法中提取Token,解析出sessionId,然后从Redis获取Session数据。如果Session不存在或无效,返回401错误。

还要考虑异常处理,比如Token过期、无效签名等情况,返回相应的HTTP状态码。

在代码结构上,可能需要配置Spring Security的过滤器链,将自定义的JWT过滤器添加到链中。同时,配置Redis连接信息,确保正确连接到Redis服务器。

最后,需要测试各个部分,确保Token生成、存储、验证和Session管理的流程正确,并且在高并发和分布式环境下稳定工作。

以下是基于Java的完整解决方案,使用Spring Boot框架配合Redis实现Token-Session绑定机制:

1. 核心依赖配置 (pom.xml)

<dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- JJWT for JWT处理 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.5</version><scope>runtime</scope></dependency>
</dependencies>

2. Session管理核心实现

Redis配置类
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}
Session服务类
@Service
public class SessionService {private static final String TOKEN_PREFIX = "token:";private static final String SESSION_PREFIX = "session:";private static final Duration TOKEN_TTL = Duration.ofMinutes(30);@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// 创建Session并生成Tokenpublic String createSession(User user) {String sessionId = UUID.randomUUID().toString();String token = generateJwtToken(sessionId, user.getId());// 存储Token-Session映射redisTemplate.opsForValue().set(TOKEN_PREFIX + token, sessionId, TOKEN_TTL);// 存储Session数据HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();ops.put(SESSION_PREFIX + sessionId, "user", user);ops.put(SESSION_PREFIX + sessionId, "creationTime", Instant.now());redisTemplate.expire(SESSION_PREFIX + sessionId, TOKEN_TTL);return token;}// 验证Token并获取Sessionpublic SessionContext validateToken(String token) {String sessionId = (String) redisTemplate.opsForValue().get(TOKEN_PREFIX + token);if (sessionId == null) {throw new InvalidTokenException("Invalid or expired token");}Map<Object, Object> entries = redisTemplate.opsForHash().entries(SESSION_PREFIX + sessionId);if (entries.isEmpty()) {throw new SessionExpiredException("Session expired");}// 更新Session有效期redisTemplate.expire(TOKEN_PREFIX + token, TOKEN_TTL);redisTemplate.expire(SESSION_PREFIX + sessionId, TOKEN_TTL);return new SessionContext(sessionId,(User) entries.get("user"),(Instant) entries.get("creationTime"));}private String generateJwtToken(String sessionId, String userId) {return Jwts.builder().setSubject(userId).claim("sessionId", sessionId).setIssuedAt(new Date()).setExpiration(Date.from(Instant.now().plus(TOKEN_TTL))).signWith(SignatureAlgorithm.HS256, "your-256-bit-secret").compact();}
}

3. 安全拦截器实现

@Component
public class JwtAuthFilter extends OncePerRequestFilter {@Autowiredprivate SessionService sessionService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {String authHeader = request.getHeader("Authorization");if (authHeader == null || !authHeader.startsWith("Bearer ")) {sendError(response, "Missing authorization header");return;}try {String token = authHeader.substring(7);SessionContext context = sessionService.validateToken(token);// 将会话上下文存入请求request.setAttribute("sessionContext", context);// 验证IP一致性(可选)validateIpConsistency(request, context);} catch (InvalidTokenException | SessionExpiredException e) {sendError(response, e.getMessage());return;}filterChain.doFilter(request, response);}private void validateIpConsistency(HttpServletRequest request, SessionContext context) {String currentIp = request.getRemoteAddr();// 首次访问记录IP,后续验证一致性if (context.getClientIp() == null) {context.setClientIp(currentIp);} else if (!context.getClientIp().equals(currentIp)) {throw new SecurityException("IP address changed during session");}}private void sendError(HttpServletResponse response, String message) throws IOException {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.setContentType("application/json");response.getWriter().write("{\"error\": \"" + message + "\"}");}
}

4. 安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JwtAuthFilter jwtAuthFilter;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class).authorizeRequests().antMatchers("/api/auth/login").permitAll().anyRequest().authenticated();}
}

5. 会话上下文管理

public class SessionContext {private final String sessionId;private final User user;private final Instant creationTime;private String clientIp;// 构造函数、getters、setters
}@RestController
@RequestMapping("/api")
public class ApiController {@GetMapping("/protected-data")public ResponseEntity<?> getProtectedData(@RequestAttribute SessionContext context) {return ResponseEntity.ok(Map.of("user", context.getUser(),"sessionId", context.getSessionId(),"data", "Sensitive information"));}
}

6. 异常处理增强

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler({InvalidTokenException.class, SessionExpiredException.class})public ResponseEntity<?> handleAuthExceptions(RuntimeException ex) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("error", ex.getMessage()));}@ExceptionHandler(SecurityException.class)public ResponseEntity<?> handleSecurityExceptions(SecurityException ex) {return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("error", ex.getMessage()));}
}

架构流程说明:

  1. Token生成

    • 用户登录成功后生成包含sessionId的JWT
    • Redis存储两个关键记录:
      • token:<jwt> → sessionId (TTL 30分钟)
      • session:<sessionId> → 完整会话数据 (TTL 30分钟)
  2. 请求处理

    Client Filter SessionService Redis Controller 携带Bearer Token 验证Token 获取sessionId 返回sessionId 获取会话数据 返回会话数据 更新TTL 传递会话上下文 返回业务数据 Client Filter SessionService Redis Controller
  3. 关键特性

    • 自动续期:每次有效访问自动延长Token和Session有效期
    • IP绑定:可选的安全增强功能
    • 分布式支持:通过Redis实现跨服务节点的会话共享
    • 安全防护:JWT签名验证 + Redis存储校验双保险

最佳实践建议:

  1. 密钥管理:使用安全密钥管理系统存储JWT签名密钥
  2. 监控报警:监控以下指标:
    // 示例监控点
    @Aspect
    @Component
    public class SessionMonitor {@Around("execution(* com.example.service.SessionService.validateToken(..))")public Object monitorValidation(ProceedingJoinPoint pjp) throws Throwable {long start = System.currentTimeMillis();try {return pjp.proceed();} finally {long duration = System.currentTimeMillis() - start;Metrics.timer("session.validation.time").record(duration);}}
    }
    
  3. 压力测试:针对Session服务进行专项压测,确保Redis集群性能
  4. 安全审计:记录关键会话事件:
    public class SessionAuditListener {@Async@EventListenerpublic void handleSessionEvent(SessionEvent event) {auditRepository.save(new AuditLog(event.getType(),event.getSessionId(),event.getUserId(),Instant.now()));}
    }
    

该方案通过严格的Token-Session绑定机制,结合Spring Security的过滤器和Redis的高性能存储,确保了外部调用在统一会话上下文中完成。所有会话状态集中存储在Redis中,天然支持分布式部署,同时通过JWT的标准验证机制保障了传输安全性。

相关文章:

token升级(考虑在分布式环境中布置token,结合session保证请求调用过程中token不会过期。)

思路&#xff1a; 首先&#xff0c;用户的需求是确保使用同一个Token的外部调用都在一个Session中处理。 需要考虑Token与Session绑定、安全措施、Session管理、分布式处理等。 使用Redis作为Session存储&#xff0c; 在Java中 通过Spring Data Redis或Lettuce库实现。 2.生成…...

Flink 通过 Chunjun Oracle LogMiner 实时读取 Oracle 变更日志并写入 Doris 的方案

文章目录 一、 技术背景二、 关键技术1、 Oracle LogMiner2、 Chunjun 的 LogMiner 关键流程3、修复 Chunjun Oracle LogMiner 问题 一、 技术背景 在大数据实时同步场景中&#xff0c;需要将 Oracle 数据库的变更数据&#xff08;CDC&#xff09; 采集并写入 Apache Doris&am…...

若依(RuoYi)框架新手使用指南

若依&#xff08;RuoYi&#xff09;框架新手使用指南 若依&#xff08;RuoYi&#xff09;是一款基于 Spring Boot Vue 的前后端分离企业级开发框架&#xff0c;集成了权限管理、代码生成、监控日志等核心功能&#xff0c;适用于快速构建中后台管理系统。以下是详细的使用指南…...

k8s-coredns-CrashLoopBackOff 工作不正常

本文作者&#xff1a; slience_me 问题描述 # 问题描述 # rootk8s-node1:/home/slienceme# kubectl get pods --all-namespaces # NAMESPACE NAME READY STATUS RESTARTS AGE # kube-flannel kube-flannel-ds-66bcs …...

【css酷炫效果】纯CSS实现粒子旋转动画

【css酷炫效果】纯CSS实现粒子旋转动画 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492008 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚看到csdn出活动了&…...

SQL 通配符

SQL 通配符 在SQL查询中&#xff0c;通配符是一种非常有用的特性&#xff0c;它允许用户在查询时使用特殊字符来匹配一系列的值。本文将详细介绍SQL中的通配符及其用法&#xff0c;帮助读者更好地理解如何在SQL查询中使用通配符。 1. 什么是通配符&#xff1f; 通配符是SQL查…...

【工具】C#防沉迷进程监控工具使用手册

一、软件简介 本工具用于监控指定进程的运行时长&#xff0c;当达到预设时间时通过声音、弹窗、窗口抖动等方式进行提醒&#xff0c;帮助用户合理控制程序使用时间。 软件在上篇文章。 二、系统要求 Windows 7/10/11.NET Framework 4.5 或更高版本 三、快速入门 1. 配置文件…...

4.数据结构-树和二叉树

树和二叉树 4.1树和二叉树的定义4.1.1树的定义4.1.2树的基本术语4.1.3二叉树的定义 4.2二叉树的性质和存储结构4.2.1二叉树的性质4.2.1二叉树的存储结构顺序存储链式存储 4.3遍历二叉树和线索二叉树4.3.1遍历二叉树根据遍历序确定二叉树先序序列创建二叉链表复制二叉树计算二叉…...

【工作记录】F12查看接口信息及postman中使用

可参考 详细教程&#xff1a;如何从前端查看调用接口、传参及返回结果&#xff08;附带图片案例&#xff09;_f12查看接口及参数-CSDN博客 1、接口信息 接口基础知识2&#xff1a;http通信的组成_接口请求信息包括-CSDN博客 HTTP类型接口之请求&响应详解 - 三叔测试笔记…...

k8s搭建kube-prometheus

后续再补一个k8s集群搭建的博客&#xff0c;从0开始搭建k8s集群。使用kube-prometheus非常方便&#xff0c;主要问题只在于拉取镜像。除了拉取镜像外其他时间5分钟即可。耐心等待拉取镜像。 一.kube-prometheus简介 kube-prometheus 是一个专为 Kubernetes 设计的开源监控解决…...

Linux应用:Linux的信号

什么是信号 信号是一种软件中断&#xff0c;用于通知进程系统中发生了某种特定事件。它是操作系统与进程之间&#xff0c;以及进程与进程之间进行异步通信的一种方式。在 Linux 系统中&#xff0c;信号是一种比较简单的进程间通信机制。当一个信号产生时&#xff0c;内核会通过…...

C++特性——RAII、智能指针

RAII 就像new一个需要delete&#xff0c;fopen之后需要fclose&#xff0c;但这样会有隐形问题&#xff08;忘记释放&#xff09;。RAII即用对象把这个过程给包起来&#xff0c;对象构造的时候&#xff0c;new或者fopen&#xff0c;析构的时候delete. 为什么需要智能指针 对于…...

springboot项目,指定用alibaba连接池所需要的配置

1、依赖&#xff1a;引入相关的两个依赖 2、application.yml...

在本地跑通spark环境

官网下载spark 下载spark 解压就好 本地配置环境变量 配置环境变量&#xff08;系统环境变量&#xff09; 新增 SPARK_HOME 变量名&#xff1a;SPARK_HOME 变量值&#xff1a;F:\class\spark\Spark_env\spark-3.4.4-bin-hadoop3 配置 PATH&#xff0c;新增如下&#xff1a…...

python-56-基于Vue和Flask进行前后端分离的项目开发示例实战

文章目录 1 创建Vue前端项目1.1 运行demo1.2 实现需求2 flask部署上述dist(前后端未分离)2.1 代码app.py2.2 运行访问3 nginx部署(前后端分离)3.1 nginx前端服务3.3.1 windows安装nginx3.3.2 修改nginx.conf配置文件3.3.3 启动nginx3.3.3 停止nginx3.2 启动后端服务3.2.1 app.p…...

云盘搭建笔记

报错问题&#xff1a; No input file specified. 伪静态 location / {if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last;break;} } location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; break; } } 设…...

学习C2CRS Ⅳ (Conversational Recommender Model)

C2CRS_Model C2CRS_Model 是一个用于对话推荐系统(Conversational Recommender System, C2CRS)的端到端模型。该模型结合了知识图谱(KG)、上下文信息、用户表示和对话生成等多个模块,以实现高效的推荐和对话功能。它通过以下模块实现: 用户表示模块(CoarseFineDRUserMo…...

【工具】huggingface 模型下载过程

前述 记录下自己下载模型的几种方式 方式 1、网页直接浏览器下载&#xff1a; 简单&#xff0c;但是随时可能断 2、git lfs # 拉代码 GIT_LFS_SKIP_SMUDGE1 git clone https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0 # 进入目录 cd stable-diffusion-…...

空调遥控器低功耗单片机方案

RAMSUN空调遥控器采用先进的32位低功耗单片机作为核心控制器&#xff0c;通过优化软件算法和硬件设计&#xff0c;实现了空调遥控器的低功耗运行。单片机集成了多种功能模块&#xff0c;包括红外发射、按键扫描、电源管理等&#xff0c;有效降低了整体功耗。同时&#xff0c;该…...

K8S学习之基础三十五:k8s之Prometheus部署模式

Prometheus 有多种部署模式&#xff0c;适用于不同的场景和需求。以下是几种常见的部署模式&#xff1a; 1. 单节点部署 这是最简单的部署模式&#xff0c;适用于小型环境或测试环境。 特点&#xff1a; 单个 Prometheus 实例负责所有的数据采集、存储和查询。配置简单&…...

Agent toolkits集成指南

文章目录 CSV Agent的集成Pandas Dataframe Agent的集成PowerBI Dataset Agent的集成Agent toolkits的集成旨在简化并增强LLM应用中的数据处理和分析功能。CSVAgent提供了一个专门的工具,允许开发者处理CSV数据。Pandas Agent则集成了Pandas框架,赋予了开发者在应用中进行高效…...

蓝桥杯关于字符串的算法题目(leetcode回文串的判断问题)

文章目录 1.题目概述2.思路分析3.代码解析 1.题目概述 这个题目主要是需要我们找到回文串&#xff0c;这个回文实际上就是文学里面的这个修辞手法&#xff0c;在这个编程的时候&#xff1a;大概说的就是这个字符串从左向右个从右向左都是一样的这个效果&#xff0c;我们把这样…...

数据结构-----队列

顺序队列&#xff08;Queue&#xff09; 一、队列核心概念 1. 基本特性 先进先出&#xff08;FIFO&#xff09;&#xff1a;最早入队的元素最先出队操作限制&#xff1a; 队尾&#xff08;Rear&#xff09;&#xff1a;唯一允许插入的位置队头&#xff08;Front&#xff09;&…...

GitHub Copilot 在 VS Code 上的终极中文指南:从安装到高阶玩法

GitHub Copilot 在 VS Code 上的终极中文指南&#xff1a;从安装到高阶玩法 前言 GitHub Copilot 作为 AI 编程助手&#xff0c;正在彻底改变开发者的编码体验。本文将针对中文开发者&#xff0c;深度解析如何在 VS Code 中高效使用 Copilot&#xff0c;涵盖基础设置、中文优化…...

深入理解 RLP 编码与 JSON:原理、应用与比较

在区块链和数据存储领域&#xff0c;RLP&#xff08;Recursive Length Prefix&#xff09;编码和**JSON&#xff08;JavaScript Object Notation&#xff09;**是两种重要的数据编码方式。它们分别适用于不同的应用场景&#xff0c;并具有不同的优缺点。本文将系统性地分析 RLP…...

AI大白话(三):深度学习——AI的‘大脑‘是如何构建的?

🌟引言: 专栏:《AI大白话》 AI大白话(一):5分钟了解AI到底是什么? AI大白话(二):机器学习——AI是怎么“学习“的? 大家好!继前两篇介绍AI基础和机器学习的文章后,今天我们来聊聊深度学习——这个让AI技术近年来突飞猛进的"神奇引擎"。别担心,我会用…...

初识R语言饼状图

目录 基础饼图 标签个性化 边界修改 密度条纹 边框颜色 基础饼图 rm(list ls())# Create Data Prop <- c(3,7,9,1,2) # Make the default Pie Plot P1 <- pie(Prop) dev.off() 标签个性化 P2 <-pie(Prop , labels c("Gr-A","Gr-B","…...

[DeepRetrieval] 用DeepSeek-R1-Zero的思路教会模型怎么用搜索引擎找文本

前段时间很火的 DeepSeek-R1-Zero&#xff0c;通过这种方式既然能增强模型的推理能力&#xff0c;那是否可以在RAG的方面上增强文本的召回呢&#xff1f; 今天带来一篇关于这个方面工作的技术报告来分享一下。 技术报告&#xff1a; https://arxiv.org/pdf/2503.00223 原文链接…...

⭐算法OJ⭐二叉树的后序遍历【树的遍历】(C++实现)Binary Tree Postorder Traversal

⭐算法OJ⭐二叉树的中序遍历【树的遍历】&#xff08;C实现&#xff09;Binary Tree Inorder Traversal ⭐算法OJ⭐二叉树的前序遍历【树的遍历】&#xff08;C实现&#xff09;Binary Tree Preorder Traversal Given the root of a binary tree, return the postorder traver…...

【LeetCode 热题100】 234. 回文链表的算法思路及python代码

234. 回文链表 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&…...

Grid布局示例代码

示例一 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Grid Layout Example</title><styl…...

【K8S】ImagePullBackOff状态问题排查。

ImagePullBackOff 是在使用 Kubernetes&#xff08;K8s&#xff09;时经常遇到的一种错误状态&#xff0c;下面为你详细介绍其含义、可能的原因及解决办法。 含义 当你在 K8s 集群中创建一个 Pod 时&#xff0c;Kubelet 会尝试从指定的镜像仓库拉取所需的容器镜像。如果拉取镜…...

在 Kubernetes(k8s)部署过程中常见的问题

在 Kubernetes(k8s)部署过程中,常见的问题主要包括以下几类,以下是具体示例及简要说明: 1. 资源配额不足(Resource Quota) 现象:Pod 处于 Pending 状态,事件日志显示 Insufficient CPU/Memory。 原因: 节点(Node)资源不足,无法满足 Pod 的 requests 或 limits。 命…...

微信小程序状态管理与计算属性同时使用:miniprogram-computed 和 mobx-miniprogram

两个框架扩展提供的 ComponentWithStore 与 ComponentWithComputed 方法无法结合使用。如果需要在一个组件中既想使用 mobx-miniprogram-bindings 又想使用 miniprogram-computed解决方案是&#xff1a; 使用旧版 API 自定义组件仍然使用 Component 方法构建组件&#xff0c;将…...

Redis设置开机自启报错start-limit-hit

Redis设置开机自启报错start-limit-hit 问题&#xff1a;在银河麒麟服务器上编译安装了redis后设置systemctl开机自启报错start-limit-hit 如何解决&#xff1f; 因为开机自启的需求是后面新增的&#xff0c;所以一开始使用的是命令启动&#xff0c;使用命令启动就会直接在前台…...

[数据结构]排序之 归并排序(有详细的递归图解)

一、非递归 基本思想&#xff1a; 归并排序&#xff08; MERGE-SORT &#xff09;是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法&#xff08; Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#x…...

pdf文件分页按需查看

pdf预览本来打算粗暴点&#xff0c;一次性查看全部&#xff0c;但是一个pdf四五百页导致手机端查看超出内存直接崩掉&#xff0c;崩掉会导致页面疯狂刷新&#xff0c;所以不得不进行优化 解决思路大致如下&#xff1a; canvas转为blob格式以图片的形式加载在页面&#xff08;B…...

栈/堆/static/虚表

在 C 里&#xff0c;栈空间主要用来存放局部变量、函数调用信息等。下面为你介绍栈空间在 C 里的运用方式。 1. 局部变量的使用 在函数内部定义的变量会被存于栈空间&#xff0c;当函数执行结束&#xff0c;这些变量会自动被销毁。 #include <iostream>void exampleFu…...

计算机网络技术服务管理基于Spring Boot-SSM

目录 一、引言 二、用户需求分析 三、功能介绍 ‌‌3.1.资源管理‌&#xff1a; ‌3.2.故障管理‌&#xff1a; ‌3.3.性能管理‌&#xff1a; ‌3.4.安全管理‌&#xff1a; ‌3.5.配置管理‌&#xff1a; ‌3.6.日志管理‌&#xff1a; ‌3.7.用户管理‌&#xff1…...

Redisson 分布式锁原理

加锁原理 # 如果锁不存在 if (redis.call(exists, KEYS[1]) 0) then# hash结构,锁名称为key,线程唯一标识为itemKey&#xff0c;itemValue为一个计数器。支持相同客户端线程可重入,每次加锁计数器1.redis.call(hincrby, KEYS[1], ARGV[2], 1);# 设置过期时间redis.call(pexpi…...

LLM(5):了解 GPT 架构

1.6 对 GPT 架构的更深入了解 GPT 最初由 OpenAI 的 Radford 等人在论文《通过生成式预训练提高语言理解能力》 中提出。GPT-3 是该模型的扩展版本&#xff0c;具有更多的参数&#xff0c;并且使用了更大的数据集进行训练。此外&#xff0c;ChatGPT 中提供的原始模型是通过在大…...

Android Zygote 启动流程梳理

和你一起终身学习&#xff0c;这里是程序员Android 本篇文章主要介绍 Android Zygote 启动分析 知识点&#xff0c;通过阅读本篇文章&#xff0c;您将收获以下内容: 一、Android 系统基本服务二、虚拟机创建和第一个Java 程序引导三、Dalvik 虚拟机基本配置四、Zygote 启动流程…...

华为OD机试-绘图机器-双指针(Java 2025 A卷 100分)

题目描述 绘图机器的绘图笔初始位置在原点 (0, 0)。机器启动后按照以下规则绘制直线: 尝试沿着横坐标正向绘制直线,直到给定的终点 E。期间可以通过指令在纵坐标轴方向进行偏移,offsetY 为正数表示正向偏移,为负数表示负向偏移。给定的横坐标终点值 E 以及若干条绘制指令,…...

ESP32(1)基于ESP32的lwIP了解

ESP32-S3 是一款集成了 Wi-Fi 和蓝牙功能的微控制器&#xff0c;而 lwIP&#xff08;轻量级 IP&#xff09;是一个为嵌入式系统设计的开源 TCP/IP 协议栈。通过使用 lwIP 库&#xff0c; ESP32-S3 可以实现与外部网络的通信&#xff0c;包括发送和接收数据包、处理网络连接等。…...

C语言预处理详解

目录 &#xff08;一&#xff09;预处理符号 &#xff08;二&#xff09;define定义常量和宏 &#xff08;三&#xff09;#符号和##符号 &#xff08;四&#xff09;undef符号的条件编译 &#xff08;五&#xff09;头文件的包括 &#xff08;一&#xff09;预处理符号 在…...

python实现接口自动化

代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码&#xff1a; 优点&#xff1a;代码灵活方便缺点&#xff1a;学习成本高 工具&#xff1a; 优点&#xff1a;易上手缺点&#xff1a;灵活度低&#xff0c;有局限性。 总结&#xff1a; 功能脚本&#xff1a;工…...

当Anaconda的安装路径与我想创建的conda虚拟环境路径不一致时,应该怎么操作?

我的anaconda安装在该路径&#xff1a;D:\Program\anaconda3 , 如果我想在F盘创建一个虚拟环境 应该怎么做呢&#xff1f; 若你想在 F 盘创建 Anaconda 虚拟环境&#xff0c;可使用 conda create 命令&#xff0c;并通过 --prefix 参数指定环境路径。以下是详细步骤&#xff1…...

MongoDB慢日志查询及索引创建

MongoDB 的慢日志&#xff08;Slow Query Log&#xff09;对于运维和程序员来说都非常重要&#xff0c;因为它直接关系到数据库的性能和应用程序的稳定性。以下分享介绍下MongoDB慢日志查询及索引创建相关的一些笔记。 一&#xff0c;准备 1. 使用 db.currentOp() 实时监控 …...

C语言指针(详细总结)

目录 1.初始C指针 几个重要的概念&#xff1a; 指针的加减 &与* 二级指针 2.指针与数组 指针数组 数组指针变量 一维数组与二维数组传参的本质 ​编辑​编辑 ​编辑 3.指针与函数 函数指针数组 4.指针与结构体 5.野指针以及常见的内存管理错误 常见的内存错…...

服务器部署Kong和Konga过程

前言 最近在想怎么将一个接口给外部提供服务,并且可以根据和对放的关系,设置不同的期限或者服务大小?并且有友好的可视化页面! 这让我了解到了 API 网关,所以我开始研究 Kong 和 Konga 的使用。 实际上我最开始研究的apisix,但是部署了好久因为etcd不支持 http 无法连接…...