发表于: 2021-09-23 20:11:36
1 1077
一,今天完成的事情
任务六。
1,换没有offset,limit排序的相对简单的语句测试。redis是有用的。
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public ExcellentStudent queryById(Long id) {
return this.excellentStudentDao.queryById(id);
}
@RequestMapping(value = "/idJson", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> excellentStudentIDJson(){
long id = 1L;
ExcellentStudent excellentStudent = excellentStudentService.queryById( id );
if (null != excellentStudent) {
return Restful.set(400, "find exc stu successfully" );
} else {
return Restful.set(200, "find exc stu error", excellentStudent);
}
}
500个5秒没有缓存的json吞吐正常
200个1秒没有缓存,证明每秒50的瓶颈到了,正常
service的缓存来了
@Override
public ExcellentStudent queryById(Long id) {
String key = "excStudentID";
ExcellentStudent excellentStudent = null;
boolean hasKey = redisTemplate.hasKey(key);
if(hasKey){
excellentStudent = (ExcellentStudent) redisTemplate.opsForValue().get(key);
}else{
excellentStudent =
excellentStudentDao.queryById(id);
if(null == excellentStudent ) {
//防止为空的总是查询
redisTemplate.opsForValue().set( key, null);
}
redisTemplate.opsForValue().set(key, excellentStudent);
}
return excellentStudent;
//return this.excellentStudentDao.queryById(id);
}
10个有缓存1秒可以运行
200个2秒缓存提速
500个有缓存
2,在Linux上安装Redis,并测试war包。测试Redis在云Linux上能使用比较有和没有Redis的表现情况。
用windows同样版本,redis-5.0.10.tar.gz
tar.gz格式的安装来一套
/usr/local/redis put this tar.gz
cd
tar -zvxf redis-5.0.10.tar.gz
cd /usr/local/redis/redis-5.0.10
make
make PREFIX=/usr/local/redis install
PREFIX= 这个关键字的作用是编译的时候用于指定程序存放的路径。比如我们现在就是指定了redis必须存放在/usr/local/redis目录。假设不添加该关键字Linux会将可执行文件存放在/usr/local/bin目录。
库文件会存放在/usr/local/lib目录。配置文件会存放在/usr/local/etc目录。其他的资源文件会存放在usr/local/share目录。这里指定号目录也方便后续的卸载,后续直接rm -rf /usr/local/redis 即可删除redis
3,启动redis
根据上面的操作已经将redis安装完成了。我是在目录/usr/local/redis/ 输入下面命令启动redis
./bin/redis-server& ./redis.conf
上面命令中的&就是后台启动。redis.conf配置文件允许自定义多个配置文件,通过启动时指定读取哪个即可。
图片告知我们,指定 Redis 监听端口,默认端口为 6379。
特别注意redis.conf的daemonize yes、no。 yes表示启用守护进程,默认是no即不以守护进程方式运行。其中Windows系统下不支持启用守护进程方式运行。
将daemonize改为yes,不然我每次启动都得在redis-server命令后面加符号&,不这样操作则只要回到Linux控制台则redis服务会自动关闭。
同时也将bind注释。
将protected-mode设置为no。保护模式,该模式控制外部网是否可以连接redis服务,默认是yes,所以默认我们外网是无法访问的,如需外网连接rendis服务则需要将此属性改为no。这样启动后我就可以在外网访问了。先设置成能被外网访问。
ps -aux | grep redis 。查看Redis是否正在运行。采取查看进程方式。
netstat -lanp | grep 6379 。采取端口监听查看方式。
可能能用到redis-cli连接本地redis服务,使用redis的脚本控制台。我的是/usr/local/redis/redis-5.0.10/src/redis-cli 。输入exit可以退出redis脚本控制台。
开放阿里云6379端口.
kill -9 的Redis端口。重新启动 ./bin/redis-server& ./redis.conf
查看还在
4,处理包和服务器访问war包配置
war包换个名字tiles_login_redis.war
位置在/usr/local/resin/conf 的resin.xml
等60s,不用重启。访问 数字地址/tiles_login_redis/,得到helloworld
测试页面可以正常访问
5,加上必须的监测,测试云Linux。
远程10个JSP页面1s正常访问
远程50个JSP页面1s正常访问,但是返回时间明显变长。
5,重新打包,war包,换个名字,加redis,测试。tiles_login_redis.war
首先要贴出我新包的service 和controller。原来的tiles_login.war包还在。这样能对比是否有Redis对访问的影响。
package com.nicole.tileslogin.service.impl;
import com.nicole.tileslogin.entity.ExcellentStudent;
import com.nicole.tileslogin.dao.ExcellentStudentDao;
import com.nicole.tileslogin.service.ExcellentStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* (ExcellentStudent)表服务实现类
*
* @author makejava
* @since 2021-08-15 15:39:30
*/
@Service("excellentStudentService")
public class ExcellentStudentServiceImpl implements ExcellentStudentService {
@Autowired
private ExcellentStudentDao excellentStudentDao;
@Autowired
private RedisTemplate redisTemplate;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public ExcellentStudent queryByIdRedis(Long id) {
String key = "excStudentID";
ExcellentStudent excellentStudent = null;
boolean hasKey = redisTemplate.hasKey(key);
if( hasKey ){
excellentStudent = (ExcellentStudent) redisTemplate.opsForValue().get(key);
}else{
excellentStudent =
excellentStudentDao.queryById(id);
if( null == excellentStudent ) {
//防止为空的总是查询
redisTemplate.opsForValue().set( key, null);
}
redisTemplate.opsForValue().set(key, excellentStudent);
}
return excellentStudent;
}
@Override
public ExcellentStudent queryById(Long id) {
return this.excellentStudentDao.queryById(id);
}
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
@Override
public List<ExcellentStudent> queryAllByLimit(int offset, int limit) {
String key = "studentList";
ValueOperations<String, List<ExcellentStudent>> valueOperations = redisTemplate.opsForValue();
List<ExcellentStudent> studentList = new ArrayList<>();
boolean hasKey = redisTemplate.hasKey(key);
if(hasKey){
studentList = valueOperations.get(key);
}else{
studentList =
excellentStudentDao.queryAllByLimit( offset, limit);
if(studentList.size() < 1) {
valueOperations.set("studentList", null);
}
valueOperations.set("studentList", studentList);
}
return studentList;
// return excellentStudentDao.queryAllByLimit(offset,limit);
}
/**
* 新增数据
*
* @param excellentStudent 实例对象
* @return 实例对象
*/
@Override
public ExcellentStudent insert(ExcellentStudent excellentStudent) {
this.excellentStudentDao.insert(excellentStudent);
return excellentStudent;
}
/**
* 修改数据
*
* @param excellentStudent 实例对象
* @return 实例对象
*/
@Override
public ExcellentStudent update(ExcellentStudent excellentStudent) {
this.excellentStudentDao.update(excellentStudent);
return this.queryById(excellentStudent.getId());
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Long id) {
return this.excellentStudentDao.deleteById(id) > 0;
}
}
package com.nicole.tileslogin.controller;
import com.nicole.tileslogin.entity.ExcellentStudent;
import com.nicole.tileslogin.rest.Restful;
import com.nicole.tileslogin.service.ExcellentStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* (ExcellentStudent)表控制层
*
* @author makejava
* @since 2021-08-15 15:39:31
*/
@Controller
@RequestMapping("/excellentStudent")
public class ExcellentStudentController {
/**
* 服务对象
*/
@Autowired
private ExcellentStudentService excellentStudentService;
@RequestMapping(value = "/idjsonredis", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> excellentStudentIDJsonRedis(){
long id = 1L;
ExcellentStudent excellentStudent = excellentStudentService.queryByIdRedis( id );
if (null != excellentStudent) {
return Restful.set(400, "find exc stu successfully",excellentStudent );
} else {
return Restful.set(200, "find exc stu error", excellentStudent);
}
}
@RequestMapping(value = "/idbyjson", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> excellentStudentIDJson(){
long id = 1L;
ExcellentStudent excellentStudent = excellentStudentService.queryById( id );
if (null != excellentStudent) {
return Restful.set(400, "find exc stu successfully",excellentStudent );
} else {
return Restful.set(200, "find exc stu error", excellentStudent);
}
}
@RequestMapping(value = "/salarydescredis", method = RequestMethod.GET)
public String salaryDesc(Map<String,Object> map){
//只看前4个记录,且按工资高低排序
int offset = 0;
int limit = 4;
List<ExcellentStudent> studentList =
excellentStudentService.queryAllByLimit( offset, limit);
map.put("excelStu",studentList);
return "excellentStudent";
}
@RequestMapping(value = "/salarydescjsonredis", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> excellentStudentJson(){
int offset = 0;
int limit = 4;
List<ExcellentStudent> studentList = excellentStudentService.queryAllByLimit( offset, limit);
if (null == studentList) {
return Restful.set(400, "find exc stu successfully" ,studentList);
} else {
return Restful.set(200, "find exc stu error", studentList);
}
}
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("selectOne")
public ExcellentStudent selectOne(Long id) {
return this.excellentStudentService.queryById(id);
}
}
6,没有带redis的页面,要同样的数据。json格式返回。
1000个7秒
1000个请求2s。有错,有瓶颈,不快。
7,测试远程,带redis就是用了redis。和6取同样的数据。json格式返回。
首先是少量10个1s,可以正常访问
1000个请求5s生成
1000个请求2s。和上面的5s比是遇到了瓶颈。
利用Redis,吞吐量增大。错误相应可能更少。我其实喜欢看average和median的情况,在Redis需要在5s内,压力更大的时候,这2个数值都比7s的没有Redis的表现更好。
1000个请求,2s,median的提升也可见。
8,原来包的jsp页面。没有Redis。逻辑有点复杂,需要排序,limit。返回列表。
复杂数据,页面也是服务器处理。只供展示所用。还是json合适。
9,有Redis的jsp页面。逻辑有点复杂,需要排序,limit。返回列表。
图片数据也在同一个服务器,没分开,图片不少,js不少的时候,数据库并不是瓶颈。
二,今天问题
用windows,有可能是本地网络不够好。但是更可能是因为Redis本来就没考虑windows开发,Linux适合作服务器,同样一个网页,远程测试能力明显提高。用windows是测试为了保证代码没错,再放上网。
三,今天的收获
jsp的页面以前测过了。Profession页面和优秀学生页面,如果不用登录,我用的是拦截器方式。拦截器的损耗比较明显。Profession页面,还不如我新的exc stu设置的变量用于测试,所以就不展示。
Redis的瓶颈最有可能是机器内存的大小或者网络带宽。因为任务六的目的在于,用JMeter压力测试,缓存帮助关系型数据库缓解压力。
JSP页面的测试,前一天的日报已经写好了。
//idjson 这样的Url,第一个左斜线是一种转义字符。
利用Redis,吞吐量增大。错误相应可能更少。json,不涉及页面处置,不是jsp页面的时候。我其实喜欢看average和median的情况,在Redis压力更大的时候,这2个数值都比没有Redis的表现更好。
返回Json,浏览器再渲染才是合适的处理方式。jsp页面也测试了。
图片数据也在同一个服务器,没分开,图片不少,js不少的时候,数据库并不是瓶颈。
四,明天的计划
任务6
评论