现在越来越多的地方需要非关系型数据库了,最近网站优化,当然从页面到服务器做了相应的优化后,通过在线网站测试工具与之前没优化对比,发现有显著提升。

服务器优化目前主要优化tomcat,在tomcat目录下的server.xml文件配置如下内容:

  1. <Connector port="1818"
  2.   protocol="HTTP/1.1"
  3.   maxHttpHeaderSize="8192"
  4.   maxThreads="1000"
  5.   minSpareThreads="100"
  6.   maxSpareThreads="1000"
  7.   minProcessors="100"
  8.   maxProcessors="1000"
  9.   enableLookups="false"
  10.   compression="on"
  11.   compressionMinSize="2048"
  12. compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
  13.   connectionTimeout="20000"
  14.   URIEncoding="utf-8"
  15.   acceptCount="1000"
  16.   redirectPort="8443"
  17.   disableUploadTimeout="true"/>
  18.  
  19. 参数说明:
  20. Protocol 采用的协议//可将HTTP/1.1改为org.apache.coyote.http11.Http11NioProtocol 启动NIO模式
  21. maxHttpHeaderSize 代表请求和响应的HTTP首部的最大长度,单位是字节。如果不指定,该属性将被设为4096(4K)。
  22. maxThreads 客户请求最大线程数
  23.   minSpareThreads Tomcat初始化时创建的 socket 线程数
  24.   maxSpareThreads Tomcat连接器的最大空闲 socket 线程数
  25.   enableLookups 若设为true, 则支持域名解析,可把 ip 地址解析为主机名
  26.   redirectPort 在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
  27.   acceptAccount 监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads )
  28.   connectionTimeout 连接超时
  29.   minProcessors 服务器创建时的最小处理线程数
  30.   maxProcessors 服务器同时最大处理线程数
  31.   URIEncoding URL统一编码
  32. compression 打开压缩功能
  33.   compressionMinSize 启用压缩的输出内容大小,这里面默认为2KB
  34.   compressableMimeType 压缩类型
  35.   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依赖

  1. <!-- redis -->
  2. <dependency>
  3. <groupId>redis.clients</groupId>
  4. <artifactId>jedis</artifactId>
  5. <version>2.1.</version>
  6. </dependency>
  7. <!-- spring-data-redis -->
  8. <dependency>
  9. <groupId>org.springframework.data</groupId>
  10. <artifactId>spring-data-redis</artifactId>
  11. <version>1.0..RELEASE</version>
  12. </dependency>
  13. <!-- mybatis-ehcache -->
  14. <dependency>
  15. <groupId>org.mybatis.caches</groupId>
  16. <artifactId>mybatis-ehcache</artifactId>
  17. <version>1.0.</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>com.alibaba</groupId>
  21. <artifactId>druid</artifactId>
  22. <version>1.0.</version>
  23. </dependency>

二、对应的application-config.xml配置

  1. <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
  2. <property name="maxIdle" value="" />
  3. <property name="testOnBorrow" value="true"/>
  4. </bean>
  5.  
  6. <!-- 连接池配置,类似数据库连接池 -->
  7. <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
  8. <property name="hostName" value="192.168.126.128"></property>
  9. <property name="port" value=""></property>
  10. <property name="password" value=""></property>
  11. <property name="poolConfig" ref="poolConfig"></property>
  12.  
  13. </bean>
  14.  
  15. <!-- 调用连接池工厂配置 -->
  16. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  17. <property name="connectionFactory" ref="connectionFactory"></property>
  18.  
  19. <!-- 如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast
  20. to String!!! -->
  21. <property name="keySerializer">
  22. <bean
  23. class="org.springframework.data.redis.serializer.StringRedisSerializer" />
  24. </property>
  25. <property name="valueSerializer">
  26. <bean
  27. class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
  28. </property>
  29. </bean>
  30.  
  31. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  32. <!-- 基本属性 url、user、password -->
  33. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  34. <property name="url" value="jdbc:mysql://localhost:3306/test" />
  35. <property name="username" value="root" />
  36. <property name="password" value="" />
  37. <property name="filters" value="stat,config" />
  38.  
  39. <!-- 配置初始化大小、最小、最大 -->
  40. <property name="initialSize" value="" />
  41. <property name="minIdle" value="" />
  42. <property name="maxActive" value="" />
  43.  
  44. <!-- 配置获取连接等待超时的时间 -->
  45. <property name="maxWait" value="" />
  46.  
  47. <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
  48. <property name="timeBetweenEvictionRunsMillis" value="" />
  49.  
  50. <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
  51. <property name="minEvictableIdleTimeMillis" value="" />
  52.  
  53. <property name="validationQuery" value="SELECT 'x' FROM DUAL" />
  54. <property name="testWhileIdle" value="true" />
  55. <property name="testOnBorrow" value="false" />
  56. <property name="testOnReturn" value="false" />
  57.  
  58. <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
  59. <property name="poolPreparedStatements" value="true" />
  60. <property name="maxPoolPreparedStatementPerConnectionSize" value="" />
  61.  
  62. <!-- 超过时间限制是否回收 -->
  63. <property name="removeAbandoned" value="true" />
  64. <!-- 超时时间;单位为秒。180秒=3分钟 -->
  65. <property name="removeAbandonedTimeout" value="" />
  66. <!-- 关闭abanded连接时输出错误日志 -->
  67. <property name="logAbandoned" value="true" />
  68.  
  69. <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
  70. <!-- property name="filters" value="stat" /-->
  71. </bean>

三、JavaBean

记得一定要实现序列化,否则会报错

  1. package com.tp.soft.entity;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class User implements Serializable{
  6.  
  7. /**
  8. *
  9. */
  10. private static final long serialVersionUID = -1695973853274402680L;
  11.  
  12. private int userid;
  13.  
  14. private String login_name;
  15.  
  16. private String login_pwd;
  17.  
  18. public User() {
  19.  
  20. }
  21.  
  22. public User(int userid, String login_name, String login_pwd) {
  23. super();
  24. this.userid = userid;
  25. this.login_name = login_name;
  26. this.login_pwd = login_pwd;
  27. }
  28.  
  29. public int getUserid() {
  30. return userid;
  31. }
  32.  
  33. public void setUserid(int userid) {
  34. this.userid = userid;
  35. }
  36.  
  37. public String getLogin_name() {
  38. return login_name;
  39. }
  40.  
  41. public void setLogin_name(String login_name) {
  42. this.login_name = login_name;
  43. }
  44.  
  45. public String getLogin_pwd() {
  46. return login_pwd;
  47. }
  48.  
  49. public void setLogin_pwd(String login_pwd) {
  50. this.login_pwd = login_pwd;
  51. }
  52.  
  53. }

四、接口类

  1. package com.tp.soft.dao;
  2.  
  3. import com.tp.soft.entity.User;
  4.  
  5. public interface UserMapper {
  6. public User getUserById(int id);
  7. }

五、接口对应的xml文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.tp.soft.dao.UserMapper">
  4. <!-- 缓存类配置 -->
  5. <cache type="com.tp.soft.redis.RedisCache" />
  6.  
  7. <select id="getUserById" parameterType="int" resultType="user" useCache="true">
  8. select * from AU_USER where userid = #{id}
  9. </select>
  10. </mapper>

六、mybatis-config.xm配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4. <configuration>
  5. <settings>
  6.  
  7. <!-- 二级缓存开启 -->
  8. <setting name="cacheEnabled" value="true"/>
  9. <setting name="lazyLoadingEnabled" value="false"/>
  10. <setting name="aggressiveLazyLoading" value="true"/>
  11. </settings>
  12. <!-- 配置映射类的别名 -->
  13.  
  14. <typeAliases>
  15. <!-- 配置entity下的所有别名 别名首字母小写 -->
  16. <package name="com.tp.soft.entity" />
  17. </typeAliases>
  18. </configuration>

七、service和service实现类

  1. package com.tp.soft.service;
  2.  
  3. import com.tp.soft.entity.User;
  4.  
  5. public interface UserSvc {
  6. public User getUser(int id);
  7. }
  1. package com.tp.soft.service.impl;
  2.  
  3. import javax.annotation.Resource;
  4.  
  5. import org.springframework.dao.DataAccessException;
  6. import org.springframework.stereotype.Service;
  7.  
  8. import com.tp.soft.dao.UserMapper;
  9. import com.tp.soft.entity.User;
  10. import com.tp.soft.service.UserSvc;
  11.  
  12. @Service("userService")
  13. public class UserSvcImpl implements UserSvc{
  14.  
  15. @Resource
  16. private UserMapper userMapper;
  17.  
  18. public User getUser(int id) {
  19. User user = null;
  20. try{
  21. user = userMapper.getUserById(id);
  22. }catch (DataAccessException e) {
  23. System.out.println(e.getLocalizedMessage());
  24. }
  25. return user;
  26. }
  27.  
  28. }

八、Controller

  1. package com.tp.soft.controller;
  2.  
  3. import javax.annotation.Resource;
  4.  
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.ui.Model;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8.  
  9. import com.tp.soft.entity.User;
  10. import com.tp.soft.service.UserSvc;
  11.  
  12. @Controller
  13. public class UserController {
  14.  
  15. @Resource
  16. private UserSvc userSvc;
  17.  
  18. @RequestMapping(value="/QueryUser")
  19. public String toQueryUser(int id,Model model){
  20.  
  21. User user = userSvc.getUser(id);
  22.  
  23. System.out.println(user.getLogin_name());
  24. model.addAttribute("user", user);
  25. return "/pc/userTest";
  26. }
  27. }

九、需用到的util

  1. package com.tp.soft.redis;
  2.  
  3. import redis.clients.jedis.Jedis;
  4. import redis.clients.jedis.JedisPool;
  5. import redis.clients.jedis.JedisPoolConfig;
  6.  
  7. public class JedisUtil {
  8. private static String ADDR = "192.168.126.128";
  9. private static int PORT = 6379;
  10. private static String AUTH = "123456";
  11.  
  12. private static int MAX_ACTIVE = 1024;
  13.  
  14. private static int MAX_IDLE = 200;
  15.  
  16. private static int MAX_WAIT = 10000;
  17.  
  18. private static int TIMEOUT = 10000;
  19.  
  20. private static boolean TEST_ON_BORROW = true;
  21.  
  22. private static JedisPool jedisPool = null;
  23.  
  24. static {
  25. try{
  26. JedisPoolConfig config = new JedisPoolConfig();
  27. config.setMaxIdle(MAX_IDLE);
  28.  
  29. config.setTestOnBorrow(TEST_ON_BORROW);
  30. jedisPool = new JedisPool(config,ADDR,PORT,TIMEOUT,AUTH);
  31. }catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35.  
  36. public synchronized static Jedis getJedis(){
  37. try{
  38. if(jedisPool != null){
  39. Jedis jedis = jedisPool.getResource();
  40. return jedis;
  41. }else{
  42. return null;
  43. }
  44. }catch (Exception e) {
  45. e.printStackTrace();
  46. return null;
  47. }
  48. }
  49.  
  50. public static void returnResource(final Jedis jedis){
  51. if(jedis != null){
  52. jedisPool.returnResource(jedis);
  53. }
  54. }
  55. }
  1. package com.tp.soft.redis;
  2.  
  3. import java.util.concurrent.locks.ReadWriteLock;
  4. import java.util.concurrent.locks.ReentrantReadWriteLock;
  5.  
  6. import org.apache.ibatis.cache.Cache;
  7.  
  8. /*
  9. * 使用第三方缓存服务器,处理二级缓存
  10. */
  11. public class RedisCache implements Cache {
  12. private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  13.  
  14. private String id;
  15.  
  16. public RedisCache(final String id) {
  17. if (id == null) {
  18. throw new IllegalArgumentException("Cache instances require an ID");
  19. }
  20. this.id = id;
  21.  
  22. }
  23.  
  24. public String getId() {
  25. return this.id;
  26. }
  27.  
  28. public void putObject(Object key, Object value) {
  29. JedisUtil.getJedis().set(SerializeUtil.serialize(key.toString()),
  30. SerializeUtil.serialize(value));
  31.  
  32. }
  33.  
  34. public Object getObject(Object key) {
  35. Object value = SerializeUtil.unserialize(JedisUtil.getJedis().get(
  36. SerializeUtil.serialize(key.toString())));
  37. return value;
  38.  
  39. }
  40.  
  41. public Object removeObject(Object key) {
  42. return JedisUtil.getJedis().expire(
  43. SerializeUtil.serialize(key.toString()), 0);
  44.  
  45. }
  46.  
  47. public void clear() {
  48. JedisUtil.getJedis().flushDB();
  49. }
  50.  
  51. public int getSize() {
  52. return Integer.valueOf(JedisUtil.getJedis().dbSize().toString());
  53. }
  54.  
  55. public ReadWriteLock getReadWriteLock() {
  56. return readWriteLock;
  57. }
  58.  
  59. }
  1. package com.tp.soft.redis;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.ObjectInputStream;
  6. import java.io.ObjectOutputStream;
  7.  
  8. public class SerializeUtil {
  9. public static byte[] serialize(Object object) {
  10. ObjectOutputStream oos = null;
  11. ByteArrayOutputStream baos = null;
  12. try {
  13. // 序列化
  14. baos = new ByteArrayOutputStream();
  15. oos = new ObjectOutputStream(baos);
  16. oos.writeObject(object);
  17. byte[] bytes = baos.toByteArray();
  18. return bytes;
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. return null;
  23. }
  24.  
  25. public static Object unserialize(byte[] bytes) {
  26. if (bytes == null)
  27. return null;
  28. ByteArrayInputStream bais = null;
  29. try {
  30. // 反序列化
  31. bais = new ByteArrayInputStream(bytes);
  32. ObjectInputStream ois = new ObjectInputStream(bais);
  33. return ois.readObject();
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. return null;
  38. }
  39. }

十、演示效果

目前本人也是刚刚用到没多久,如果那里有问题,欢迎大家指教

其实性能的瓶颈和mysql有关系,目前对于mysql相关的原理等不是特别了解,需后面多加努力学习

网站性能优化小结和spring整合redis的更多相关文章

  1. 网站性能优化(Yahoo 35条)

    Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...

  2. Yahoo团队经验:网站性能优化的34条黄金法则

    Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 ...

  3. 网站性能优化实战——从12.67s到1.06s的故事

    文章摘自https://juejin.im/post/5b0b7d74518825158e173a0c 作为互联网项目,最重要的便是用户体验.在举国“互联网+”的热潮中,用户至上也已经被大多数企业所接 ...

  4. Spring整合Redis&JSON序列化&Spring/Web项目部署相关

    几种JSON框架用法和效率对比: https://blog.csdn.net/sisyphus_z/article/details/53333925 https://blog.csdn.net/wei ...

  5. Yahoo网站性能优化的34条规则

    摘自:http://blog.chinaunix.net/uid/20714478/cid-74195-list-1.html Yahoo网站性能优化的34条规则 1.尽量减少HTTP请求次数 终端用 ...

  6. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  7. Yahoo! 35条网站性能优化建议

    Yahoo! 35条网站性能优化建议 Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客 ...

  8. Yslow网站性能优化工具

    Yslow是一款网站性能优化的插件:

  9. asp.net网站性能优化2则

    摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...

随机推荐

  1. 无法从其“Checked”属性的字符串表示形式“checked”创建“System.Boolean”类型

    如果你要在后台进行设置的话...在<input type="radio" id="dd" name="dd" runat=" ...

  2. 使用 Immutable Subject 来驱动 Angular 应用

    现状 最近在重构手上的一个 Angular 项目,之前是用的自己写的一个仿 Elm 架构的库来进行的状态管理,期间遇到了这些痛点: 样板代码太多 异步处理太过繁琐 需要单独维护一个 npm 包 其中, ...

  3. C++桥接模式【转】

    https://www.cnblogs.com/jiese/p/3164940.html 将抽象部份与它的实现部份分离,使它们都可以独立地变化. 桥接模式号称设计模式中最难理解的模式之一,关键就是这个 ...

  4. 通过jQuery制作电子时钟表的代码

    源码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <titl ...

  5. 用 JS 写 (轮播图 / 选项卡 / 滑动门)

    页面中经常会用到各式各样的轮播图,今天贺贺为大家介绍一种常用的方法,对于JS我们需要举一反三,一种方法可以对多个轮播样式进行渲染. <head> <meta charset=&quo ...

  6. VUE 实现复制内容到剪贴板功能

    注: 依赖第三方插件 clipboard 一.安装插件 npm install vue-clipboard2 --save 二.全局注入(main.js) import VueClipboard fr ...

  7. javascript arguments参数问题

    function f(a, b, c){ alert(arguments.length); // result: "2" a = 100; alert(arguments[0]); ...

  8. OSPF协议总结

    总结: 1.ospf协议报文不会泛洪扩散,而是逐级路由器处理后,再从所有ospf启用端口发送出去,也就是说,只能从邻居接收到ospf报文,报文的源ip是邻居的ip地址,目的ip是组播ip. 2.开启o ...

  9. Python中列表

    names=["Linda","Lily","Lucy","Grace","Paul"] #切片 p ...

  10. Info.plist的CFBundleIdentifier、CFBundleName、BundleDisplayName

    plist关键字段: CFBundleIdentifier:应用包名.唯一标识 CFBundleVersion:文件版本号,可以每次发版本递增 CFBundleShortVersionString:a ...