网站性能优化小结和spring整合redis
现在越来越多的地方需要非关系型数据库了,最近网站优化,当然从页面到服务器做了相应的优化后,通过在线网站测试工具与之前没优化对比,发现有显著提升。
服务器优化目前主要优化tomcat,在tomcat目录下的server.xml文件配置如下内容:
<Connector port="1818"
protocol="HTTP/1.1"
maxHttpHeaderSize="8192"
maxThreads="1000"
minSpareThreads="100"
maxSpareThreads="1000"
minProcessors="100"
maxProcessors="1000"
enableLookups="false"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
connectionTimeout="20000"
URIEncoding="utf-8"
acceptCount="1000"
redirectPort="8443"
disableUploadTimeout="true"/> 参数说明:
Protocol 采用的协议//可将HTTP/1.1改为org.apache.coyote.http11.Http11NioProtocol 启动NIO模式
maxHttpHeaderSize 代表请求和响应的HTTP首部的最大长度,单位是字节。如果不指定,该属性将被设为4096(4K)。
maxThreads 客户请求最大线程数
minSpareThreads Tomcat初始化时创建的 socket 线程数
maxSpareThreads Tomcat连接器的最大空闲 socket 线程数
enableLookups 若设为true, 则支持域名解析,可把 ip 地址解析为主机名
redirectPort 在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
acceptAccount 监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads )
connectionTimeout 连接超时
minProcessors 服务器创建时的最小处理线程数
maxProcessors 服务器同时最大处理线程数
URIEncoding URL统一编码
compression 打开压缩功能
compressionMinSize 启用压缩的输出内容大小,这里面默认为2KB
compressableMimeType 压缩类型
connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间
网站性能优化,参照了《高性能网站建设指南》这本书和部分知识博客
就我们项目而言,我参照这本书,按照这么几个规范进行,书上提出了,优化十四个建议,不过,并不是十四建议通通采纳,网站性能一定能上升的非常好,要结合项目的实际情况。
这是我们采取的前端性能优化措施:
1.减少http请求 比如外部的css,js和图片等组件,访问一个网站时,这些组件都会被加载,组件过多,加载时间长,特别是图片等,所以减少http请求,可有效提高网站性能
2.头部引用外部css和底部引用js 初次点击进入网站,网站的背景图和其他非js效果的css效果会最先加载,j如果不放在头部的话,首先看到的就是空白,然后就有相应的css渲染效果,底部引用js,在视觉上让用户觉得加载快了,而且外部的css和js方便管理,内联的js和css过度使用,会导致页面代码重构和后续其他人开发,会比较吃力。同时这样做也是一种很好的规范。js放在尾部也就是</body>标签前,它会被最后加载,如果统统放在<head></head>下,并行加载,会导致阻塞后面文件的下载和会导致后面的css渲染变慢。因此放在尾部是比较好的选择。
3.压缩组件。目前通过tomcat中的上述配置实行gzip压缩
4.合并css和js文件 大家要知道加载一个js和加载两个js文件的速度完全是不一样的,尽快前者js文件的容量大于后者两个。总之一个请求的速度总会大于两个请求的速度。
从http请求的角度解析,客户端发出请求给服务器,服务器响应数据返回给客户端。一个请求到响应的速度始终大于两个请求。还是回到之前的减少http请求。另外合并不代表一个无关的js和另外好几个无关js合在一起,这样不利于后面管理,合并应该是相关js函数合在一起,不相关js文件如果内容很多,可不必合并,如果只有单独的一两个函数,可与另外一两个函数合并,切记要写注释,同时合并js,不可合并过多
后台采取的措施:
1.sql优化 查询尽量查出符合需要的字段,严禁用*,同时in和not in尽可能用exists和not exists替换等
2.Java代码复用,减少冗余,特别是后台很多重复的service,将其公共通用部分写成一个函数,以供用到的Controller进行复用(当然这对于优化网站性能方面,可能帮助不大,但有利于后续开发的进行)
下面进行正式的spring整合redis:
为什么要用redis?
就目前我们项目而言,打开pms后台加载过慢,当然原因包括没用的js过多引用进来加载时间长,自然速度慢,频繁的http请求,布局不合理(js全部放在头部),sql没有优化等。
上述问题都可以解决。
回到上述问题,为什么使用redis。使用redis做缓存,R可以将所有的数据先保存到缓存中,然后再存入mysql中,减小数据库压力,提高效率 。
redis为什么访问数据的速度大于mysql?
因为前者访问的是内存,后者是磁盘
因为cpu是直接与内存进行数据交互的
演示实例:
注意ssm框架,jdk8,tomcat8服务器
一、pom依赖
<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.</version>
</dependency>
<!-- spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.0..RELEASE</version>
</dependency>
<!-- mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.</version>
</dependency>
二、对应的application-config.xml配置
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="" />
<property name="testOnBorrow" value="true"/>
</bean> <!-- 连接池配置,类似数据库连接池 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<property name="hostName" value="192.168.126.128"></property>
<property name="port" value=""></property>
<property name="password" value=""></property>
<property name="poolConfig" ref="poolConfig"></property> </bean> <!-- 调用连接池工厂配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"></property> <!-- 如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast
to String!!! -->
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="filters" value="stat,config" /> <!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="" />
<property name="minIdle" value="" />
<property name="maxActive" value="" /> <!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="" /> <property name="validationQuery" value="SELECT 'x' FROM DUAL" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="" /> <!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="true" />
<!-- 超时时间;单位为秒。180秒=3分钟 -->
<property name="removeAbandonedTimeout" value="" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" /> <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
<!-- property name="filters" value="stat" /-->
</bean>
三、JavaBean
记得一定要实现序列化,否则会报错
package com.tp.soft.entity;
import java.io.Serializable;
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = -1695973853274402680L;
private int userid;
private String login_name;
private String login_pwd;
public User() {
}
public User(int userid, String login_name, String login_pwd) {
super();
this.userid = userid;
this.login_name = login_name;
this.login_pwd = login_pwd;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getLogin_name() {
return login_name;
}
public void setLogin_name(String login_name) {
this.login_name = login_name;
}
public String getLogin_pwd() {
return login_pwd;
}
public void setLogin_pwd(String login_pwd) {
this.login_pwd = login_pwd;
}
}
四、接口类
package com.tp.soft.dao;
import com.tp.soft.entity.User;
public interface UserMapper {
public User getUserById(int id);
}
五、接口对应的xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tp.soft.dao.UserMapper">
<!-- 缓存类配置 -->
<cache type="com.tp.soft.redis.RedisCache" /> <select id="getUserById" parameterType="int" resultType="user" useCache="true">
select * from AU_USER where userid = #{id}
</select>
</mapper>
六、mybatis-config.xm配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings> <!-- 二级缓存开启 -->
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="false"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
<!-- 配置映射类的别名 --> <typeAliases>
<!-- 配置entity下的所有别名 别名首字母小写 -->
<package name="com.tp.soft.entity" />
</typeAliases>
</configuration>
七、service和service实现类
package com.tp.soft.service;
import com.tp.soft.entity.User;
public interface UserSvc {
public User getUser(int id);
}
package com.tp.soft.service.impl; import javax.annotation.Resource; import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service; import com.tp.soft.dao.UserMapper;
import com.tp.soft.entity.User;
import com.tp.soft.service.UserSvc; @Service("userService")
public class UserSvcImpl implements UserSvc{ @Resource
private UserMapper userMapper; public User getUser(int id) {
User user = null;
try{
user = userMapper.getUserById(id);
}catch (DataAccessException e) {
System.out.println(e.getLocalizedMessage());
}
return user;
} }
八、Controller
package com.tp.soft.controller; import javax.annotation.Resource; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import com.tp.soft.entity.User;
import com.tp.soft.service.UserSvc; @Controller
public class UserController { @Resource
private UserSvc userSvc; @RequestMapping(value="/QueryUser")
public String toQueryUser(int id,Model model){ User user = userSvc.getUser(id); System.out.println(user.getLogin_name());
model.addAttribute("user", user);
return "/pc/userTest";
}
}
九、需用到的util
package com.tp.soft.redis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; public class JedisUtil {
private static String ADDR = "192.168.126.128";
private static int PORT = 6379;
private static String AUTH = "123456"; private static int MAX_ACTIVE = 1024; private static int MAX_IDLE = 200; private static int MAX_WAIT = 10000; private static int TIMEOUT = 10000; private static boolean TEST_ON_BORROW = true; private static JedisPool jedisPool = null; static {
try{
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(MAX_IDLE); config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config,ADDR,PORT,TIMEOUT,AUTH);
}catch (Exception e) {
e.printStackTrace();
}
} public synchronized static Jedis getJedis(){
try{
if(jedisPool != null){
Jedis jedis = jedisPool.getResource();
return jedis;
}else{
return null;
}
}catch (Exception e) {
e.printStackTrace();
return null;
}
} public static void returnResource(final Jedis jedis){
if(jedis != null){
jedisPool.returnResource(jedis);
}
}
}
package com.tp.soft.redis; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ibatis.cache.Cache; /*
* 使用第三方缓存服务器,处理二级缓存
*/
public class RedisCache implements Cache {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private String id; public RedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id; } public String getId() {
return this.id;
} public void putObject(Object key, Object value) {
JedisUtil.getJedis().set(SerializeUtil.serialize(key.toString()),
SerializeUtil.serialize(value)); } public Object getObject(Object key) {
Object value = SerializeUtil.unserialize(JedisUtil.getJedis().get(
SerializeUtil.serialize(key.toString())));
return value; } public Object removeObject(Object key) {
return JedisUtil.getJedis().expire(
SerializeUtil.serialize(key.toString()), 0); } public void clear() {
JedisUtil.getJedis().flushDB();
} public int getSize() {
return Integer.valueOf(JedisUtil.getJedis().dbSize().toString());
} public ReadWriteLock getReadWriteLock() {
return readWriteLock;
} }
package com.tp.soft.redis; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static Object unserialize(byte[] bytes) {
if (bytes == null)
return null;
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
十、演示效果

目前本人也是刚刚用到没多久,如果那里有问题,欢迎大家指教
其实性能的瓶颈和mysql有关系,目前对于mysql相关的原理等不是特别了解,需后面多加努力学习
网站性能优化小结和spring整合redis的更多相关文章
- 网站性能优化(Yahoo 35条)
Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...
- Yahoo团队经验:网站性能优化的34条黄金法则
Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 ...
- 网站性能优化实战——从12.67s到1.06s的故事
文章摘自https://juejin.im/post/5b0b7d74518825158e173a0c 作为互联网项目,最重要的便是用户体验.在举国“互联网+”的热潮中,用户至上也已经被大多数企业所接 ...
- Spring整合Redis&JSON序列化&Spring/Web项目部署相关
几种JSON框架用法和效率对比: https://blog.csdn.net/sisyphus_z/article/details/53333925 https://blog.csdn.net/wei ...
- Yahoo网站性能优化的34条规则
摘自:http://blog.chinaunix.net/uid/20714478/cid-74195-list-1.html Yahoo网站性能优化的34条规则 1.尽量减少HTTP请求次数 终端用 ...
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
input屏蔽历史记录 设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处 ;(function($){$.ex ...
- Yahoo! 35条网站性能优化建议
Yahoo! 35条网站性能优化建议 Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客 ...
- Yslow网站性能优化工具
Yslow是一款网站性能优化的插件:
- asp.net网站性能优化2则
摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...
随机推荐
- 转STM32官方固件库简介
ST(意法半导体)为了方便用户开发程序,提供了一套丰富的 STM32 固件库.固件库就是函数的集合,固件库函数的作用是向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API) .固件库将这些寄 ...
- java基础之XML
目录 java基础之XML 1. XML解析概述 2. DOM4J介绍 2.1 常用包 2.2 内置元素 2.2 Element类 2.3 Attribute类 2.4 常用操作 3. 代码演示 3. ...
- Gauss-Laguerre quadrature rule
% matlab script to derive the 2-point Gauss-Laguerre quadrature rule % and use it on an example % in ...
- Python 练习: 计算器
import re def format_string(s): # 对表达式进行格式化 s = s.replace(' ', '') s = s.replace("--", &qu ...
- React报错:Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix,
今天在开发时报了以下错误,记录一下 我们不能在组件销毁后设置state,防止出现内存泄漏的情况 出现原因直接告诉你了,组件都被销毁了,还设置个锤子的state啊 解决方案: 利用生命周期钩子函数:co ...
- php获取数据库中数据
<?php header("Content-type:text/html;charset=utf-8");//字符编码设置 $servername = "local ...
- (网页)angularjs中的验证input输入框只能输入数字和小数点
百度的资料:自己记录看下 把js的验证方法改成angular可使用的方法 AngularJS文件的写法: $scope.clearNoNum = function(obj,attr){ //先把非数字 ...
- SELinux 是什么?
一.SELinux的历史 SELinux全称是Security Enhanced Linux,由美国国家安全部(National Security Agency)领导开发的GPL项目,它拥有一个灵活而 ...
- Opengl正交矩阵 glOrthof 数学原理(转)
http://blog.sina.com.cn/s/blog_6084f588010192ug.html 在opengles1.1中设置正交矩阵只要一个函数调用就可以了:glOrthof,但是open ...
- 【PAT】B1033 旧键盘打字(20 分)
#include<stdio.h> #include<algorithm> #include<ctype.h> using namespace std; bool ...