性能战术:
性能战术:
性能战术的目标是对一定的时间限制内到达系统的事件生成一个响应,这些事件可以是消息到达、定时器到时,系统状态的变化。
性能战术包括3个分类:
1.资源需求——分析影响性能的资源因素
2.资源管理——提高资源的应用效率
3.资源仲裁——解决资源的争用
其中影响响应时间的两个因素:资源消耗和闭锁时间
资源消耗(Resource consumption):资源包括CPU、数据存储、网络通信带宽和内存等;资源消耗是指实际需要耗费的时间;
闭锁时间(Blocked time ):由于资源争用、资源不可用或长时间计算导致事件无法处理,这是指计算机可能等待的时间。
资源需求:
事件流是资源需求的源。
需求的两个特性是:1.资源流中的事件之间的时间;2.每个请求所消耗的资源是多少。
减少处理一个事件流所需要的资源。
l 提高计算效率,如改进关键算法,如大二所学数据结构中的七大查找算法。
例:在我们进行数据查找时,使用二分法:
//二分递归 int BinarySearch(int a[], int value, int low, int high) { int mid = low+(high-low)/2; if(a[mid]==value) return mid; if(a[mid]>value) return BinarySearch(a, value, low, mid-1); if(a[mid]<value) return BinarySearch(a, value, mid+1, high); }
l 减少计算开销。
比如保存上次计算的结果。如设计模式中的备忘录模式
demo入口
package com.wc.momoto; /** * 类似白箱备忘录模式 * @author weichyang * */ public class Client { /** * 客户端 * * @param args */ public static void main(String[] args) { int state = 3; Originator originator = new Originator(); Caretaker caretaker = new Caretaker(); originator.setState(state); /** * 创建备忘录对象的 缓存起来 */ caretaker.saveMemento(originator.creatMementoObject()); /* * 进行设置重新还原 */ originator.setState(5); System.out.println("发起人更改状态:" + originator.getState()); originator.restoreMemento(caretaker.retrieveMemento()); } }
管理者
package com.wc.momoto; /** * 管理者 负责管理Caretaker * * @author weichyang * */ public class Caretaker { private Memento memento; /** * 备忘录的取值方法 */ public Memento retrieveMemento() { return this.memento; } /** * 备忘录的赋值方法 */ public void saveMemento(Memento memento) { this.memento = memento; } }
备忘录:
package com.wc.momoto; /** * 备忘录 * * @author weichyang * */ public class Memento { private int state; public Memento() { super(); } public Memento(int state) { this.state = state; System.out.println("备忘录 当前保存 状态:" + state); } public int getState() { return state; } public void setState(int state) { this.state = state; } }
可以通过资源管理减少响应时间。
引入并发(Introduce concurrency ):通过并行处理,减少闭锁时间;
维持数据或计算的多个副本(Maintain multiple copies ):维持副本可以减少相同的计算;
增加可用资源(Increase available resources ):比如增加CPU速度、增加内存等。
l 限制执行时间。
比如,我们读取硬件数据,要求必须在指定的最长时间内返回。
l 限制队列大小,控制处理事件数量。
比如,限制消息队列的大小,不接受过多的事件涌入。
l 数据流的关闭
编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) { if (conn != null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (rs != null) { try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
l数据库连接池和线程池的使用
这两个池都是用于重用对象的,前者可以避免频繁地打开和关闭连接,后者可以避免频繁地创建和销毁线程
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/qytp</property> <property name="user">root</property> <property name="password">root</property> <property name="initialPoolSize">5</property> <property name="maxPoolSize">20</property> </default-config> <named-config name="test"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/qytp</property> <property name="user">root</property> <property name="password">root</property> </named-config> </c3p0-config>
dao层
import entity.Goods; import java.sql.SQLException; import java.util.List; /** * Created by teaGod on 2017/9/18. */ public interface GoodsDao { List<Goods> queryAllGoods() throws SQLException; List<Goods> queryAllGoods2() throws SQLException; List<Goods>search(String name)throws SQLException; List<Goods>search3(String name)throws SQLException; }
package dao; import entity.Goods; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import utils.ReadDataSource; import javax.sql.DataSource; import java.sql.SQLException; import java.util.List; /** * Created by teaGod on 2017/9/18. */ public class GoodsDaoImpl implements GoodsDao { DataSource dataSource = ReadDataSource.getDataSource(); @Override public List<Goods> queryAllGoods() throws SQLException { QueryRunner queryRunner = new QueryRunner(dataSource); String sql = "select * from data"; // queryRunner.update("delete from apple where id=?",22);//删除 // queryRunner.update("insert into apple values(?,?) ",222,"E");//增加 // queryRunner.update("update apple set id=? where name=?",636,"Z");//改 return queryRunner.query(sql, new BeanListHandler<>(Goods.class)); } @Override public List<Goods> search(String name) throws SQLException { // TODO Auto-generated method stub QueryRunner queryRunner = new QueryRunner(dataSource); String sql = "select * from data where name='"+name+"'"; return queryRunner.query(sql, new BeanListHandler<>(Goods.class)); } @Override public List<Goods> search3(String name) throws SQLException { // TODO Auto-generated method stub QueryRunner queryRunner = new QueryRunner(dataSource); String sql = "select * from data2 where name='"+name+"'"; return queryRunner.query(sql, new BeanListHandler<>(Goods.class)); } @Override public List<Goods> queryAllGoods2() throws SQLException { QueryRunner queryRunner = new QueryRunner(dataSource); String sql = "select * from data2"; // queryRunner.update("delete from apple where id=?",22);//删除 // queryRunner.update("insert into apple values(?,?) ",222,"E");//增加 // queryRunner.update("update apple set id=? where name=?",636,"Z");//改 return queryRunner.query(sql, new BeanListHandler<>(Goods.class)); } }
一个数据库连接对象对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库联接对象),由应用程序动态地对池中的连接进行申请、使用和释放。
对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。