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

瑞吉外卖2.0 Redis 项目优化 Spring Cache MySQL主从复制 sharding-JDBC Nginx

Git版本控制

Linux从安装到实战&瑞吉外卖项目部署

Redis基础

Redis入门 redis.io

nosql没有表的概念

注意关闭防火墙

systemctl stop firewalld

启动redis

 src/redis-server ./redis.conf

数据类型

常用命令

字符串 string 操作命令

哈希 hash 操作命令

列表list(类似 栈 )操作命令

集合set 操作命令

sdiff key1 [key2] :key1-key2;

有序集合 sorted set (zset) 操作命令

通用命令

TTL return -1 表示永久;

在Java中操作Redis

介绍

Jedis

Spring Data Redis

Redis服务默认会给16个数据库在redis.windows.conf里面修改

默认是在0号数据库操作,更换数据库:select 1

String
hash
List
Set
ZSet
通用操作,针对不同数据类型都可以操作

项目优化-缓存优化

环境搭建

如何查看本地Ip

配置RedisConfig:为了自定义序列化器

@Configuration
public class RedisConfig extends CachingConfigurerSupport {@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();//默认的Key序列化器为:JdkSerializationRedisSerializerredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}
}

缓存短信验证码

保存方式:Session-->Redis

  @Autowiredprivate RedisTemplate redisTemplate;
@PostMapping("/sendMsg")public R<String> sendMsg(@RequestBody User user, HttpSession session){String phone = user.getPhone();//获取手机号if(StringUtils.isNotEmpty(phone)){//手机号非空//工具类 生成随机的4位验证码String code = ValidateCodeUtils.generateValidateCode(4).toString();log.info("code={}",code);//调用阿里云提供的短信服务API("签名","模板",手机号,动态验证码)完成发送短信//SMSUtils.sendMessage("瑞吉外卖","",phone,code);//需要将生成的验证码保存到Session//session.setAttribute(phone,code);//将生成的验证码保存到SessionredisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);return R.success("手机验证码短信发送成功");}return R.error("短信发送失败");}
@PostMapping("/login")public R<User> login(@RequestBody Map map, HttpSession session){log.info(map.toString());//获取手机号String phone = map.get("phone").toString();//获取验证码String code = map.get("code").toString();//从Session中获取保存的验证码//Object codeInSession = session.getAttribute(phone);//从redis中获得缓存的验证码Object codeInSession = redisTemplate.opsForValue().get(phone);//进行验证码的比对(页面提交的验证码和Session中保存的验证码比对)if(codeInSession != null && codeInSession.equals(code)){//如果能够比对成功,说明登录成功LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getPhone,phone);User user = userService.getOne(queryWrapper);if(user == null){//判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册user = new User();user.setPhone(phone);user.setStatus(1);userService.save(user);}session.setAttribute("user",user.getId());//如果用户登录成功,删除redis中缓存的验证码redisTemplate.delete(phone);return R.success(user);}return R.error("登录失败");}

链接redis报错 ERROR org.springframework.boot. ; ERR invalid password;java.io.IOException:

缓存菜品数据

 @GetMapping("/list")//改造listpublic R<List<DishDto>> list(Dish dish){List<DishDto> dishDtoList =null;//动态构造keyString key="dish_"+dish.getCategoryId()+"_"+dish.getStatus();////1.先从redis中获取缓存数据,按照菜单分类缓存dishDtoList= (List<DishDto>) redisTemplate.opsForValue().get(key);if(dishDtoList != null) {//2.如果存在!=null,直接返回,不用查询数据库return R.success(dishDtoList);}//构造查询条件LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(dish.getCategoryId() != null ,Dish::getCategoryId,dish.getCategoryId());//添加条件,查询状态为1(起售状态)的菜品queryWrapper.eq(Dish::getStatus,1);//添加排序条件 排序顺序,创建时间倒序queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);List<Dish> list = dishService.list(queryWrapper);dishDtoList = list.stream().map((item) -> {DishDto dishDto = new DishDto();BeanUtils.copyProperties(item,dishDto);Long categoryId = item.getCategoryId();//分类id//根据id查询分类对象Category category = categoryService.getById(categoryId);if(category != null){String categoryName = category.getName();dishDto.setCategoryName(categoryName);}//当前菜品的idLong dishId = item.getId();LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);//SQL:select * from dish_flavor where dish_id = ?List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);dishDto.setFlavors(dishFlavorList);return dishDto;}).collect(Collectors.toList());//3.不存在,需要查询数据库,将查询到的数据缓存到redisredisTemplate.opsForValue().set(key,dishDtoList,60, TimeUnit.HOURS);//60分钟return R.success(dishDtoList);}
@PostMappingpublic R<String> save(@RequestBody DishDto dishDto){log.info(dishDto.toString());dishService.saveWithFlavor(dishDto);//1.更新完 就清理所有缓存数据//Set keys = redisTemplate.keys("dish_*");//获得所有以‘dish_’开头的key//redisTemplate.delete(keys);//2.精确 清理缓存数据(只清理 被更新类别 的缓存数据)String key="dish_" + dishDto.getCategoryId()+"_1";redisTemplate.delete(key);return R.success("新增菜品成功");}@PutMapping//改造update&savepublic R<String> update(@RequestBody DishDto dishDto){log.info(dishDto.toString());dishService.updateWithFlavor(dishDto);//1.更新完 就清理所有缓存数据//Set keys = redisTemplate.keys("dish_*");//获得所有以‘dish_’开头的key//redisTemplate.delete(keys);//2.精确 清理缓存数据(只清理 被更新类别 的缓存数据)String key="dish_" + dishDto.getCategoryId()+"_1";redisTemplate.delete(key);return R.success("修改菜品成功");}

Spring Cache框架

介绍 基于注解的缓存 (Cache译为缓存)

常用注解

#result: 代表方法返回值(condition关键字里没有result用unless代替); #root.method: 方法对象 ;

#root.args[0] / #p0 / #a0(a0我感觉也行) : 方法第一个参数

使用方式

缓存套餐数据

项目优化—读写分离

Mysql主从复制

配置主库Master

先登录 mysql -uroot -p1234(你的密码)

GRANT REPLICATION SLAVE ON *.* to 'xiaoming'@'%' identified by 'Root@1234';(我的密码比他少两位)

从库Slave #192.168.138.132; root@1234

关闭防火墙链接mysql

 change master to master_host='192.168.138.100',master_user='xiaoming',master_password='Root@1234',master_log_file='mysql-bin.000001',master_log_pos=439;

后两个要跟这里的对应;

测试主从复制连接

主库怎么操作,从库也会复制操作;就说明链接成功

读写分离案例

背景

sharding-JDBC介绍

入门案例

项目实现读写分离

直接往主库里面导入,从库就会自动复制;

报错:

create connection SQLException, url: jdbc:mysql://192.168.138.100:3306/reggie?characterEncoding=utf-8, errorCode 0, state 08S01

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

create connection SQLException, url: jdbc:mysql://192.168.138.100:3306/reggie?characterEncoding=utf-8, errorCode 0, state 08S01

修改两个URL:

url: jdbc:mysql://192.168.138.101:3306/rw?characterEncoding=utf-8&useSSL=false

Nginx

Nginx概述

1.5安装wget

4.5 创建文件夹 :mkdir -p /usr/local/nginx ; 6:先编译然后 install; 安装tree命令查看目录结构

Nginx命令

查看版本

要先cd /usr/local/nginx/sbin

检查配置文件正确性

启动和停止

关闭防火墙: systemctl stop firewalld ; 如下页面,访问成功

重新加载配置文件

要写路径启动nginx -->不想写路径;

解决方案:把nginx的二进制文件路径配置到系统的环境变量 实现 nginx 即可启动的效果

vim /etc/profile
PATH=$JAVA_HOME/bin:$PATH   # 追加成下面的
PATH=/usr/local/nginx/sbin:$JAVA_HOME/bin:$PATH
source /etc/profile
nginx -s reload  # 不报错说明添加环境变量成功

Nginx配置文件结构

全局块、Events块、Http块

Nginx具体应用

部署静态资源

部署html成功

反向代理(用的最多)

负载均衡

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

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

相关文章:

瑞吉外卖2.0 Redis 项目优化 Spring Cache MySQL主从复制 sharding-JDBC Nginx

Git版本控制Linux从安装到实战&瑞吉外卖项目部署Redis基础Redis入门 redis.ionosql没有表的概念注意关闭防火墙 systemctl stop firewalld启动redissrc/redis-server ./redis.conf数据类型常用命令字符串 string 操作命令哈希 hash 操作命令列表list(类似 栈 )操作命令集合…...

【C++】从0到1入门C++编程学习笔记 - 提高编程篇:STL常用容器(map/ multimap容器)

文章目录一、map基本概念二、map构造和赋值三、map大小和交换四、map插入和删除五、map查找和统计六、map容器排序一、map基本概念 简介&#xff1a; map中所有元素都是pairpair中第一个元素为key&#xff08;键值&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素…...

十一、Gio->Resource

struct GResource {/* No available fields */ }应用程序applications和库libraries通常包含二进制或文本数据&#xff0c;这些数据实际上是应用程序的一部分&#xff0c;而不是用户数据。例如GtkBuilder .ui文件&#xff0c;splashscreen图像&#xff0c;GMenu标记XML, CSS文件…...

vm+centos设置NAT

centos 设置 NAT模式 系统环境 VMWare&#xff1a; Workstation16 Pro centos&#xff1a;7.9 [rootowl owl]# cat /etc/centos-release CentOS Linux release 7.9.2009 (Core)[rootowl owl]# uname -a Linux owl.com 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 U…...

Metaprogram 对一个程序进行编程

metaprogram含有对一个程序进行编程的意思&#xff0c;换句话说&#xff0c;编程系统将会执行我们所写的代码&#xff0c;来生成新的代码&#xff0c;而这些新的代码才真正实现了我们所期望的功能&#xff0c;通常而言&#xff0c;metaprogram 这个概念意味着一种反射的特性&am…...

【测开篇】测试基础

文章目录名词解释&#xff1a;1. 什么是需求&#xff1f;2. 什么是Bug&#xff1f;3. 什么是测试用例&#xff1f;软件的生命周期开发模型1. 瀑布模型2. 螺旋模型3. 增量模型和迭代模型4. 敏捷模型测试模型1. V模型2. W模型软件测试的生命周期Bug如何描述一个Bug&#xff1f;Bu…...

力扣第331场周赛题解

rankT1T2T3T4331 / 42560:01:460:06:18 (1)0:11:580:57:29 (4) T1 从数量最多的堆取走礼物模拟题&#xff0c;每次操作找出最大值maxxmaxxmaxx并将其变成sqrt(maxx)sqrt(maxx)sqrt(maxx)&#xff0c;kkk次操作后求和。 数据范围很小&#xff0c;可以暴力模拟&#xff0c;更好的…...

基于LDA模型的非监督分类算法介绍

前言基于LDA&#xff08;Latent Dirichlet Allocation&#xff09;模型的非监督分类算法&#xff0c;将LDA模型从文本分析的应用过渡到遥感高分辨率影像处理的应用&#xff0c;利用Gibbs采样方法设计基于LDA模型的非监督分类算法&#xff0c;并使用IDL语言实现。在一定程度上解…...

以安全有效为目标的综合运营

一、安全行业的现状所有做安全的方案大多会在开始介绍安全的案例&#xff0c;都会列举近期国内外发生的重大安全事件&#xff0c; 基本上都是惨不忍睹&#xff0c;危害巨大。这里就不一一列举了&#xff0c;稍微了解这个行业的人都能看到大量的案例。但业界又有个很奇怪的现象就…...

mysql常见面试题--03 事务常考题以及事务的隔离

什么是事务&#xff1f; 对数据库的一系列操作,要么全执行,要么不执行. 事务时逻辑上的一组操作&#xff0c;要么全部执行&#xff0c;要么都不执行。 事务的三大特征 原子性 A 事务是最小执行单位&#xff0c;要么全部执行&#xff0c;要么都不执行一致性 C 事务执行前后&…...

数据库管理工具dbForge SQL Complete 如何增强总两个开发团队之间的协作

Devart 提供包括Oracle、SQL Server、MySQL、PostgreSQL、InterBase以及Firebird在内的专业数据库远程管理软件&#xff0c;dbForge Studio for MySQL是一个在Windows平台被广泛使用的MySQL客户端&#xff0c;它能够使MySQL开发人员和管理人员在一个方便的环境中与他人一起完成…...

Cuda Streams的概述(一)-- Cuda介绍

最近在做有关Cuda的一个项目&#xff0c; 碰到匪夷所思的问题&#xff0c;在异步的时候发现并没有达到预期的效果&#xff0c;程序没有异步起来&#xff0c;然后在网上找了一个Nvida的有关Cuda Streams的一个ppt&#xff0c;然后照着里面的提示&#xff0c;使程序达到了异步的效…...

Docker介绍与入门

1. Mac版Docker(DfM) Mac版Docker底层是基于Linux VM运行的。Server的OS/Arch属性中显示的值是linux/amd64Client组件是原生的Mac应用&#xff0c;运行在Mac操作系统Darwin内核之上 2. 升级Docker引擎 需要重视升级前的每个前置条件&#xff0c;包括确保容器配置了正确的重启…...

Docker引擎介绍

1. Docker引擎简介 Docker引擎是用来运行和管理容器的核心软件Docker引擎主要的组件构成&#xff1a;Docker客户端&#xff08;Docker Client&#xff09;&#xff0c; Docker守护进程&#xff08;Docker deamon&#xff09;&#xff0c;containerd以及runc。 2. Docker引擎详…...

纵观Docker

1. 运维视角 两个主要部件&#xff1a; Docker客户端和Docker daemon&#xff08;daemon实现了Docker引擎的API&#xff09;使用linux默认安装的时候&#xff0c;客户端与daemon之间的通信是通过本地IPC/UNIX Socket完成的 1.1. 容器 docker container run – 从镜像启动容…...

Cuda Streams的概述(二) -- cuda Streams介绍

Cuda Streams Streams介绍&#xff1a; 流可以看成是在设备上work的一个队列&#xff0c;host端将work加入队列&#xff0c;然后继续添加。设备在资源free时&#xff0c;开始调度streams里面的work。CUDA的操作也是在流里面&#xff0c;比如Kernel的启动&#xff0c;内存的拷…...

Cuda Streams的概述(三)-- 并发内存拷贝

并发内存拷贝 首先&#xff0c;回顾一下CUDA的内存。 设备内存&#xff1a; 通过cudaMalloc申请内存。不能分页 主机端可分页内存&#xff1a; 默认申请方式&#xff08;malloc&#xff0c; calloc&#xff0c;new&#xff09;可以在OS中调入和调出。 主机端页锁内存&#xf…...

Cuda Streams的概述(四)-- 同步

同步 同步的APIs 同步所有的事情 //阻塞host端&#xff0c;直到所有的CUDA调用完成。 cudaDeviceSynchronize();同步主机端特定的流 //阻塞host端&#xff0c;直到流里的CUDA调用完成。 cudaStreamSynchronize(stream); 通过主机端或设备用events CUDA Events 当操作在流…...

Cuda Streams的概述(五)-- Streaming性能

Streaming性能 profiling工具 windows&#xff1a; Nsight Visual Studio EditionNVIDIA Visual Profiler Linux&#xff0c;Mac&#xff1a; Nsight Eclipse EditionNVIDIA Visual Profilernvprof NVVP PROFILER TIMELINE Host API CallsMulti-threadedMulti-GPUMulti-pro…...

Cuda Streams的概述(六)-- 常见问题

常见问题 问题1:使用默认流 问题2&#xff1a;内存传输问题 问题3:隐式同步 问题4:主机端的限制 问题5:启动overhead限制 问题6:过度同步 问题7&#xff1a;PROFILER OVERHEAD case 1-A for(int i0;i<repeat;i) {kernel<<<1,1,0,stream1>>>();ke…...