注意事项
1.京淘文件上传
文件上传api
京淘图片上传 利用静态代码块赋值
图片上传优化(动态赋值) uuid去掉横线
2.反向代理机制(正向反向代理说明)
nginx学习
nginx实现反向代理 (图片回显)
Hosts文件说明 switchhosts软件
3.nginx实现tomcat集群部署
nginx实现 负载均衡 项目打包发布
1. 京淘文件上传
2021后谷歌禁用flash插件了,先用360代替访问吧。
1.1 文件上传入门案例
1.1.1 文件上传页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>实现文件上传</h1>
<!--enctype="开启多媒体标签",想要文件上传就要添加这个标签。文件上传参数比较多用post提交 -->
<form action="http://localhost:8091/file" method="post"
enctype="multipart/form-data">
<input name="fileImage" type="file" />
<input type="submit" value="提交"/>
</form>
</body>
</html>
1.1.2 编辑FileController
package com.jt.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
public class FileController {
/**
* 文件上传的入门案例
* url:http://localhost:8091/file
* 参数: fileImage 名称 (一般由标签的内部进行定义)
* 返回值: 文件上传成功!!!
*
* 文件输入一般用输入流:InputStream,但是用流需要读取字节信息
* 还要开关流,比较麻烦,如何解决呢?
* SpringMVC 提供了工具API 专门操作流文件.
*
* 文件上传的具体步骤:
* 1.准备文件目录
* 2.准备文件的全名 xxxx.jpg
* 3.准备文件上传的路径 D:/JT-SOFT/images/xxxx.jpg(文件的全路径+文件名)
* 4.将字节信息输出即可.
* 大小不要超过1M
*/
@RequestMapping("/file")
public String file(MultipartFile fileImage) throws IOException {
//注意这个文件上传的参数类型:MultipartFile
//1.准备文件目录(注意windows识别"\\",linux不识别"\\")
String dirPath="D:/JT-SOFT/images";
//1.1判断文件路径是否有效
File dirFile=new File(dirPath);//准备文件对象
if(!dirFile.exists()){
dirFile.mkdirs();//如果不存在则创建文件目录.(用mkdirs)
}
//2.获取文件名(从你上传的文件中获取)
String fileName=fileImage.getOriginalFilename();
//3.准备文件全路径
String filePath=dirPath+ "/" +fileName;
File file=new File(filePath);//封装为一个文件对象
//4.字节信息输出(需要处理异常:暂时抛出)
fileImage.transferTo(file);//将字节信息输出到指定位置
return "文件上传成功";
}
}
访问测试:
1.2 实现京淘图片上传操作
1.2.1 图片上传页面分析
1).url
2).js
1.2.2 封装VO对象
注意:
1.这个vo只有在后端使用所以写在manage项目中即可。
2.返回值说明:因为这里的文件上传用的是富文本编辑器插件,所以返回值需要按照它的要求返回特定的json串。
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {
//{"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
private Integer error; //错误信息 0程序运行正常 1.文件上传有误.
/* url:图片访问的虚拟路径.
* 解释:文件上传后一定会在计算机本地留下文件上传的记录,这个
* 地址只能是你自己在本机上访问(磁盘的真实路径:D:\JT-SOFT\images\2.jpg),
* 为了让其它人能访问够看到,所以封装为一个虚拟路径地址。
* */
private String url;
private Integer width; // >0 图片的宽高单位为:像素 至少>0
private Integer height; // >0
//设定上传失败的方法
public static ImageVO fail(){
return new ImageVO(1,null,null,null);
}
//设定上传成功的方法 这个成功方法不需要重载,因为成功后值都需要传过去。
public static ImageVO success(String url,Integer width,Integer height){
return new ImageVO(0,url,width,height);
}
}
1.2.3 编辑FileController
post请求,这个dir=image意思是说明上传的是个图片。
@Autowired
private FileService fileService;
/**
* 实现商品后台的文件上传
* url地址: http://localhost:8091/pic/upload?dir=image
* 参数: uploadFile: 文件的字节信息.
* 返回值: {"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
* ImageVO对象... (解释:因为这里的文件上传用的是富文本编辑器插件,所以返回值需要
* 按照它的要求返回特定的json串。)
*/
@RequestMapping("/pic/upload")
public ImageVO upload(MultipartFile uploadFile){
return fileService.upload(uploadFile);
}
查看参数名,由标签控制。
1.2.4 编辑FileService
package com.jt.service;
import com.jt.vo.ImageVO;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Service
public class FileServiceImpl implements FileService{
private String rootDirPath = "D:/JT-SOFT/images";
//1.2 准备图片的集合 包含了所有的图片类型.(还可以通过io流读取配置文件循环遍历进行赋值)
private static Set<String> imageTypeSet;
static {
imageTypeSet = new HashSet<>();
imageTypeSet.add(".jpg");
imageTypeSet.add(".png");
imageTypeSet.add(".gif");
}
/**
* 完善的校验的过程:数据库入库,一般数据没啥影响,但是
* 像文件 图片之类的需要校验后在入库,不然什么都能传入
* 对数据库会有影响。
* 1. 校验是否为图片
* 2. 校验是否为恶意程序(病毒)
* 3. 防止文件数量太多,分目录存储.(所有的文件都像一个目录存检索不方便)
* 4. 防止文件重名(比如:手机拍照的名字一般按照当前时间命名,若在同一时间拍照又上
* 传为同一网站会造成文件同名文体。)
* 5. 实现文件上传.
* @param uploadFile
* @return
*/
@Override
public ImageVO upload(MultipartFile uploadFile) {
//1.校验图片类型 jpg|png|gif..JPG|PNG....
//1.1 获取当前图片的名称 之后截取其中的类型. abc.jpg
String fileName = uploadFile.getOriginalFilename();
int index = fileName.lastIndexOf("."); //获取"."的下标
String fileType = fileName.substring(index);//从指定下标出开始截取字符串 .jpg
/*1.2 准备图片的集合(set:里面值要求不重复) 包含了所有的图片类型.(准备一个蓝本把得到的图片类型与这个蓝本进行
比较,如果符合其中的蓝本说明正确。) 但是写在方法里,用户每次调用都要生成set集合。所以把
它放在静态代码块里面。
Set<String> imageTypeSet = new HashSet<>();
imageTypeSet.add(".jpg");
imageTypeSet.add(".png");
imageTypeSet.add(".gif");*/
//将数据转化为小写(java代码不识别大小写,windows识别大小写)
fileType = fileType.toLowerCase();
//1.3 判断图片类型是否正确.
if(!imageTypeSet.contains(fileType)){
//图片类型不匹配
return ImageVO.fail();
}
//2.校验是否为恶意程序 根据宽度/高度进行判断
try {
//2.1 利用工具API对象 读取字节信息.获取图片对象类型(转不成功一定不是图,转成功大概率是图需要进一步判断。)
BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
//2.2 校验是否有宽度和高度(进一步判断图片的特有属性)
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if(width==0 || height==0) {
return ImageVO.fail();
}
//到这说明是图片
//3.分目录存储 yyyy/MM/dd 按照年月日分隔 (目录一般3~4级,太多会导致递归太消耗内存)
//3.1 将时间按照指定的格式要求 转化为字符串.
String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
.format(new Date());
//3.2 拼接文件存储的目录对象
String fileDirPath = rootDirPath + dateDir;//D:/JT-SOFT/images/yyyy/MM/dd
File dirFile = new File(fileDirPath);
//3.3 动态创建目录
if(!dirFile.exists()){
dirFile.mkdirs();
}
//4.防止文件重名 uuid.jpg 动态拼接(思路:给她拼接个uuid名字就不重复了。)
//4.1 动态生成uuid 实现文件名称拼接 名.后缀
//原始的UUID:c0311619-fe56-11eb-aa1c-5405dbff8fae (去掉"-",用空串代替。)
String uuid = UUID.randomUUID().toString().replace("-", "");
String realFileName = uuid + fileType;
//5 实现文件上传
//5.1 拼接文件真实路径 dir/文件名称.
String realFilePath = fileDirPath + realFileName;
//5.2 封装对象 实现上传
File realFile = new File(realFilePath);
uploadFile.transferTo(realFile);
//返回:实现文件上传成功!!!!(url暂时用虚拟路径)
String url = "https://img14.360buyimg.com/n0/jfs/t1/45882/22/7027/53284/5d49358aE9c25c1bd/fb7365463f6a1a7b.jpg";
return ImageVO.success(url,width,height);
} catch(IOException e) {
e.printStackTrace();
return ImageVO.fail();
}
}
}
1.2.5 上传效果
这个地方有京东的水印是因为:上传的是自己的图,回显的url为京东的虚拟地址。
1.3 文件上传优化
1.3.1 url优化
分析:当前页面会显的url是随便写的别人家的图片地址,实际情况这里应该是回显自己的图片地址。
说明: 如果需要通过网络虚拟路径访问服务器.则应该按照如下的配置实现.
本地磁盘路径: D:\JT-SOFT\images\2020\09\30\a.jpg
网络虚拟路径: http://image.jt.com\2020\09\30\a.jpg(域名+目录路径+文件名)
解释:一般在浏览器访问某一商品信息时,通常url是虚拟路径(域名暂时随便写的,在公司有专门的域名.) 但是现在只能是通过真实路径访问这个图片信息。
1.3.2 编辑pro配置文件(file)
# key=value 结构 数据类型本身就是String不需要加"". 不要有空格 image这个前缀是自己加的目的是标识这是图片的。
image.rootDirPath = D:/JT-SOFT/images
image.urlPath=http://image.jt.com
1.3.3 完成属性的动态赋值
修改了:添加了注解、去除空格、修改了url的接收
package com.jt.service;
import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Service
@PropertySource("classpath:/properties/images.properties") //容器动态加载指定的配置文件
public class FileServiceImpl implements FileService{
/*
*由于属性的值后期可能会发生变化,所以应该动态的获取属性数据.(如果要
* 改编代码就需要重新打包部署,不方便。利用pro配置文件注入)
*/
@Value("${image.rootDirPath}")
private String rootDirPath = "D:/JT-SOFT/images";
@Value("${image.urlPath}")
private String urlPath="http://image.jt.com";
//1.2 准备图片的集合 包含了所有的图片类型.(还可以通过io流读取配置文件循环遍历进行赋值)
private static Set<String> imageTypeSet;
static {
imageTypeSet = new HashSet<>();
imageTypeSet.add(".jpg");
imageTypeSet.add(".png");
imageTypeSet.add(".gif");
}
/**
* 完善的校验的过程:数据库入库,一般数据没啥影响,但是
* 像文件 图片之类的需要校验后在入库,不然什么都能传入
* 对数据库会有影响。
* 1. 校验是否为图片
* 2. 校验是否为恶意程序(病毒)
* 3. 防止文件数量太多,分目录存储.(所有的文件都像一个目录存检索不方便)
* 4. 防止文件重名(比如:手机拍照的名字一般按照当前时间命名,若在同一时间拍照又上
* 传为同一网站会造成文件同名文体。)
* 5. 实现文件上传.
* @param uploadFile
* @return
*/
@Override
public ImageVO upload(MultipartFile uploadFile) {
//0.为了防止配置文件的参数有多余的空格,在这里做一个去空格的处理
rootDirPath.trim();
urlPath.trim();
//1.校验图片类型 jpg|png|gif..JPG|PNG....
//1.1 获取当前图片的名称 之后截取其中的类型. abc.jpg
String fileName = uploadFile.getOriginalFilename();
int index = fileName.lastIndexOf("."); //获取"."的下标
String fileType = fileName.substring(index);//从指定下标出开始截取字符串 .jpg
/*1.2 准备图片的集合(set:里面值要求不重复) 包含了所有的图片类型.(准备一个蓝本把得到的图片类型与这个蓝本进行
比较,如果符合其中的蓝本说明正确。) 但是写在方法里,用户每次调用都要生成set集合。所以把
它放在静态代码块里面。
Set<String> imageTypeSet = new HashSet<>();
imageTypeSet.add(".jpg");
imageTypeSet.add(".png");
imageTypeSet.add(".gif");*/
//将数据转化为小写(java代码不识别大小写,windows识别大小写)
fileType = fileType.toLowerCase();
//1.3 判断图片类型是否正确.
if(!imageTypeSet.contains(fileType)){
//图片类型不匹配
return ImageVO.fail();
}
//2.校验是否为恶意程序 根据宽度/高度进行判断
try {
//2.1 利用工具API对象 读取字节信息.获取图片对象类型(转不成功一定不是图,转成功大概率是图需要进一步判断。)
BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
//2.2 校验是否有宽度和高度(进一步判断图片的特有属性)
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if(width==0 || height==0) {
return ImageVO.fail();
}
//到这说明是图片
//3.分目录存储 yyyy/MM/dd 按照年月日分隔 (目录一般3~4级,太多会导致递归太消耗内存)
//3.1 将时间按照指定的格式要求 转化为字符串.
String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
.format(new Date());
//3.2 拼接文件存储的目录对象
String fileDirPath = rootDirPath + dateDir;//D:/JT-SOFT/images/yyyy/MM/dd
File dirFile = new File(fileDirPath);
//3.3 动态创建目录
if(!dirFile.exists()){
dirFile.mkdirs();
}
//4.防止文件重名 uuid.jpg 动态拼接(思路:给她拼接个uuid名字就不重复了。)
//4.1 动态生成uuid 实现文件名称拼接 名.后缀
//原始的UUID:c0311619-fe56-11eb-aa1c-5405dbff8fae (去掉"-",用空串代替。)
String uuid = UUID.randomUUID().toString().replace("-", "");
String realFileName = uuid + fileType;
//5 实现文件上传
//5.1 拼接文件真实路径 dir/文件名称.
String realFilePath = fileDirPath + realFileName;
//5.2 封装对象 实现上传
File realFile = new File(realFilePath);
uploadFile.transferTo(realFile);
//返回:实现文件上传成功!!!!(url暂时用虚拟路径)
//String url = "https://img14.360buyimg.com/n0/jfs/t1/45882/22/7027/53284/5d49358aE9c25c1bd/fb7365463f6a1a7b.jpg";
//实现文件上传成功!!! http://image.jt.com\2020\09\30\a.jpg(域名+目录路径+图片名称)
String url = urlPath + dateDir + realFileName;
return ImageVO.success(url,width,height);
} catch(IOException e) {
e.printStackTrace();
return ImageVO.fail();
}
}
}
访问测试:
这里只能用真实路径访问。
2. 反向代理机制说明
2.1 为什么需要反向代理
需求:当完成文件上传时,业务返回页面的是虚拟地址路径ur址:http://image.jt.com/2020/09/30/a.jpg,而真实图片地址为:D:/JTSOFT/image/2020/09/30/a.jpg
问题: 如何让用户通过url访问 找到真实的磁盘地址的图片.
2.2 反向代理介绍
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。
总结:
1.反向代理服务器介于用户和真实服务器之间
2.用户以为反向代理服务器就是真实的服务器
3.用户不需要了解真实的服务器到底是谁.
4反向代理服务器保护了真实服务器信息.
5.反向代理服务器是服务器端代理.
2.3 正向代理机制
2.3.1 需求引入
1.宽带: 电信运营商 账号/密码 只能被一台机器使用.
2.路由器: 在家庭的内部创建了局域网 使得局域网中的设备可以通过路由器的功能与外界通信.
2.3.2 正向代理介绍
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
总结:
1.正向代理位于客户与服务器之间
2.客户端在发起请求之前 确定了目标服务器的地址.(eg:用手机刷抖音访问的是抖音的服务器)
3.服务器不清楚到底是哪台客户端访问的我,以为只是路由器访问的.
4.正向代理保护了客户的信息,所以也称之为 客户端代理
2.4 Nginx介绍
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
特点:
1.内存少 不超过2M tomcat服务器启动 300-500M
2.并发能力强 并发3万-5万次 tomcat并发 150-220之间
3.Nginx使用C语言开发.
2.5 Nginx安装和下载
2.5.1 nginx下载
官网:http://nginx.org/en/download.html
2.5.2 nginx安装的注意事项
1.Nginx服务器启动时会占用80端口.
2.Nginx服务安装时不要出现:中文+空格问题 , C盘慎用.(程序员操守,如果只有c盘则新建一个文件,但不要放在系统文件下,因为有些系统目录含有空格)
3.Nginx底层开发是用C语言写的,所以注释使用#号 独占一行完成注释(代码和注释不要写在同一行)
4.计算机名称如果是中文的 需要改为英文 (控制面板–用户账户–用户账户–更改名称) windows+L 锁屏快捷键 可以快数查看电脑的用户名
5.nginx服务器启动的速度特别快, 窗口会闪退 只启动一次即可
6.nginx命令的运行必须在nginx.exe所在的目录中执行.(先解压压缩包)
2.5.3 nginx命令
cls: 清屏
dir:查看当前文件下的所有目录
启动nginx: start nginx
(启动过不能再启动,多余的在任务管理器中进行关闭)
重启nginx: nginx -s reload
(-s代表同时关闭主线程和守护线程)
关闭nginx: nginx -s stop
出现以下界面说明成功:(localhost:80)
这个页面文件在
2.5.3 nginx启动项说明:
注意:每次启动nginx服务时会启动2个进程项.
nginx守护进程: 防止主进程意外关闭的. 如果意外了则重启主进程.(所以想要关闭nginx整个服务先关闭.守护线程,在关闭主线程) (守护线程占用的内存资源少)。
nginx主进程: 主要提供反向代理服务. (主线程占用的内存多)。
关闭nginx:nginx -s stop("s"代表关闭所有进程,包含主线程和守护线程)
2.5.4 nginx不能正常启动的说明
查看刘老师博客集。
2.6 Nginx反向代理入门案例
此文件在conf目录下
# nginx 需要使用http/https协议的
http {
#反向代理服务 一个服务就是一个server,所以配置多个反向代理就配置多个server,并且在{
}里面
server {
# nginx监听(拦截)的端口号 默认监听80端口 端口号可以重复
listen 80;
#监听的域名 域名不能重复.
server_name localhost;
#执行的反向代理的动作 /:拦截所有的路径
location / {
# root关键字 代理的是一个目录 (html:目录名)
root html;
#默认跳转页面
index index.html index.htm;
}
}
}
所以localjost:80可以访问默认的页面。
2.7 Nginx实现图片回显
2.7.1 需求说明
使用url:http://image.jt.com:80/2020/09/04/a.png 找到位于(域名后没有显示是因为80默认省略了.)D:\JT-SOFT\images\2020/09/04/a.png目录下的文件.最终实现图片回显.
分析:
拦截的域名: image.jt.com.
拦截的端口:80
转向的目录: D:\JT-SOFT\images
2.7.2 nginx反向代理配置
说明:当修改完成nginx之后.则重启nginx(注意nginx只启动一次,不要多启)
#配置图片服务器
server{
listen 80;
server_name image.jt.com;
location / {
## 转向目录 由于windows操作系统问题 所以需要替换/
root D:/JT-SOFT/images;
}
}
访问测试:
2.7.3关于HOSTS文件说明
说明:操作系统为了开发人员测试方便,可以通过hosts执行文件的域名与IP的映射关系.如果配置了hosts文件,则先走hosts之后执行全球DNS域名解析服务.
2.7.4 编辑hosts文件
说明: 操作系统为开发者提供了一个hosts文件.该文件可以实现域名与IP地址的映射关系.但是由于只是测试时使用.所以该配置只对本机有效. (想要用域名需要掏钱,没钱在测试中用就用这个hosts文件)
位置:
C:\Windows\System32\drivers\etc
如果是盗版系统可能没有这个文件,解决复制一个文件,在把里面的内容进行配置,注意不要新建一个文件因为可能需要权限.
具体配置
#@SwitchHosts! {
"url": null, "icon_idx": 0, "title": "\u5f53\u524d\u7cfb\u7edf hosts"}
# 京淘配置
#左侧写IP地址 右侧写域名 中间使用空格分隔
#为了实现Linux发布修改如下
#192.168.126.129 image.jt.com
#192.168.126.129 manager.jt.com
127.0.0.1 image.jt.com
127.0.0.1 manage.jt.com
127.0.0.1 www.jt.com
127.0.0.1 sso.jt.com
文件如果无法保存,需要修改权限: 错题集 百度
2.7.5 SwitchHosts编辑hosts文件
因为这个host文件所在目录比较多,所以如果经常需要配置这个文件 可以安装一个软件快速定位到这个host文件。
右键以管理员方式打开:
用法: 文件----新建—本地方案 (如果想要不想更改以前的配置,把原始的配置复制一份到本地方案中)
注意:编写完成后点击右下角对勾------进切换hosts环境 改不了:右键—以管理员身份运行这个软件,在进行编译.还不行百度/错题集.
具体配置:
# 京淘配置
#左侧写IP地址 右侧写域名 中间使用空格分隔
127.0.0.1 image.jt.com #图片服务器域名
127.0.0.1 manage.jt.com #京淘后台管理域名
#实现 nginx的
#192.168.126.129 image.jt.com
#192.168.126.129 manage.jt.com
127.0.0.1 www.jt.com #前端域名
#Bug 有时在使用该软件时可能会出现丢失最后一个字母的现象.
# sso.jt.com-->sso.jt.co
127.0.0.1 sso.jt.com #单点登录域名
再次测试回显:
3.nginx实现tomcat集群部署
3.1 集群分析
为什么要实现tomact集群:因为单台tomact服务器的处理请求的能力是有限的,多台tomact可以提高并发能力。
3.2 服务器反向代理(域名)
#配置京淘后台管理系统
# manage.jt.com localhost:8091服务器
server {
#用户是通过域名访问的所以这里监听的是域名的端口号 80
listen 80;
server_name manage.jt.com;
location / {
#root 代表文件目录
#index 代表默认的访问 首页页面
#proxy_pass 代表发起url请求
proxy_pass http://localhost:8091;
}
}
修改nignx服务器之后,重启nginx,之后访问测试。
3.3 动态获取端口
3.3.1 确定端口位置
需求:如果配置了多台tomact服务器,用户通过反向代理的调用,不清楚自己到底访问的是哪台服务器.那么应该如何测试负载均衡呢???
解决方案: 通过1个url请求获取访问服务器端口号即可(知道返回的端口号就知道访问不同服务器的概率了,也就可以测试负载均衡了).
说明:服务器端口号一般写在配置文件中,通过@value注解获取即可。
3.3.2 编辑PortController(manage中)
package com.jt.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PortController {
/**
* 通过Spring容器动态获取YML配置文件中的端口即可
*/
@Value("${server.port}")
private int port;
@RequestMapping("/getPort")
public String getPort(){
return "当前访问的端口号为:"+port;
}
}
访问测试:
3.4 搭建tomcat服务器集群
1、聚合工程直接 打父级的包 端口号换为8081,先停掉控制台的服务器。
2.先双击clean在双击install
之后从manage项目的target目录中复制jar包文件到一个目录中,改下名字准备集群部署.(因为测试的是manage的负载均衡所以只需要复制mannage的打包好后的jar包即可.)
3.4.1 项目发布命令
注意事项: 当前的命令执行 会占用dos命令窗口 打印控制台信息. 当dos命令窗口关闭 服务器停止(所以想要发布2个项目就要启动2个Dos窗口).
退出dos命令窗口: ctrl + c
java: java -jar 8081.war
访问测试:因为改了端口号在nginx中不能够映射,所以现在只能通过端口号访问。
3.5 实现Nginx集群配置
3.5.1 业务说明
当用户通过manage.jt.com的方式访问服务器时,要求通过反向代理的方式实现.要求配置nginx中集群.
3.5.2 配置nginx
#配置后台管理系统
server {
listen 80;
server_name manage.jt.com;
location / {
#root 代表文件目录
#index 代表默认的访问页面
#proxy_pass 代表发起url请求
#proxy_pass http://localhost:8091; 表示映射单台
#表示映射的是集群
proxy_pass http://jtW;
}
}
#配置集群的关键字 通过集群配置tomcat服务器即可
#默认: 1.轮询的机制 注意在windows中localhost=127.0.0.1
upstream jtW {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
测试:先重启nginx,通过域名访问结果为一次8081,一次8082轮询显示。
3.6 关于nginx负载均衡策略说明
3.6.1 轮询策略
说明:根据配置文件的顺序,之后依次访问服务器. 该策略也是默认的机制.(改完之后重启一下nginx服务器)
#默认: 1.轮询的机制
upstream jtW {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
server 127.0.0.1:8083;
}
3.6.2 权重策略
场景说明: 公司采购服务器都是有时间间隔的. 但是由于服务器新旧不同,硬件版本不同,导致服务器处理能力不同!!!
如果上述的问题不做处理,依然采用轮询的机制,则会出现严重的负载不均衡的现象.
所以需要通过权重的方式平衡压力.
#配置集群的关键字 通过集群配置tomcat服务器即可
# 2.权重策略
upstream jtW {
server 127.0.0.1:8081 weight=6; #数字写几都可以,代表10次用6次
server 127.0.0.1:8082 weight=3;
server 127.0.0.1:8083 weight=1;
}
访问结果:大多数为8081
3.6.3 IPHASH策略
需求:当某些业务需要用户特定的访问固定的服务器时,就要选用iphash机制.
配置:
# 3.IPHASH
upstream jtW {
ip_hash;
server 127.0.0.1:8081 weight=6;
server 127.0.0.1:8082 weight=3;
server 127.0.0.1:8083 weight=1;
}
访问结果:都为8081
IPHASH原理介绍:
3.7 关于Nginx负载均衡补充
3.7.1 down属性
说明:如果tomcat服务器发生了宕(dang)机的现象,则通过配置文件标识down的属性,则nginx将不会再次访问故障机.
#默认: 1.轮询的机制 2.权重策略 3.IPHASH
upstream jtW {
#ip_hash;
server 127.0.0.1:8081 down;
server 127.0.0.1:8082 ;
server 127.0.0.1:8083 ;
}
3.7.2 backup属性
说明:通常情况下 都会部署一些备用机防止由于主机宕机,剩余的机器不能实现高负载从而导致整个服务宕机的问题.
如果设置了备用机,则正常情况下用户不会访问.但是当主机宕机或者主机遇忙时才会访问.
#配置集群的关键字 通过集群配置tomcat服务器即可
#默认: 1.轮询的机制 2.权重策略 3.IPHASH
upstream jtW {
#ip_hash;
server 127.0.0.1:8081 down;
server 127.0.0.1:8082 ;
server 127.0.0.1:8083 backup;
}
但是以上属性配置 需要手动一个一个的去写,一旦宕机就要加上这个属性太麻烦,怎么有一种健康检查机制如果宕机了就是要备用机,恢复了还是原来的服务器.
3.7.3 tomcat高可用配置
属性配置:
1.max_fails=1 配置nginx访问服务器的最大的失败次数.
2.fail_timeout=60s; 理解为一个时间周期. 如果发现服务器宕机,则在60秒内不会再次访问故障机.
#配置集群的关键字 通过集群配置tomcat服务器即可
#默认: 1.轮询的机制 2.权重策略 3.IPHASH
upstream jtW {
#ip_hash;
server 127.0.0.1:8081 max_fails=1 fail_timeout=60s;
server 127.0.0.1:8082 max_fails=1 fail_timeout=60s;
server 127.0.0.1:8083 max_fails=1 fail_timeout=60s;
}