Nginx调优

Posted on

Nginx调优

这篇文章的目的是要谈谈我的 Nginx 调优经验,就不涉及数据库调优的内容了。

初始服务器设置

我的服务器运行在亚马逊 EC2 t1 micro 上,选择 Nginx + PHP5-fpm 作为后端,因为一些安全因素还打开了SSL。

性能测试

我使用了Blitz.io 来进行压力测试。下面是我使用的命令: 1 -p

1-250:60 https://mydomian.com

这是一个用户线性递增的测试,每个测试用户跑60秒。Blitz.io为每个请求每秒增加4个( = rise / run = 260 / 60)测试用户。

结论

我把结论提前写在这里,如果你不想读完整篇文章也没有问题。

  1. Nginx默认设置的DH算法(译注:Diffie-Hellman key exchange algorithm)是影响SSL性能的最大因素,因此采用如下设置能增加SSL性能: 1

2 3

4 5 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ECDHE

-RSA

-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM; ssl_prefer_server_ciphers on;

ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;

  1. 升级硬件 Upgrade your EC2 from t1.micro to c1.medium
  2. 正确配置 Nginx的worker进程数量 Set Nginx to have 2 worker processes as a c1.medium gives you 2 CPUs

细节解释

以下是我进行测试的详细过程。

尝试1:升级硬件

直觉告诉我,想解决性能问题的直接途径就是升级硬件,我把EC2实例从t1.micro升级到了为高流量而优化过的c1.medium

升级后的测试结果:

巅峰时服务器的hits达到50/sec,压力增加时,time-out增加,hits减少。

尝试2:测试CPU性能

我打开top然后重启了测试,注意到2个CPU的使用率不到13%,内存使用了300Mb,很明显硬件没有充分利用。所以我更改了nginx的设置

worker_processes 2;

尝试3,4,5:调整Nginx和PHP5-fpm

以下尝试得到的结果都和尝试1相同

尝试3:

nginx.conf 1

2 3

4 5

6 worker_processes 2;

events { worker_connections 19000;

multi_accept on; }

...

尝试4:

nginx.conf 1

2 3

4 5

6 7

8 9

10 11

12 13

14 15 worker_processes 2;

events { worker_connections 19000;

multi_accept on; }

http { gzip on;

gzip_disable "msie6"; gzip_min_length 1000;

gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml application/javascript text/css application/x-javascript;

… }

...

尝试5:

在尝试4未变的情况下我更改了php5-fpm的设置: 1

2 3

4 5 pm.max_children = 160

pm.start_servers = 24 pm.min_spare_servers = 20

pm.max_spare_servers = 35 pm.max_requests = 1500

尝试6**:在另一个服务器部署**

我有一个1.5Gb RAM和8CPU的Linode服务器,采用刚才的设置,这是我的测试结果:

Linode的服务器的结果棒极了!我的第一个直觉是难道Linode比EC2好吗。在我把我的服务迁移到Linode之前我想确保两者仅有的对性能有可能产生影响的不同被排除掉。

尝试7:大惊喜

我Google到Nginx在SSL上有些问题。Nginx默认使用DHE算法来产生密匙,改变这个设置应该能使它快一些。

这里是我参考的一些文章:

http://matt.io/entry/ur

http://auxbuss.com/blog/posts/2011_06_28_ssl_session_caching_on_nginx/

所以我更改了nginx.conf,删掉了kEDH算法 1

2 3

4 5

6 7

8 9

10 11

12 13

14 15 worker_processes 2;

events { worker_connections 1024;

} http {

gzip on; gzip_disable "msie6";

gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth;

gzip_types text/plain application/xml application/javascript text/css application/x-javascript; ssl_ciphers ALL:!kEDH!ADH:RC4+RSA:+HIGH:+EXP;

… }

...

下图是测试结果:

效果很显著!

尝试8: 硬件提升是必要的吗

现在我的EC2和Linode表现差不多了。但是我真的需要升级到c1.medium实例才能实现这个性能的提升吗?或许不是这样……所以我把我改回了t1.micro。因为t1.micro实例只有一个CPU,所以我把worder_processes设置改回1。下面是测试的结果:

所以答案是肯定的,硬件上的提升是必要的。

尝试9:

有人在 Hacker News 上反馈说我的SSL密匙不能满足Perfect Forward Secrecy,我采用了他们的建议,对我的SSL设置做了如下更改: 1

2 3

4 5 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM; ssl_prefer_server_ciphers on;

ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;

现在这个设置应该满足Perfect Forward Secrecy协议了。我重新跑了测试:

attempt10

太棒了,性能也没有下降。很棒的学习经验!

来源: <Nginx SSL性能调优 - 博客 - 伯乐在线>

XSD文件知识汇总

Posted on

XSD文件知识汇总

什么是XML Schema

XML Schema如同DTD一样是负责定义和描述XML文档的结构和内容模式。它可以定义XML文档中存在哪些元素和元素之间的关系,并且可以定义元素和属性的数据类型。

XML Schema本身是一个XML文档,它符合XML语法结构。可以用通用的XML解析器解析它。 **

为什么要使用Schema

我们前面已经使用DTD来定义一个XML的结构和数据类型,那为什么还要Schema呢?

因DTD有着不少缺陷:

1) DTD是基于正则表达式的,描述能力有限; 2) DTD没有数据类型的支持,在大多数应用环境下能力不足; 3) DTD的约束定义能力不足,无法对XML实例文档作出更细致的语义限制; 4) DTD的结构不够结构化,重用的代价相对较高; 5) DTD并非使用XML作为描述手段,而DTD的构建和访问并没有标准的编程接口,无法使用标准的编程方式进行DTD维护。

而XML Schema正是针对这些DTD的缺点而设计的,XML Schema的优点:

1) XML Schema基于XML,没有专门的语法 2) XML可以象其他XML文件一样解析和处理 3) XML Schema支持一系列的数据类型(int、float、Boolean、date等) 4) XML Schema提供可扩充的数据模型。 5) XML Schema支持综合命名空间 6) XML Schema支持属性组。 **

一个简单的XML Schema文档

在这个Schema里面定义了一个元素:quantity,它的类型是nonNegativeInteger(非负整数),xmlns是Schema的命名空间,这在前面第3部分已经叙述过了。

下面的XML片段是合法的:

5

下面的XML片段是非法的:

-4 ** Schema中的类型 Schema中主要包括三种部件:元素(element)、属性(attribute)、注释(notation)。 这三种基本的部件还能组合成以下的部件: a)类型定义部件: 简单类型和复合类型 b)组部件 c)属性组部件 简单类型 XML Schema中定义了一些内建的数据类型,这些类型可以用来描述元素的内容和属性值。 一个元素中如果仅仅包含数字、字符串或其他数据,但不包括子元素,这种被称为简单类型。 如同图中元素quantity就是一个简单类型。它的元素内容必须是非负整数,不包括任何属性和子元素。 some ** 所有内建的简单类型 原始类型 string,boolean,decimal,float,double,duration datetime,time,date,gYearMonth,gYear,gMonthDay, dDay,gMonth,hexBinary,base64Binary,any URI,QName NOTATION 衍生类型(括号中为基类型) normalizedString(string),language(tonken),token(normalizedString) NMTOKEN(token),Name(token),NCName(Name),ID(NCName),IDREF(NCName) IDREFS(list of IDREF),ENTITY(NCName),ENTITIES(list of ENTITY) integer(decimal),nonPositiveInteger(integer), negativeInteger(noPositiveInteger),long(integer),int(long), short(int),byte(short),nonNegativeInteger(integer) unsignedLong(nonNegativeInteger),unsignedInt(unsignedLong), unsignedShort(unsignedInt),unsignedByte(unsignedShort), positiveInteger(nonNegativeInteger) ** 创建简单类型 图中我们先创建了一个简单类型:quantityType,它是从integer继承过来的,minInclusive和maxInclusive定义了它的最小值2和最大值5。最后我们定义元素quantity的类型为quantityType。 正确: 3

错误: 10

aaa

使用restriction我们可以限制只能接受一定数值或者只能接受一定文字, 基本方面:equal,ordered,bounded,cardinality,numeric

限制方面:length,minLength,maxLength pattern,enumeration

whiteSpace maxInclusive,maxExclusive,minInclusive,minExclusive

totalDigits,fractionDigits **

简单类型的例子 1

这个SKU的类型的取值:3个数字后面根着一个连字号接着跟着两个大写的英文字母。

pattern后面跟的是正则表达式。有关正则表达式的语法请参阅其他书籍。 正确: 123-AB

错误: abc-AB

123-ab

简单类型的例子 2

这是一个用来描述美国州名的类型USState,通过enumeration来列出所有州名,取值时就只能取里面列出的州名。

<!-- and so on ...-> 这是一个注释语句。 正确: AK

错误: Alaska

列表类型

list可以用来定义列表类型,listOfIntType这个类型被定义为一个Integer的列表,元素listOfMyInt的值可以几个整数,他们之间用空格隔开。 正确: 1 5 15037 95977 95945

错误: 1 3 abc

联合类型

图中用union来定义了一个联合类型,里面的成员类型包括USState和listOfMyIntType,应用了联合类型的元素的值可以是这些原子类型或列表类型中的一个类型的实例,但是一个元素实例不能同时包含两个类型。 正确: CA

95630 95977 95945 AK

错误: CA 95630 匿名类型定义

前面我们在定义元素类型时总是先定义一个数据类型,然后再把元素的type设成新定义的数据类型。如果这个新的数据类型只会用一次,我们就可以直接设置在元素定义里面,而不用另外来设置。如图中元素quantity的类型就是一个从1到99的整数。

这种新的类型没有自己的名字的定义方法我们称之为匿名类型定义。

复合类型

前面我们所讲到的都是属于简单类型,即元素里面只有内容,不再包括属性或者其它元素。接下来我们要让元素里面包含属性和其它元素,称之为复合类型。

图中我们用complexType表示这是一个复合类型(这里我们是用匿名类型定义的)。simpleContent表示这个元素下面不包括子元素,extension表示这个元素值是decimal的,attribute来设置它的一个属性currency,类型为string. 正确:423.46 **

混合内容

同样,我们采用了匿名类型方式来定义一个元素salutation。我们注意到在complexType后面多了一个mixed="true",这表明这是一个混合类型:里面既有元素本身的内容,又有其它子元素。name元素就是salutation的子元素。 正确: Dear Mr.Robert Smith.

错误: Dear Mr.

sequence表示子元素出现的顺序要和schema里面的顺序一样。我们在后面还会讲到和sequence对应的choice和all两种方式。

空内容

有的时候元素根本没有内容,他的内容模型是空。为了定义内容是空的类型,我们可以通过这样的方式:首先我们定义一个元素,它只能包含子元素而不能包含元素内容,然后我们又不定义任何子元素,依靠这样的方式,我们就能够定义出内容模型为空的元素。

图中complexConet表示只包含子元素,然后我们定义了两个属性currency和value,但是却不定义任何子元素。 正确:

错误:

Here is a mistake!

还要更简洁的方法定义:

因为一个不带有simpleContent 或者complexContent的复合类型定义,会被解释为带有类型定义为anyType的complexContent,这是一个默认的速记方法,所以这个简洁的语法可以在模式处理器中工作。

anyType

一个anyType类型不以任何形式约束其包含的内容。我们可以象使用其他类型一样使用anyType,如图第一个语句,这个方式声明的元素是不受约束的。所以元素的值可以为423.46,也可以为任何其他的字符序列,或者甚至是字符和元素的混合。实际上,anyType是默认类型,所以上面的可以被重写为第二个语句。

如果需要表示不受约束的元素内容,举例来说在元素包含散文,其中可能需要嵌入标签来支持国际化的表示,那么默认的声明(无约束)或者有些微约束的形式会很合适。

注释

为了方便其他读者和应用来理解模式文档,XML Schema提供了三个元素用来注释。 annotation

documentation appinfo

图中,我们在documentation元素中放置了一个基本的模式描述和版权信息,这是放置适合人阅读的信息的推荐位置。我们推荐你在任何的documentation元素中使用xml:lang属性来表示这些描述信息使用的语言。 **

构造内容模型

图中,我们在purchaseOrderType定义中引入两个元素组定义,购买订单就可以有两种选择来描述地址:第一种是包含彼此独立的送货地址和收款地址,第二种情况则是仅包含一个简单的地址,这个地址即是送货地址也是收款地址.

对于choice组元素而言,在实例中仅仅允许出现这个组中的一个子内容。对于图中的例子而言,第一个子内容是一个内部group元素,引用以shipAndBill命名的元素组,这个元素组由元素序列shipTo、billTo组成。第二个子内容为singleUSAddress。因此,在一个实例文档中,purchaseOrder元素必须,要么包含一个billTo元素和一个shipTo元素,要么包含一个singleUSAddress元素。

choice组后面跟着的是comment和items元素声明。元素和组的声明都是sequence 组的子内容。这样定义的效果是comment和items元素必须按顺序跟在地址元素后面。

在内容模型中被命名或未被命名的元素组(分别由group、choice、sequence、all所表现)可以带有minOccurs 和maxOccurs属性

属性组

我们可以建立一个被命名的属性组来包含所有item元素所期望的属性,并且在item元素声明中通过名字来引用这个属性组ItemDeleivery

通过这种方法来使用属性组,可以提高模式文档的可读性,同时也便于更新模式文档。这是因为一个属性组能够在一个地方定义和编辑,同时能够在多个定义和声明中被引用。注意到一个属性组可以包含其他属性组,同时还要注意到属性组的声明和引用必须在复合类型定义的最后。

空值(Nil)

XML Schema 空值机制包括一个空值信号。换句话说,作为元素内容而言,并没有没有真正的空值,代之的是一个说明元素的内容是空值的属性。为了显示这点,我们修改shipDate元素的声明,这样空值就能够被明确地告知用户了。

为了在实例文档中明确的表示shipDate有一个空值,我们可以设置nil属性为真:

Xml Schema**的用途**

1. 定义一个Xml文档中都有什么元素

2. 定义一个Xml文档中都会有什么属性

3. 定义某个节点的都有什么样的子节点,可以有多少个子节点,子节点出现的顺序

4. 定义元素或者属性的数据类型

5. 定义元素或者属性的默认值或者固定值

Xml Schema**的根元素:**

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 表示数据类型等定义来自w3

targetNamespace="http://www.w3schools.com" 表示文档中要定义的元素来自什么命名空间

xmlns="http://www.w3schools.com"表示此文档的默认命名空间是什么

elementFormDefault="qualified"> 表示要求xml文档的每一个元素都要有命名空间指定

……定义主体部分……

如何定义一个简单元素

<xs:element 此处表示要定义一个元素

name=”color” 表示要定义元素的名称

type=”xs:string” 表示要定义元素的数据类型

default=”red” 表示定义元素的默认值

fixed=”red”/> 表示要定义元素的固定值,此元素只可以取“red”值

以上定义了一个简单元素,元素实例:red

如何定义一个属性

<xs:attribute

     name=”birthday” 表示要定义属性的名字

     type=”xs:date” 表示要定义属性的数据类型

     default=”2001-01-11” 表示要定义属性的默认值

     fixed=”2001-01-11” 表示要定义属性的固定值

     use=”required”/> 表示此属性是否是必须指定的,即如果不指定就不符合Schema,默认没有use=”required”属性表示属性可有可无

如何定义元素或者属性值的限制

1.最大值最小值限制

大于等于0,表示最小值但是不包括指定值

小于等于120,

2.枚举限制,指只能在指定的几个值中取值

     <xs:element name="car" type="carType"/>
<xs:enumeration value="Audi"/>

<xs:enumeration value="Golf"/>

<xs:enumeration value="BMW"/>

3.模式(pattern)限制 ,指字符串的格式必须满足制定的匹配模式 例子

说明

<xs:pattern value="[a-z]"/>

表示只能在小写字母中取一个值

<xs:pattern value="[A-Z][A-Z][A-Z]"/>

表示必须是三个大写字母

<xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>

表示必须是三个字母,可以是大写或小写的

<xs:pattern value="[xyz]"/>

表示必须是xyz中的一个

<xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>

表示数字的范围是0-99999

<xs:pattern value="([a-z])/*"/>

表示必须是0或者多个小写字符组成的序列

<xs:pattern value="([a-z][A-Z])+"/>

表示必须是多个字母。

<xs:pattern value="male|female"/>

表示是male或者female中的一个

<xs:pattern value="[a-zA-Z0-9]{8}"/>

表示必须是8个字母数字字符

4.字符串长度的限制

<xs:length value="8"/>

长度必须是8。

<xs:minLength value="5"/>

<xs:maxLength value="8"/>

表示长度在5-8之间

6. 对于空白字符的限制 示例

说明

<xs:whiteSpace value="preserve"/>

保留原样,表示xml处理器不会移除或者替换任何空白字符

<xs:whiteSpace value="replace"/>

指回车,换行,Tab都会被替换成空格处理

<xs:whiteSpace value="collapse"/>

去掉多于一个空格,和html中处理方式相同

如何定义复杂类型**

复杂类型是指定义元素中包含属性或者子元素的类型

1. 定义只包含子元素的复杂类型

<xs:sequence>

  <xs:element name="firstname" type="xs:string"/>

  <xs:element name="lastname" type="xs:string"/>

</xs:sequence>

2. 定义只包含属性的复杂类型

3. 定义只包含内容的复杂类型

<xs:extension base="xs:integer">

  <xs:attribute name="country" type="xs:string" />

</xs:extension>

4. 定义包含内容和子元素混合的复杂类型

<xs:sequence>

  <xs:element name="name" type="xs:string"/>

  <xs:element name="orderid" type="xs:positiveInteger"/>

  <xs:element name="shipdate" type="xs:date"/>

</xs:sequence>

以上定义对应的Xml

Dear Mr.John Smith. Your order 1032 will be shipped on 2001-07-13.

5. 定义包含属性和子元素的复杂类型

使用指示器**

在Xsd中的指示器包括

1. 顺序指示器

1) All

指示子元素可以以任何顺序出现,并且每一个元素都必须出现一次

<xs:all>

  <xs:element name="firstname" type="xs:string"/>

  <xs:element name="lastname" type="xs:string"/>

</xs:all>

2) Choice

指示子元素中可以出现一个或者另一个

<xs:choice>

  <xs:element name="employee" type="employee"/>

  <xs:element name="member" type="member"/>

</xs:choice>

3) Sequence

指示子元素必须按照顺序出现

<xs:sequence>

  <xs:element name="firstname" type="xs:string"/>

  <xs:element name="lastname" type="xs:string"/>

</xs:sequence>

2. 出现次数指示器minOccurs,maxOccurs

<xs:sequence>

  <xs:element name="full_name" type="xs:string"/>

  <xs:element name="child_name" type="xs:string"

  maxOccurs="10" minOccurs="0"/>

</xs:sequence>

3. 组指示器(group Indicators)

用来定义相关的一组元素

<xs:element name="firstname" type="xs:string"/>

<xs:element name="lastname" type="xs:string"/>

<xs:element name="birthday" type="xs:date"/>

<xs:group ref="persongroup"/>

<xs:element name="country" type="xs:string"/>

用来定义一组相关的属性

<xs:attributeGroup ref="personattrgroup"/>

Any**关键字**

表示可以有任意元素

<xs:sequence>

  <xs:element name="firstname" type="xs:string"/>

  <xs:element name="lastname" type="xs:string"/>

  <xs:any minOccurs="0"/>

</xs:sequence>

anyAttribute**关键字**

<xs:sequence>

  <xs:element name="firstname" type="xs:string"/>

  <xs:element name="lastname" type="xs:string"/>

</xs:sequence>

<xs:anyAttribute/>

substitutionGroup**关键字**

表示某一个元素和另一个替代元素定义相同

<xs:element ref="name"/>

摘自

http://www.onlyblog.com/blog2/linxiaoya/9613.html

http://www.cnblogs.com/yukaizhao/archive/2007/03/25/xsd_tutorial.html 来源: [http://blog.csdn.net/begtostudy/article/details/3218310](http://blog.csdn.net/begtostudy/article/details/3218310)

软件级负载均衡器(LVS

Posted on

软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比

软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比

现在网站发展的趋势对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术: 一种是通过硬件来进行进行,常见的硬件有比较昂贵的NetScaler、F5、Radware和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用;另外一种就是类似于LVS/HAProxy、Nginx的基于Linux的开源免费的负载均衡软件策略,这些都是通过软件级别来实现,所以费用非常低廉,所以我个也比较推荐大家采用第二种方案来实施自己网站的负载均衡需求。

近期朋友刘鑫(紫雨荷雪)的项目成功上线了,PV达到了亿级/日的访问量,最前端用的是HAProxy+Keepalived双机作的负载均衡器/反向代理,整个网站非常稳定;这让我更坚定了以前跟老男孩前辈聊的关于网站架构比较合理设计的架构方案:即Nginx/HAProxy+Keepalived作Web最前端的负载均衡器,后端的MySQL数据库架构采用一主多从,读写分离的方式,采用LVS+Keepalived的方式。 在这里我也有一点要跟大家申明下:很多朋友担心软件级别的负载均衡在高并发流量冲击下的稳定情况,事实是我们通过成功上线的许多网站发现,它们的稳定性也是非常好的,宕机的可能性微乎其微,所以我现在做的项目,基本上没考虑服务级别的高可用了。相信大家对这些软件级别的负载均衡软件都已经有了很深的的认识,下面我就它们的特点和适用场合分别说明下。

LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability),感谢章文嵩博士为我们提供如此强大实用的开源软件。 LVS的特点是: 1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的; 2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率; 3、工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived; 4、无流量,保证了均衡器IO的性能不会收到大流量的影响; 5、应用范围比较广,可以对所有应用做负载均衡; 6、软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。 7、如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。 Nginx的特点是: 1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一; 2、Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在; 3、Nginx安装和配置比较简单,测试起来比较方便; 4、也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量; 5、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测; 6、Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势; 7、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。 8、Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。 HAProxy的特点是: 1、HAProxy是支持虚拟主机的,以前有朋友说这个不支持虚拟主机,我这里特此更正一下。 2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作 3、支持url检测后端的服务器出问题的检测会有很好的帮助。 4、它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。 5、HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。 6、HAProxy的算法现在也越来越多了,具体有如下8种: ①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的; ②static-rr,表示根据权重,建议关注; ③leastconn,表示最少连接者先处理,建议关注; ④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注; ⑤ri,表示根据请求的URI; ⑥rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name; ⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求; ⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

本文出自 “抚琴煮酒” 博客,请务必保留此出处http://andrewyu.blog.51cto.com/1604432/697466 来源: [http://andrewyu.blog.51cto.com/1604432/697466](http://andrewyu.blog.51cto.com/1604432/697466)

java.net.SocketException Too many open files解决方法

Posted on

java.net.SocketException Too many open files解决方法 糊涂虫

登录

登录 下次自动登录 夜深了! 2012年2月22日 星期三 潍坊oa-中硕为中小企业信息化提供解决方案

详细内容

CSS隐藏文字的方法

详细内容

PHP magic_quotes_gpc的详细使用方法

详细内容

phpweb修改分页信息,去掉 右下角的 首页 尾页信息

详细内容

现在的位置: 首页linux, lnmp>正文

RSS

上篇 下篇

java.net.SocketException: Too many open files解决方法

2011年12月06日 ⁄ linux, lnmp暂无评论 最近随着网站访问量的提高把web服务器移到linux下了,在移服务器的第二天,tomcat频繁的报

java.net.SocketException: Too many open files错误,错误日志达到了100多兆,郁闷了,windows上运行了很长

时间都没出现这个错误,后来才知道linux对进程的打开文件数是有限制的。

用命令ulimit -a查看

[root@test security]/# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited [root@test security]/# 通过以上命令,我们可以看到open files 的最大数为1024

对于并发量比较大的网站这个限制是有些捉襟见肘的,所以我通过这个命令

ulimit -n 4096 把打开文件数的上限设为了4096,这下好了,项目又稳定了

没想到过两天后又重新出这个错误了,郁闷,两个小时报一次,报之后就挂掉了

在重新用ulimit -a查看,发现open files (-n) 1024 又变回了1024了,

报这个错误就在我那次登陆更新之后又报的,原来ulimit -n 4096 命令只能临时的改变open files 的值,当

重新登陆后又会恢复,所以需要永久设置open files 的值才行啊, 用ulimit -n 修改open files 总是不能保持。所以用下面一个简单的办法更好些。修改/etc/security/limits.conf 添加如下一行:

/* - nofile 1006154

修改/etc/pam.d/login添加如下一行

session required /lib/security/pam_limits.so

这次永久修改后程序就再没那个问题了,一直稳定运行。

另外遇到这个问题这后还需要检查我们的程序对于操作io的流是否在操作完之后关闭,这才是从最更本上的解决。


linux 上tomcat 服务器抛出socket异常“文件打开太多”的问题 java.net.SocketException: Too many open files at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384) at java.net.ServerSocket.implAccept(ServerSocket.java:450) at java.net.ServerSocket.accept(ServerSocket.java:421) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) at org.apache.tomcat.util.net.PoolTcpEndpoint.acceptSocket(PoolTcpEndpoint.java:407) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:70) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) at java.lang.Thread.run(Thread.java:595)

原本以为是tomcat的配置或是应用本身的问题,"谷歌"一把后才发现,该问题的根本原因是由于系统文件资源的限制导致的。

具体可以参考http://www.bea.com.cn/support_pattern/Too_Many_Open_Files_Pattern.html 的说明。具体的解决方式可以参考一下: 1。ulimit -a 查看系统目前资源限制的设定。 [root@test security]/# umlimit -a -bash: umlimit: command not found [root@test security]/# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited [root@test security]/# 通过以上命令,我们可以看到open files 的最大数为1024 那么我们可以通过一下命令修改该参数的最大值

  1. ulimit -n 4096 [root@test security]/# ulimit -n 4096 [root@test security]/# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 4096 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited

这样我们就修改了系统在同一时间打开文件资源的最大数,基本解决以上问题。

以上部分是查找网络上的解决方法。设置了之后段时间内有作用。

后来仔细想来,问题还是要从根本上解决,于是把以前的代码由认真地看了一遍。终于找到了,罪魁祸首。

在读取文件时,有一些使用的BufferedReader 没有关闭。导致文件一直处于打开状态。造成资源的严重浪费。

修改之后的简单代码如下: public void test(){ BufferedReader reader =null; try{ reader = 读取文件; String line = ""; while( ( ine=reader.readLine())!=null){ 其他操作 }

} catch (IOException e){
    System.out.println(e);
} finally{  
     if(reader !=null){
            try {
                reader.close();
            } catch (IOException e) {
                  e.printStackTrace();
            }
      }
}

}

返回

作者: 糊涂虫

该日志由 糊涂虫 于79 天前发表在linux, lnmp分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。 转载请注明: java.net.SocketException: Too many open files解决方法 | 糊涂虫+复制链接

【上篇】Linux系统利用Crontab命令实现定时重启 【下篇】中小型的软件公司发展模式总结

您可能还会对这些文章感兴趣!

  1. linux 挂装u盘
  2. linux干掉进程的方法
  3. Linux系统利用Crontab命令实现定时重启

中小型的软件公司发展模式总结

变成了有车一族了,纪念一下 (2011-06-04 17:03:55) PHP magic_quotes_gpc的详细使用方法

phpweb修改分页信息,去掉 右下角的 首页 尾页信息

给我留言

点击这里取消回复。 留言无头像?

昵称 /*

邮箱 /*

网址

正在提交, 请稍候...

/#

插入图片

使用新浪微博登陆

有人回复时邮件通知我

最活跃的读者

网站统计

日志总数:27篇

评论总数:11条

分类总数:14个

标签总数:0个

友情链接:1个

网站运行:210天 最后更新:2012年2月22日

返回首页

Copyright © 2011-2012 糊涂虫 保留所有权利. 基于WordPress 技术创建 Theme by Robin

×

新浪微博 腾讯微博

haproxy 解决 多主机session共享问题 的三种方法

Posted on

haproxy 解决 多主机session共享问题 的三种方法

haproxy 解决 多主机session共享问题 的三种方法

1 session知识储备 2 haproxy三种方法保持客户端session一致 3 实验环境及结构 4 安装配置及管理 5 本实验中使用到相同的index.php代码 6 联系方法及扩展阅读 感谢 不就是要我命 QQ 47034839 提供测试主机 1 session知识储备 Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。 而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。 服务器也通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。 php.ini 里几个session相关值的 其它的值请参考《PHP与Mysql5程序设计》 session.use_cookies = 1 /#表示 服务端和客户端交互session是通过cookie的方式 默认值 session.name = 9ai9 /#默认值是PHPSESSID 我这里改成9ai9是为了和默认值区别 session.cache_limiter = nocache /#此设置确保对每个请求,在可能提供缓存的版本前,先请求发送到最初的服务器。这个值联系到下文中 cookie识别中的相关参数 2 haproxy三种方法保持客户端session一致 2.1 用户IP 识别

haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令) 配置指令 balance source 实例访问http://sourceip.9ai9.net:8080 2.2 cookie 识别
haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。 配置指令例举 cookie SESSION_COOKIE insert indirect nocache http://cookie.9ai9.net:8080 用firebug可以观察到用户的请求头的cookie里 有类似" Cookie 9ai9=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=12" SESSION_COOKIE=12就是haproxy添加的内容 2.3 session 识别
haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。 配置指令例举 appsession 9ai9 len 64 timeout 5h request-learn 注意 9ai9 这个值替换成 你的php.ini 里session.name的值。 实例访问 http://appsession.9ai9.net:8080 2.4 只做简单轮询对比 实例访问 http://nosession.9ai9.net:8080 3 实验环境及结构 CentOS 5.3 64 haproxy 113.106.185.245 WEB1 REALsrv_70 184.82.239.70 WEB2 REALsrv_120 220.162.237.120
4 安装配置及管理 useradd -M -s /sbin/nologin haproxy wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.13.tar.gz tar zxvf haproxy-1.4.13.tar.gz cd haproxy-1.4.13 make TARGET=linux26 PREFIX=/usr/local/haproxy install mkdir /usr/local/haproxy/conf vim /usr/local/haproxy/conf/haproxy.cfg

  1. global
  2. log 127.0.0.1 local0 info
  3. maxconn 4096
  4. user haproxy
  5. group haproxy
  6. daemon
  7. nbproc 1
  8. pidfile /var/run/haproxy.pid
  9. defaults
  10. mode http
  11. maxconn 2000
  12. contimeout 5000
  13. clitimeout 30000
  14. srvtimeout 30000
  15. option httplog
  16. option redispatch
  17. option abortonclose
  18. retries 3
  19. listen admin_stats
  20. bind 113.106.185.245:443
  21. mode http
  22. log 127.0.0.1 local0 err
  23. stats uri /qhappy_stats
  24. stats realm 9ai9.net\ Qhappy
  25. stats auth qhappy:qhappy
  26. stats refresh 5s
  27. listen site_status
  28. bind 113.106.185.245:445
  29. mode http
  30. log 127.0.0.1 local0 err
  31. monitor-uri /site_status
  32. frontend WEB_SITE
  33. bind 0.0.0.0:8080
  34. mode http
  35. log global
  36. option httplog
  37. option httpclose
  38. option forwardfor
  39. acl COOKIE hdr_reg(host) -i ^(cookie.9ai9.net)
  40. acl SOURCE hdr_reg(host) -i ^(sourceip.9ai9.net)
  41. acl APPSESSION hdr_reg(host) -i ^(appsession.9ai9.net)
  42. acl NOSESSION hdr_reg(host) -i ^(nosession.9ai9.net)
  43. use_backend COOKIE_srv if COOKIE
  44. use_backend SOURCE_srv if SOURCE
  45. use_backend APPSESSION_srv if APPSESSION
  46. use_backend NOSESSION_srv if NOSESSION
  47. /# default_backend ai_server
  48. backend COOKIE_srv
  49. mode http
  50. cookie SESSION_COOKIE insert indirect nocache
  51. server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
  52. server REALsrv_120 220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1
  53. backend SOURCE_srv
  54. mode http
  55. balance source
  56. server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
  57. server REALsrv_120 220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1
  58. backend APPSESSION_srv
  59. mode http
  60. appsession 9ai9 len 64 timeout 5h request-learn
  61. server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
  62. server REALsrv_120 220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1 1.
  63. backend NOSESSION_srv
  64. mode http
  65. balance roundrobin
  66. server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
  67. server REALsrv_120 220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1
  68. backend ai_server
  69. mode http
  70. balance roundrobin
  71. cookie SERVERID
  72. server REALsrv_70 184.82.239.70:80 cookie 2 check inter 1500 rise 3 fall 3 weight 1
  73. server REALsrv_120 220.162.237.120:80 cookie 1 check inter 1500 rise 3 fall 3 weight 1 复制代码 haproxy 启动重启等管理脚本 cd /etc/init.d/ wget http://www.9ai9.net/download/shell/haproxy chmod 755 haproxy chkconfig --add haproxy 使用方法 你懂的 /etc/init.d/haproxy {start|stop|status|checkconfig|restart|try-restart|reload|force-reload} 5 本实验中使用到相同的index.php代码 如下
  74. <?php
  75. session_start();
  76. $_SESSION['time'] =date("Y:m:d:H:s",time());
  77. echo "本次访问时间"."".$_SESSION['time'].""."
    ";
  78. echo "访问的服务器地址是"."".$_SERVER['SERVER_ADDR'].""."
    ";
  79. echo "访问的服务器域名是"."".$_SERVER['SERVER_NAME'].""."
    ";
  80. echo "SESSIONNAME是"."".session_name().""."
    ";
  81. echo "SESSIONID是"."".session_id().""."
    ";
  82. ?> 复制代码6 联系方法及扩展阅读 笔者 水煮鱼@溢 微博 http://t.qq.com/cllxy1234 欢迎收听 haproxy 官网 http://haproxy.1wt.eu/download/1.4/doc/configuration.txt 董旗宇 http://www.9ai9.net/download/art/HAProxy配置使用说明.pdf
    刘天斯 http://blog.liuts.com/post/223/ linuxtone http://bbs.linuxtone.org/thread-73-1-1.html

来源: [http://bbs.linuxtone.org/thread-9526-1-1.html](http://bbs.linuxtone.org/thread-9526-1-1.html)