1. 缓存优化(Redis)
1. 配置
1.1. Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.2. 配置Redis
1.3. 调整key的序列化
//这个是配置类,调整redis的序列化方式,如果不调整的话,存进去的值经过序列化后输出的值相当于乱码
//修改其序列化器为StringRedisSerializer
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
//默认的Key序列化器为:JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
2. 缓存短信验证码
之前缓存在session中,现在转为redis
3. 缓存菜品数据(经常使用的菜品)
注意:如果添加或者更新了菜品,需要清理缓存数据,以达到数据库中数据和缓存中数据一致
二.Spring Cache
1.简介
spring:
#配置应用名称,可选
application:
name: regie_take_out #如果不配置默认是工程名(也就是src上层的名字)
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/shanghai&useUnicode=true&characterEncoding=utf-8
username: root
password: jiarong520
cache:
redis:
time-to-live: 1800000#设置缓存数据的过期时间
#配置reids
redis:
host: 192.168.10.100
port: 6379
password: 123456
database: 0
mvc:
hiddenmethod:
filter:
enabled: true
2. 使用
2.1. @EnableCaching
放到启动类上,开启缓存 注解功能
2.2.@CacheAble
这个方法就算在数据库中查找不到值,也会将数据null缓存,因此我们需要设定条件:unless = “#result == null”,当查找数据库的值为null不缓存
/*
* condition:满足条件才缓存(没有#result)
* unless:满足条件不缓存(有#result)
* */
@Cacheable(value = "userCache",key = "#id", unless = "#result == null")
@GetMapping("/{id}")
public User getById(@PathVariable Long id){
User user = userService.getById(id);
return user;
}
//查询条件不同,对应的值也会不同,key也要因此区别
@Cacheable(value = "userCache",key = "#user.id +''+#user.name")
@GetMapping("/list")
public List<User> list(User user){
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(user.getId() != null,User::getId,user.getId());
queryWrapper.eq(user.getName() != null,User::getName,user.getName());
List<User> list = userService.list(queryWrapper);
return list;
}
2.3. @CachePut(方法的返回值放入缓存)
/*
* value = "userCache"相当于开辟了一个名为userCache的缓存空间
* CachePut:将方法的返回值(user)放入缓存
* #result——方法的返回值(user)
* */
@CachePut(value = "userCache",key = "#result.id")
@PostMapping
public User save(User user){
userService.save(user);
return user;
}
#result——方法的返回值
#user——与自定义中的User user保持一致,也就是传入的参数
2.4. @CacheEvict(删除缓存)
@CacheEvict(value = "userCache",key = "#id")
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id){
userService.removeById(id);
}
@DeleteMapping
@CacheEvict(value = "setMealCache",allEntries = true)
public Result<String> deleteByIds(@RequestParam List<Long> ids) {
log.info("要删除的套餐id为:{}", ids);
setmealService.removeWithDish(ids);
return Result.success("删除成功");
}
获取参数:
1. key = #id
2. key = #root.args[0]——如果是1的话就是第二个参数
3. key = #p[0] —— 如果是#p[1]就是第二个参数
allEntries = true : 删除这个分类套餐下的所有缓存数据
3. 注意事项
3.1. 用缓存的方法的返回对象要实现序列化接口(implements Serializable)
public class Result<T> implements Serializable
三.读写分离
1. Mysql主从复制
1. 主库配置
server-id = 100是自定义的服务器唯一标识,只要确保多台服务器的唯一标识不同即可
/mysql
去查找[mysql]位置
修改完后需要重启mysql:
systemctl restart mysql
登录mysql数据库:
mysql -uroot -proot
注意,执行以上操作后就不要再执行其他操作了,否则上面的文件位置会发生变化
2. 从库配置
登录Mysql数据库指令: mysql -uroot -proot
注意:上面类似表格的输出将内容复制粘贴到文本文件查看才清晰
3. 用Sharding-JDBC实现读写分离
3.1. 配置
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
spring:
shardingsphere:
datasource:
names: #数据源的名称,上下对应
master,slave
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# 后面的rw是数据库的名字
url: jdbc:mysql://192.168.138.100:3306/rw?characterEncoding=utf-8
username: root
password: root
# 从数据源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.138.101:3306/rw?characterEncoding=utf-8
username: root
password: root
masterslave:
# 读写分离配置
# 从库负载均衡策略
load-balance-algorithm-type: round_robin #轮询
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master
# 从库数据源名称列表,多个逗号分隔
slave-data-source-names: slave
props:
sql:
show: true #开启SQL显示,默认false
main:
allow-bean-definition-overriding: true
2. 项目中实现
配置到项目中后项目中原先的dateSource就不需要了(下面这部分不需要)
四.Nginx
1. 简介
2. 下载和安装
yum -y install gcc pcre-devel zlib-devel openssl spenssl-devel
tar -zxvf nginx-1.16.1.tar.gz
cd nginx-1.16.1
./configure --prefix=/usr/local/nginx
make && make install
3. Nginx 目录结构
树形结构:
yum install tree
tree
4. Nginx常用命令
1. 查看版本(./nginx -v)
注意在 这个目录下
2. 检查配置文件的正确性(./nginx -t)
3. 启动或停止服务
4. 重新加载配置文件(./nginx -s reload)
5. 将nginx路径配置到环境变量
cd /
vim ect/profile
source etc/profile
5. Nginx配置文件结构(conf/nginx.conf)
cd /usr/local/nginx/conf/nginx.conf
全局块:文件开始到events块之前
上面Server块定义了端口号
6. Nginx具体应用
部署静态资源
反向代理
负载均衡
1.部署静态资源 (比tomcat高效)
只需要将文件复制到Nginx安装目录下的html目录
index index.html:指的是默认的首页,如果我们直接输入ip地址没有在后面附加什么html页面就会显示这个默认的页面
2. 反向代理
区别:
正向代理:用户在客户端设置代理服务器(知道代理服务器和目标服务器)
反向代理:用户把反向代理服务器当作目标服务器,访问反向代理服务器就得到结果(无需知道目标服务器的地址,也无需设定)
只需要在conf/nginx.conf配置以下信息即可
Web服务器要跑jar包
java -jar
3. 负载均衡
targetserver自定义:上下对应就好
负载均衡策略
默认是轮询操作
如果是权重则:
五. 前后端分离
1.YApi
2.Swagger
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
@Slf4j
@Configuration
@EnableSwagger2
@EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 设置静态资源映射
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始进行静态资源映射...");
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
/**
* 扩展mvc框架的消息转换器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器...");
//创建消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//设置对象转换器,底层使用Jackson将Java对象转为json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//将上面的消息转换器对象追加到mvc框架的转换器集合中
converters.add(0,messageConverter);
}
@Bean
public Docket createRestApi() {
// 文档类型
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.itheima.reggie.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("瑞吉外卖")
.version("1.0")
.description("瑞吉外卖接口文档")
.build();
}
}
常用注解(http://localhost:8080/doc.html#/home查看)
3. 项目部署
3.1. 部署前端项目
如果没有rewrite:
代理后的路径:http:// 192.168.138.101:8080/api/employee/login
但是我们想要的是:http:// 192.168.138.101:8080/employee/login(没有/api)
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass
}
上面的$1匹配的就是前面.*的内容
3.2. 部署后端项目
jdk: java -version检查
maven : mvn -v检查
git: yum install git 安装
chmod 777 reggieStart.sh
注意:图片位置在Linux需要修改(改成以下格式)