发表于: 2021-09-23 20:11:36

1 1078


一,今天完成的事情

任务六。


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




返回列表 返回列表
评论

    分享到