技术栈
项目结构
POJO,VO,DTO,Entity
比如说前后端通过json来传输数据,就需要用到DTO。需要展示前端的(列表,表单)数据,就需要VO。entity,dto,vo都属于pojo,只是为了功能的区别二细分。
nginx
反向代理
就是将前端发送的动态请求由 nginx 转发到后端服务器
意义:
-
提高访问速度(做了数据缓存nginx就直接可把数据返回,不需要真正地访问服务端)
数据缓存就相当于将从前端的数据提前存储到nginx(这里的nginx就相当于一个存储数据的容器)中,让tomcat可以随取随用。
把tomcat比作一只小猫,浏览器比作人,nginx相当于猫粮的盆,人通过路径http://localhost/api/employee/login把猫粮放在盆子里面,tomcat通过http://localhost:8080/admin/employee/login把猫粮吃掉,nginx就充当了存储猫粮的角色,
-
进行负载均衡(把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器)
-
后端服务安全(后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口)
使用例子,nginx.conf配置文件中的相关内容如下:
server {
listen 90; # 运行端口
server_name localhost;
# 反向代理,处理管理端发送的请求
location /api/ {
proxy_pass http://localhost:8080/admin/;
#proxy_pass http://webservers/admin/;
}
# 反向代理,处理用户端发送的请求
location /user/ {
proxy_pass http://webservers/user/;
}
如果用户在浏览器访问http://localhost/api/employee/login,首先是nginx先接收用户的请求,根据nginx.conf配置文件中的配置,转到http://localhost:8080/admin/,所以根据配置/api更换为/admin,最后组装起来的请求地址为http://localhost:8080/admin/employee/login,和后台服务的访问地址一致。
负载均衡
所谓的负载均衡就是把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器。
名称 | 说明 | 实际运用 |
轮询 | 默认方式 | 适用于后端服务器性能配置完全相同的集群场景 |
weight | 权重方式,默认为1,权重越高,被分配的客户端请求就越多 | 适用于服务器性能不均等的场景,如新老服务器混用(新服务器配置高,设置更大权重) |
ip_hash | 依据ip分配方式,这样每个访客可以固定访问一个后端服务 | 适用于需要会话保持的场景,如:购物车系统,用户登录状态维护,文件上传/下载等需要连续会话的业务 |
least_conn | 依据最少连接方式,把请求优先分配给连接数少的后端服务 | 适用于处理长连接的场景,如:实时通讯服务(WebSocket),游戏服务器,视频流媒体服务 |
url_hash | 依据url分配方式,这样相同的url会被分配到同一个后端服务 | 适用于资源缓存优化的场景,如: 静态资源服务器(图片/CSS/JS) |
fair | 依据响应时间方式,响应时间短的服务将会被优先分配 | 适用于服务器性能差异较大或需要动态调整的场景 |
使用权重方式进行负载均衡配置:
完善登录功能
密码加密-MD5
代码实现:使用Spring加密工具类-DigestUtils实现
注意MD5是不可逆的
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
/**
* 员工登录
*
* @param employeeLoginDTO
* @return
*/
public Employee login(EmployeeLoginDTO employeeLoginDTO) {
String username = employeeLoginDTO.getUsername();
String password = employeeLoginDTO.getPassword();
//1、根据用户名查询数据库中的数据
Employee employee = employeeMapper.getByUsername(username);
//2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)
if (employee == null) {
//账号不存在
throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
}
//密码比对
password = DigestUtils.md5DigestAsHex(password.getBytes()); // 使用 MD5 加密密码
// 暂略
//3、返回实体对象
return employee;
}
}
MD5可以被破解,所以现在流行的是加盐。解密MD5的网址:MD5在线加密/解密/破解—MD5在线
在线接口
使用接口管理平台Yapi导入与管理接口,利用Swagger(knife4j)生成在线接口调试页面
knife4j常用注解
注解 | 说明 |
@Api | 用在类上,例如Controller,表示对类的说明 |
@ApiModel | 用在类上,例如entity、DTO、VO |
@ApiModelProperty | 用在属性上,描述属性信息 |
@ApiOperation | 用在方法上,例如Controller的方法,说明方法的用途、作用 |
- 在pom.xml文件中导入坐标
<!-- knife4j依赖 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
-
在config包下的配置类中添加knife4j配置
@Bean表示由Spring框架创建且管理此对象(Docket);
在apiinfo中创建接口文档的信息,比如标题,版本与描述;
/**
通过knife4j生成接口文档
@return
*/
@Bean // 注解作用 由Spring创建并管理此对象(Docket)
public Docket docket() {
ApiInfo apiInfo = new ApiInfoBuilder() // apiInfo对象生成接口文档的信息
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo) // 生成接口文档信息
.select()
// (重要!)指定接口文档需要扫描的包,扫描controller下的包与方法来生成接口文档
.apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
-
设置静态资源映射,否则接口文档页面无法访问
/**
设置静态资源映射
@param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
使用例
package com.sky.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(description = "员工登录时传递的数据模型")
public class EmployeeLoginDTO implements Serializable {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}