4.9(day1)初始化
nginx负载均衡
1.反向代理,转发到指定路径
2.负载均衡策略
①轮训:依此分发
upstream backend_servers {
server 192.168.1.101;
server 192.168.1.102;
}
②带权轮训:按权重分发
upstream backend_servers {
server 192.168.1.101 weight=3; # 处理3个请求后轮到下一台
server 192.168.1.102 weight=1;
}
③哈希:固定分发(会话保持)
upstream backend_servers {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
}
④最少连接:分发到连接最少的服务器
upstream backend_servers {
least_conn;
server 192.168.1.101;
server 192.168.1.102;
}
MD5加密(不适用于密码)
如果两个密码完全相同 (包括字符大小写、空格、特殊字符等),并且在计算MD5哈希值时采用相同的编码方式 (如UTF-8),那么它们的MD5哈希值一定是相同的。这是因为MD5是一种确定性哈希函数,相同的输入必然生成相同的输出。因为hash算法是固定的,所以同一个字符串计算出来的hash串是固定的。
解决办法:加盐
为哈希添加随机盐(Salt)是防止彩虹表攻击。随机盐方式较为繁琐。
使用 BCrypt
(推荐,需第三方库)更安全的密码哈希方案
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.7.3</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
public class BCryptExample { public static void main(String[] args) { String rawPassword = "123456"; // 哈希密码(自动生成盐) BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12); // 强度系数 12 String hashedPassword = encoder.encode(rawPassword); // 验证密码 boolean isValid = encoder.matches(rawPassword, hashedPassword); System.out.println("验证结果: " + isValid); } }
彩虹表攻击
是一种预先计算的哈希值到明文密码的映射表,通过对比数据库泄露的哈希值与彩虹表中的条目,直接获取原始密码。
- 生成大量可能的密码。
- 对每个密码计算哈希值。
- 将
明文密码 -> 哈希值
的映射存储为表
Knife4j
@Api(tags = "员工相关接口")写在Controller上
@ApiOperation("员工登录")写在Controller方法上
参数中有实体类,会自动解析
@ApiModel(description = "员工登录时传递的数据模型")写在实体类方法上
@ApiModelProperty("用户名")写在实体类方法的属性上
打开接口文档http://localhost:8080/doc.html,图示对应上方代码顺序

4.10(day2)
JWT
生成token(Header.Payload.Signature)
Header:Base64编码(对称加密算法HS256) 注:只是算法名称,并未加密
Payload:Base64编码(参数)
Signature:HS256加密(Header+Payload)
ThreadLocal
线程隔离,为线程提供独立的副本,由ThreadLocalMap存储,一般用于传递用户信息
get/set 获取/设置当前线程变量
remove 防止线程泄漏
线程和进程
进程
计算机程序在进行某数据集合的一次运行活动,是操作系统进行资源分配的最小单位,是一次程序的实例
线程
线程是进程的执行单元,共享进程的共享资源,是CPU调度的基本单位
序列化
对象转为字节流,实现Serialization类
用途:
验证数据版本一致性(VersionID)
持久化存储 / 深拷贝
MVC消息转换器
将Http中的内容转化为JAVA对象,重写WebMvcConfigurationSupport类中的MappingJackson2HttpMessageConverter方法,基于反序列化实现,应用于多种数据格式的转换
4.12(day3)
MyBatis 中的 动态 SQL 和 静态 SQL
静态SQL:SQL固定不变,建议直接写Mapper层(注解方式)
name = #{name},
动态SQL:根据传入的参数动态拼接SQL语句
<if test="name != null">name = #{name},</if>
仅更新传递时带有的参数,其它参数不做更新
优点:多复用,状态更改,更新数据
4.13(day4)
AOP切面实现公共字段填充(INSERT,UPDATE)
自定义注解 @interface
@Target( ElementType.METHOD)//方法注解
@Retention(RetentionPolicy.RUNTIME)//运行时注解
OperationType value();枚举类
@Aspect 切面类
@Pointcut切点方法上
@Before("autoFillPointcut()")切点执行前执行
禁用外键约束
首先,外键一定是另一个表的主键,就会涉及到多个表之间的关联查询。
1.Upadte和Delete时都需要考虑外键约束
2.并发时行级锁导致性能下降
3.级联时会导致级联删除
4.导致耦合度高
@ConditionalOnMissingBean
用于配置类,避免Bean重复创建
Bean生命周期
实例化=>属性赋值=> 初始化 =>使用 =>销毁