Springboot整合shiro
导入依赖
<!-- 引入springboot的web项目的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- shiro --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.12.0</version></dependency>
配置类
package com.qf.shiro2302.config;
import com.qf.shiro2302.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.List;
@Configuration
@Slf4j
public class ShiroConfig {
@Beanpublic Realm realm(){AuthorizingRealm authorizingRealm = new AuthorizingRealm() {
/**** @param token 这的token就是调用login方法时,传入的token对象* @return AuthenticationInfo 对象中,封装了用户的身份信息(principals),密码(credentials),提供信息的realm的名字* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("===========获取身份信息===============");//查询数据库获取当前用户名对应的User对象String username = (String) token.getPrincipal();System.out.println("username="+username);System.out.println("this.getName()={}"+this.getName());User user=getUserFromDB(username);
//需要返回shiro规定的AuthenticationInfo类型的对象//这个对象中,包含了用户的身份认证信息// SimpleAuthenticationInfo的构造函数中的第一个参数,principals代表用户的身份信息// 一般可以使用 user对象,或者使用用户名也可以// 第三个参数,代表当前realm的名字,固定写法//Authentication 证明的意思SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
return authenticationInfo;}
@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("============获取授权===============");
// 从数据库表中查询当前用户具有的角色和权限字符串User user = (User) principalCollection.getPrimaryPrincipal();
List<String> roles= getRolesFromDB(user);List<String> permissions= getPermissionFromDB(user);
// 按照约定返回AuthorizationInfo对象SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();// 放入从数据库中查询到的当前用户的角色信息
// authorizationInfo.addRole("test");authorizationInfo.addRoles(roles);
// 放入从数据库中查询到的当前用户的权限信息
// authorizationInfo.addStringPermission("document:read");authorizationInfo.addStringPermissions(permissions);return authorizationInfo;}};
return authorizingRealm;
}
private List<String> getRolesFromDB(User user) {return Arrays.asList("test","admin");}
private List<String> getPermissionFromDB(User user) {return Arrays.asList("document:read","document:write");}
private User getUserFromDB(String username) {User user = new User(100, "数据库用户", "123456", "123@qq.com");return user;}
@Beanpublic ShiroFilterChainDefinition shiroFilterChainDefinition() {//ShiroFilterChainDefinition 此接口就一个实现类 默认Shiro过滤器链定义类DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// 让登录接口直接被shiro的过滤器放行//第一个参数:接口的路径//第二个参数:shiro内部的过滤器的名字,anon代表无需登录即可访问的特殊的过滤器,注意过滤器的名字是固定的,不能乱写chainDefinition.addPathDefinition("/login/dologin", "anon");// 放行springboot的错误页面的请求url 这个页面就是个response拼接的页面chainDefinition.addPathDefinition("/error", "anon");
//增加角色或者权限,对于某些请求// logged in users with the 'test' role
// chainDefinition.addPathDefinition("/test/**", "authc, roles[test,admin], perms[document:read,document:write]"); 这个如果改成anon,就不能加后面的角色或者权限,否则,将会被认为需要登录,重定向到登录页
// all other paths require a logged in userchainDefinition.addPathDefinition("/**", "authc");return chainDefinition;}
}
调用接口
package com.qf.shiro2302.controller;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController {
@PostMapping("/dologin")public String dologin(String username,String password){
//使用Shiro进行登录处理Subject subject = SecurityUtils.getSubject();//获取shiro核心对象//为了调用shiro的登录方法,需要准备一个Token对象UsernamePasswordToken token = new UsernamePasswordToken(username,password);System.out.println(token);subject.login(token);//使用shiro登录流程
return "登陆成功 ";
}
}
获取ShiroSession中的用户,注解添加权限
package com.qf.shiro2302.controller;
import com.qf.shiro2302.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@RequiresRoles({"test","admin"})@RequiresPermissions({"document:read","document:write"})@RequestMapping("/test1")public String hello1(){return "hello shiro !!!";}
@RequestMapping("/test2")public User hello2(){//如果使用shiro获取当前登录用户的身份信息Subject subject = SecurityUtils.getSubject();User principal = (User) subject.getPrincipal();System.out.println(principal);return principal;}
}
shiro:loginUrl: /login.html#配置没登陆的时候重定向的页面。这个请求是可以放行的
优化整合shiro,登录密码MD5Hash加密,内置处理
1.配置类
package com.qf.shiroHomework.config;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.shiroHomework.entity.*;
import com.qf.shiroHomework.mapper.TPersMapper;
import com.qf.shiroHomework.mapper.TRoleMapper;
import com.qf.shiroHomework.mapper.TRolePermsMapper;
import com.qf.shiroHomework.mapper.TUserRoleMapper;
import com.qf.shiroHomework.service.ITUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Configuration
@Slf4j
public class ShiroConfig {
@Autowiredprivate ITUserService itUserService;@Autowiredprivate TUserRoleMapper tUserRoleMapper;@Autowiredprivate TRolePermsMapper tRolePermsMapper;@Autowiredprivate TPersMapper tPersMapper;@Autowiredprivate TRoleMapper tRoleMapper;
//将Realm对象放入IOC容器里@Beanpublic Realm realm(){AuthorizingRealm authorizingRealm = new AuthorizingRealm() {
/**** @param token 这的token就是调用login方法时,传入的token对象* @return AuthenticationInfo 对象中,封装了用户的身份信息(principals),密码(credentials),提供信息的realm的名字* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("===========获取身份信息===============");//获取身份信息String username = (String) token.getPrincipal();
QueryWrapper<TUser> wrapper = new QueryWrapper<>();wrapper.eq("username",username);TUser user = itUserService.getOne(wrapper);
// 需要返回shiro规定的AuthenticationInfo类型的对象// 这个对象中,包含了用户的身份认证信息// SimpleAuthenticationInfo的构造函数中的第一个参数,principals代表用户的身份信息// 一般可以使用 user对象,或者使用用户名也可以// 第三个参数: 盐// 第四个参数,代表当前realm的名字,就是一个标识,标识是这个Bean调用的这个方法,没有作用,固定写法
SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());
return authenticationInfo;}
@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {TUser user = (TUser) principalCollection.getPrimaryPrincipal();SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();log.info("用户角色={}",getRolesFromDB(user));log.info("用户权限={}",getPermissionFromDB(user));authorizationInfo.addRoles(getRolesFromDB(user));authorizationInfo.addStringPermissions(getPermissionFromDB(user));return authorizationInfo;}};
// 把HashedCredentialsMatcher对象设置到authorizingRealm对象中authorizingRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return authorizingRealm;}
@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//设置算法名称matcher.setHashAlgorithmName("md5");//设置hash次数matcher.setHashIterations(1024);return matcher;
}
//配置Shiro过滤器链@Beanpublic ShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();chainDefinition.addPathDefinition("/register.html","anon");chainDefinition.addPathDefinition("/error/500.html","anon");chainDefinition.addPathDefinition("/error","anon");chainDefinition.addPathDefinition("/user/register","anon");chainDefinition.addPathDefinition("/user/login","anon");chainDefinition.addPathDefinition("/user/**","authc");chainDefinition.addPathDefinition("/**","authc");
return chainDefinition;
}
public List<String> getPermissionFromDB(TUser user) {if (user.getPerms()!=null){return user.getPerms();}
Integer id = user.getId();//通过用户ID找到角色
QueryWrapper<TUserRole> wrapper1 = new QueryWrapper<>();wrapper1.eq("userid",id);TUserRole tUserRole = tUserRoleMapper.selectOne(wrapper1);Integer roleid = tUserRole.getRoleid();System.out.println(roleid);
QueryWrapper<TRolePerms> wrapper = new QueryWrapper<>();wrapper.select("permsid").eq("roleid",roleid);List<Object> permsidList = tRolePermsMapper.selectObjs(wrapper);System.out.println(permsidList);List<Integer> integers = permsidList.stream().map(o -> {return (Integer) o;}).collect(Collectors.toList());List<TPers> tPers = tPersMapper.selectBatchIds(integers);System.out.println(tPers);ArrayList<String> strings = new ArrayList<>();for (TPers tPer : tPers) {strings.add(tPer.getName());}user.setPerms(strings);
return strings;}
public List<String> getRolesFromDB(TUser user) {
if (user.getRoleName()!=null){return user.getRoleName();}
Integer id = user.getId();//通过用户ID找到角色QueryWrapper<TUserRole> wrapper1 = new QueryWrapper<>();wrapper1.eq("userid",id);TUserRole tUserRole = tUserRoleMapper.selectOne(wrapper1);Integer roleid = tUserRole.getRoleid();QueryWrapper<TRole> wrapper = new QueryWrapper<>();wrapper.select("name").eq("id",roleid);List<Object> roles = tRoleMapper.selectObjs(wrapper);List<String> strings = roles.stream().map(o -> {return (String) o;}).collect(Collectors.toList());user.setRoleName(strings);return strings;}
}
实体类
package com.qf.shiroHomework.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.List;
import lombok.*;
/*** <p>* * </p>** @author jmj* @since 2023-08-10*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@TableName("t_user")
public class TUser implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)private Integer id;
private String username;
private String password;
private String salt;
@TableField(exist = false) // 说明当前这个属性在数据库表中没有对应的字段,让mp生成sql时忽略这个属性private List<String> roleName;@TableField(exist = false)private List<String> perms;
}
Controller
//复杂密码匹配器@PostMapping("/login")public String login(TUser user){//使用Shiro进行登录处理Subject subject = SecurityUtils.getSubject();//获取shiro核心对象//为了调用shiro的登录方法,需要准备一个Token对象
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
subject.login(usernamePasswordToken);
return "redirect:/show.html";
}
以前手写MD5处理的方法
// 简单密码匹配器方案
// @PostMapping("/login")
// public String login(TUser user){
// //使用Shiro进行登录处理
// Subject subject = SecurityUtils.getSubject();//获取shiro核心对象
// //为了调用shiro的登录方法,需要准备一个Token对象
// //添加Where 条件
// QueryWrapper<TUser> wrapper = new QueryWrapper<>();
// wrapper.eq("username",user.getUsername());
// TUser u = itUserService.getOne(wrapper);
// if (u==null){
// return "redirect:/index.html";
// }else {
//
// //MD5加密
// Md5Hash md5Hash = new Md5Hash(user.getPassword(), u.getSalt(), 1024);
// String newPassword = md5Hash.toHex();
//
//
// UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), newPassword);
//
// subject.login(usernamePasswordToken);
// }
//
// return "redirect:/show.html";
//
// }
相关文章:
Springboot整合shiro
导入依赖 <!-- 引入springboot的web项目的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> <!-- shiro --><depende…...
阻塞/非阻塞、同步/异步(网络IO)
1.阻塞/非阻塞、同步/异步(网络IO) 【思考】典型的一次 IO 的两个阶段是什么? 数据就绪 和 数据读写 数据就绪 :根据系统 IO 操作的就绪状态 阻塞 非阻塞 数据读写 :根据应用程序和内核的交互方式 同步 异步 陈硕:在处理 IO …...
为什么大家会觉得考PMP没用?
一是在于PMP这套知识体系,是一套底层的项目管理逻辑框架,整体是比较抽象的。大家在学习工作之后,会有人告诉你很多职场的一些做事的规则,比如说对于沟通,有人就会告诉如何跟客户沟通跟同事相处等等,这其实就…...
AVR128单片机 USART通信控制发光二极管显示
一、系统方案 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 void port_init(void) { PORTA 0xFF; DDRA 0x00;//输入 PORTB 0xFF;//低电平 DDRB 0x00;//输入 PORTC 0xFF;//低电平 DDRC 0xFF;//输出 PORTE 0xFF; DDRE 0xfE;//输出 PO…...
为什么5G 要分离 CU 和DU?(4G分离RRU 和BBU)
在 Blog 一文中,5G--BBU RRU 如何演化到 CU DU?_5g rru_qq_38480311的博客-CSDN博客 解释了4G的RRU BBU 以及 5G CU DU AAU,主要是讲了它们分别是什么。但是没有讲清楚 为什么,此篇主要回答why。 4G 为什么分离基站为 RRU 和 BBU…...
Python中的数据输入
获取键盘输入 input语句 使用input()可以从键盘获取输入,使用一个变量来接收 print("你是谁?") name input() print(f"我知道了,你是{name}")# print("你是谁?") name input("你是谁&…...
cms系统稳定性压力测试出现TPS抖动和毛刺的性能bug【杭州多测师_王sir】
一、并发线程数100,分10个阶梯,60秒加载时间,运行1小时进行压测,到10分钟就出现如下 二、通过jstat -gcutil 16689 1000进行监控...
【UE】材质描边、外发光、轮廓线
原教学视频链接: ue4 材质描边、外发光、轮廓线_哔哩哔哩_bilibili 步骤 1. 首先新建一个材质,这里命名为“Mat_outLine” 在此基础上创建一个材质实例 2. 在视口中添加一个后期处理体积 设置后期处理体积为无限范围 点击添加一个数组 选择“资产引用”…...
百模大战,打响AI应用生态的新赛点
点击关注 文|郝鑫 黄小艺,编|刘雨琦 “宇宙中心”五道口,又泛起了昔日的光芒。 十字路口一角的华清嘉园里,各种互联网大佬们,王兴、程一笑、张一鸣等人的创业传说似乎还有余音,后脚搬进来的AI…...
【C++二叉树】进阶OJ题
【C二叉树】进阶OJ题 目录 【C二叉树】进阶OJ题1.二叉树的层序遍历II示例代码解题思路 2.二叉搜索树与双向链表示例代码解题思路 3.从前序与中序遍历序列构造二叉树示例代码解题思路 4.从中序与后序遍历序列构造二叉树示例代码解题思路 5.二叉树的前序遍历(非递归迭…...
C++——vector:resize与reserve的区别,验证写入4GB大数据时相比原生操作的效率提升
resize和reserve的区别 reserve:预留空间,但不实例化元素对象。所以在没有添加新的对象之前,不能引用容器内的元素。而要通过调用push_back或者insert。 resize:改变容器元素的数量,且会实例化对象(指定或…...
基础配置xml
# 配置端口 server.port8081# 文件上传配置 # 是否支持文件上传 spring.servlet.multipart.enabledtrue # 是否支持文件写入磁盘 spring.servlet.multipart.file-size-threshold0 # 上传文件的临时目录 spring.servlet.multipart.locationd:/opt/tmp # 最大支持上传文件大小 sp…...
win环境安装SuperMap iserver和配置许可
SuperMap iServer是我国北京超图公司研发的基于跨平台GIS内核的云GIS应用服务器产品,通过服务的方式,面向网络客户端提供与专业GIS桌面产品相同功能的GIS服务,能够管理、发布多源服务,包括REST服务、OGC服务等。 SuperMap iserve…...
【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)
文章目录 TASK系列解析文章前言PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER功能介绍PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER相关配置PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER流程确定优化变量定义目标函数定义约束ProcessSetUpStatesAndBoundsOptimizeByQPCheckSpeedLimitF…...
pytest parametrize多参数接口请求及展示中文响应数据
编写登陆接口 app.py from flask import Flask, request, jsonify, Responseapp Flask(__name__)app.route(/login, methods[POST]) def login():username request.form.get(username)password request.form.get(password)# 在这里编写你的登录验证逻辑if username admin…...
电视连续剧 ffmpeg 批量去掉片头片尾
思路: 一、用python获取每集的总时长 二、把每集的时间,拼接成想要的ffmpeg的剪切命令命令。 1、用python获取每集的总时长 1,安装moviepy库,直接安装太慢,换成国内的源 pip install moviepy -i http://mirrors.aliyu…...
二进制搭建kubernetes
二进制搭建kubernetes 一、常见的K8S部署方式1.Minikube2.Kubeadmin3.二进制安装部署 二、二进制搭建K8S(单台master)1.部署架构规划2.系统初始化配置3.部署 docker引擎4.部署 etcd 集群4.部署 Master 组件5.部署 Worker Node 组件6.部署网络组件 三、负载均衡部署1.配置load b…...
TDengine函数大全-系统函数
以下内容来自 TDengine 官方文档 及 GitHub 内容 。 以下所有示例基于 TDengine 3.1.0.3 TDengine函数大全 1.数学函数 2.字符串函数 3.转换函数 4.时间和日期函数 5.聚合函数 6.选择函数 7.时序数据库特有函数 8.系统函数 系统函数 TDengine函数大全DATABASECLIENT_VERSIONSE…...
北京互联网营销服务商浩希数字科技申请1350万美元纳斯达克IPO上市
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,总部位于北京的互联网营销服务商浩希数字科技(Haoxi Health Technology Limited )近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯…...
ElementUI浅尝辄止22:Alert 警告
用于页面中展示重要的提示信息。 常见于消息提示或警告框。 1.如何使用? 页面中的非浮层元素,不会自动消失。 //Alert 组件提供四种主题,由type属性指定,默认值为info。<template><el-alerttitle"成功提示的文案&…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
