月度归档 2014年8月31日

通过清心醉

合理设置apache的连接数及进程工作方式(转)

网站在线人数增多,访问时很慢。初步认为是服务器资源不足了,但经反复测试,一旦连接上,不断点击同一个页面上不同的链接,都能迅速打开,这种现象就是说 明apache最大连接数已经满了,新的访客只能排队等待有空闲的链接,而如果一旦连接上,在keeyalive 的存活时间内(KeepAliveTimeout,默认5秒)都不用重新打开连接,因此解决的方法就是加大apache的最大连接数。

1.在哪里设置
服务器的为FreeBSD 6.2 ,apache 2.24,使用默认配置(FreeBSD 默认不加载自定义MPM配置),默认最大连接数是250
在/usr/local/etc/apache22/httpd.conf中加载MPM配置(去掉前面的注释):
# Server-pool management (MPM specific)
Include etc/apache22/extra/httpd-mpm.conf
可见的MPM配置在/usr/local/etc/apache22/extra/httpd-mpm.conf,但里面根据httpd的工作模式分了很多块,哪一部才是当前httpd的工作模式呢?可通过执行 apachectl -l 来查看:
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
看到prefork,因此可见当前httpd应该是工作在prefork模式,prefork模式的默认配置是:

StartServers                      5
MinSpareServers                   5
MaxSpareServers                  10
MaxClients                      150
MaxRequestsPerChild               0

2.要加到多少
连接数理论上当然是支持越大越好,但要在服务器的能力范围内,这跟服务器的CPU、内存、带宽等都有关系。
查看当前的连接数可以用:
ps aux | grep httpd | wc -l
或:
pgrep httpd|wc -l

计算httpd占用内存的平均数:
ps aux|grep -v grep|awk ‘/httpd/{sum+=$6;n++};END{print sum/n}’

由于基本都是静态页面,CPU消耗很低,每进程占用内存也不算多,大约200K。服务器内存有2G,除去常规启动的服务大约需要500M(保守估计),还剩1.5G可用,那么理论上可以支持1.5*1024*1024*1024/200000 = 8053.06368
约8K个进程,支持2W人同时访问应该是没有问题的(能保证其中8K的人访问很快,其他的可能需要等待1、2秒才能连上,而一旦连上就会很流畅)控制最大连接数的MaxClients ,因此可以尝试配置为:

StartServers                      5
MinSpareServers                   5
MaxSpareServers                  10
ServerLimit                    5500
MaxClients                     5000
MaxRequestsPerChild               100

注意,MaxClients默认最大为250,若要超过这个值就要显式设置ServerLimit,且ServerLimit要放在MaxClients之前,值要不小于MaxClients,不然重启httpd时会有提示。
重 启httpd后,通过反复执行pgrep httpd|wc -l 来观察连接数,可以看到连接数在达到MaxClients的设值后不再增加,但此时访问网站也很流畅,那就不用贪心再设置更高的值了,不然以后如果网站访 问突增不小心就会耗光服务器内存,可根据以后访问压力趋势及内存的占用变化再逐渐调整,直到找到一个最优的设置值。
(MaxRequestsPerChild不能设置为0,可能会因内存泄露导致服务器崩溃)
更佳最大值计算的公式:
apache_max_process_with_good_perfermance < (total_hardware_memory / apache_memory_per_process ) * 2
apache_max_process = apache_max_process_with_good_perfermance * 1.5

附:
实时检测HTTPD连接数:
watch -n 1 -d “pgrep httpd|wc -l”

持久连接
一 个客户机连接到 Web 服务器时,允许客户机通过同一个 TCP 连接发出多个请求,这减少了与多个连接相关的延迟。在一个 Web 页面引用了多幅图片时,这就很有用:客户机可以通过一个连接先请求页面,再请求所有图片。其缺点在于服务器上的 worker 进程必须等待客户机要关闭的会话,之后才能转到下一个请求。
Apache 使您能够配置如何处理持久连接(称为 keepalives),httpd.conf 全局级的 KeepAlive 5 允许服务器在连接强制关闭之前处理一个连接上的 5 个请求。将此值设置为 0 将禁用持久连接。同样位于全局级上的 KeepAliveTimeout 确定在会话关闭之前,Apache 将等待另外一个连接多久。
持久连接的处理并非 “一刀切” 式的配置。对于某些 Web 站点,禁用 keepalives 更合适(KeepAlive 0);而对于其他一些站点,启用它会带来巨大的收益。惟一的解决之道就是尝试使用这两种配置,自己观察哪种更合适。但若启用了 keepalives,使用较小的超时时间较为明智,例如 2,即 KeepAliveTimeout 2。这能确保希望发出另外一个请求的客户机有充足的时间,还能确保 worker 进程不会一直空闲,等待可能永远不会出现的下一个请求。

压缩
Web 服务器能够在将输出发回给客户机之前压缩它。这将使通过 Internet 发送的页面更小,代价是 Web 服务器上的 CPU 周期。对于那些负担得起 CPU 开销的服务器来说,这是提高页面下载速度的好办法 —— 页面压缩后大小变为原来的三分之一这种事情并不罕见。
图片通常已经是压缩过的,因此压缩应仅限于文本输出。Apache 通过 mod_deflate 提供压缩。尽管 mod_deflate 可轻松启用,但它涉及到太多的复杂性,很多手册都解释了这些复杂的内容。本文不会介绍压缩的配置,但提供了相应文档的链接。

调优PHP

PHP 是运行应用程序代码的引擎。应该仅安装计划使用的那些模块,并配置您的 Web 服务器,使之仅为脚本文件(通常是以 .php 结尾的那些文件)使用 PHP,而非所有静态文件。

操作码缓存
请 求一个 PHP 脚本时,PHP 会读取该脚本,并将其编译为 Zend 操作码,这是要执行的代码的一种二进制表示形式。随后,此操作码由 PHP 执行并丢弃。操作码缓存将保存这个编译后的操作码,并在下一次调用该页面时重用它。这会节省很多时间。有多种缓存可用,我比较常用的是 eAccelerator。
要安装 eAccelerator,您的计算机上需要有 PHP 开发库。由于不同的 Linux 发布版存放文件的位置不同,所以最好直接从 eAccelerator 的 Web 站点获得安装说明(参见 参考资料 部分获得链接)。您的发布版也有可能已经包含了一个操作码缓存,只需安装即可。
无论如何在系统上安装 eAccelerator,都有一些配置选项需要注意。配置文件通常是 /etc/php.d/eaccelerator.ini。eaccelerator.shm_size 定义共享高速缓存的大小,编译后的脚本就存储在这里。该值的单位是兆字节(MB)。根据您的应用程序确定恰当的大小。eAccelerator 提供了一个脚本来显示缓存的状态,其中包含内存占用,64MB 是个不错的选择(eaccelerator.shm_size=”64″)。如果您选择的值未被接受,那么必须修改内核的最大共享内存的大小。向 /etc/sysctl.conf 添加 kernel.shmmax=67108864,运行 sysctl -p 来使设置生效。kernel.shmmax 值的单位是字节。
如果共享内存的分配超出极限,eAccelerator 必须将旧脚本从内存中清除。默认情况下,这是被禁用的;eaccelerator.shm_ttl = “60” 指定:当 eAccelerator 用完共享内存时,60 秒内未被访问的所有脚本都将被清除。
另一种流行的 eAccelerator 替代工具是 Alternative PHP Cache(APC)。Zend 的厂商也提供了一种商业操作码缓存,包括一个进一步提高效率的优化器。

php.ini
PHP 的配置是在 php.ini 中完成的。四个重要的设置控制 PHP 可使用多少系统资源,如表 1 所列。
表 1. php.ini 中与资源相关的设置设置    描述    建议值
max_execution_time    一个脚本可使用多少 CPU 秒     30
max_input_time    一个脚本等待输入数据的时间有多长(秒)    60
memory_limit    在被取消之前,一个脚本可使用多少内存(字节)    32M
output_buffering    数据发送给客户机之前,有多少数据(字节)需要缓存    4096

具 体数字主要取决于您的应用程序。如果要从用户处接收大文件,那么 max_input_time 可能必须增加,可以在 php.ini 中修改,也可以通过代码重写它。与之类似,CPU 或内存占用较多的程序也可能需要更大的设置值。目标就是缓解超标程序的影响,因此不建议全局禁用这些设置。关于 max_execution_time,还有一点需要注意:它表示进程的 CPU 时间,而不是绝对时间。因此一个进行大量 I/O 和少量计算的程序的运行时间可能远远超过 max_execution_time。这也是 max_input_time 可以大于 max_execution_time 的原因所在。
PHP 可执行的日志记录数是可配置的。在生产环境中,禁用除最重要的日志以外的一切日志记录能够减少磁盘写操作。如果需要使用日志来排除问题,那么可以按需启用 日志记录。error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR 将启用足够的日志记录,使您发现问题,同时从脚本中消除大量无用的内容。

apache的参数设置
如何知道apache是工作在哪个模式下的,答案很简单:apachectl -l即可。这里,我先以prefork模式为例来说明参数的设置,其缺省设置一般如下:

StartServers               5
MinSpareServers            5
MaxSpareServers           10
MaxClients               150
MaxRequestsPerChild        0

prefork 控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两 个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。这种模式 可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个 值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为 MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。 MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自 动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:1、可防止意外的内存泄 漏。2、在服务器负载下降的时侯会自动减少子进程数。因此,可根据服务器的负载来调整这个值。MaxClients是这些指令中最为重要的一个,设定的是 Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep httpd|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。虽然理论上这个值越大,可以 处理的请求就越多,但Apache默认的限制不能大于256。ServerLimit指令无须重编译Apache就可以加大MaxClients。
注 意,虽然通过设置ServerLimit,我们可以把MaxClients加得很大,但是往往会适得其反,系统耗光所有内存。以我手头的一台服务器为例: 内存2G,每个apache进程消耗大约0.5%(可通过ps aux来确认)的内存,也就是10M,这样,理论上这台服务器最多跑200个apache进程就会耗光系统所有内存,所以,设置MaxClients要慎 重。

再来看看work模式,缺省参数一般如下:

StartServers               2
MaxClients               150
MinSpareThreads           25
MaxSpareThreads           75
ThreadsPerChild           25
MaxRequestsPerChild        0

Worker 由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样, 为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients 设置了同时连入的clients最大总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。MinSpareThreads和 MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。 ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时 也需要显式声明ServerLimit(最大值是20000)。需要注意的是,如果显式声明了ServerLimit,那么它乘以 ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则 Apache将会自动调节到一个相应值。
—————————————-
对apache中并发控制参数prefork理解和调优
一 个apache有linux下的并发不是很高的,大约到3K的样子(其实处理的http的请求可能只有300/s),普通的服务器都会不同程度的出现问 题.apache有关并发控制主要是 prefork和worker二个其中一个来控制.我们可以使用httpd -l来确定当前使用的MPM是prefork.c,还是Worker.c.下面是apache中有关prefork的配置.下面是我优化过的参数.

#有这个参数就不必像apache1一样修改源码才能修改256客户数的限制,听讲要放到最前面才会生效,2000是这个参数的最大值
ServerLimit 2000
#指定服务器启动时建立的子进程数量,prefork默认为5。
StartServers 25
#指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。
MinSpareServers 25
# 设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数 不要设的太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成”MinSpareServers+1″。
MaxSpareServers 50
#限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit 。
MaxClients 2000
#每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为”0″,子进程将永远不会结束。
MaxRequestsPerChild 10000

将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

工作方式:
一 个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身 份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于设置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有 读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。

对上面的有些值,一定要记的不是越大越好.这个需要经过几次尝试和 出错之后才能选好要使用的值(不同的硬件处理水平不一样)。最重要的值是maxclient允许足够多的 工作进程,同时又不会导致服务器进行过度的交换(死机)。如果传入的请求超出处理能力而让服务器当掉的话,那么至少满足此值的那些请求会得到服务,其他请 求被阻塞这样会更加好。

我们调优常常要查看httpd进程数(即prefork模式下Apache能够处理的并发请求数):
#ps -ef | grep httpd | wc -l
出现的结果,就是当前Apache能够处理的多少个并发请求,这个值Apache根据负载情况自动调.
查看Apache的并发请求数及其TCP连接状态:
#netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

返回结果示例:
LAST_ACK 5
SYN_RECV 38
ESTABLISHED 1600
FIN_WAIT1 51
FIN_WAIT2 515
TIME_WAIT 1857
其中的SYN_RECV表示正在等待处理的请求数;ESTABLISHED表示正常数据传输状态;TIME_WAIT表示处理完毕,等待超时结束的请求数。
状态:描述
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

可以使用Linux下的webbench来作压力测试.
apache 的 MaxRequestsPerChild 指令设置不合理导致并发连接过高会导致服务器负荷增大,尝试优化和调整服务器,首先是从 Apache 的优化和调整开始的。
从网络上搜索到一篇文章,说加大 MaxRequestsPerChild 可以促使增加子进程的复用,从而提高效率。不记得那篇文章是否提到了其使用的 Apache 的 MPM ,版本是 2.0 的没错,反正不是 woker 就是 prefork 了。
我使用的 prefork ,参考那篇文章,将 MaxRequestsPerChild 由 300 调整到了 3000 。
结果,后两天的监控结果是,在网站访问期的高峰期,服务器负荷很重,数据库的并发连接频频超过最高限制。Apache 的并发连接也几乎一直保持在最高,网站访问速度很慢,频繁出现访问超时的问题。
最开始以为是网站访问量过大,达到服务器硬件极限导致的正常现象,不过,手动重启 Apache 后,数据库并发连接迅速降低,之后缓慢增加,一直达到最高并发连接限制,并且很长时间无法减小。
之后,认为是数据库并发连接过高,导致系统负荷过大,而 Apache 过多的 KeepAlice 连接导致数据库的并发连接无法及时释放从而消耗大量系统资源,导致系统负荷过重。最后,怀疑到 MaxRequestsPerChild 的 300 设置是否合理。
阅 读 Apache 手册关于 MaxRequestsPerChild 的说明后,认为 prefork 下,KeepAlice 开启的情况下,每一个新连接都会导致一个 Apache 子进程开启, MaxRequestsPerChild 设置过大,导致新连接产生新的子进程后,长期 idle ,这样并不一定合理。
根据网站的访问情况,并不需要那么大的 MaxRequestsPerChild ,客户端和 Apache 采用 http 进行连接,网站都是一些大小不大的文件,客户端在和 Apache 服务器数次交互后,就应该完成一次访问了,用户点击网站的频率也不会那么高,所以 MaxRequestsPerChild 不应该设置那么高,而应该设置低一些,以尽快释放数据库连接,尽快回收系统资源,以尽可能快速的满足新的请求的连接需求。将 MaxRequestsPerChild 重新调整回默认的 300 ,情况有所改观。
最后,就像那句古话所说的,尽信书不如无书,换到互联网上也一样。不能盲目的参考网上的资料,特别是非严格发表的个人经验文档。网上的资料始终都只能作为参考,必须要经过自己的理解,再结合实际情况,进行调整。不然,导致的结果可能是无法预计的。
MaxRequestsPerChild 这个指令设定一个独立的子进程将能处理的请求数量。在处理“MaxRequestsPerChild 数字”个请求之后,子进程将会被父进程终止,这时候子进程占用的内存就会释放,如果再有访问请求,父进程会重新产生子进程进行处理。如果 MaxRequestsPerChild缺省设为0(无限)或较大的数字(例如10000以上)可以使每个子进程处理更多的请求,不会因为不断终止、启动 子进程降低访问效率,但MaxRequestsPerChild设置为0时,如果占用了200~300M内存,即使负载下来时占用的内存也不会减少。内存 较大的服务器可以设置为0或较大的数字。内存较小的服务器不妨设置成30、50、100,以防内存溢出。

如何避免apache的httpd进程占用比较多的内存
目 前apache的主流工作模式MPM模式。MPM是Multi-Processing-Modules的简称,意思是多道处理模块。MPM模块有不同的种 类。现在用的比较多的MPM种类主要是prefork和worker。prefork的工作方式是多个进程工作,每个进程会在处理一定数量的请求后结束 (这个数量可能是无穷),没有线程的概念。worker被看作apache未来的主流工作模式,它是一种多进程与多线程混合的模式。
最近发现一个 比较奇怪的现象,某台以prefork模式工作的服务器的内存使用率在每次重启apache之后会不停的上涨,直到swap用完,直到死机。后来查出来是 因为apache使用的某一些脚本存在内存泄露的代码段。而apache启动的调用这些代码段的进程的处理请求数被设置为无穷。也就是说这些进程只有在 apache重启(stop-start模式)或者服务器(指的是机器)重启的情况下才会被kill,否则将一直运行下去,直到耗尽系统的最后一点资源 (主要是内存)。
问题貌似已经解决了。但是,还有点不对,就是为什么有将近4G的可用空间(内存2G加上swap2G,除去操作系统部分),资源 还是很快就耗尽了?虽然进程在每处理一个请求的情况下都会吃掉一点内存,但是在看了内存泄露的那段代码后发现每次处理泄露的内存也不过2K左右。要消耗掉 3G的空间,需要至少15.7w次请求。但是目前的手机统计平台上一天的点击量也不过5w。其实top命令下就能看出来,每个httpd进程的内存使用率 有2.4%,3.2%等等。对于一个2G内存的服务器,一个进程2%就等于是40M。仅仅一个普通的请求,没有post参数的,没有大规模数据库查询的, 怎么会用这么多内存?httpd的进程在被apache的主控进程创建的时候,会预先加载一些包,这些包是在apache配置文件里设置的。然后发现在 apache加载的包目录下,有一个很大的包,是用来根据手机号查找手机卡的信息的。去掉这个包之后,每个httpd的进程使用内存就正常了。
总结有两点:
1、MaxRequestsPerChild不能设置为0,最好设置为一个相对不大的数字,防止httpd进程有意外的内存泄露(当然,也不建议设置为1,否则apache就会不停的fork新的进程了,cpu的资源也就过多消耗了);
2、不要加载过多的包,尤其是比较大的包。如果费用不可,最好能够用数据库来存储包里的一些静态信息。

Apache连接数的设置方法
prefork几乎还是目前的唯一MPM,我在下面主要还是讨论它的工作原理和相关指令调整。查看缺省生成的httpd.conf配置文件,会发现里面包含如下的配置段:
以下为引用的内容:

StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0

prefork 的工作原理是这样的:控制进程在最初建立StartServers个子进程后, 为了满足MinSpareServers设置的需要,创建一个进程,等待一秒钟,继续创建第二个,等待一秒钟,继而创建四个,如此按指数级增加创建的进程 数,最多达到每秒32个,直到满足MinSpareServers设置的值为止,这也就是预派生(prefork)的由来。这种模式可以使得不必在请求到 来时再产生新的进程,从而减小了系统开销以增加性能。
axSpareServers 设置了最大的空闲进程数,如果空闲进程数大于这个值,apache(Unix平台最流行的WEB服务器平台)会自动kill某些多余进程。这个值一般不要 设的过大,但如果设的比MinSpareServers小,apache(Unix平台最流行的WEB服务器平台)会自动把它调整为 MinSpareServers+1。如果站点负载较大的话,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild 设置的是每个子进程可以处理的请求数。每个子进程在处理了MaxRequestsPerChild个请求后将自动销毁。0意味着无限,即子进程永不销毁。 虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
1、可防止意外的内存卸漏;
2、在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值,如果非零的话,笔者认为10000左右是比较合适的。事实上这个值对apache(Unix平台最流行的WEB服务器平台)的性能影响不是很大。
MaxClients 是这些指令中最为重要的一个,它设定的就是apache(Unix平台最流行的WEB服务器平台)可以同时处理的请求,这是对apache(Unix平台 最流行的WEB服务器平台)性能影响最大的参数.在我个人看来,缺省的150是远远不够的,如果请求总数已达到这个值(可通过ps –ef|grep httpd|wc –l来确认),那么下面的请求就要排队,直到某个已处理请求完毕。这就是为什么系统资源还剩下很多,而http访问却很慢的主要原因。系统管理员可以根据 硬件配置和负载情况来动态调整这个值,虽然理论上这个值越大,可以处理的请求就越多,但apache(Unix平台最流行的WEB服务器平台)默认的限制 是不能大于256。如果把这个值设为大于256那么apache(Unix平台最流行的WEB服务器平台)将无法起动。事实上,256对于负载稍重的站点 也是很不够的。在apache(Unix平台最流行的WEB服务器平台)1.3 中这是个硬限制,如果要加大这个值,必须在configure前手工修改源代码树下的src/include/httpd.h,查找256,会发 现#define HARD_SERVER_LIMIT 256这行,把256改为你要增大的值如4000,然后重新编译apache(Unix平台最流行的WEB服务器平台)即可。我想这个方法稍有些经验的 apache(Unix平台最流行的WEB服务器平台)系统管理员都知道,不过我相信在apache(Unix平台最流行的WEB服务器平台)2.0中知 道如何加大这个值的人就不会太多了。
在apache(Unix平台最流行的WEB服务器平台)2.0中新加入了ServerLimit指令,使得无须重编译apache(Unix平台最流行的WEB服务器平台)就可以加大MaxClients。下面是笔者的prefork配置段。

以下为引用的内容:

StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1500
MaxRequestsPerChild 10000

BTW: ServerLimit的最大值是20000,这对于大多数站点是足够了,但如果你一定要再加大的话,那么这个值位于源代码树下的server/mpm/prefork/prefork.c中。里面的
#define DEFAULT_SERVER_LIMIT 256
#define MAX_SERVER_LIMIT 20000

这两行就对应着MaxClients和ServerLimit的限制值。但我相信很少有人可以用到20000的并发连接数。

通过清心醉

apache 修改连接数

refork几乎还是目前的唯一MPM,我在下面主要还是讨论它的工作原理和相关指令调整。查看缺省生成的httpd.conf配置文件,会发现里面包含如下的配置段:
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
prefork的工作原理是这样的:控制进程在最初建立StartServers个子进程后, 为了满足MinSpareServers设置的需要,创建一个进程,等待一秒钟,继续创建第二个,等待一秒钟,继而创建四个,如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止,这也就是预派生(prefork)的由来。这种模式可以使得不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MaxSpareServers 设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill某些多余进程。这个值一般不要设的过大,但如果设的比MinSpareServers小,Apache会自动把它调整为MinSpareServers+1。如果站点负载较大的话,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild设置的是每个子进程可以处理的请求数。每个子进程在处理了MaxRequestsPerChild个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
1. 可防止意外的内存卸漏;
2. 在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值,如果非零的话,笔者认为10000左右是比较合适的。事实上这个值对Apache的性能影响不是很大。
MaxClients 是这些指令中最为重要的一个,它设定的就是Apache可以同时处理的请求,这是对Apache性能影响最大的参数.在我个人看来,缺省的150是远远不够的,如果请求总数已达到这个值(可通过ps –ef|grep httpd|wc –l来确认),那么下面的请求就要排队,直到某个已处理请求完毕。这就是为什么系统资源还剩下很多,而http访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值,虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制是不能大于256。如果把这个值设为大于256那么Apache将无法起动。事实上,256对于负载稍重的站点也是很不够的。在Apache1.3中这是个硬限制,如果要加大这个值,必须在configure前手工修改源代码树下的src/include/httpd.h,查找256,会发现#define HARD_SERVER_LIMIT 256这行,把256改为你要增大的值如4000,然后重新编译Apache即可。我想这个方法稍有些经验的Apache系统管理员都知道,不过我相信在Apache2.0中知道如何加大这个值的人就不会太多了。
在Apache2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段。
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1500
MaxRequestsPerChild 10000
BTW: ServerLimit的最大值是20000,这对于大多数站点是足够了,但如果你一定要再加大的话,那么这个值位于源代码树下的server/mpm/prefork/prefork.c中。里面的
#define DEFAULT_SERVER_LIMIT 256
#define MAX_SERVER_LIMIT 20000
这两行就对应着MaxClients和ServerLimit的限制值。我相信有一些站可以用到20000的并发连接数。
实际操作下:
先修改./apache/conf/httpd.conf文件。
       # vi httpd.conf
       将“#Include conf/extra/httpd-mpm.conf”前面的 # 去掉。
       保存。
  
再修改./apache/conf/extra/httpd-mpm.conf文件。
       # vi httpd-mpm.conf
      找到<IfModule mpm_prefork_module> 这一行
         原:
            <IfModule mpm_prefork_module>
             StartServers         5
             MinSpareServers      5
             MaxSpareServers      10
             MaxClients           150
             MaxRequestsPerChild  0
          </IfModule>       修改后
           <IfModule mpm_prefork_module>
             StartServers         5
             MinSpareServers      5
             MaxSpareServers      10
             ServerLimit          1500
             MaxClients           1000
             MaxRequestsPerChild  0
        

   注意:1、一定要加ServerLimit,并且要在MaxClients前面,且数值要比MaxClient的值大;
         2、重启apache,仅仅/bin/apachectl restart无效,
            需要先apachectl stop 然后再apachectl start

通过清心醉

Linux 简单防DDOS攻击.

执行

#sysctl -a|grep net.ipv4.tcp_max_syn_backlog

在返回的”net.ipv4.tcp_max_syn_backlog=512″中显示 Linux队列的最大半连接容量是512

简单数量的DDOS分布式攻击就可以让网站打不开

可以修改其最大连接限制,如修改为2000;

# sysctl -w net.ipv4.tcp_max_syn_backlog=2000

这样就设置了最大的连接数,不会因为连接数量被占用导致网站打不开.

打开SYN COOKIE功能:

# sysctl -w net.ipv4.tcp_syncookies=1

还可以执行以下指令:

# sysctl -w net.ipv4.tcp_synack_retries=1

Linux中建立TCP连接时,在客户端和服务器之间创建握手过程中,当服务器未收到客户端的确认包时,会重发请求包,一直到超时才将此条目从未连接队列是删除,也就是说半连接存在一定的存活时间,超过这个时间,半连接就会自动断开.半连接存活时间实际上是系统所有重传次数等待的超时时间之和,这个值越大,半连接数占用的Backlog队列的时间就越长,系统能处理的 SYN请求就越少,因此,缩短超时时间就可以有效防御SYN攻击,这可以通过缩小重传超时时间和减少重传次数来实现.在Linux中默认的重传次数为5 次,总超时时间为3分钟

以上指令就是将重传次数改1,有效减少DDOS的攻击造成的服务器崩溃.

因为DDOS基本都是使用”肉鸡”实现TCP攻击,占用服务器资源,很难查找出发起点的IP,但被”肉鸡”的IP还是可以查看的

执行: netstat -atnp

查看当前连接的IP,使用kill命令来杀除

当然也可以记下IP,添加到APAPCHE或者.htaccess,进行拦截.

*********************************************

附加其他iptable指令的其他防御方法:

防止同步包洪水(Sync Flood)
# iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT

也可以写成:
#iptables -A INPUT -p tcp –syn -m limit –limit 1/s -j ACCEPT
–limit 1/s 限制syn并发数每秒1次,可以根据自己的需要修改

防止各种端口扫描
# iptables -A FORWARD -p tcp –tcp-flags SYN,ACK,FIN,RST RST -m limit –limit 1/s -j ACCEPT

Ping洪水攻击(Ping of Death)
# iptables -A FORWARD -p icmp –icmp-type echo-request -m limit –limit 1/s -j ACCEPT

iptables -A FORWARD -p icmp –icmp-type
echo-request -j DROP

**********************************************

针对更多apache查看连接数和并发数的相关方法:

查看apache当前并发访问数:
执行: # netstat -an | grep ESTABLISHED | wc -l
对比httpd.conf中MaxClients的数字差距多少。
查看现有进程数:
# ps aux|grep httpd|wc -l
218
统计httpd进程数,连个请求会启动一个进程,使用于Apache服务器。
以上数据表示Apache能够处理218个并发请求,这个值Apache可根据负载情况自动调整。
#netstat -nat|grep -i “80”|wc -l
netstat -nat会打印系统当前网络链接状态
而grep -i “80”是用来提取与80端口有关的连接的,wc -l进行连接数统计。
最终返回的数字就是当前所有80端口的请求总数。
#netstat -na|grep ESTABLISHED|wc -l
210
netstat -an会打印系统当前网络链接状态,而grep ESTABLISHED 提取出已建立连接的信息。 然后wc -l统计。
最终返回的数字就是当前所有80端口的已建立连接的总数。
netstat -nat||grep ESTABLISHED|wc – 可查看所有建立连接的详细记录
查看Apache的并发请求数及其TCP连接状态:
Linux命令:
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
执行: # ulimit -n 10240
可以将apache连接开启10240 个连接数
通过清心醉

随便写写4

没有懦弱的人,何以衬托出善战的英勇?

没有自私的人,怎能展现出贡献的伟大?

没有失败的填坑,成功怎么能屡屡获胜?

没有黑社会的黑暗,熟知活在健全的法制社会下是种幸福?

没有廉洁清官的心寒,怎知贪官贪图所甚?

相对等却非相等,我们茫然相信眼睛看到的以为那就是真,其实对错是非都在内心转折刹那间 。

想比大周之王武则天,贵为妃时,为己活命,不惜弑己女;如此的懦弱怕死,如此的自私,连自己女儿都保护不了的失败,官庭的黑暗,问世人谁乃第二武王,大唐转周,熟知她为社绩付出的努力背后,是一身的伤痕。

通过清心醉

随便写写3

不要只用仇恨思考问题,不然会降低你的智慧,不要讨厌你的敌人,不然会降低你的判断能力。
转摘曹操名言集;

没有“敌人”的挑战,你永远看不到你的能力;血腥解决事情,只能让你“武”中生有,要知道,聪明之人,懂的“借刀杀人”,也许你血腥之斗能胜,也只为聪明之人的一颗棋子而已。
如哪日你走路上被狗咬,不一定要用咬回狗的方式来报复狗,别失去了本有的理性。否则你永远和你敌人一样,永远不能战胜敌人。

通过清心醉

随便写写2

社会腐败的成长之因,萌芽了法律失效之果;人心贪婪无止尽,歉意之心几人有;民团结,国富强,强国之,权宜重,重则用,用于本,个别官,使国权,不为民,权生钱,更为钱,权压民;权力,用之不当即忘本,钱力,取之有念过无边;社会正走向利益时代,人心正变向个人朝代。
贪是人的死性,倘若舍他人之生死求己一欲之贪者,与魔何以乎?

通过清心醉

随便写写1

人善良是对是错?是好是坏?
以前的自己,喜欢看死人,看着每一个死去的人的脸庞,铭记在心。

人都不能知道另一个人在想什么,所以我强克自己学会换位思想。
把他人的思想强加到自己的感觉里面
从此让我看透每一个人的心
辛酸却强行支撑的、
开心却面无表情的等等。
体会了“他们”的点点滴滴

看他们砍人的时候凶狠无比,其实却可以懂得他们的善良
看被人砍的很无辜,其实更体会的到他们往时的咎由自取

活着的每一个生命,为何不能和睦相处?
比如人要吃肉,必须要杀猪啊,羊啊,鸡鸭等等
其实为的就是自己的生存

人也一样,生存的时候,也许牺牲的不是其他的生命,而是人类

我到底是人是鬼是神?

苍天何苦给我那么多的感觉

真羡慕那些傻子,永远没有这些思想
安静的等待着死亡

但我却好好的活着

体会一滴滴人世的沧桑
更要自作多情的去感受其他人

如果让我受如此的折磨,能改变我的换位感觉的现实社会
那就算消失了,世界能改变,又何尝不是一种补救?

我爱这世界的一切生命,因为都是生死有命
我憎恨这世界的一切,因为有死才有生,创造出如此黑暗的世界

活着的人,好好的活着吧

别真当了奄奄一息的时候,才感觉到活着是种罪过

如果说活着是享受生命,不如说活着是在承受罪过

日子你过的再好,没有体会过人世间的点点滴滴

那或者才是枉费人世走一回

通过清心醉

打造自己的VPS站群四:空间及数据库大小限制

部分可以使用分区的方式来分出各个空间的使用大小。

避免不法分子滥用服务器硬盘数据

这时可以使用LINUX的计划任务

创建一个脚本:

#脚本开始

#!/bin/bash
dir=/home/ww1
size=0
file=`ls $dir`
for i in  `ls -l $dir | awk '{print $5}'`
do
   size=`expr $size + $i`
   if [ $size -ge 102400 ];then
    chattr  +i  $dir
    for  j in `ls $dir`
        do
            chattr +i  /$dir/$j
        done
        fi
done 
#脚本结束

以上方法是限制了100MB的空间的限制,面对不同的需要,只需修改下数值就可以了,然后加入自动任务中 
针对自动任务的使用,请参考:http://www.qingxinzui.com/?p=364

至于数据库,操作比较麻烦,但也是以目录形式显示,以上代码可以针对修改为数据库的目录,具体的作者也没实际操作过。如有更好的实现办法,必定跟上。
通过清心醉

打造自己的VPS站群三:服务器的配置

上文说到了FTP配置不同用户的不同目录,可是就作者的来说,APACHE只认/home/www这个目录为站点

如何设置APACHE,让站点完全站群化呢?

很简单,修改APACHE的配置文件http.conf

文件在:/etc/httpd/conf/httpd.conf

 

<VirtualHost x.x.x.x>
DocumentRoot /home/www   #网站目录
ServerName WWW    # 访问的名称
</VirtualHost>
#下面这个,就是博主从配置内生成多一个站点,x.x.x.x为IP地址
<VirtualHost x.x.x.x.>
DocumentRoot /home/www1
ServerName www.qingxinzui.com
</VirtualHost>
这样就新加了一个站点了,而站点的数据不需要使用SSH远程登陆来传放文件,比如说你做了一个站点,不可能给个SSH的用户给别人吧?这就是FTP的好处。我可以通过user1上传文件到/home/ww1/目录,可是这样没有权限,即网站不能运行,
需要加上这句:
<Directory “/home/ww1”>
Options Indexes FollowSymLinks ExecCGI Includes
AllowOverride All
 Require all granted
</Directory>
这样一个简单的VPS站点就完成了。
通过清心醉

打造自己的VPS站群二:FTP空间的划分

搭配好了服务器环境,就是对空间的划分。

#groupadd ftpusers  创建FTP用户组,

然后创建不同用户的不同目录

比如作者的服务器,网站主目录为:/home/www

然后创建一个文件夹,为另一个用户使用

mkdir  /home/ww1
chmod -R 777 /home/ww1
useradd -d /home/ww1/ -g ftpusers -s /bin/fales user1

//user1为用户名

#修改用户密码
passwd lava
#然后输入你的密码

这样就创建了一个FTP帐户为user1的FTP空间。

根据自己的需求和硬件的支持可以创建N+1个不同的空间。

FTP的用户大家都知道拉,不详细说了,就是提供一个帐号密码给你,让你可以登陆属于你的专署空间,放装你想要的网站文件等等。

 

通过清心醉

打造自己的VPS站群一:了解站群的概念

以VPS做站群为标题,在百度基本上都是广告的多。

首先我们了解下什么是站群:

一台主机/VPS内可以安装多个网站环境,当然在LINUX下,无非还是APACHE+PHP+MYSQL了。 一个APACHE配置下,可以生成无数个站点,比如作者这博客 http:www.qingxinzui.com和XXX…XXX,当然还有部分的二级域创建的论坛等站点,都是单一的VPS里规划出来的。没错,一个服务器/VPS下有多个网站,就是站群了。

至于APACHE+PHP+MYSQL平台的安装,做者有写过:http://www.qingxinzui.com/?p=401

如果实在不懂安装的,建议直接安装LAMP环境。

 

站群的话,数据固然就是分开的,使用过MYSQL的都应该懂的,这个毫无疑问,不同的是网站资料不一样,目录方法的不同而已。划分了的不同的用户文件夹,这就叫空间了。

作者没有类似万网这种后台控制空间,只是可以通过FTP的来区。

通过清心醉

关于长城防火墙对信息过滤的利于弊

为了不违法国家相关法律法规,下文内容只是一点点作者的观点。小小博站,又怎能引起国家的注意。

首先,作者是一名纯自学的计算机从业人员,Win98时就接触了计算机的系统平台。由于是农村家里,都是到了初中毕业后就边工作,边琢磨边学习,一直走到现在的阶段。

随着学习的内容更多、更深,需求的教材越来越多。国内的教材质量,已经远远不够了。

也许有人会说,你那么喜欢国外的东西,你怎么不移民去国外呢,在中国做什么中国人。

知识,是无区域性的分别的。

计算机起源是欧美,核心使用是欧美,长城防火墙却拦截了大部分访问境外的数据。

国家有国家的考虑,很多不法份子在国外乱写我国领导人的坏事,对于这些乱写的脑残货,我就想说雷怎么没把你劈死?

长城防火墙拦截了这些,就不会引起不必要的恶意文章。

可是,做为一名求学者,长城防火墙是否可以设置实名制进行访问登记IP等方法来实现境外网站的登陆。实施信息化跟踪呢?

现在已经是信息化的年代,想想中国发明的火药,到了外国他们造就了枪炮,为什么我们就不能利用国外的IT科技的发达,造就我们自己的IT信息化国家?让更多想求学于信息化技术的人更多的学习空间?

有时想看看代码的学习,更多的在百度搜索,可是很多说的不够全面,部分甚至写的是需要的淘宝买,我要有钱,我还学什么啊?我早就换其他行业或者请人了。国内的IT业因为没有得到开源化,很多都是高手在卖萌,新手在迷漫。导致部分想学习更多的,而且必须境外查找资料的。(比如GOOGLE搜索想学习的资料)会使用翻墙软件等。

就以作者来说,使用自由门翻墙,翻墙了,我能找到我需要的教材,可是,因为使用的是其他地区的第三方软件,弹出好多恶意针对国家的信息,这也属于一种无奈,长城防火墙的工作人员,这些你们也是能猜到的。也是作为一名中国人都不愿看到的。

文章短小,博克简陋,也不可能引起工作人员的注视,可是,这一不争的问题,是否能得到优化?使用更多的实名制的方法来开放部分求学者的追求。

通过清心醉

magento外贸商城之必备插件

reviews_slidebar评分插件:http://connect20.magentocommerce.com/community/Reviews_Sidebar

说明:在分类左侧和产品详细页右侧显示评分的产品,用于站内推广。

ET_IpSecurity IP禁止插件:
http://connect20.magentocommerce.com/community/ET_IpSecurity

说明:一款用于拦截恶意IP的插件,该插件在1.8++的平台上运行不稳定,实施编译后将造成全站崩溃。

支付宝:
http://connect20.magentocommerce.com/community/Cosmo_Community_AlipayPaymentGateway

说明:一种收款方式。

快钱(base版本):
http://connect20.magentocommerce.com/community/Cosmo_Community_99BillPaymentGateway

说明:一种收款方式,由于是base的版本,所以安装的时候需要选择base的安装,方法请参考http://www.qingxinzui.com/?p=392
清除产品对比功能:
http://connect20.magentocommerce.com/community/Wfs_DisableCompare

说明:如果客户在进行产品对比而网络延迟的时候,会不停的“慢”加载,客户如果选择刷新,就会发生404错误页,解决方法就是清除游览器记录即可。但为了保险,如不需要还是屏蔽为好。

通过清心醉

外贸网站屏蔽百度爬虫

做外贸的,很忌讳国内的同行可以查看到自己站点的信息。

同时更不喜欢百度爬重带走索引,增加不必要的流量。

特别是国内同行的恶意竞争。

网上有很多屏蔽百度爬虫的,但要爬虫不遵守robots协议的话,照抓你站点。

使用robots文件的屏蔽方法站长工具就可以查看,但要实现完全屏蔽,可以使用以下方法:

在.htaccess文件中加入可以完全屏蔽

屏蔽内容一:

RewriteEngine on

RewriteCond %{HTTP_USER_AGENT} ^Baiduspider [NC]

RewriteRule .* – [F]

屏蔽内容二:

SetEnvIfNoCase User-Agent “^Baiduspider” bad_bot

<Limit GET POST>

Order Allow,Deny

Allow from all

Deny from env=bad_bot

</Limit>

通过清心醉

.htaccess文件的使用

Apache屏蔽IP的方法已经有了。

不懂的请参考:http://www.qingxinzui.com/?p=500

至于VPS站群又该如何去屏蔽呢?以下是方法。

首先确保Apache服务器配置文件httpd.conf文件里的AllowOverride的参数是否为All。

直接上代码:

<Limit GET HEAD POST>

order allow,deny

# Country: CHINA

# ISO Code: CN

# Total Networks: 1,616

# Total Subnets:  210,789,888

deny from 58.14.0.0/15

deny from 222.249.192.0/18

#

allow from all

</Limit>

该代码添加到.htaccess文件中,然后重启下Apache就可以屏蔽掉以上两个IP段

 

当然,部分用户用了翻墙软件,这样IP就没效果了

这时候可以使用以下代码屏蔽中文游览器

## enable rewrites

Options +FollowSymLinks
RewriteEngine on

RewriteCond %{HTTP:Accept-Language} ^zh-cn.*$ [NC,OR]
RewriteCond %{HTTP:Accept-Language} ^zh.*$ [NC]

RewriteRule ^/?$ http://www.qingxinzui.com [R=301,L]

#301重定向到.

如果直接复制作者的代码无法使用,自行修改下符号哦。

没有不透风的墙,如果遇到非中文版的中国用户翻墙,一样不受屏蔽效果。

如果实在不想,干脆屏蔽所有并设置允许的吧。

通过清心醉

Apache屏蔽IP

对于简单的Apache屏蔽IP的方法,无法就是配置httpd.conf文件

然后在

<Directory  “网站目录”>    </Directory>里写上IP就可以

比如要屏蔽192.168.1.101的IP

<Directory  “你的网站根目录”>

    Options Indexes FollowSymLinks

    AllowOverride None

    Order  deny,allow

    Deny from 192.168.1.101    #这就是屏蔽了。

</Directory>

 

再来说说里面的参数信息:

AllowOverride 有两个参数,分别为All和None

参数为:None时,站点的.htaccess文件不生效

相反参数为:All时,站点的.htaccess文件生效

这里顺便说下.htaccess文件的作用

比如一台VPS,用于做站群,每个网站对IP限制都不同

比如A站点只想禁止192.168.1.111,B站点只想禁止192.168.1.200

这时如果在httpd.conf配置文件把这两个IP禁止掉的话

那么A和B两个站点,192.168.1.111和192.168.1.200两个IP都无法访问。

简单来说,.htaccess文件就是针对单一网站数据进行权限控制。

 

Order deny,allow

Deny from 192.168.1.111

该命令达到了屏蔽了IP的作用。

附上其他常用的命令:

允许所有访问:

Order deny,allow

Allow from All

 

屏蔽所有访问:

Order deny,allow

Deny from All #这里ALL改成屏蔽的IP地址,一样可以屏蔽指定的IP

屏蔽192.168.1IP段:

Order deny,allow

Deny from 192.168.1.123/24

除192.168.1.2IP外的全部屏蔽:

Order deny,allow

Deny from All

Allow from 192.168.1.2

#在这里要特别注意下格式哦,因为第二行已经禁止了所有IP,第三行才允许192.168.1.2这IP访问,如果改错顺序入:

Order deny,allow

Allow from 192.168.1.2

Deny from All

#那这样的效果就是先允许192.168.1.2的IP访问,然后第三行命令又全部屏蔽了,过程式

 

 

通过清心醉

magento分类列表使用评分排序

好的产品客人可以给予评分,只要你的magento有评分的功能,就可以用于分类列表提供用户做排序选择。

一:把文件app/code/core/Mage/Catalog/Block/Product/List.php复制到app/code/local/Mage/Catalog/Block/Product/List.php并打开编辑。

在新的List.php文件里找到下面这一行(大概在86行):

$this->_productCollection = $layer->getProductCollection();

//在这添加以下内容:

$this->_productCollection- >joinField(‘rating_summary’, ‘review_entity_summary’, ‘rating_summary’, ‘entity_pk_value=entity_id’, array(‘entity_type’=>1, ‘store_id’=> Mage::app()->getStore()->getId()), ‘left’);

二:添加一个选项让客户可以选择按评分来排序。

把文件app/code/core/Mage/Catalog/Model/Config.php复制到app/code/local/Mage/Catalog/Model/Config.php并编辑。

在新的Config.php文件里找到下面这一行(大概在298行):

$options = array(

‘position’  => Mage::helper(‘catalog’)->__(‘Position’)

);

把以上代码替换成:

$options = array(

‘position’  => Mage::helper(‘catalog’)->__(‘Position’),

‘rating_summary’ => Mage::helper(‘catalog’)->__(‘Rating’)

);

 

通过清心醉

Magento多级分类URL去掉父目录

Magento去掉多级分类URL

如果一个产品在多个分类里,那么在不同的产品分类里查看magento的分类产品时就会显示父分类的URL,就导致一个产品在多个URL里页面重复.

方法如下:

打开app/code/core/Mage/Catalog/Model/Url.php这个php文件,找到(有两处)代码修改注释为即可:
// if (null === $parentPath) {
// $parentPath = $this->getResource()->getCategoryParentPath($category);
// }
// elseif ($parentPath == ‘/’) {
$parentPath = ”; //注这有两个’;而不是”
// }其实1.8版本过后的版本在系统,配置,分类里也可以设置是否使用父级分类的,可能是因为对核心代码有进行修改,或者没编译的关系.

通过清心醉

magento 显示paypal不支持的货币

修改文件
app/code/core/mage/payment/block/form/Container.php
app/code/core/mage/paypal/model/Standard.php

1.app/code/core/mage/payment/block/form/Container.php
找到函数_canUseMethod 大概在第54行,换成如下代码

protected function _canUseMethod($method)
{
if (!$method->canUseForCountry($this->getQuote()->getBillingAddress()->getCountry())) {
return false;
}

//if (!$method->canUseForCurrency(Mage::app()->getStore()->getBaseCurrencyCode())) {
if (!$method->canUseForCurrency(Mage::app()->getStore()->getCurrentCurrencyCode())) {
return false;
}

/**
* Checking for min/max order total for assigned payment method
*/
$total = $this->getQuote()->getBaseGrandTotal();
$minTotal = $method->getConfigData(‘min_order_total’);
$maxTotal = $method->getConfigData(‘max_order_total’);

if((!empty($minTotal) && ($total  $minTotal)) || (!empty($maxTotal) && ($total > $maxTotal))) {
return false;
}
return true;
}

2.app/code/core/mage/paypal/model/Standard.php
找到函数validate,大概在127行,换成如下代码

public function validate()

{

parent::validate();

//$currency_code = $this->getQuote()->getBaseCurrencyCode();

$currency_code = Mage::app()->getStore()->getCurrentCurrencyCode();

if (!in_array($currency_code,$this->_allowCurrencyCode)) {

Mage::throwException(Mage::helper(‘paypal’)->__(‘Selected currency code (‘.$currency_code.’) is not compatible with PayPal’));

}

return $this;

}

找到函数getStandardCheckoutFormFields,大概在158行,改成如下代码

if ($this->getQuote()->getIsVirtual()) {
$a = $this->getQuote()->getBillingAddress();
$b = $this->getQuote()->getShippingAddress();
} else {
$a = $this->getQuote()->getShippingAddress();
$b = $this->getQuote()->getBillingAddress();
}
/*tweak version
init currency conversion
if currency is not the same as base currency, set convert boolean to true
*/
$currency_code = Mage::app()->getStore()->getCurrentCurrencyCode();

$storeCurrency = Mage::getSingleton(‘directory/currency’)
->load($this->getQuote()->getStoreCurrencyCode());

$bConvert = $currency_code != $this->getQuote()->getBaseCurrencyCode();

$sArr = array(
‘charset’ => self::DATA_CHARSET,
‘business’ => Mage::getStoreConfig(‘paypal/wps/business_account’),
‘return’ => Mage::getUrl(‘paypal/standard/success’,array(‘_secure’ => true)),
‘cancel_return’ => Mage::getUrl(‘paypal/standard/cancel’,array(‘_secure’ => false)),
‘notify_url’ => Mage::getUrl(‘paypal/standard/ipn’),
‘invoice’ => $this->getCheckout()->getLastRealOrderId(),
‘currency_code’ => $currency_code,
‘address_override’ => 1,
‘first_name’ => $a->getFirstname(),
‘last_name’ => $a->getLastname(),
‘address1’ => $a->getStreet(1),
‘address2’ => $a->getStreet(2),
‘city’ => $a->getCity(),
‘state’ => $a->getRegionCode(),
‘country’ => $a->getCountry(),
‘zip’ => $a->getPostcode(),
‘bn’ => ‘Varien_Cart_WPS_US’
);

$logoUrl = Mage::getStoreConfig(‘paypal/wps/logo_url’);
if($logoUrl){
$sArr = array_merge($sArr, array(
‘cpp_header_image’ => $logoUrl
));
}

if($this->getConfigData(‘payment_action’)==self::PAYMENT_TYPE_AUTH){
$sArr = array_merge($sArr, array(
‘paymentaction’ => ‘authorization’
));
}

$transaciton_type = $this->getConfigData(‘transaction_type’);
/*
O=aggregate cart amount to paypal
I=individual items to paypal
*/
if ($transaciton_type==’O’) {
$businessName = Mage::getStoreConfig(‘paypal/wps/business_name’);
$storeName = Mage::getStoreConfig(‘store/system/name’);
$amount = ($a->getBaseSubtotal()+$b->getBaseSubtotal())-($a->getBaseDiscountAmount()+$b->getBaseDiscountAmount());
//convert the amount to the current currency
if ($bConvert) {
$amount = $storeCurrency->convert($amount, $currency_code);
}
$sArr = array_merge($sArr, array(
‘cmd’ => ‘_ext-enter’,
‘redirect_cmd’ => ‘_xclick’,
‘item_name’ => $businessName ? $businessName : $storeName,
‘amount’ => sprintf(‘%.2f’, $amount),
));
$_shippingTax = $this->getQuote()->getShippingAddress()->getBaseTaxAmount();
$_billingTax = $this->getQuote()->getBillingAddress()->getBaseTaxAmount();
$tax = $_shippingTax + $_billingTax;
//convert the amount to the current currency
if ($bConvert) {
$tax = $storeCurrency->convert($tax, $currency_code);
}
$tax = sprintf(‘%.2f’, $tax);
if ($tax>0) {
$sArr = array_merge($sArr, array(
‘tax’ => $tax
));
}

} else {
$sArr = array_merge($sArr, array(
‘cmd’ => ‘_cart’,
‘upload’ => ‘1’,
));
$items = $this->getQuote()->getAllItems();
if ($items) {
$i = 1;
foreach($items as $item){
if ($item->getParentItem()) {
continue;
}
//echo “”; print_r($item->getData()); echo””;
$amount = ($item->getBaseCalculationPrice() – $item->getBaseDiscountAmount());
if ($bConvert) {
$amount = $storeCurrency->convert($amount, $currency_code);
}
$sArr = array_merge($sArr, array(
‘item_name_’.$i => $item->getName(),
‘item_number_’.$i => $item->getSku(),
‘quantity_’.$i => $item->getQty(),
‘amount_’.$i => sprintf(‘%.2f’, $amount),
));
$tax = $item->getBaseTaxAmount();
if($tax>0){
//convert the amount to the current currency
if ($bConvert) {
$tax = $storeCurrency->convert($tax, $currency_code);
}
$sArr = array_merge($sArr, array(
‘tax_’.$i => sprintf(‘%.2f’,$tax/$item->getQty()),
));
}
$i++;
}
}
}

$totalArr = $a->getTotals();
$shipping = $this->getQuote()->getShippingAddress()->getBaseShippingAmount();
if ($shipping>0 && !$this->getQuote()->getIsVirtual()) {
//convert the amount to the current currency
if ($bConvert) {
$shipping = $storeCurrency->convert($shipping, $currency_code);
}
$shipping = sprintf(‘%.2f’, $shipping);

if ($transaciton_type==’O’) {
$sArr = array_merge($sArr, array(
‘shipping’ => $shipping
));
} else {
$shippingTax = $this->getQuote()->getShippingAddress()->getBaseShippingTaxAmount();
//convert the amount to the current currency
if ($bConvert) {
$shippingTax = $storeCurrency->convert($shippingTax, $currency_code);
}
$sArr = array_merge($sArr, array(
‘item_name_’.$i => $totalArr[‘shipping’]->getTitle(),
‘quantity_’.$i => 1,
‘amount_’.$i => sprintf(‘%.2f’,$shipping),
‘tax_’.$i => sprintf(‘%.2f’,$shippingTax),
));
$i++;
}
}

$sReq = ”;
$sReqDebug = ”;
$rArr = array();

foreach ($sArr as $k=>$v) {
/*
replacing & char with and. otherwise it will break the post
*/
$value = str_replace(“&”,”and”,$v);
$rArr[$k] = $value;
$sReq .= ‘&’.$k.’=’.$value;
$sReqDebug .= ‘&’.$k.’=’;
if (in_array($k, $this->_debugReplacePrivateDataKeys)) {
$sReqDebug .= ‘***’;
} else {
$sReqDebug .= $value;
}

}

if ($this->getDebug() && $sReq) {
$sReq = substr($sReq, 1);
$debug = Mage::getModel(‘paypal/api_debug’)
->setApiEndpoint($this->getPaypalUrl())
->setRequestBody($sReq)
->save();
}
return $rArr;

 

通过清心醉

GOOGLE优化关键字网站排名

搜索引擎使用关键字的相关程度来决定网页的先后顺序。例如,如果有人搜索” butterbeans ”,那么一个标题为” The Butterbean Bazaar ”、里面有十余处单词” butterbeans ”的网页,可能就会排在搜索结果顶端;而那种只出现了一两次” butterbeans ”的网站,则排列在稍后的地方;网站上有” beans ”单词的,就排在更后面的地方;只有” beanless ”这样的单词的网站,则根本不会出现在搜索结果中。每个搜索引擎,都有它自己的排列搜索结果的公式,而且它们被作为机密保存起来。但基本规则是,一个网页 出现某个关键字的次数越多,那么,该网页与关键字的相关程度就高,该网页在搜索结果中的排列位置就越靠前。另外,网页标题、章节标题中的关键字,相关程度 更高。

知道了这个规则,很多”聪明人”就在他们的网页上,布置大量” mp3 ”、” free ”之类的热门词汇。有些文章更介绍了诸如”隐形文本”、”隐藏关键字”等提高排名的作弊技巧,这些招数被大量甚至疯狂使用,使搜索引擎的查阅效果大打折 扣。显然,如果大家都这样做,那么,搜索引擎迟早会变得毫无用处。到了某天,说不定不管你搜索什么,得到的总是色情网站。所以,搜索引擎展开了一场反作弊 的斗争。只要它们怀疑你在有意”制造”关键字,那么,就可能取消你的注册。

例如,现在,很多搜索引擎不接受使用”隐形文本”网站的注册。

其实,”关键字”的使用,犹如一把”双刃剑”,一方面,为了使网站在搜索引擎的排名靠前,你的网页应该包含尽量多的关键字,但是另一方面,一旦过 度,你就可能面临取消注册资格的危险。所以,前面我们说,向搜索引擎注册并不是首要任务。真正关键的,除了网站本身要有好的内容、产品或服务及设计效果 外,就是使你的网页与搜索引擎友好相处,说白了,一要适当使用关键字,二要避免”冒犯”搜索引擎,不要使用那些容易让它”误会”的设计技术,例如,框架和 某些动态网页注册。那么,如何使用关键字才算适当呢?

找出人们搜索你的这类网站时,可能使用的所有词汇(关键字),并将它们尽可能地串起来,给你的网站写个简短的描述。例如,如果你要销售 butterbeans (棉豆),并且你已经列出了下面的关键字:

Butterbeans

Beans

Lima beans

Biscuits

Southern cooking

你可以这样写描述:

” We sell butterbeans and lima beans, which taste great with biscuits and other Southern cooking. Free butterbean recipes and a butterbean discussion forum 。”

注意,如何组合重要的关键字(事实上,你的关键字列表可能更长,可以将其中重要的串起来),如何将最重要的那个(如 butterbeans )用上两次。但是,这个描述读起来应该跟普通句子一样,不要只是一个关键字列表。

这个网站描述会用在好几个地方,因此多话一些精力写好它,是值得的。当你向搜索引擎注册的时候,需要填网站描述,当人们搜索到你的网站的时候,这个 描述也会出现,所以,要尽量利用它,吸引人们浏览你的网站,但不要简单使用夸大性的词句。另外,网站描述(或将其修改后)还应该放在 TITLE 标记中。

TITLE 标记位于 HTML 网页的 HEAD 部分。当冲浪者浏览一个网页的时候,它的内容会出现在浏览器最顶端。如果有人将你的网站保存到”书签”( Netscape )或”收藏夹”( IE ), TITLE将作为”书签”名或”收藏”名。 TITLE 标记应该以你网站的正式名称开头,并包括网站简要描述。例如:

< TITLE>The Butterbean Bazaar – We sell butterbeans and lima beans, and offer
free butterbean recipes and a butterbean discussion forum.< /TITLE>

不要将关键字列表放在 TITLE 中,这样做弊大于利。也不要在那里放冗长无用的内容,如” Welcome to the Web Site ”,这纯粹是浪费网络资源。

HEAD 部分还有两个对网站宣传很重要的标记: META DEscriptION 和 META KEYWORDS 标记。某些(但不是所有)搜索引擎,使用这些标记的内容来决定你网站的排列位次。用于 META DEscriptION 标记的规则与 TITLE 的基本上一样。而 META KEYWORDS 标记,就是一个关键字列表,注意,在这里放入太多单词,并没有什么益处,因为,大多数专家都认为,搜索引擎对此只作有限量搜索。因此,挑选出人们真正会用 的关键字,才是有价值的。多数人认为,这些关键字应该小写,并且用逗号或空格分开。

网页上的关键字最重要。但别高兴——必须是普通的、可读的文本,那种将一大堆关键字随便放到网页上的做法,属于作弊行为,将得不到注册。你可以让最重要的关键字在网页出现一到两次,当然,还可以放到网页标题、文章标题中。

 

摘自站长之家.