SpringBoot优化

一、Git

1.1 Git简介与安装

  1. Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理。通过Git 仓库来存储和管理这些文件,Git仓库分为两种:
    本地仓库:开发人员自己电脑上的Git仓库
    远程仓库:远程服务器上的Git仓库

    commit:提交,将本地文件和版本信息保存到本地仓库
    push:推送,将本地仓库文件和版本信息上传到远程仓库
    pull:拉取,将远程仓库文件和版本信息下载到本地仓库
  2. 安装:Git官网下载地址,安装完在任意目录下右键显示Git GUI Here(Git图形界面)和Git Bash Here(Git命令行)即安装成功。

1.2 Git代码托管服务

  1. 常见Git代码托管服务
    (1)GitHub(地址: https://github.com/ ),是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub。
    (2)码云(地址: https://gitee.com/ ),是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快。
    (3)GitLab(地址: https://about.gitlab.com/ ),是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
    (4)BitBucket(地址: https://bitbucket.org/ ),是一家源代码托管网站,采用Mercurial和Git作为分布式版本控制系统,同时提供商业计划和免费账户。
  2. 使用码云创建新的仓库

1.3 Git常用命令

  1. Git全局设置:设置用户名称和Email地址,在Git命令行中执行以下命令
    (1) 设置用户信息(name和email只是一个标识,非必须是账号)
    git config --global user.name "superm"
    git config --global user.email "zhc_cg1999@163.com"
    (2) 查看配置信息
    git config --list
    
  2. 获取Git仓库
    (1)在本地初始化一个Git仓库:在任意空目录下右键打开Git Bash,执行命令git init,即可创建一个**.git隐藏文件夹**。
    (2)从远程仓库克隆:git clone https://gitee.com/superm_chao/superm-git-practice.git
  3. 工作区、暂存区、版本库
    (1)版本库:.git隐藏文件夹就是版本库,版本库中存储了很多配置信息、日志信息和文件版本信息等。
    (2)工作区:包含.git文件夹的目录就是工作区,也称为工作目录,主要用于存放开发的代码。
    (3)暂存区:.git文件夹中有很多文件,其中有一个index文件就是暂存区,也可以叫做stage,暂存区是一个临时保存修改文件的地方。
  4. Git工作区文件的状态
    (1)untracked:未跟踪(未被纳入版本控制)
    (2)tracked:已跟踪(被纳入版本控制),Unmodified(未修改状态);Modified(已修改状态);Staged(已暂存状态)
  5. 本地仓库操作
    (1)git status:查看文件状态
    (2)git add:将文件的修改加入暂存区(git add test.java)
    (3)git reset:将暂存区的文件取消暂存(git reset test.java)或者是切换到指定版本(git reset --hard 版本号)
    (4)git commit:将暂存区的文件修改提交到版本库(git commit -m “提交了一个test.java文件” test.java)
    (5)git log:查看日志,可以看出版本号
  6. 远程仓库操作
    (1)git remote:查看远程仓库(git remote -v)
    (2)git remote add:添加远程仓库(git remote add 远程仓库别名 远程仓库URL地址),将本地仓库与远程仓库进行关联
    (3)git clone:从远程仓库克隆(git clone 远程仓库URL地址)
    (4)git pull:从远程仓库拉取(git pull 远程仓库别名 分支名),对于本地初始化的仓库拉取需要加–allow-unrelated-histories
    (5)git push:推送到远程仓库(git push 远程仓库别名 分支名),第一次需要进行身份认证(码云的账号和密码)
  7. 分支操作
     分支可以把工作从开发主线上分离开来,同一仓库可以有多个分支,各个分支相互独立,互不干扰。
    (1)git branch:查看分支,git branch(查看本地分支);git branch -r(查看远程分支);git branch -a(查看所有分支)
    (2)git branch [name]:创建名为name的分支,会继承分支的所有内容,可以git rm -rf .
    (3)git checkout [name]:切换为name的分支
    (4)git push [short-name] [name]:推送至别名为short-name(一般为origin)远程仓库的name分支
    (5)git merge [name]:合并分支,若两分支存在同名且内容不同的文件,则会出错,需手动处理合并问题
  8. 标签操作
     Git中的标签,指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态(静态的)。
    (1)git tag:列出已有的标签
    (2)git tag [name]:创建名为name的标签
    (3)git push [short-name] [name] :将名为name的标签推送至别名为short-name的远程仓库
    (4)git checkout -b [branch] [name] :检出name标签到新的分支branch上

1.3 IDEA中使用Git

  1. 在IDEA中配置Git
     File->Settings->Version Control->Git->Path to Git executable:选择git安装后位于bin文件夹下的git.exe文件,点击右侧Test按钮进行测试是否成功。
  2. 获取Git仓库
    (1)本地初始化仓库:VCS->Create Git Repository,选择Git工作区目录即可。
    (2)从远程仓库克隆:VCS->Get from Version Control…,输入URL和选择要克隆到的文件路径,点击clone即可
  3. .gitignore文件
     .gitignore文件可以指定忽略对哪些文件的Git托管
  4. 本地仓库操作
    (1)将文件加入暂存区:选中文件->右键->Git->Add,文件由红色变为绿色。
    (2)将暂存区的文件提交到版本库:选中文件->右键->Git->Commit File…,选择要提交的文件,并填写提交注释,点击Commit提交即可,提交后文件会由绿色变为黑色。或直接选择文件夹->右键->Git->Commit Directory…。或直接点击下面绿色对勾即可(不需要add放入暂存区也可以直接提交)。

    (3)查看日志:点击下方的git栏即可查看,或选中文件->右键->Git->Show History
  5. 远程仓库操作
    (1)添加与查看远程仓库:选中任意文件->右键->Git->Manage Remotes…,即可添加与查看远程仓库,一个本地仓库可以对应多个远程仓库。
    (2)推送至远程仓库:选中任意文件->右键->Git->Push,选择要推送的库与分支,点击Push即可。或直接点击下面绿色斜向上箭头即可(前提是在本地存在提交)。或在提交的时候点击Commit and Push按钮即可同时实现提交和推送

    (3)从远程仓库拉取:选中文件->右键->Git->Pull。或直接点击下面蓝色斜向下箭头即可拉取
  6. 分支操作
     在右下角进行一系列分支操作(创建、切换、合并、查看)。
  7. 标签操作
     项目右键->Git->New Tag,写明Tag Name,再右键->Git->Push(勾选左下角Push Tags)即可。

1.4 Git代码冲突

 当本地文件的版本与目标分支中文件的版本不一致时,当存在同一行的内容不同时在进行合并时会出现冲突。

  1. IDEA图形界面解决合并时的冲突,Merge->修改并Apply->Push。
  2. 手动解决,修改合并冲突后的内容,Add到暂存区,Commit文件,Push到远程仓库即可。
  3. 先拉取后Push。

二、Linux

2.1 Linux简介与安装

  1. Linux特点:免费、开源、多用户、多任务,安全、稳定,常用于服务器操作系统。

  2. Linux系统的安装方法
    (1)物理机安装:直接将操作系统安装到服务器硬件上
    (2)虚拟机安装:通过虚拟机软件安装,虚拟机( Virtual Machine)指通过软件模拟的具有完整硬件系统功能、运行在完全隔离环境中的完整计算机系统。常用虚拟机软件VMware。
  3. 虚拟机安装CentOS发行版Linux系统
    (1)安装VMware虚拟机
    (2)下载CentOS7镜像http://mirrors.ustc.edu.cn/centos/7.9.2009/isos/x86_64/
    (3)在VMware创建新的虚拟机并设置镜像路径
    (4)网卡设置:由于启动服务器时未加载网卡,导致IP地址初始化失败,如果输入ip addr命令没有显示ip地址,则需要修改网络初始化配置,设定网卡在系统启动时初始化:
    (1) 编辑ifcfg-ens33文件
    cd /etc/sysconfig/network-scripts 
    vi ifcfg-ens33
    (2) 按I进入编辑状态
    (3) 移动光标修改ONBOOT=yes
    (4) 按Esc后输入:wq再按Enter保存并退出
    (5) 重启虚拟机客户端
    
  4. 安装SSH连接工具
     SSH(Secure Shell),建立在应用层基础上的安全协议,通过SSH连接工具就可以实现从本地连接到远程的Linux服务器,常用的SSH连接工具:FinalShell官网下载、Xshell(配合Xftp使用)。

2.2 Linux常用命令

2.2.1 Linux命令

  1. Linux命令使用技巧
    (1)Tab键实现自动补全
    (2)连续两次Tab键,给出操作提示
    (3)使用上下箭头快速调出使用过的命令
    (4)使用clear命令或Ctrl+L快捷键实现清屏
  2. Linux命令格式

2.2.2 文件目录操作命令

  1. ls:显示指定目录下的内容,语法:ls [-a|-l|-al] [dir]
    (1)-a:显示所有文件及目录(.开头的隐藏文件也会列出)
    (2)-l:除文件名称外,同时将文件型态(d表示目录,-表示文件)、权限、拥有者、文件大小等信息详细列出。ll命令等同于ls -l
    (3)-al:上边两种选项的结合
  2. cd:切换当前工作目录,即进入指定目录,语法:cd [dirName]
    (1)~:表示当前用户的home目录
    (2).:表示目前所在的目录
    (3)..:表示目前目录位置的上级目录
  3. cat:用于显示文件内容,语法:cat [-n] fileName,-n用于显示行号
  4. more:以分页的形式显示文件内容,语法:more fileName
    (1)回车键:向下滚动一行
    (2)空格键:向下滚动一屏
    (3)B:返回上一屏
    (4)q或Ctrl+C:退出more
  5. tail:查看文件末尾的内容,语法:tail [-f] fileName
    (1)-number:默认查看末尾10行,可以通过-20查看末尾20行
    (2)-f:动态读取文件末尾内容并显示,通常用于日志文件的内容输出
  6. mkdir:创建目录,语法:mkdir [-p] dirName,-p用于多层目录同时创建
  7. rmdir删除空目录,语法:rmdir [-p] dirName,-p用于多层空目录的删除
  8. rm:删除文件或者目录,语法:rm [-r|-f] name
    (1)-r:将目录及目录中所有文件(目录)逐一删除,即递归删除
    (2)-f:无需确认,直接删除
    (3)-rf:上边两种选项的结合
  9. pwd:查看当前所在目录
  10. touch:如果文件不存在,新建文件,语法:touch fileName

2.2.3 拷贝移动命令

  1. cp:用于复制文件或目录,语法:cp [-r] source dest,-r在复制目录时必须使用此选项
  2. mv:为文件或目录改名、或将文件或目录移动到其它位置,语法:mv source dest

2.2.4 打包压缩命令

  1. tar:对文件进行打包、解包、压缩、解压,语法:tar [-z|-c|-x|-v|-f] fileName [files],包文件后缀为.tar表示只是完成了打包,并没有压缩;包文件后缀为.tar.gz表示打包的同时还进行了压缩。
    (1)-z:z代表的是gzip,通过gzip命令处理文件,gzip可以对文件压缩或者解压
    (2)-c:c代表的是create,即创建新的包文件,打包
    (3)-x:x代表的是extract,实现从包文件中还原文件,解包
    (4)-v:v代表的是verbose,显示命令的执行过程
    (5)-f:f代表的是file,用于指定包文件的名称
    (6)-cvf:tar -cvf test.tar test ,将test打包成test.tar,且显示执行过程
    (7)xvf:tar -xvf test.tar ,将test解包,且显示执行过程
    (8)-zcvf:tar -zcvf test.tar.gz test ,将test打包并压缩成test.tar.gz,且显示执行过程
    (9)-zxvf:tar -zxvf test.tat.gz -C /,将test.tat.gz解压并解包到指定目录,且显示执行过程

2.2.5 文本编辑命令

  1. vi/vim:vi命令是Linux系统提供的一个文本编辑工具,可以对文件内容进行编辑,语法:vi/vim fileName,vim是从vi发展来的一个功能更加强大的文本编辑工具,在编辑文件时可以对文本内容进行着色,方便我们对文件进行编辑处理,所以实际工作中vim更加常用。通过yum install vim对vim进行安装。
  2. 在使用vim命令编辑文件时,如果指定的文件存在则直接打开此文件,如果指定的文件不存在则新建文件
  3. vim在进行文本编辑时共分为三种模式,分别是命令模式(Command mode),插入模式(Insert mode)和底行模式(Last line mode)。
  4. 命令模式:命令模式下可以查看文件内容、移动光标(上下左右箭头、gg、G),通过vim命令打开文件后,默认进入命令模式,另外两种模式需要首先进入命令模式,才能进入彼此。
  5. 插入模式:插入模式下可以对文件内容进行编辑,在命令模式下按[I,A,O]任意一个,就可以进行插入模式,下方会出现insert字样,在插入模式下按Esc键,回到命令模式。
  6. 底行模式:底行模式下可以通过命令对文件内容进行查找、显示行号、退出等操作,在命令模式下按[:,/]任意一个,可以进入底行模式,通过/方式进入底行模式后,可以对文件内容进行查找;通过:方式进入底行模式后,可以输入wq(保存并退出)、q!(不保存退出)、set nu(显示行号)。

2.2.6 查找命令

  1. find:在指定目录下查找文件,语法:find dirName -name fileName,fileName可以使用通配符*
  2. grep:从指定文件中查找指定的文本内容,语法:grep word fileName,word指的是要查找的文本内容(区分大小写),fileName可以使用通配符*

2.2.7 防火墙操作

  1. 查看防火墙状态:systemctl status firewalld、firewall-cmd --state
  2. 暂时关闭防火墙:systemctl stop firewalld
  3. 永久关闭防火墙:systemctl disable firewalld
  4. 开启防火墙:systemctl start firewalld
  5. 开放指定端口:firewall-cmd --zone=public --add-port=8080/tcp --permanent
  6. 关闭指定端口:firewall-cmd --zone=public --remove-port=8080/tcp --permanent
  7. 立即生效:firewall-cmd --reload
  8. 查看开放的端口:firewall-cmd --zone=public --list-ports
    systemctl是管理Linux中服务的命令,可以对服务进行启动、停止、重启、查看状态等操作
    firewall-cmd是Linux中专门用于控制防火墙的命令

2.3 软件安装

  1. 软件安装方式
    (1)二进制发布包安装:软件已经针对具体平台编译打包发布,只要解压,修改配置即可。
    (2)rpm安装:软件已经按照redhat的包管理规范进行打包,使用rpm命令进行安装,不能自行解决库依赖问题。
    (3)yum安装:一种在线软件安装方式,本质上还是rpm安装,自动下载安装包并安装,安装过程中自动解决库依赖问题。
    (4)源码编译安装:软件以源码工程的形式发布,需要自己编译打包。
  2. 安装JDK
    (1)下载Linux版的JDK,Linux版JDK17,并使用FinalShell自带的上传工具将JDK的二进制发布包上传到Linux.
    (2)解压安装包,命令:tar -zxvf jdk-17_linux-x64_bin.tar.gz -C /usr/local
    (3)配置环境变量,使用vim命令修改/etc/profile文件,在文件末尾加入配置:JAVA_HOME=/usr/local/jdk-17.0.7 PATH=$JAVA_HOME/bin:$PATH
    (4)重新加载profile文件,使更改的配置立即生效,命令:source /etc/profile
    (5)检查安装是否成功,命令为java -version
  3. 安装Tomcat
    (1)下载Tomcat二进制发布包Tomcat9,并上传到Linux
    (2)解压安装包,命令:tar -zxvf apache-tomcat-9.0.75.tar.gz -C /usr/local
    (3)进入Tomcat的bin目录启动服务,命令:sh startup.sh./startup.sh,要关闭防火墙或开放指定端口才可以使用Tomcat服务器
    (4)查看启动日志:more /usr/local/apache-tomcat-9.0.75/logs/catalina.out 或 tail -50 /usr/local/apache-tomcat-9.0.75/logs/catalina.out
    (5)ps -ef:查看当前运行的所有进程的详细信息,可以配合|管道符(将前一个命令的结果输出给后一个命令作为输入)查看特定进程,如ps -ef | grep tomcat,就可以查看有关tomcat的进程信息。
    (6)进入Tomcat的bin目录停止服务,命令:sh shutdown.sh./shutdown.sh
    (7)kill -9:强制结束进程,后根进程id
  4. 安装MySQL
    (1)检测当前系统中是否安装MySQL数据库,RPM(Red-Hat Package Manager),是红帽Linux用于管理和安装软件的工具。
    rpm -qa:查询当前系统中安装的所有软件
    rpm -qa | grep mysql:查询当前系统中安装的名称带mysql的软件
    rpm -qa | grep mariadb:查询当前系统中安装的名称带mariadb的软件,CentOS7自带mariadb,与MySQL数据库冲突
    (2)卸载已安装的冲突软件
    rpm -e --nodeps 软件名称
    (3)下载MySQL的rpm安装包MySQL官网下载,选择对应操作系统,后缀为.rpm-bundle.tar文件,上传到Linux
    (4)在/usr/loacl中创建新的目录mkdir mysql,tar -xvf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar -C /usr/local/mysql
    (5)进入/usr/local/mysql,强制安装:rpm -ivh *.rpm --nodeps --force,通过yum update升级现有软件以及系统内核,或yum install安装指定的工具。
    (6)启动MySQL
    systemctl status mysqld:查看mysql服务状态
    systemctl start mysqld:启动mysql服务,同样要关闭防火墙或开启指定端口才能访问
    systemctl enable mysqld:开机启动mysql服务
    netstat -tunlp:查看已经启动的服务,可以netstat -tunlp | grep mysql,前提已经yum install net-tools安装net-tools工具
    (7)查看MySQL临时密码:cat /var/log/mysqld.log | grep password
    (8)登录MySQL,修改密码,开放访问权限
    mysql -uroot -p		#登录mysql
    alter user 'root'@'localhost' identified by 'Superm_chao34';	# 先设置一个复杂的密码
    set global validate_password.length=4; 		# 设置密码长度最低位数
    set global validate_password.policy=LOW;	# 设置密码安全等级低
    alter user 'root'@'localhost' identified by '123456';	# 设置密码为123456
    select user,host from mysql.user;	# 查看用户和主机
    rename user 'root'@'localhost' to 'root'@'%';	# 更改为远程也可以访问
    
  5. 安装lrzsz
     Yum(全称为Yellow dog Updater,,Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。
    (1)搜索lrzsz安装包,命令为yum list lrzsz
    (2)yum在线安装,命令为yum install lrzsz
    (3)使用命令rz即可用于从Windows向Linux上传文件

2.4 项目部署

  1. 手动部署项目
    (1)将SpringBoot项目打包成jar包,并上传到Linux中。
    (2)java -jar boot工程.jar:启动项目(需要开启指定的端口,防火墙)
    (3)后台运行java -jar命令,并将日志输出到某文件:nohup java -jar boot工程.jar &> boot.log &
    (4)停止项目:kill杀死进程
  2. Shell脚本自动部署
    (1)在Linux中安装Git:yum list gityum install git
    (2)使用Git克隆代码(先转到指定目录):git clone 仓库的url
    (3)在Linux中安装Maven,将Maven安装包上传并解压Maven3.9二进制压缩包:tar -zxvf apache-maven-3.9.2-bin.tar.gz -C /usr/local
    (1) vim /etc/profile 	# 修改配置文件,加入以下内容
    export MAVEN_HOME=/usr/local/apache-maven-3.9.2
    export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
    (2) source /etc/profile 	# 重新加载配置文件
    (3) mvn -version 	# 查看Maven版本
    (4) vim /usr/local/apache-maven-3.9.2/conf/settings.xml	# 修改本地仓库,先创建repo目录
    <localRepository>/usr/local/repo</localRepository>
    
    (4)编写Shell脚本(拉取代码、编译、打包、启动)
    #!/usr/local/sh/reggie.sh
    echo =================================
    echo  自动化部署脚本启动
    echo =================================
    
    echo 停止原来运行中的工程
    APP_NAME=reggie_take_out
    
    tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
    if [ ${tpid} ]; then
        echo 'Stop Process...'
        kill -15 $tpid
    fi
    sleep 2
    tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
    if [ ${tpid} ]; then
        echo 'Kill Process!'
        kill -9 $tpid
    else
        echo 'Stop Success!'
    fi
    
    echo 准备从Git仓库拉取最新代码
    cd /usr/local/javaapp/reggie_take_out
    
    echo 开始从Git仓库拉取最新代码
    git pull
    echo 代码拉取完成
    
    echo 开始打包
    output=`mvn clean package -Dmaven.test.skip=true`
    
    cd target
    
    echo 启动项目
    nohup java -jar reggie_take_out-1.0-SNAPSHOT.jar &> reggie_take_out.log &
    echo 项目启动完成
    
    (5) 为用户授予执行Shell脚本的权限
    chmod(change mode)命令可以控制用户对文件的权限,Linux中的权限分为:读(r)、写(w)、执行(x)三种权限;Linux的文件调用权限分为三级︰文件所有者(Owner)、用户组(Group)、其它用户(Other Users)。只有文件的所有者和超级用户可以修改文件或目录的权限,要执行Shell脚本需要有对此脚本文件的执行权限,如果没有则不能执行。


    (6)执行Shell文件,./shell文件名.sh
    (7)设置静态IP:重启虚拟机后,IP不会发生改变,修改完毕重启服务systemctl restart network
    vim /etc/sysconfig/network-scripts/ifcfg-ens33	# 不同Linux系统文件名不一样,可通过ip addr查看文件名
    BOOTPROTO="static"			# 修改:使用静态IP地址,默认为dhcp
    IPADDR="192.168.47.128"     # 新增:设置的静态IP地址,需要与编辑->虚拟网络编辑器一致
    NETMASK="255.255.255.0"     # 新增:设置子网掩码
    GATEWAY="192.168.47.130"    # 新增:设置网关地址
    DNS1="192.168.47.130"       # 新增:设置DNS服务器
    ONBOOT=yes					# 新增:配置网卡开机自启动,之前已经设置过
    

三、Redis

 Redis是一个基于内存的key-value结构的数据库,基于内存存储,读写性能高;适合存储热点数据(热点商品、咨询、新闻);应用广泛。

3.1 Redis入门

 Redis是一个开源的基于内存的数据结构存储系统,它可以用作∶缓存、任务队列、消息队列、分布式锁Redis官网
 Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。
 NoSql (Not only sQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。

  1. Linux系统安装Redis
    (1)下载Redis,并上传到Linux
    (2)解压安装包:tar -zxvf redis-7.0.11.tar.gz -C /usr/local
    (3)安装Redis的依赖环境gcc:yum install gcc-c++
    (4)进入/usr/local/redis-7.0.11,进行编译,命令:make
    (5)启动redis-server,在/usr/local/redis-7.0.11/src目录下,运行:./redis-server,后台运行如下操作

    vim /usr/local/redis-7.0.11/redis.conf	# 编辑配置文件
    daemonize yes	# 修改,默认为yes,可以查找找到对应的位置,打开守护进程
    requirepass 123456	# 修改,取消注释,默认为oobared,修改密码为123456
    protected-mode no	# 修改,关闭保护模式,默认为yes
    bind 127.0.0.1 -::1	# 注释掉,或改为0.0.0.0
    bind 0.0.0.0	# 修改,所有主机都可以连接
    /usr/local/redis-7.0.11/src/redis-server /usr/local/redis-7.0.11/redis.conf	# 后台运行redis-server,同时运行配置文件
    

    (6)启动redis-cli,在/usr/local/redis-7.0.11/src目录下,运行:./redis-cli,也可以通过./redis-cli -h localhost -p 6379 -a 123456,直接指定主机、端口和密码连接(前提要关闭防火墙,或开放6379端口)。

  2. Windows系统安装Redis:下载Redis

3.2 Redis常用的五种基本数据类型以及命令

  1. 通用命令
    (1)keys pattern:查找所有符合给定模式(pattern)的key
    (2)exists key:检查给定的key是否存在
    (3)type key:返回key所存储的值的类型
    (4)ttl key:返回给定key的剩余生存时间(TTL,time to live),以秒为单位
    (5)del key:在key存在时删除key
    (6)select index:Redis默认有16个数据库,默认使用0号数据库
  2. String字符串Redis中文网
     String的数据结构是简单的Key-Value模型,适用于计数器(点赞量、播放量)
    (1)set key value:设置指定key的值,若key相同,会覆盖之前的value的值
    (2)get key:获取指定key的值
    (3)setex key seconds value:设置指定key的值,并将key的过期时间设为seconds秒
    (4)setnx key value:只有在key不存在时设置key的值,常用于分布式锁
  3. Hash散列表
     Redis哈希表是一个Sting类型的Field和Value的映射表,适合用于存储对象
    (1)hset key field value:将哈希表key中的字段field的值设为value
    (2)hget key field:获取存储在哈希表中指定字段的值
    (3)hdel key field:删除存储在哈希表中的指定字段
    (4)hkeys key:获取哈希表中所有字段
    (5)hvals key:获取哈希表中所有值
    (6)hgetall key:获取在哈希表中指定key的所有字段和值
  4. List列表
     Redis列表是简单的字符串列表,本质是一个链表(功能类似一个双端队列),按照插入顺序排序,适合用于消息队列
    (1)lpush key value1 [value2]:将一个或多个值插入到列表头部,还有rpush(插入到尾部)
    (2)lrange key start stop:获取列表指定范围内的元素
    (3)rpop key [count]:移除并获取列表最后count个元素,还有lpop(删除并获取列表前count个元素)
    (4)llen key:获取列表长度
    (5)brpop key1 [key2] timeout:移除并获取列表的最后一个元素,如果列表没有元素会阻塞队列直到等待超时或发现可弹出元素为止,还有blpop(第一个元素)
  5. Set(无序集合)
     Redis无序集合是String类型的,集合成员唯一,通过哈希表实现的,适用于存放共同的东西(共同好友)
    (1)sadd key member1 [member2]:向集合添加一个或多个成员
    (2)smembers key:返回集合中的所有成员
    (3)scard key:获取集合的成员数
    (4)sismember key value:查看value是否存在
    (5)sinter key1 [key2]:返回给定所有集合的交集
    (6)sunion key1 [key2]:返回给定所有集合的并集
    (7)sdiff key1 [key2]:返回给定所有集合的差集
    (8)srem key member1 [member2]:移除集合中一个或多个成员
  6. SortedSet( 有序集合)
     Redis有序集合,集合成员唯一,每个元素都会关联一个double类型的分数(score),分数可以重复,Redis通过分数给集合中的成员进行从小到大排序。适用于有序的(成绩表)
    (1)zadd key score1 member1 [score2 member2]:向有序集合添加一个或多个成员,或者更新已存在成员的分数
    (2)zrange key start stop [withscores]:通过索引区间返回有序集合中指定区间内的成员
    (3)zincrby key increment member:有序集合中对指定成员的分数加上增量increment
    (4)zrem key member1 [member2]:移除有序集合中的一个或多个成员

3.3 Redis的Java操作

  1. 导入依赖spring-boot-starter-data-redis
    <!-- Spring data redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置Redis
    spring:
      data:
        redis:
          host: 192.168.142.128
          port: 6379
          password: 123456
          jedis:
            pool:
              max-active: 8 # 最大连接数
              max-wait: 1ms # 连接池最大阻塞等待时间
              max-idle: 4   # 连接池中的最大空闲连接
              min-idle: 0   # 连接池中的最小空闲连接
    
  3. ValueOperations:简单K-V操作
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Test
    void testString() {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("name", "superm`超"); //set key value
        String name = valueOperations.get("name"); //get key value
        valueOperations.set("age", "23", 100L, TimeUnit.SECONDS); //setex key value
        valueOperations.setIfAbsent("age", "24"); //setnx key value
        String age = valueOperations.get("age");
        System.out.println(name + " " + age);
    }
    
  4. HashOperations:Hash类型数据操作,类似Map
    @Test
    void testHash() {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        hashOperations.put("user1", "name", "superm`超"); //hset key field value
        hashOperations.put("user1", "age", "23");
        String name = (String) hashOperations.get("user1", "name"); //hget key field
        String age = (String) hashOperations.get("user1", "age");
        System.out.println(name + " " + age);
        Set<Object> keys = hashOperations.keys("user1");//hkeys key
        List<Object> values = hashOperations.values("user1");//hvals key
        System.out.println(Arrays.toString(keys.toArray()));
        System.out.println(Arrays.toString(values.toArray()));
    }
    
  5. ListOperations:List类型数据操作
    @Test
    void testList() {
        ListOperations<String, String> listOperations = redisTemplate.opsForList();
        listOperations.leftPush("mylist", "a"); //lpush key value
        listOperations.leftPushAll("mylist", "b", "c", "d"); //lpush key value1 value2
        listOperations.rightPop("mylist"); //rpop ley
        List<String> mylist = listOperations.range("mylist", 0, -1);//lrange key start stop
        System.out.println(mylist);
    }
    
  6. SetOperations:Set类型数据操作
    @Test
    void testSet() {
        SetOperations<String, String> setOperations = redisTemplate.opsForSet();
        setOperations.add("myset", "a", "b", "c", "a"); //sadd key member1 [member2]
        setOperations.remove("myset", "b"); //srem key member1 [member2]
        Set<String> myset = setOperations.members("myset"); //smembers key
        System.out.println(myset);
    }
    
  7. ZSetOperations:ZSet类型数据操作
    @Test
    void testZSet() {
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("myzset", "a", 2); //zadd key score member
        zSetOperations.add("myzset", "b", 1);
        zSetOperations.add("myzset", "c", 3);
        zSetOperations.incrementScore("myzset", "b", 4); //zincrby key increment member
        zSetOperations.remove("myzset", "a"); //zrem key member
        Set<ZSetOperations.TypedTuple<String>> myzset = zSetOperations.rangeWithScores("myzset", 0, -1);//zrange key start stop withscores
        System.out.println(myzset);
    }
    
  8. 通用命令
    @Test
    void testCommon() {
        redisTemplate.keys("*"); //keys *
        redisTemplate.hasKey("name"); //exists key
        redisTemplate.delete("myset"); //del key
        redisTemplate.type("myzset"); //type key
    }
    

3.4 缓存穿透

 缓存穿透是指在缓存系统中,无论是使用Redis还是其他缓存技术,查询数据库中不存在的数据时,由于缓存中没有对应的数据,每次请求都会直接查询后端数据库或服务,导致频繁的无效查询,增加了系统负载,降低了性能

  1. 布隆过滤器(Bloom Filter):使用布隆过滤器可以快速判断一个请求是否为无效请求。布隆过滤器是一种数据结构,用于判断一个元素是否存在于一个集合中,它可以高效地过滤掉大部分无效请求,减轻对后端资源的压力。需要缓存预热将一些信息提前存入布隆过滤器,后期添加数据时也存入布隆过滤器,实现方法:Guava、Redisson 。
  2. 缓存空对象(Cache null objects):对于查询数据库后返回空结果的请求,可以将空结果缓存起来,设置一个较短的过期时间,这样下次相同的请求可以直接从缓存中获取结果,避免查询数据库。
  3. 请求参数校验(Input Validation):在应用层对请求参数进行有效性校验,过滤掉明显无效的请求。例如,对于非法的请求参数,可以直接返回错误响应,而不查询缓存或后端资源。
  4. 预先加载(Preloading):在系统启动时或低峰期,可以预先加载一些常用数据到缓存中,以提高缓存的命中率。这样即使有无效请求绕过了缓存,系统仍然可以从缓存中获取到大部分数据。
  5. 限制请求频率(Rate Limiting):对于频繁发送请求的用户,可以采用限制请求频率的策略,例如使用令牌桶算法或漏桶算法限制每秒的请求数量,从而降低恶意请求的影响。

3.5 缓存雪崩

 缓存雪崩是指在缓存系统中,大量的缓存失效或过期,导致所有的请求都直接访问后端数据库或服务,造成系统性能急剧下降甚至崩溃的现象。这种情况通常发生在具有相同过期时间的一组缓存数据同时失效或更新时。原因:缓存数据过期时间集中、缓存服务故障

  1. 缓存数据的过期时间分散:为缓存数据设置不同的过期时间,避免大量数据同时失效。可以使用随机值或根据数据的特性设置不同的过期时间。
  2. 引入缓存预热:在缓存数据过期之前,提前对缓存进行更新,避免大量请求同时访问后端系统。可以定期刷新缓存或在数据写入时同时更新缓存。
  3. 多级缓存架构:引入多级缓存,如本地缓存和分布式缓存,将缓存数据分散存储在不同的节点上,减少单点故障的风险。
  4. 限流和熔断机制:在缓存失效时,通过限制请求的并发数或采用熔断机制,控制对后端系统的访问压力,保护系统的稳定性。
  5. 监控和预警:建立监控系统,实时监测缓存系统的状态和缓存数据的过期情况,及时发现潜在问题并采取相应的措施。

3.6 缓存击穿

 缓存击穿是指在缓存系统中,针对某个特定的缓存键(key)频繁发起请求,但该缓存键对应的数据在缓存中不存在或已过期,导致每次请求都需要访问后端数据库或服务来获取数据,从而造成性能下降和系统压力增加的情况。原因:热点数据、高并发缓存失效

  1. 设置热点数据永不过期:对于一些热点数据,可以将其缓存设置为永不过期,确保始终能够从缓存中获取数据。
  2. 使用互斥锁或分布式锁:在缓存失效时,使用互斥锁或分布式锁来保护后端系统的访问,只允许一个请求去加载数据,其他请求等待加载完成后再获取数据。
  3. 引入缓存穿透保护机制:在缓存中设置一个空值(null)或特殊标记,表示该缓存键对应的数据不存在,当请求发现缓存中存在该标记时,可以直接返回,避免对后端系统的无效访问。
  4. 引入预加载机制:在缓存过期之前,提前异步加载缓存数据,确保在缓存失效期间能够快速重新加载有效数据。
  5. 使用缓存策略:针对不同的缓存数据,可以采用不同的缓存策略,如LRU(最近最少使用)或LFU(最不经常使用)等,根据数据的访问频率和重要性进行缓存设置。
  6. 监控和预警:建立监控系统,实时监测缓存击穿的情况,及时发现异常并采取相应的措施。

3.7 分布式锁

 分布式锁是一种用于在分布式系统中实现互斥访问的机制。在多个节点或进程同时访问共享资源时,分布式锁可以确保同一时间只有一个节点或进程能够获得对资源的独占访问权,从而保证数据的一致性和正确性。

  1. 基于数据库的实现:通过在数据库中创建唯一索引、使用乐观锁(先读取资源;记录版本或标识,通常用版本号、时间戳或哈希值;修改资源,只有匹配的版本或标识才能修改成功;适用于对资源的读操作远远超过写操作的情况)或行级锁(与分布式缓存协作)来实现分布式锁。当节点或进程尝试获取锁时,将在数据库中插入一条特定的记录,其他节点或进程将无法插入相同的记录,从而实现互斥访问。
  2. 基于缓存的实现:使用分布式缓存(如Redis)来实现分布式锁。通过在缓存中设置一个特定的键作为锁,并使用原子操作(如SETNX,setIfAbsent方法,注意锁的超时机制、错误处理和锁的可重入性)尝试获取锁。只有一个节点或进程能够成功设置该键,其他节点或进程将无法设置相同的键,从而实现互斥访问。
  3. 基于ZooKeeper的实现:使用ZooKeeper分布式协调服务来实现分布式锁。每个节点或进程可以创建一个临时有序节点,尝试获取锁时,只有序号最小的节点能够成功获取锁,其他节点将监听前一个节点的删除事件,从而实现互斥访问。

3.7.1 SETNX

  1. 设置超时时间:出现异常,也可释放对锁的占用;时间过短则可能尚未处理完数据库,就释放了锁,被其它线程抢走,造成重复操作数据库;时间过长则会影响效率性能。
  2. 手动删除锁:当操作完成后,解除对锁的占用;但是可能超时时间到了,删除了其它线程的锁,造成连环影响;因此需要先判断当前的锁是否是自己的锁,但由于CPU按时间片调度,可能判断是自己的锁,然后还没有删除就调别的,此时时间过期,然后又删除了别的锁,因此需要保证用Lua脚本保证原子性,但过期时间的大小仍是一个问题。

3.7.2 Rdeisson

 线程去获取锁,获取成功:执行Lua脚本,保存数据到redis。线程去获取锁,获取失败:一直通过while循环尝试获取锁,获取成功后,执行Lua脚本,保存数据到redis。WatchDog自动延期看门狗机制:服务器宕机,默认30秒会自动释放锁,为了防止死锁;若默认30秒还没有执行完毕,就不断延长key的生存时间。

@Autowired
private RedissonClient redissonClient; // 自动注入Redission

RLock lock = redissonClient.getLock("myLock"); // 获取分布式锁对象
lock.lock(); // 获取分布式锁,默认30秒;如果主线程未释放且未执行unlock,则进入WatchDog机制;若已执行了unlock,则直接释放锁
try {
	// 执行需要互斥访问的任务
	// ...
} finally {
	lock.unlock(); // 释放锁
}

四、SpringBoot缓存

4.1 Redis缓存

  1. 缓存短信验证码
    (1) 注入StringRedisTemplate,用于操作redis
    @Autowired
    private StringRedisTemplate redisTemplate;
    (2) 发送验证码的时候,将手机号和验证码存入redis,并设置生存时间
    redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES); //存入redis缓存中
    (3) 如果登录成功,则删除redis缓存
    redisTemplate.delete(phone); //删除验证码缓存
    
  2. Redis缓存经常访问的数据
     如果对某些数据用户经常频繁访问,在高并发的情况下,频繁的查询数据库会导致系统性能下降,服务端响应时间增长,可以将这些频繁访问的数据放入缓存(先查看Redis缓存中是否存在数据,若不存在,则再从数据库中进行查询),提高系统的性能。同时,在使用缓存过程中,要保证数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化(增、删、改),需要及时清理缓存数据
    (1)缓存存取数据
    (1) 动态生成唯一key,自定义,根据前端传的参数和一些固定的说明组成
    (2) 缓存存在则取出,不存在则查找数据库
    List<User> userList;
    if (redisTemplate.hasKey(key)) { //若有对应的缓存,则取出
        userList = JSON.parseObject(redisTemplate.opsForValue().get(key), new TypeReference<List<User>>() {} );
    } else { //缓存中不存在,则从数据库中取出数据,同时存入缓存中
        userList = 数据库操作取出数据
        redisTemplate.opsForValue().set(key, JSON.toJSONString(userList), 60, TimeUnit.MINUTES);
    }
    return Result.success(userList);
    
    (2)清理缓存数据
    (1) 清理全部缓存数据
    Set<String> keys = redisTemplate.keys("user_*");
    redisTemplate.delete(keys);
    (2) 精确清理缓存数据
    String key = "user_" + user.getUserId();
    redisTemplate.delete(key);
    

4.2 Spring Cache

 Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。CacheManager是Spring提供的各种缓存技术抽象接口。
 在SpringBoot项目中,使用缓存技术只需要在项目中导入相关缓存技术的依赖包(若不导包,则默认会用HashMap来实现一个缓存映射,不过这个是基于内存的,项目关闭就会消失),并在启动类上使用@EnableCaching注解开启缓存支持即可。

  1. @EnableCaching:开启缓存注解功能
  2. @Cacheable:在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中。
    (1)value:缓存的名称,每个缓存名称下面可以有多个key
    (2)key:缓存的key,方法的返回值作为对应的值value
    (3)condition:对入参进行判断,符合条件的缓存,不符合的不缓存,condition不能使用#result
    (4)unless:对出参进行判断,符合条件的不缓存,不符合的缓存,如unless=“#result.code==1”,符合就缓存
  3. @CachePut:将方法的返回值放到缓存中,key属性可用Spring Expression Language (SpEL)表达式来表示。如:#p0(指方法的第一个参数)、#root.args[0](指方法的第一个参数)、#id(方法的形参名)、#result(方法的结果)等,可以拼接字符串。
  4. @CacheEvict:将一条或多条数据从缓存中删除,allEntries = true 就将指定value的全部数据删除。
  5. 在SpringBoot项目中使用Spring Cache(采用redis缓存技术)
    (1)导入Maven坐标,spring-boot-starter-data-redis、spring-boot-starter-cache
    <!-- Spring data redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- Spring cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    (2)配置application.yml
    spring:
      cache:
        redis:
          time-to-live: 3600000 # 设置缓存有效期,单位毫秒
    
    (3)在启动类上加@EnableCaching注解,开启缓存注解功能
    (4)在Controller的方法上加@Cacheable@CachePut@CacheEvict等实现对应缓存功能

五、MySQL主从复制与读写分离

5.1 MySQL主从复制

 MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的二进制日志功能。就是一台或多台NysQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库〉进行日志的复制然后再解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。MySQL主从复制是MySQL数据库自带功能,无需借助第三方工具。
(1)master将改变记录到二进制日志(binary log)
(2)slave将master的binary log拷贝到它的中继日志(relay log)
(3)slave重做中继日志中的事件,将改变应用到自己的数据库中

  1. 主库配置
    (1)修改MySQL数据库的配置文件/etc/my.cnf

    log-bin=mysql-bin	# 开启二进制日志
    server-id=34		# 服务器唯一ID	
    

    (2)重启MySQL服务:systemctl restart mysqld
    (3)登录MySQL,创建有操作从库权限的用户superm,密码为Root@123456:

    (1) 选择数据库mysql
    use mysql;
    (2) 创建用户superm
    create user 'superm'@'%' identified by 'Root@123456';
    (3) 授予操作从库的权限
    grant replication slave on *.* to 'superm'@'%';
    

    (4)登录MySQL数据库,执行:show master status; 记录结果中FilePosition的值,可以reset master回到初始状态。

  2. 从库配置
    (1)修改MySQL数据库的配置文件/etc/my.cnf:server-id=58 ,服务器唯一ID,若虚拟机克隆得来,则需更改UUID
    (2)重启MySQL服务:systemctl restart mysqld
    (3)登录MySQL,执行下面命令,当Slave_IO_Running: Yes和Slave_SQL_Running: Yes,就成功了,若Slave_SQL_Running变为了No则是MySQL发生了同步故障,重启即可。

    change master to master_host='192.168.142.128',master_user='superm',master_port=3306,master_password='Root@123456',master_log_file='mysql-bin.000001',master_log_pos=157;
    stop slave;	# 若之前绑定并开启过,则可以先停止,再执行上边的命令
    reset slave;
    start slave; # 启动slave,开启IO线程和SQL线程,用于读写主库的binlog
    show slave status\G;	# 查看
    

5.2 读写分离

 面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM(Object Relational Mapping,对象关系映射)框架。使用Sharding-JDBC可以在程序中轻松的实现数据库读写分离:
(1)适用于任何基于JDBC的ORM框架,如: JPA Hibernate,Mybatis,Spring JDBC Template或直接使用JDBC。
(2)支持任何第三方的数据库连接池,如:DBCP,C3PO,BoneCP,Druid,HikariCP等。
(3)支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。

  1. 导入依赖Sharding-JDBC
    <!-- Sharding-JDBC -->
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <version>4.1.1</version>
    </dependency>
    
  2. 配置application.yml文件
    spring:
      shardingsphere:
        datasource:
          names: master,slave
          # 主数据源
          master:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.142.128:3306/reggie?characterEncoding=utf-8
            username: root
            password: 123456
          # 从数据源
          slave:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.142.129:3306/reggie?characterEncoding=utf-8
            username: root
            password: 123456
        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  # 允许Bean覆盖
    

六、Nginx

 Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上Nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网站有:百度、京东、新浪、网易、腾讯、淘宝等。Nginx官网

  1. Nginx的下载与安装
    (1)安装依赖包:yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
    (2)下载Nginx安装包:wget https://nginx.org/download/nginx-1.24.0.tar.gz
    (3)解压:tar -zxvf nginx-1.24.0.tar.gz
    (4)跳转目录:cd nginx-1.24.0
    (5)创建目录:mkdir -p /usr/local/nginx
    (6)检查环境:./configure --prefix=/usr/local/nginx
    (7)编译并安装:make && make install

  2. Nginx常用命令
    (1)配置环境变量:vim /etc/profile ,添加路径:export PATH=/usr/local/nginx/sbin:$PATH
    (2)查看Nginx版本命令:nginx -v
    (3)检查配置文件是否有错:nginx -t
    (4)启动Nginx服务(可以通过80端口查看首页):nginx
    (5)停止Nginx服务:nginx -s stop
    (6)重新加载配置文件:nginx -s reload

  3. Nginx配置文件(conf/nginx.conf)
    (1)全局块:Nginx运行相关的全局配置
    (2)events块:网络连接相关的配置
    (3)http块:代理、缓存、日志记录、虚拟主机配置。
       http全局块
       Server块(一个http块可以有多个Server块)
         Server全局块
         location块(一个Server块可以有多个location块)

  4. Nginx部署静态资源
     Nginx可以作为静态Web服务器来部署静态资源。静态资源指在服务端真实存在并且能够直接展示的一些文件,比如常见的html页面、css文件、js文件、图片、视频等资源。相对于Tomcat,Nginx处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到Nginx中。将静态资源部署到Nginx非常简单,只需要将文件复制到Nginx安装目录下的html目录中即可。

  5. Nginx反向代理
    正向代理:一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理一般是在客户端设置代理服务器,通过代理服务器转发请求,最终访问到目标服务器。
    反向代理:反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。用户不需要知道目标服务器的地址,也无须在用户端作任何设定,对用户来讲是透明的。

    server {
    	listen 81;
    	server_name localhost;
    	location / {
    		proxy_pass http://192.168.142.129:8080;	# 反向代理配置,将请求转发到指定服务
    	}
    }
    
  6. Nginx负载均衡
    应用集群:将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据。
    负载均衡器:将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理。

    upstream targetserver {	# upstream指令可以定义一组服务器
    	server 192.168.138.101:8080;
    	server 192.168.138.102:8080;
    }
    
    server {
    	listen 8080;
    	server_name localhost;
    	location / {
    		proxy_pass http://targetserver;	# 反向代理配置,将请求转发到指定服务
    	}
    }
    

七、前后端分离

7.1 YApi

 YApi是高效、易用、功能强大的API管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 APl,YApi还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理。YApi让接口开发更简单高效,让接口的管理更具可读性、可维护性,让团队协作更合理。YApi官网

7.2 Swagger

 使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。Swagger官网SpringBoot3整合失败,SpringBoot2版本可以

  1. SpringBoot2整合Swagger
    (1)导入依赖knife4j

    <!-- Knife4j -->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    

    (2)导入knife4j相关配置(WebMvcConfig)并设置静态资源映射(否则接口文档页面无法访问)

    @Configuration
    @EnableSwagger2
    @EnableKnife4j
    public class WebMvcConfig implements WebMvcConfigurer {
    	//设置静态资源映射
        @Override
        protected void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
    
        @Bean
        public Docket createRestApi() {
            // 文档类型
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.superm.controller"))
                    .paths(PathSelectors.any())
                    .build();
        }
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("superm")
                    .version("1.0")
                    .description("superm接口文档")
                    .build();
        }
    }
    

    (3)放行指定的路径(不需要登录就可以访问):“/doc.html”、“/webjars/**”、“/swagger-resources”、“/v2/api-docs”
    (4)配置请求路径与SpringMVC处理映射匹配策略

    spring:
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher
    

    (5)运行,访问doc.html即可

  2. Swagger常用注解
    (1)@Api:用在请求的类上,例如Controller,表示对类的说明。
    (2)@ApiModel:用在类上,通常是实体类,表示一个返回响应数据的信息。
    (3)@ApiModelProperty:用在属性上,描述响应类的属性。
    (4)@ApiOperation:用在请求的方法上,说明方法的用途、作用。
    (5)@ApilmplicitParams:用在请求的方法上,表示一组参数说明。
    (6)@ApilmplicitParam:用在@ApilmplicitParams注解中,指定一个请求参数的各个方面。
    (7)@ApiResponse:接口响应描述信息。

7.3 Springdoc-Openapi

SpringBoot3整合springdoc-openapi springdoc-openapi官网

  1. 导入依赖springdoc-openapi
    <!-- Springdoc-openapi -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.1.0</version>
    </dependency>
    
  2. 添加配置类SpringDocConfig
    @Configuration
    public class SpringDocConfig {
        @Bean
        public OpenAPI openAPI() {
            return new OpenAPI()
                    .info(new Info().title("标题")    //这些类都是io.swagger.v3.oas.models下的
                            .description("API文档")
                            .version("v1")
                            .license(new License().name("Apache 2.0").url("http://springdoc.org"))) //springdoc-openapi官网V1
                    .externalDocs(new ExternalDocumentation()
                            .description("SpringDoc Wiki Documentation")
                            .url("http://springdoc.org/v2"));   //springdoc-openapi官网V2
        }
    }
    
  3. OpenAPI注解
    (1)@Tag(name="" , description=""):用在请求的类上,例如Controller,表示对类的说明。
    (2)@Schema(name="" , title=""):用在类上,通常是实体类,表示一个返回响应数据的信息。
    (3)@Schema(title=""):用在属性上,描述响应类的属性。
    (4)@Operation(summary="" , description="" , parameters={}):用在请求的方法上,说明方法的用途、作用。
    (5)@Parameter(name="" , description=""):用在@Operation注解中或@Parameters注解中,指定一个请求参数的各个方面。
    (6)@ApiResponse(responseCode="" , description=""):接口响应描述信息。
  4. 访问http://localhost:8080/swagger-ui/index.html

7.4 前后端项目部署

(1)服务器一:Nginx:部署前端项目、配置反向代理;Mysql:主从复制结构中的主库。
(2)服务器二:JDK:运行java项目;Git:版本控制工具;Maven:项目构建工具;Jar:SpringBoot项目打成jar包基于内置Tomcat运行;Mysql:主从复制结构中的从库。
(3)服务器三:Redis:缓存中间件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值