网站性能优化小结和spring整合redis

news/2024/5/10 8:00:30/文章来源:https://blog.csdn.net/weixin_34235457/article/details/89623375

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

服务器优化目前主要优化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.0</version>  </dependency><!-- spring-data-redis --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.0.2.RELEASE</version></dependency><!-- mybatis-ehcache --><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.24</version></dependency>

 

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

 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="1000" /><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="6379"></property><property name="password" value="123456"></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="1234" /><property name="filters" value="stat,config" /><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="1" /><property name="minIdle" value="1" /> <property name="maxActive" value="40" /><!-- 配置获取连接等待超时的时间 --><property name="maxWait" value="60000" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000" /><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="20" /><!-- 超过时间限制是否回收 --> <property name="removeAbandoned" value="true" /> <!-- 超时时间;单位为秒。180秒=3分钟 --> <property name="removeAbandonedTimeout" value="180" /> <!-- 关闭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{@Resourceprivate 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 {@Resourceprivate 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相关的原理等不是特别了解,需后面多加努力学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_712004.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相关内容学习网站

2019独角兽企业重金招聘Python工程师标准>>> 大数据学习之路&#xff1a;https://blog.csdn.net/sinat_33518009/article/details/79434177 Zookeeper ZooKeeper学习第一期---简单介绍&#xff1a;http://www.cnblogs.com/wuxl360/p/5817471.html ZooKeeper学习第二…

vue 写门户网站_你不得不知道的Vue项目技巧

最近公司来了不少实习生和经验不是特别丰富的前端开发人员&#xff0c;带着他们做项目的时候&#xff0c;发现有很多入行0-3年的前端者欠缺一些东西。那么&#xff0c;这里我就以一个 vue 项目为例给大家分享一下 vue 项目的一些技巧。其实有很多人的项目可能都是直接 vue-cli …

百度seo排名规则_百度seo排名优化要点讲解(已帮助5184人)

内容导读本文针对百度seo排名优化要点的问题讲得比较泛&#xff0c;只讲到了点而没有具体展开说明。事实上&#xff0c;百度seo排名优化是个庞大的系统工程&#xff0c;其细节不可能在几篇文章中就能完全说明白。笔者建议&#xff0c;若想要真正搞懂百度seo排名优化的要点&…

网页制作中点一张图片变成图片浏览式_如何建设响应式网站?

随着H5响应式网站建设技术的日趋成熟&#xff0c;它大大降低了网站建设成本。在技术成熟之前&#xff0c;需要制作两套模板&#xff0c;一套是PC端一套是手机端。H5响应网站在访问浏览器时通过区分浏览器而不同。H5自适应网站是一组屏幕&#xff0c;可以以具有不同屏幕分辨率的…

网站漏洞修复方案防止SQL注入攻击漏洞

SQL注入漏洞在网站漏洞里面属于高危漏洞&#xff0c;排列在前三&#xff0c;受影响范围较广&#xff0c;像asp、.net、PHP、java、等程序语言编写的代码&#xff0c;都存在着sql注入漏洞&#xff0c;那么如何检测网站存在sql注入漏洞&#xff1f; SQL注入漏洞测试方法 在程序代…

大型网站技术架构(八)网站的安全架构

2019独角兽企业重金招聘Python工程师标准>>> 从互联网诞生起&#xff0c;安全威胁就一直伴随着网站的发展&#xff0c;各种Web攻击和信息泄露也从未停止。常见的攻击手段有XSS攻击、SQL注入、CSRF、Session劫持等。 1、XSS攻击 XSS攻击即跨站点脚本攻击&#xff08;…

ASP.NET MVC多语言 仿微软网站效果

文章转载自&#xff1a;https://blog.csdn.net/cooldiok/article/details/78313513 微软作为ASP.NET的创造者&#xff0c;它对于官网的结构设计肯定有值得我们借鉴和参考的地方 本项目是基于VS2017 pro开发的&#xff0c;将从你已经创建了一个MVC项目开始介绍&#xff1a; 流程…

2018程序员必备的4大网站推荐(代码、编程、SQL等)

科技时代&#xff0c;程序员是一个热门行业&#xff0c;也是一个高薪行业&#xff0c;很多人很羡慕程序员&#xff0c;其实作为一名合格的程序员&#xff0c;要不断的提升自己&#xff0c;因为科技也在不断进步&#xff0c;所以&#xff0c;接下来小编分享5个程序员必备网站&am…

python如何爬取网站所有目录_用python爬虫爬取网站的章节目录及其网址

认识爬虫 网络爬虫&#xff08;又被称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索…

最大的脚本网站_网站页面性能优化注意事项

为了更好地提升用户的浏览体验&#xff0c;《移动落地页体验白皮书4.0》中规定&#xff1a;页面的首屏内容应在1.5秒内加载完成。百度搜索对用户行为的研究表明&#xff0c;页面首屏的加载时间在1.5秒以内的页面&#xff0c;会带给用户流畅快捷的极速体验。近期发现有部分站点移…

基于django的视频点播网站开发-step10-后台评论管理功能...

本讲中&#xff0c;我们会讲到评论管理功能&#xff0c;数据库中的每一条是来自用户的评价&#xff0c;因此后台中的评论管理只有评论列表和评论删除功能&#xff0c;没有增加评论和编辑评论。 照例我们先添加评论管理的相关路由 path(comment_list/, views.CommentListView.as…

这个机器学习论文大众评审网站,要让每篇arXiv论文都得到讨论

圆栗子 发自 凹非寺 量子位 出品 | 公众号 QbitAI研究机器学习的人类们&#xff0c;通常喜欢把研究成果发上ArXiv。不过&#xff0c;ArXiv上面没有讨论板&#xff0c;公开讨论场所多集中在Reddit和推特上。而社交平台又无法提供纯粹的学术环境&#xff0c;讨论过程中很容易歪楼…

不要在网站上无限滚动!

人们在浏览网站的时候是喜欢用“无限滚动”&#xff0c;还是喜欢点击“阅读更多”或“查看更多”?无限滚动消除了分页的需要——分页是将数字内容分离到不同页面的过程。但这种方式真的好吗&#xff1f;作者 | Monish reddy译者 | 风车云马&#xff0c;责编 | 屠敏出品 | CSDN…

SEO技巧--代码优化

SEO技巧 一、搜索引擎工作原理 当我们在输入框中输入关键词&#xff0c;点击搜索或查询时&#xff0c;然后得到结果。深究其背后的故事&#xff0c;搜索引擎做了很多事情。 在搜索引擎网站&#xff0c;比如百度&#xff0c;在其后台有一个非常庞大的数据库&#xff0c;里面存储…

php网站用框架与不用的区别,做前端网页是不是必须要用网页框架

做前端网页是不是必须要用网页框架2017-09-15做前端网页是不是必须要用网页框架&#xff1f;个人感觉这分为两种情况&#xff0c;一种是能力超强&#xff0c;时间够用的情况&#xff0c;另外一种就是用前端网页框架&#xff0c;可以节约开发时间和减少工作量&#xff0c;这可以…

5个资源满满的网站,都是百度找不到的好资源,30T的硬盘瞬间爆满

日常最让人心烦的事莫过于在百度上找不到自己想要的资源了&#xff0c;如果不急可以慢慢找那还行&#xff0c;但是如果是非常急&#xff0c;现在就要用的话&#xff0c;真的瞬间就想砸了电脑。找不到自己想要的资源&#xff0c;配置再高的电脑也没用。其实&#xff0c;既然在百…

想快速了解AI各领域的前沿研究成果?可以来这个网站看看 | 资源

乾明 发自 凹非寺 量子位 报道 | 公众号 QbitAI想了解AI各领域的前沿研究成果吗&#xff1f;现在&#xff0c;只需要点几下鼠标就行了。近日&#xff0c;一个名为StateOfTheArt.ai的网站在NeurIPS大会期间上线&#xff0c;收罗了人工智能各个领域的前沿研究成果。并按照领域、任…

PC比电脑好玩的秘密是什么?答案就是因为有这些神奇的网站!

五花八门小工具合集http://www.nicetool.net/ 该网站真的很“乱”&#xff01;因为里面的小功能真的很多&#xff01;无论是Gif制作、证件照换底色、还是搞笑的王思聪微博生成&#xff0c;它都能让你得心意手&#xff01; 根据你的星座推荐电影https://magicmoviesorter.com/ 如…

傅立叶变换还能画简笔画?谷歌工程师开发的这个试玩网站火了| 附资源

晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI无论是处理声音和图像信号&#xff0c;都必须用到傅立叶变换。其实除了这些“正经”用途&#xff0c;它还能做一些有意思的事情。最近&#xff0c;一位名叫Jez Swanson的谷歌工程师自己写了篇博客&#xff0c;教你用傅立叶变换画出…

程序员去交友网站找女友,结果意外了...

1024程序员节&#xff08;今天是活动最后一天&#xff09;&#xff0c;CSDN旗下的码书商店为程序员放个“价”&#xff0c;全场所有书籍8折&#xff0c;电子产品可以拥有大额优惠券&#xff0c;购买前可加文末客服微信领取优惠券哦&#xff01;卫衣原价249元&#xff0c;1024专…