DeBug:从windows日志追寻到网站程序的性能瓶颈

上文提到,在windows日志中,经常看到这样的错误:

查询处理器用尽了内部资源,无法生成查询计划。这种情况很少出现,只有在查询极其复杂或引用了大量表或分区时才会出现。请简化查询。如果您认为该消息的出现纯属错误,请与客户支持服务部门联系,了解详细信息。

这对于一个拥有十来个二级栏目,每个栏目都是一套独立的程序,并且集中在一个站点的网站来说,找出发生错误的那部分程序,是相当不容易的事情。

第一步,通过日志的来源,确定错误来源于MSSQL SERVER。上文提到,这是使用IN关键词产生的错误描述。并且已经明确,是由于查询的数据量太大,导致资源耗尽还没有得到查询结果。

第二步,通过SQL Server Profiler追踪数据库的查询情况。我把追踪结果存入数据库,然后通过查询Duration数值最大的前100条数据,结果有一个惊人的发现。一条类似这样的查询语句让我震惊了:

[pre]

select * from (select top 1520 articleid,classId,classname,articlemark,articletitle,hits,case smallpic when ” then ‘jnews/images/newslist_26.gif’ else smallpic end as smallpic,description,addtime,author,tag from cms_article where classID=3 and ischeck=1  and articleid in (316577,112553,59078,332886,255516,381339,98365,368853,50991,…..(此处省略一万字以上)

[/pre]

打开项目源代码,查找该查询语句的某些特征字符串,例如:“case smallpic when ” then ‘jnews/images/newslist_26.gif’ else ”,很快找到了相应的函数。

第三步,分析了一下原查询语句的意图,无非是想对符合某些条件的文章进行分页读取。明白了意图,剩下来的工作就是重写这个方法,以相对高效的方式实现相同的任务。利用MSSQL Server 2005之后新增的row_number()属性,将该功能的查询修改成:

[pre]

string ausql = “select * from ( ” +                 “select row_number() over(order by articleid desc) as rownumber,* ” +                 “from cms_article where ischeck = 1 and ” +                 “classid in (select classid from cms_artclass where ” +                 ” classid = ” + classID + ” or parentid = ” + classID +                 ” or parentpath like ‘%,” + classID + “,%’) ” + str + ” ) as t ” +                 “where rownumber between ” + startpage + ” and ” + endpage;

[/pre]

条件中也许会由于使用到LIKE关键词而降低效率,不过该字段类型通常为nvarchar(50)左右,应该在可接受的范围之内。相对原来的查询,显得微不足道了。这从Duration的值就可以看出来。新查询的Duration是700左右,旧查询的某次Duration是5500314!

 

 

Transact-SQL:数据量大是慎重使用IN关键字

使用IN关键字的查询语句效率是非常低下的。不是万不得已,费用不可的情况,千万别用!当数据量巨大时,还可能会产生以下错误:

在 IN 子句中包括数量非常多的值(数以千计)可能会消耗资源并返回错误 8623 或 8632。若要解决这一问题,请将这些项存储于某个表的 IN 列表中。

错误 8623:   查询处理器用尽了内部资源,无法生成查询计划。这种情况很少出现,只有在查询极其复杂或引用了大量表或分区时才会出现。请简化查询。如果您认为该消息的出现纯属错误,请与客户支持服务部门联系,了解详细信息。

错误 8632:   内部错误: 达到了表达式服务限制。请在您的查询中查找潜在的复杂表达式,并尝试简化它们。

参考:http://msdn.microsoft.com/zh-cn/library/ms177682.aspx

解决办法只有一种:修改查询语句,不要用IN语法。

而更麻烦的问题是,当程序相对复杂时,你可能要通过数据库工具找到产生错误的查询语句,然后改善之!

FastCGI设置解决大量php-cgi.exe进程导致服务器堵塞

这几天服务器出现了一个问题,流量不高,但是服务器打开超级慢,往往超时了还没有加载完页面。检查了服务器,发现有大量的php-cgi.exe进程,用netstat查询,发现有大量CLOSE_WAIT的链接。用360检查了连接数,居然达到1500个连接以上!

服务器只有不到5个的php站点,怎么会出现这么多的php-cgi.exe进程呢?程序池中,已经设置了“最大工作进程”为1啦!

经过研究,发现在FastCGI中也有类似的设置。把“最大实例数”由0改成1即可解决问题。可是在流量不高的情况下,站点打开的速度还是不快,不明白是什么原因。

vim快捷键


basic:
↑
←   h   j   k   l   →
↓

:w
write / save
:w {file}       write to file / save as
:wq / ZZ
write and quit / save and quit
:q! / ZQ        force quit / quit without
saving

d{motion}       delete / cut
y{motion}       yank / copy
p
put / paste

cursor -> line:
a               append
after the cursor
A               append after the line
i
insert before the cursor
I               insert before the line
r
replace at the cursor
R               replace the line
s
substitute at the cursor
S               substitute the line
u
undo            CTRL-R      undo the undo
U               undo the
line
v               start visual mode per character
V               start
visual mode line-wise

forward -> backward:
x               delete
characters forward
X               delete characters backward
p
put after the cursor
P               put before the cursor
o
open a line below
O               open a line above

f{char}
find {char} forward
F{char}         find {char} backward
t{char}
till {char} forward
T{char}         till {char} backward
;
next {char} occurrence
,               previous {char}
occurrence

/{pattern}      search {pattern} forward
?{pattern}
search {pattern} backward
n               next {pattern} occurrence
N
previous {pattern} occurrence

motion / word -> WORD:
w
forward to the start of word
W               forward to the start
of WORD
e               forward to the end of word
E               forward
to the end of WORD
b               backward to the start of word
B
backward to the start of WORD
ge              backward to the end of
word
gE              backward to the end of WORD

0               to
the first character of the line
^               to the first non-blank
character of the line
$               to the last character of the
line
g_              to the last non-blank character of the line

d
-> dd -> D:
d{motion}       delete
dd              delete a
line
D               delete to the end of the line
c{motion}
change
cc              change a line
C               change to the end of
the line
y{motion}       yank/copy
yy              yank/copy a line
Y
same as yy, unfortunately we are not in a perfect
world

advanced:
H               High / to first line on the
window
M               Middle / to middle line of the window
L
Low / to last line on the window

:1 / gg         to first line of the
file
:[+/-]{number}  to relative/absolute line number
:$ / G          to
last line of the file

%               find a matching

:s/old/new
substitute once
:s/old/new/g    substitute all on a
line
:%s/old/new/g   substitute all in the file
:%s/old/new/gi  substitute
all in the file, ignore case
:%s/old/new/gn  count occurrence only, do not
substitute
:%s/old/new/gc  substitute all in the file, with
confirmation

:!{cmd}         execute {cmd} with the shell
:!!
repeat last shell command

:w !sudo tee %  save as root

来源:http://forum.ubuntu.org.cn/viewtopic.php?f=68&t=290466

其实记住vim有两个状态就好:插入状态和命令状态。i,进入插入文本状态,ESC,返回命令状态。输入命令前记得先打冒号:

windows7:清理远程桌面连接历史记录

一、清除远程桌面连接下拉地址列表,具体操作:定位注册表到“HKEY_CURRENT_USER\Software\Microsoft \Terminal Server Client\Default”,将右侧所有以“MRU”开头的值删除,如“MR0,MR1,MR2”等

二、清除远程桌面连接主机名和用户名,具体操作:定位注册表到“HKEY_CURRENT_USER\Software\Microsoft \Terminal Server Client\Servers\”,在左侧将其下所有类型为IP地址的项删除。

安全要从细节抓起,共用电脑,更加要注意安全,防止泄露敏感信息。

IIS:释放程序池占用的内存:针对无法正常释放资源的程序

asp.net网站程序设计一个重要的课题就是如何保证资源的释放。作为系统管理员,网站占用太大的系统资源往往是一件让人头疼的问题。这段时间围绕着这个问题,做了多种尝试。

1、修改程序,以保证资源利用率,保证内存的释放。这是治本的办法,但也是最麻烦的办法,因为不但要改动程序,还要通过各种测试,找到不完善的程序。

2、定期重启IIS服务。通过计划任务,定期重启IIS。这种做法是简单的做法,但也是最不靠谱的做法。因为每次重启IIS,所有的网站都无法访问,造成WEB服务不稳定的现象。

3、设定程序池回收触发事件。这个方法应该是最好的解决方法了。给.NET的垃圾回收器添加不同的触发条件,尤其是针对w3wp.exe占用很大的内存无法释放这种情况特别有效。为其中的“专用内存限制”一项设置合理的值,例如500,000KB,当该程序池的物理内存占用量达到这个限制时,垃圾回收器就会启动。

注意,虚拟内存限制最好不要修改,否则可能引发试图验证失败的异常。

经过这样设置,即使程序写得不好,也不会对整个服务器造成影响,最多是CPU的负担重一点而已。当然,要从根本上解决,还是要把程序设计好。

修改系统管理员帐号导致数据库作业失败的解决方法

前几天为了加强服务器安全,把默认管理员账号Administrator改掉了。之后发现所有数据库的作业都失败了。检查日志发现下面的错误:

消息
[298] SQLServer 错误:  15404,无法获取有关 Windows NT 组/用户 ‘WIN-SFFO8TI8JLB\Administrator’ 的信息,错误代码 0×534。 [SQLSTATE 42000] (ConnIsLoginSysAdmin)

很明显是修改了管理员账号引起的。解决方法肯定是修改执行数据库作业的账号了。在这里修改,打开sql代理的作业,修改其“所有者”:

本想改成修改后的新名称,但是保存不了,迫不得已只能使用sa代替了。然后再执行作业就顺利完成了。有文章称要删除作业重新建立,貌似没有这个必要。

软件环境:windows server 2008 r2 / sql server 2008 r2

 

3条措施防止服务器管理员账号被暴力破解

上文《安全日志:成千上万的“审核失败”,帐户登录失败日志》提到,服务器管理员账号有可能正在被暴力破解中,作为服务器管理员,我不能坐以待毙,不知了以下3道防线:

1,修改管理员账号。把管理员账号administrator修改成一个不常见的用户名,例如lazyperson,并使用比较复杂的密码,最好包含有大小写英文、数字、特殊符号,10个字符以上。

2,修改远程桌面服务端口。远程桌面服务端口默认是3389,在连接时不需要提供。这给黑客提供了方便,只需要知道服务器IP就可以不断地尝试用户密码了。于是我把这个端口改掉了。

3,关闭135端口。今天上服务器查看,发现有人正在尝试管理员的账号密码,于是用命令netstat -ano查看,发现对应IP连接的是135端口。找了一下资料,说是RPC服务所使用的端口。服务我决定先不去管它,用防火墙先把135端口封掉试试看吧!

查看日志,暂时没有再生成相应的“安全”日志了,不知道是攻击者暂停了还是防火墙其效果了。过两天再验证一下吧!

安全日志:成千上万的“审核失败”,帐户登录失败日志

近日来发现服务器的“安全”日志中有大量的“审核失败”日志。常规信息是这样的:

帐户登录失败。

主题:
安全 ID:  NULL SID
帐户名:  -
帐户域:  -
登录 ID:  0×0

登录类型:   3

登录失败的帐户:
安全 ID:  NULL SID
帐户名:  administrator
帐户域:  7LW-2641557B0EF

失败信息:
失败原因:  未知用户名或密码错误。
状态:   0xc000006d
子状态:  0xc0000064

进程信息:
调用方进程 ID: 0×0
调用方进程名: -

网络信息:
工作站名: 7LW-2641557B0EF
源网络地址: 211.144.76.14
源端口:  3625

详细身份验证信息:
登录进程:  NtLmSsp
身份验证数据包: NTLM
传递服务: -
数据包名(仅限 NTLM): -
密钥长度:  0

登录请求失败时在尝试访问的计算机上生成此事件。

“主题”字段指明本地系统上请求登录的帐户。这通常是一个服务(例如 Server 服务)或本地进程(例如 Winlogon.exe 或 Services.exe)。

“登录类型”字段指明发生的登录的种类。最常见的类型是 2 (交互式)和 3 (网络)。

“进程信息”字段表明系统上的哪个帐户和进程请求了登录。

“网络信息”字段指明远程登录请求来自哪里。“工作站名”并非总是可用,而且在某些情况下可能会留为空白。

“身份验证信息”字段提供关于此特定登录请求的详细信息。
-“传递服务”指明哪些直接服务参与了此登录请求。
-“数据包名”指明在 NTLM 协议之间使用了哪些子协议。
-“密钥长度”指明生成的会话密钥的长度。如果没有请求会话密钥,则此字段为 0。

除此之外,“系统”日志中还经常有这样的错误日志:

RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接。

这两者,有联系吗?是不是有人通过远程桌面暴力破解服务器的管理员账号呢?为了解决这个安全隐患,我采取了《3条措施防止服务器管理员账号被暴力破解》。

windows server 2008 修改远程桌面端口的方法

1、首先增加防火墙的入站规则,打开新的TCP端口,例如:8000

2、修改注册表,有两个地方:

找到:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp] 双击右边 PortNumber——点十进制——更改值为:8000 —— 点确定。

然后找到: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp] 双击右边 PortNumber——点十进制——更改值为:8000 —— 点确定。

重启服务器让修改生效。使用非默认端口连接到远程桌面的写法:

IP:端口号,例如:202.116.64.6:8000

Pages: 1 2 3 4 5 6 7 8 9 10 ...192 193 194 Next