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

【SpringBoot3+Vue3】三【实战篇】-后端(优化)

目录

一、登录优化-redis

1、SpringBoot集成redis

1.1 pom

1.2 yml 

1.3 测试程序(非必须)

1.4 启动redis,执行测试程序 

2、令牌主动失效(代码优化)

2.1  UserController设置token到redis

2.2 登录拦截器LoginCheckInterceptor

2.3 UserController更新密码删除redis的token(jwt)

2.4 验证

2.4.1 调用登录接口

2.4.2 调用更新密码接口 ​编辑

二、SpringBoot项目部署

1、pom检查是否有打包插件

 2、打包

3、运行jar

4、测试

三、属性配置方式 

1、命令参数方式

2、环境变量方式

3、外部配置文件方式

 4、配置优先级

四、多环境开发-Profiles 

1、多环境开发-介绍

2、 多环境开发-Profiles(同一个yaml)

3、多环境开发-Profiles(不同yml)

4、多环境开发-Profiles(分组)


前言:针对【SpringBoot3+Vue3】二篇进行一些后端优化和一些实用的后端技术

一、登录优化-redis

1、SpringBoot集成redis

1.1 pom

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

1.2 yml 

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springbdfdfoot_vue?serverTimezone=UTCusername: rootpassword: ddfdfdfdmain:banner-mode: off  # 关闭控制台springboot的logodata:redis:host: localhostport: 6379

1.3 测试程序(非必须)

package com.bocai;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;import java.util.concurrent.TimeUnit;@SpringBootTest //如果在测试类上添加这个注解,那么将来单元测试方法执行之前,会先初始化Spring容器
public class RedisTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testpublic void testSet(){// 往redis中存储一个键值对  StringRedisTemplateValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.set("username","仓颉书");operations.set("woman","舒淇",15, TimeUnit.SECONDS); //设置有效时间}@Testpublic void testGet(){//从redis获取一个键值对ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();System.out.println(operations.get("username"));}
}

1.4 启动redis,执行测试程序 

2、令牌主动失效(代码优化)

2.1  UserController设置token到redis

登录完成生成token时,同时将token存储到redis,按键值对方式,注意设置了时效要与token生成时的时效一致性。

package com.bocai.controller;import com.bocai.common.Result;
import com.bocai.pojo.User;
import com.bocai.service.UserService;
import com.bocai.utils.JwtUtils;
import com.bocai.utils.Md5Util;
import com.bocai.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@RestController
@Slf4j
@Validated
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 用户注册* @param username* @param password* @return*/@PostMapping("/register")public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password){log.info("注册用户名:{},密码为:{}",username,password);// 查询用户User user = userService.queryUserByUsername(username);if (user == null){//没有占用,可以注册//注册用户userService.register(username,password);return Result.success();}else{return Result.error("用户名被占用");}}@PostMapping("/login")public Result login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password) {log.info("登录用户名:{},密码为:{}", username, password);// 查询用户User loginUser = userService.queryUserByUsername(username);// 判断用户是否存在if (loginUser == null) {return Result.error("用户名不存在");}// 判断密码是否正确,loginUser对象中的password是密文if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){// 登录成功Map<String, Object> claims = new HashMap<>();claims.put("id", loginUser.getId());claims.put("username",loginUser.getUsername());String jwt = JwtUtils.generateJwt(claims); //让jwt包含了当前登录的员工信息// 把token存储到redisValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.set(jwt,jwt,12, TimeUnit.HOURS); //过期时间与jwt设置的时效要一致性return Result.success(jwt);}return Result.error("密码错误!");}/*** 查询用户信息(从线程获取)* @return*/@GetMapping("/userInfo")public Result userInfo(){// 从线程获取存储的jwt信息Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");log.info("查询用户全部信息,从token获取信息为:{}",username);//根据用户名查询用户User user = userService.queryUserByUsername(username);return Result.success(user);}//使用上面的的优化版本
//    /**
//     * 查询用户信息(从token获取)
//     * @param token
//     * @return
//     */
//    @GetMapping("/userInfo")
//    public Result userInfo(@RequestHeader(name = "Authorization")String token){
//        log.info("查询用户全部信息,从token获取信息为:{}",token);
//        //根据用户名查询用户
//        Map<String, Object> claims = JwtUtils.parseJWT(token);
//        String username = (String) claims.get("username");
//        User user = userService.queryUserByUsername(username);
//        return Result.success(user);
//    }/*** 更新用户* @param user* @return*/@PutMapping("/update")public Result update(@RequestBody @Validated  User user){log.info("修改的用户为:{}",user);userService.updateUser(user);return Result.success();}/*** 更新头像* @param avatarUrl* @return*/@PatchMapping("/updateAvatar")public Result updateAvatar(@RequestParam @URL String avatarUrl){log.info("头像地址是{}",avatarUrl);userService.updateAvatar(avatarUrl);return Result.success();}/*** 更新密码* @param params json数据包含old_pwd,new_pwd,re_pwd* @return*/@PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String, String> params){log.info("修改密码传过来数据是:{}",params);// 1、校验参数String old_pwd = params.get("old_pwd");String new_pwd = params.get("new_pwd");String re_pwd = params.get("re_pwd");if(!StringUtils.hasLength(old_pwd) || !StringUtils.hasLength(new_pwd) || !StringUtils.hasLength(re_pwd)){return Result.error("缺少必要参数!");}//原密码是否正确Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User loginUser = userService.queryUserByUsername(username);if(!loginUser.getPassword().equals(Md5Util.getMD5String(old_pwd))){return Result.error("原密码不正确!");}//新、老密码是否一致if(old_pwd.equals(new_pwd)){return Result.error("新、老密码一样!!");}//新密码和确认密码不一致!if(!re_pwd.equals(new_pwd)){return Result.error("新密码和确认密码不一致!!");}// 2 、调用userServiceuserService.updatePwd(new_pwd);return Result.success();}
}

2.2 登录拦截器LoginCheckInterceptor

登录拦截器当中查询redis当中是否存在相同token(jwt),如果不存在所有失效了。抛出异常

package com.bocai.interceptor;import com.alibaba.fastjson.JSONObject;
import com.bocai.common.Result;
import com.bocai.utils.JwtUtils;
import com.bocai.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import java.util.Map;/***   =========================LoginCheckInterceptor 拦截器 interceptor========================*/
@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {//1.获取请求url。String url = req.getRequestURL().toString();log.info("请求的url: {}",url);//2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。if(url.contains("login")){log.info("登录操作, 放行...");return true;}//3.获取请求头中的令牌( Authorization)。String jwt = req.getHeader("Authorization");//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。if(!StringUtils.hasLength(jwt)){log.info("请求头Authorization为空,返回未登录的信息");Result error = Result.error("NOT_LOGIN");//手动转换 对象--json --------> 阿里巴巴fastJSONString notLogin = JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return false;}//5.解析token,如果解析失败,返回错误结果(未登录)。try {// 从redis中获取获取相同的token(jwt)ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();String redisJwt = operations.get(jwt);if(redisJwt == null){// token 已经失效throw new RuntimeException();}//解析jwtMap<String, Object> claims = JwtUtils.parseJWT(jwt);//6.把业务数据存储到ThreadLocal中ThreadLocalUtil.set(claims);//7.放行。log.info("令牌合法, 放行");return true;} catch (Exception e) {//jwt解析失败e.printStackTrace();log.info("解析令牌失败, 返回未登录错误信息");Result error = Result.error("NOT_LOGIN");//手动转换 对象--json --------> 阿里巴巴fastJSONString notLogin = JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return false;}}@Override //目标资源方法运行后运行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle ...");}@Override //视图渲染完毕后运行, 最后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 清空ThreadLocal中的数据,防止内存泄漏ThreadLocalUtil.remove();System.out.println("afterCompletion...");}
}

2.3 UserController更新密码删除redis的token(jwt)

更新密码的时候同时需要将redis存储的jwt删除掉。这里在更新密码方法上面使用从请求头当中获取Authorization

package com.bocai.controller;import com.bocai.common.Result;
import com.bocai.pojo.User;
import com.bocai.service.UserService;
import com.bocai.utils.JwtUtils;
import com.bocai.utils.Md5Util;
import com.bocai.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@RestController
@Slf4j
@Validated
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 用户注册* @param username* @param password* @return*/@PostMapping("/register")public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password){log.info("注册用户名:{},密码为:{}",username,password);// 查询用户User user = userService.queryUserByUsername(username);if (user == null){//没有占用,可以注册//注册用户userService.register(username,password);return Result.success();}else{return Result.error("用户名被占用");}}@PostMapping("/login")public Result login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password) {log.info("登录用户名:{},密码为:{}", username, password);// 查询用户User loginUser = userService.queryUserByUsername(username);// 判断用户是否存在if (loginUser == null) {return Result.error("用户名不存在");}// 判断密码是否正确,loginUser对象中的password是密文if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){// 登录成功Map<String, Object> claims = new HashMap<>();claims.put("id", loginUser.getId());claims.put("username",loginUser.getUsername());String jwt = JwtUtils.generateJwt(claims); //让jwt包含了当前登录的员工信息// 把token存储到redisValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.set(jwt,jwt,12, TimeUnit.HOURS); //过期时间与jwt设置的时效要一致性return Result.success(jwt);}return Result.error("密码错误!");}/*** 查询用户信息(从线程获取)* @return*/@GetMapping("/userInfo")public Result userInfo(){// 从线程获取存储的jwt信息Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");log.info("查询用户全部信息,从token获取信息为:{}",username);//根据用户名查询用户User user = userService.queryUserByUsername(username);return Result.success(user);}//使用上面的的优化版本
//    /**
//     * 查询用户信息(从token获取)
//     * @param token
//     * @return
//     */
//    @GetMapping("/userInfo")
//    public Result userInfo(@RequestHeader(name = "Authorization")String token){
//        log.info("查询用户全部信息,从token获取信息为:{}",token);
//        //根据用户名查询用户
//        Map<String, Object> claims = JwtUtils.parseJWT(token);
//        String username = (String) claims.get("username");
//        User user = userService.queryUserByUsername(username);
//        return Result.success(user);
//    }/*** 更新用户* @param user* @return*/@PutMapping("/update")public Result update(@RequestBody @Validated  User user){log.info("修改的用户为:{}",user);userService.updateUser(user);return Result.success();}/*** 更新头像* @param avatarUrl* @return*/@PatchMapping("/updateAvatar")public Result updateAvatar(@RequestParam @URL String avatarUrl){log.info("头像地址是{}",avatarUrl);userService.updateAvatar(avatarUrl);return Result.success();}/*** 更新密码* @param params json数据包含old_pwd,new_pwd,re_pwd* @param jwt 从请求头中获取Authorization赋值给jwt参数* @return*/@PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String, String> params,@RequestHeader("Authorization") String jwt){log.info("修改密码传过来数据是:{}",params);// 1、校验参数String old_pwd = params.get("old_pwd");String new_pwd = params.get("new_pwd");String re_pwd = params.get("re_pwd");if(!StringUtils.hasLength(old_pwd) || !StringUtils.hasLength(new_pwd) || !StringUtils.hasLength(re_pwd)){return Result.error("缺少必要参数!");}//原密码是否正确Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User loginUser = userService.queryUserByUsername(username);if(!loginUser.getPassword().equals(Md5Util.getMD5String(old_pwd))){return Result.error("原密码不正确!");}//新、老密码是否一致if(old_pwd.equals(new_pwd)){return Result.error("新、老密码一样!!");}//新密码和确认密码不一致!if(!re_pwd.equals(new_pwd)){return Result.error("新密码和确认密码不一致!!");}// 2 、调用userServiceuserService.updatePwd(new_pwd);// 更新密码之后,删除redis中对应的token(jwt)ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.getOperations().delete(jwt);return Result.success();}
}

2.4 验证

2.4.1 调用登录接口

2.4.2 调用更新密码接口 

二、SpringBoot项目部署

1、pom检查是否有打包插件

  <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>              
   </plugin>

 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>

 2、打包

插曲:

1、无效的标记: --release 

这里要与你得jdk版本一致性

2、注意test当中的case

3、运行jar

java -jar SS.jar

4、测试

三、属性配置方式 

1、命令参数方式

2、环境变量方式

 

3、外部配置文件方式

 4、配置优先级

四、多环境开发-Profiles 

1、多环境开发-介绍

2、 多环境开发-Profiles(同一个yaml)

3、多环境开发-Profiles(不同yml)

4、多环境开发-Profiles(分组)

分组实现

相关文章:

【SpringBoot3+Vue3】三【实战篇】-后端(优化)

目录 一、登录优化-redis 1、SpringBoot集成redis 1.1 pom 1.2 yml 1.3 测试程序&#xff08;非必须&#xff09; 1.4 启动redis&#xff0c;执行测试程序 2、令牌主动失效&#xff08;代码优化&#xff09; 2.1 UserController设置token到redis 2.2 登录拦截器Log…...

DevExpress中文教程 - 如何在macOS和Linux (CTP)上创建、修改报表(上)

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 DevExpress Reports — 跨平台报表组件&#x…...

一个iOS tableView 滚动标题联动效果的实现

效果图 情景 tableview 是从屏幕顶部开始的&#xff0c;现在有导航栏&#xff0c;和栏目标题视图将tableView的顶部覆盖了 分析 我们为了达到滚动到某个分区选中标题的效果&#xff0c;就得知道 展示最顶部的cell或者区头在哪个分区范围内 所以我们必须首先获取顶部的位置 …...

代码执行相关函数以及简单例题

代码/命令 执行系列 相关函数 &#xff08;代码注入&#xff09;...

大数据爬虫分析基于Python+Django旅游大数据分析系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Python和Django的旅游大数据分析系统是一种使用Python编程语言和Django框架开发的系统&#xff0c;用于处理和分…...

C# 结构体介绍

文章目录 定义结构体实例化结构体结构体的值类型特性结构体和类的区别限制 C# 中的结构体&#xff08;Struct&#xff09;是一种值类型数据结构&#xff0c;用于封装不同或相同类型的数据成一个单一的实体。结构体非常适合用来表示轻量级的对象&#xff0c;比如坐标点、颜色值或…...

【机器学习】特征工程:特征预处理,归一化、标准化、处理缺失值

特征预处理采用的是特定的统计方法&#xff08;数学方法&#xff09;将数据转化为算法要求的数字 1. 数值型数据 归一化&#xff0c;将原始数据变换到[0,1]之间 标准化&#xff0c;数据转化到均值为0&#xff0c;方差为1的范围内 缺失值&#xff0c;缺失值处理成均值、中…...

Pytorch torch.norm函数详解用法

torch.norm参数定义 torch版本1.6 def norm(input, p"fro", dimNone, keepdimFalse, outNone, dtypeNone)input input (Tensor): the input tensor 输入为tensorp p (int, float, inf, -inf, fro, nuc, optional): the order of norm. Default: froThe following …...

【DevOps】Git 图文详解(二):Git 安装及配置

Git 图文详解&#xff08;二&#xff09;&#xff1a;Git 安装及配置 1.Git 的配置文件2.配置 - 初始化用户3.配置 - 忽略.gitignore Git 官网&#xff1a;https://www.git-scm.com/ 下载安装包进行安装。Git 的使用有两种方式&#xff1a; 命令行&#xff1a;Git 的命令通过系…...

亚马逊美国站CPC认证ASTM F963测试项目要求有哪些?

ASTM F963是美国材料和试验联合会&#xff08;ASTM&#xff09;制定的儿童玩具安全性的标准规范&#xff0c;专门针对儿童玩具产品的安全性进行了规定和要求。 ASTM F963标准的内容和要求包括&#xff1a; 1、物理机械性能&#xff1a;规定了玩具的物理机械性能要求&#xff0…...

通付盾Web3专题 | KYT/AML:Web3合规展业的必要条件

与传统证券一样&#xff0c;基于区块链技术发展出来的虚拟资产交易所经历了快速发展而缺乏有效监管的行业早期。除了科技光环加持的各种区块链项目方、造富神话之外&#xff0c;交易所遭到黑客攻击、内部偷窃作恶、甚至经营主体异常而致使投资人血本无归的案例亦令人触目惊心。…...

Centos8配置Zabbix5.0中文汉化

1.点击【Sign in】按钮&#xff0c;输入用户名和密码进入Zabbix的首页&#xff0c;结果如图。 2.点击左边导航栏的【User settings】链接&#xff0c;进入用户个性化设置界面&#xff0c;结果如图。 3.在搭建Zabbix的虚拟机上使用yum命令下载中文包。 yum install glibc-langpa…...

元数据管理,数字化时代企业的基础建设

随着新一代信息化、数字化技术的应用&#xff0c;众多领域通过科技革命和产业革命实现了深度化的数字改造&#xff0c;进入到以数据为核心驱动力的&#xff0c;全新的数据处理时代&#xff0c;并通过业务系统、商业智能BI等数字化技术和应用实现了数据价值&#xff0c;从数字经…...

大数据之Hive:regexp_extract函数案例

目录 一、正则的通配符简介1、正则表达式的符号及意义2、各种操作符的运算优先级&#xff1a; 二、案例数据要求分析实现输出结果实现2实现3 总结 一、正则的通配符简介 1、正则表达式的符号及意义 符号含义实列/做为转意&#xff0c;即通常在"/"后面的字符不按原来…...

tsconfig.json无法写入文件“XXXX“因为它会覆盖输入文件

在开发ts项目的时候&#xff0c;包错提示无法写入文件&#xff1a; tsconfig.json无法写入文件"XXXX"因为它会覆盖输入文件 这是tsconfig.json文件配置问题&#xff0c;需要加入下面的配置就好了&#xff1a; {"compilerOptions": {"outDir": …...

本周Github有趣项目:draw-a-ui等

有趣的项目、工具和库 gpt-crawler 抓取网站以生成知识文件&#xff0c;从而从 URL 创建您自己的自定义 GPT。 需要步骤&#xff1a; 配置运行爬虫、 将您的数据上传到 OpenAI&#xff1a;使用此选项通过 UI 访问您生成的知识&#xff0c;您可以轻松与他人共享 创建自定义助…...

VBA如何快速识别Excel单元格中的文本数字

Excel中一种非常特殊的数字&#xff0c;这些数字看似数字&#xff0c;其实是文本格式&#xff08;下文简称为文本数字&#xff09;&#xff0c;在单元格的左上角会有一个绿色小三角作为标志&#xff0c;如B1:B3单元格。 在编程时为什么需要区分普通数字和文本数字呢&#xff…...

Mysql数据库 16.SQL语言 数据库事务

一、数据库事务 数据库事务介绍——要么全部成功要么全部失败 我们把完成特定的业务的多个数据库DML操作步骤称之为一个事务 事务——就是完成同一个业务的多个DML操作 例&#xff1a; 数据库事务四大特性 原子性&#xff08;A&#xff09;&#xff1a;一个事务中的多个D…...

docker 部署Redis集群(三主三从,以及扩容、缩容)

1&#xff1a;创建6个redis容器 docker run -d --name redis01 --net host --privilegedtrue -v /opt/redis/redis01:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381 docker run -d --name redis02 --net host --privilegedtrue -v /opt/redis/redis0…...

JavaScript 浮点数运算的精度问题及解决

JavaScript 浮点数运算的精度问题及解决 在 JavaScript 中整数和浮点数都属于 Number 数据类型&#xff0c;当浮点数做数学运算的时候&#xff0c;你经常会发现一些问题&#xff0c;举几个例子&#xff1a; 0.1 0.2 0.30000000000000004 console.log(0.1 0.2) 0.3000000…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...