Hibernate(四)
Hibernate的二级缓存
- 理解缓存定义:
- 缓存(Cache):计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。
- 理解二级缓存的定义:
- Hibernate中提供了两个级别的缓存
- 一级缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存是由Hibernate管理的,一般情况下无需进行干预。
- 二级缓存是SessionFactory级别的缓存,它是属于进程范围的缓存。
- Hibernate的SessionFactory缓存可以分为两类:
- 内置缓存:Hibernate自带的,不可拆卸。通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放到SessionFactory的缓存中,映射元数据是映射文件中数据(*.hbm.xml文件中的数据)的复制,该内置缓存是只读的。
- 外置缓存(二级缓存):一个可排至的缓存插件,在默认情况下,SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或硬盘。
- Hibernate中提供了两个级别的缓存
- 使用Hibernate的二级缓存:
- 适合放入二级缓存中的数据:
- 很少被修改。
- 不是很重要的数据,允许出现偶尔的并发问题。
- 不适合放入二级缓存中的数据:
- 经常被修改。
- 财务数据,绝对不允许出现并发问题。
- 与其他应用程序共享的数据。
- 适合放入二级缓存中的数据:
- Hibernate的二级缓存的架构
- 二级缓存的并发访问策略:
- 两个并发的事务同时访问吃就吃的缓存的相同数据时,也有可能出现各类并发问题。
- 二级缓存可以设定一下4中类型的并发访问策略,每一种访问策略对应一种事务的隔离级别。
- 非严格读写(nonstrict-read-wirte):不保证缓存与数据库中数据的一致性。提供Read Uncommited事务隔离级别。对于极少被修改,而且允许脏读的数据,可以采用这种策略。
- 读写型read-write):提供Read Committed数据隔离级别。对于经常读但是很少被修改的数据,可以采用这种隔离烈性,因为它可以防止脏读。
- 事务型(transaction):仅仅在受管理环境下使用。它提供了Repeatable Read 事务隔离级别。对于经常读但是很少被修改的数据,可以采用这种隔离级别,因为它可以防止脏读和不可以重复读。
- 只读型(read-only):提供Serializable数据隔离级别。对于从来不会被修改的数据,可以采用这种访问策略。
- 管理Hibernate的二级缓存
- Hibernate的二级缓存是进程或集群范围内的缓存。
- 二级缓存是可配置的插件,Hibernate允许选用以下类型的缓存插件:
- EHCache:可作为进程分为内的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
- OSCache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
- SwarmCache:可作为集群范围内的缓存,但是不支持Hibernate的查询缓存。
- JBossCache:可作为集群范围内的缓存,支持Hibernate的查询缓存。
- 4种缓存插件的并发访问策略
缓存插件 | read-only | nonstrict-read-write | read-write | transaction |
EHCache | √ | √ | √ | |
OSCache | √ | √ | √ | |
SwarmCache | √ | √ | ||
JBossCache | √ | √ |
- 使用Hibernate的二级缓存的步骤:
- 加入二级缓存插件的jar包及配置文件。
- backport-util-concurrent.jar
- commons-logging.jar
- ehcache-1.5.0.jar
- ehcache.xml
- 配置hibernate.cfg.xml
- 配置启动Hibernate的二级缓存
<!-- 启用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
- 配置启动Hibernate的二级缓存
- 加入二级缓存插件的jar包及配置文件。
- 配置二级缓存的提供商
- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
- 配置那些类使用二级缓存
<!-- 配置那个类使用二级缓存 -->
<class-cache usage="read-only" class="cn.hibernate3.demo4.Customer"/>
- 配置二级缓存的提供商
- 二级缓存的示例:证明二级缓存的存在
- 配置演示环境:实体类,对应的映射文件及核心配置文件
- 实体类:
- Customer.java
package cn.hibernate3.demo4; import java.io.Serializable; import java.util.HashSet; /** * 客户实体 */ import java.util.Set; public class Customer implements Serializable{ private Integer cid; private String cname; //一个客户有多个订单 private Set<Order> orders = new HashSet<Order>(); public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders = orders; } }
- Order.java
package cn.hibernate3.demo4; import java.io.Serializable; /** * 订单实体 */ public class Order implements Serializable{ private Integer oid; private String addr; //订单属于某一个客户 private Customer customer ; public Integer getOid() { return oid; } public void setOid(Integer oid) { this.oid = oid; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
- 映射文件:
- Customer.hbm.xml
- 映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入约束 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.hibernate3.demo4.Customer" table="customer" lazy="true"> <!-- 配置唯一标识 --> <id name="cid" column="cid"> <generator class="native"/> </id> <!-- 配置普通属性 --> <property name="cname" column="cname" type="java.lang.String"/> <!-- 建立映射 --> <!-- 配置集合 --> <!-- set标签中的name表示关联对象的属性名称 --> <set name="orders" cascade="save-update"> <!-- key标签中的column用来一对多的多的一方的外键 --> <key column="cno"/> <!-- 配置一个one-to-many --> <one-to-many class="cn.hibernate3.demo4.Order" /> </set> </class> </hibernate-mapping>
- Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入约束 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.hibernate3.demo4.Order" table="orders"> <!-- 配置唯一标识 --> <id name="oid" column="oid"> <generator class="native"/> </id> <!-- 配置普通属性 --> <property name="addr" column="addr" type="java.lang.String"/> <!-- 建立映射 --> <!-- many-to-one标签 属性: name:关联对象的属性名称。 column:表中外键的名称。 class:关联对象的全路径。 --> <many-to-one name="customer" column="cno" class="cn.hibernate3.demo4.Customer"></many-to-one> </class> </hibernate-mapping>
- 核心映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 配置数据库的基本信息 --> <!-- 驱动的名称 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 访问数据库的url --> <property name="hibernate.connection.url"> jdbc:mysql:///hibernate_day03 </property> <!-- 用户名 --> <property name="hibernate.connection.username">root</property> <!-- 密码 --> <property name="hibernate.connection.password">root</property> <!-- 方言 --> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- C3P0连接池设定--> <!-- 使用c3po连接池 配置连接池提供的供应商--> <property name="connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider </property> <!--在连接池中可用的数据库连接的最少数目 --> <property name="c3p0.min_size">5</property> <!--在连接池中所有数据库连接的最大数目 --> <property name="c3p0.max_size">20</property> <!--设定数据库连接的过期时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 --> <property name="c3p0.timeout">120</property> <!--每3000秒检查所有连接池中的空闲连接 以秒为单位--> <property name="c3p0.idle_test_period">3000</property> <!-- 可选配置 --> <!-- 显示SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- hbm:映射 2:to ddl:create drop alter --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 1—Read uncommitted isolation 2—Read committed isolation 4—Repeatable read isolation 8—Serializable isolation --> <property name="hibernate.connection.isolation">4</property> <property name="hibernate.current_session_context_class">thread</property> <!-- 启用二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!-- 配置使用的二级缓存提供商 --> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" /> <mapping resource="cn/hibernate3/demo4/Order.hbm.xml" /> <!--
<class-cache usage="read-write" class="cn.hibernate3.demo4.Customer"/>
<class-cache usage="read-write" class="cn.hibernate3.demo4.Order"/>
<collection-cache usage="read-write" collection="cn.hibernate3.demo4.Customer.orders"/>
--> </session-factory> </hibernate-configuration>
- 测试类
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1); System.out.println(customer1.getCname()); tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); System.out.println(customer2.getCname()); tx.commit(); session.close(); }
- 设置Customer类使用二级缓存。其核心配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 配置数据库的基本信息 --> <!-- 驱动的名称 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 访问数据库的url --> <property name="hibernate.connection.url"> jdbc:mysql:///hibernate_day03 </property> <!-- 用户名 --> <property name="hibernate.connection.username">root</property> <!-- 密码 --> <property name="hibernate.connection.password">root</property> <!-- 方言 --> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- C3P0连接池设定--> <!-- 使用c3po连接池 配置连接池提供的供应商--> <property name="connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider </property> <!--在连接池中可用的数据库连接的最少数目 --> <property name="c3p0.min_size">5</property> <!--在连接池中所有数据库连接的最大数目 --> <property name="c3p0.max_size">20</property> <!--设定数据库连接的过期时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 --> <property name="c3p0.timeout">120</property> <!--每3000秒检查所有连接池中的空闲连接 以秒为单位--> <property name="c3p0.idle_test_period">3000</property> <!-- 可选配置 --> <!-- 显示SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- hbm:映射 2:to ddl:create drop alter --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 1—Read uncommitted isolation 2—Read committed isolation 4—Repeatable read isolation 8—Serializable isolation --> <property name="hibernate.connection.isolation">4</property> <property name="hibernate.current_session_context_class">thread</property> <!-- 启用二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!-- 配置使用的二级缓存提供商 --> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" /> <mapping resource="cn/hibernate3/demo4/Order.hbm.xml" />
<!-- 配置那个类使用二级缓存-->
<class-cache usage="read-write" class="cn.hibernate3.demo4.Customer"/>
<class-cache usage="read-write" class="cn.hibernate3.demo4.Order"/>
<!-- 集合缓存区 -->
<collection-cache usage="read-write" collection="cn.hibernate3.demo4.Customer.orders"/>
</session-factory> </hibernate-configuration>
- 类缓存区的特点:缓存的是对象的散装的数据。
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1); Customer customer2 = (Customer) session.get(Customer.class, 1); System.out.println(customer1==customer2); tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer customer3 = (Customer) session.get(Customer.class, 1); Customer customer4 = (Customer) session.get(Customer.class, 1); System.out.println(customer3 == customer4); System.out.println(customer1 == customer3); tx.commit(); session.close(); }
- 集合缓存区的特点:缓存的是对象的id,需要依赖类缓存区的配置。
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1); System.out.println(customer1.getOrders().size()); tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer custome2 = (Customer) session.get(Customer.class, 1); System.out.println(custome2.getOrders().size()); tx.commit(); session.close(); }
- list()方法和iterate()方法的区别
- list()方法:会向二级缓存中存放数据,但是不会使用二级缓存中的数据。
- 证明:list()方法会向二级缓存中存放数据。
- list()方法:会向二级缓存中存放数据,但是不会使用二级缓存中的数据。
@Test //list()方法会向二级缓存中存放数据,但是不会使用二级缓存中的数据 //证明list()方法会向二级缓存中存放数据 public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); List<Customer> list = session.createQuery("from Customer").list();//发送SQL语句 for (Customer customer : list) { System.out.println(customer.getCname()); } tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1);//不发送SQL语句,从二级缓存中获取 System.out.println(customer.getCname()); tx.commit(); session.close(); }
- 证明:list()不会使用二级缓存中的数据。
@Test //list()方法会向二级缓存中存放数据,但是不会使用二级缓存中的数据 //证明list()方法不会使用二级缓存中的数据 public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); List<Customer> list = session.createQuery("from Customer").list();//发送SQL语句 for (Customer customer : list) { System.out.println(customer.getCname()); } tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); list = session.createQuery("from Customer").list();//发送SQL语句 for (Customer customer : list) { System.out.println(customer.getCname()); } tx.commit(); session.close(); }
- iterate()方法:
- 和list()方法一样也能执行查询操作。
- list()方法执行的SQL语句包含实体类对象的数据表中的所有字段。
- iterate()方法执行SQL语句中仅包含实体类对应的数据表的id字段。
- 当遍历结果集的时候,该方法先到session缓存及二级缓存中查看是否存在特定oid的对象,如果存在,就直接返回该对象,如果不存在,就通过相应的SQL select语句到数据库中加载特定的实体对象。
- 大多数情况下,应考虑使用list()方法执行查询操作,iterate()方法仅在满足以下条件对的场合,可以稍微提高查询性能:
- 要查询的数据表中包含大量的字段。
- 启用了二级缓存,且二级缓存中可能已经包含了待查询的对象。
- iterate()方法:
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //发送N+1条SQL去查询 Iterator<Customer> iterator = session.createQuery("from Customer").iterate(); while(iterator.hasNext()){ Customer customer = iterator.next(); System.out.println(customer.getCname()); } tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); iterator = session.createQuery("from Customer").iterate(); while(iterator.hasNext()){ Customer customer = iterator.next(); System.out.println(customer.getCname()); } tx.commit(); session.close(); }
- 一级缓存更新同步到二级缓存及二级缓存配置文件
- 证明一级缓存更新同步到二级缓存
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1); customer.setCname("哈哈"); tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); System.out.println(customer2.getCname()); tx.commit(); session.close(); }
- 二级缓存的配置文件
- 更新时间戳区
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1); session.createQuery("update Customer set cname='呵呵' where cid= 1").executeUpdate(); tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); System.out.println(customer2.getCname()); tx.commit(); session.close(); }
- 查询缓存区
- 比二级缓存功能更加强大,而且查询缓存必须依赖二级缓存。
- 二级缓存:对类或对象的缓存。
- 查询缓存:针对类中的属性的缓存。
- select c.cname from Customer c;
- 查询缓存的配置
- 前提是二级缓存已经配置完毕。
- 在核心配置文件中配置
- <property name="hibernate.cache.use_query_cache">true</property>
- 编写代码的时候,添加如下代码(详解示例):
@Test public void demo13(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("select c.cname from Customer c"); query.setCacheable(true); List<Object> list = query.list(); for (Object object : list) { System.out.println(object); } tx.commit(); session = HibernateUtils.openSession(); tx = session.beginTransaction(); query = session.createQuery("select c.cname from Customer c"); query.setCacheable(true); list = query.list(); for (Object object : list) { System.out.println(object); } tx.commit(); session.close(); }
Hibernate(四)的更多相关文章
- hibernate(四) 双向多对多映射关系
序言 莫名长了几颗痘,真TM疼,可能是现在运动太少了,天天对着电脑,决定了,今天下午花两小时去跑步了, 现在继上一章节的一对多的映射关系讲解后,今天来讲讲多对多的映射关系把,明白了一对多,多对多个人感 ...
- Hibernate(四)之对象状态及一级缓存
一.Hibernate中的对象状态 1.1.瞬时态(临时态) 没有与Hibernate产生关联 与数据库中的记录没有产生关联(有关联就是与数据库中表的id相对应) 获得:一般都只直接创建(new) 瞬 ...
- Hibernate(四)结构-基础语义和事务
一.基础语义 核心: Configuration SessionFactory Session 二.Configuration Configuration类负责管理Hibernate的配置信息,Hib ...
- hibernate(四)__由表逆向创建Domain对象和对象关系映射文件
之前我们是手写Domain对象和对象关系映射文件->然后生成数据库中的Table. 现在我们反过来先在数据库中建好Table->然后用工具生成Domain对象和对象关系映射文件. 步骤: ...
- Hibernate四 批量处理
Hibernate批量处理一 批量插入将很多条记录插入数据库时,Hibernate通常会采用以下做法:public void test() { for(int i=0;i<1000;i++){ ...
- Hibernate(四)——缓存策略+lazy
Hibernate作为和数据库数据打交道的框架,自然会设计到操作数据的效率问题,而对于一些频繁操作的数据,缓存策略就是提高其性能一种重要手段,而Hibernate框架是支持缓存的,而且支持一级和二级两 ...
- ORM框架Hibernate (四) 一对一单向、双向关联映射
简介 在上一篇博客说了一下多对一映射,这里再说一下一对一关联映射,这种例子在生活中很常见,比如一个人的信息和他的身份证是一对一.又如一夫一妻制等等. 记得在Java编程思想上第一句话是“一切皆对象”, ...
- ssh架构之hibernate(四)二级缓存
二级缓存使用步骤: 1.拷贝jar包 2.配置Hibernate.cfg.xml文件 a.#开启二级缓存 hibernate.cache.use_second_level_cache=true b.# ...
- Hibernate(四)
==================================投影(查询)=============================投影查询:查询一个持久化类的一个或多个属性值 1.将每条 ...
- Hibernate(四)--延迟加载(lazyload)
hibernate中的延迟加载(lazyload)分属性的延迟加载和关系的延迟加载 属性的延迟加载: 当使用load的方式来获取对象的时候,只有访问了这个对象的属性,hibernate才会到数据库中进 ...
随机推荐
- UML 解析
UML 解析 泛化 表示类与类之间的继承关系.接口与接口之间的继承关系: 实现 表示类对接口的实现 依赖 当类与类之间有使用关系时就属于依赖关系,不同于关联关系,依赖不具有"拥有关系&quo ...
- const vector<int> 和 vector<const int>问题讨论
1.const vector <int> vec(10) —— 与const int a[10]是一回事,意思是vec只有10个元素,不能增加了,里面的元素也是不能变化的 vector&l ...
- dynamic-load-apk 插件与宿主方法互调
新建项目 DlPluginHost,下载dynamic-load-apk源码 1.将dynamic-load-apk 文件夹中的lib做为module导入到DlPlginHost 2.导入到Plugi ...
- tp框架为什么验证码加载不出来?----- ob_clean() 可解决
在用tp做验证码时,代码逻辑都正确,但就是加载不出图片来,如何解决呢?在创建验证码之前加上 ob_clean(); public function haha(){ ob_clean(); $v = n ...
- 浅入深出之Java集合框架(下)
Java中的集合框架(下) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,哈哈这篇其实也还是基础,惊不惊喜意不意外 ̄▽ ̄ 写文真的好累,懒得写了.. ...
- Struts2国际化信息机制
国际化信息机制 (三种 Action范围. Package范围. 全局) 1. 全局国际化配置信息文件 全局国际化文件,对所有Action 生效,任何程序都可以访问到,需要在struts.xml 配 ...
- 腾讯地图JS API实现带方向箭头的线路Polyline
最近产品提出一个需求,在我们使用的腾讯地图上为线路polyline添加线路方向.例如下图所示: 查找腾讯地图JS API提供的API,没有找到对应的支持,询问负责腾讯地图的人也得到了同样的答案,即地图 ...
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...
- 如何给Ionic写一个cordova插件
写一个cordova插件 之前由javaWeb转html5开发,由于面临新技术,遂在适应的过程中极为挣扎,不过还好~,这个过程也极为短暂:现如今面临一些较为复杂的需求还会有一丝丝头痛,却没有一开始那么 ...
- Haproxy的配置
1,下载Haproxy 下载Haproxy 1.6 2,安装haproxy uname -r cd /usr/local/src/haproxy-1.6.9/ make TARGET=linux31 ...